From nobody Wed Jun 17 04:16:12 2026 Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 31C8C223DE7; Fri, 12 Jun 2026 01:16:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=114.242.206.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781226986; cv=none; b=drPYvy2+eHXdsDUdB0dkcWSevlECksxVgkwTKUzHYlnWGXM/dnIJ+SM+VCqsiMcoTCAhy0YTVOiGtmbu2nSPGjl5y0WTrc8V3AuZdAjjv8LkzecGsK0X/mDP9qztQfhMitSYZKE+cb1J5ap6IRmfSydqxZSFBtRCqzkLCXDFlRY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781226986; c=relaxed/simple; bh=sJkufXQGE0sZOoLABtQrGctwRbHzGSr281jZzn4mS6c=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=AZBwHd3Fl3N6gTdnPyBnk/Fa12d0mFCgnYuqiS/w3L3VLstaq/+RpM+VLa2MN2Jk4RI+iB7CFiivAVwJpZ0gUd1weLrzaSquFBkG1Pf222wu8eFMkfBAXmcnBqwxej06cCqnNWF7REQl9iEDfViPhiapYRc6Jvhqo2NONw2gEO8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=loongson.cn; spf=pass smtp.mailfrom=loongson.cn; arc=none smtp.client-ip=114.242.206.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=loongson.cn Received: from loongson.cn (unknown [113.200.148.30]) by gateway (Coremail) with SMTP id _____8DxhunlXStqtk0TAA--.51125S3; Fri, 12 Jun 2026 09:16:21 +0800 (CST) Received: from linux.localdomain (unknown [113.200.148.30]) by front1 (Coremail) with SMTP id qMiowJCxvsLgXStqTHCjAA--.47687S3; Fri, 12 Jun 2026 09:16:20 +0800 (CST) From: Tiezhu Yang To: Huacai Chen , Hengqi Chen Cc: loongarch@lists.linux.dev, bpf@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 1/3] LoongArch: Implement CONFIG_THREAD_INFO_IN_TASK Date: Fri, 12 Jun 2026 09:16:14 +0800 Message-ID: <20260612011616.27771-2-yangtiezhu@loongson.cn> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20260612011616.27771-1-yangtiezhu@loongson.cn> References: <20260612011616.27771-1-yangtiezhu@loongson.cn> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qMiowJCxvsLgXStqTHCjAA--.47687S3 X-CM-SenderInfo: p1dqw3xlh2x3gn0dqz5rrqw2lrqou0/ X-Coremail-Antispam: 1Uk129KBj9fXoWfJw47KFyxXry7Zw4rWr1UXFc_yoW8Aw4fKo WavF4qyr18Jw4UWa98trnxtFW5Xr1qkrWDZ3y2vanxGa1xJ347WryUGw13tFy3Xa4kWa9r C34agw4vvas7trn3l-sFpf9Il3svdjkaLaAFLSUrUUUUjb8apTn2vfkv8UJUUUU8wcxFpf 9Il3svdxBIdaVrn0xqx4xG64xvF2IEw4CE5I8CrVC2j2Jv73VFW2AGmfu7bjvjm3AaLaJ3 UjIYCTnIWjp_UUUYj7kC6x804xWl14x267AKxVWUJVW8JwAFc2x0x2IEx4CE42xK8VAvwI 8IcIk0rVWrJVCq3wAFIxvE14AKwVWUXVWUAwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xG Y2AK021l84ACjcxK6xIIjxv20xvE14v26r1I6r4UM28EF7xvwVC0I7IYx2IY6xkF7I0E14 v26r4j6F4UM28EF7xvwVC2z280aVAFwI0_Gr0_Cr1l84ACjcxK6I8E87Iv6xkF7I0E14v2 6r4j6r4UJwAS0I0E0xvYzxvE52x082IY62kv0487Mc804VCY07AIYIkI8VC2zVCFFI0UMc 02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7IYx2IY67AKxVWUtVWrXwAv7VC2z280aVAF wI0_Gr0_Cr1lOx8S6xCaFVCjc4AY6r1j6r4UM4x0Y48IcxkI7VAKI48JMxAIw28IcxkI7V AKI48JMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCj r7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVWUAVWUtwCIc40Y0x0EwIxGrwCI42IY6x IIjxv20xvE14v26r1I6r4UMIIF0xvE2Ix0cI8IcVCY1x0267AKxVW8JVWxJwCI42IY6xAI w20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Jr0_Gr1lIxAIcVC2z280aVCY1x 0267AKxVW8JVW8JrUvcSsGvfC2KfnxnUUI43ZEXa7IU8l38UUUUUU== Content-Type: text/plain; charset="utf-8" Like other architectures such as x86, arm64, riscv, powerpc and s390, select THREAD_INFO_IN_TASK for LoongArch to move thread_info off the stack into task_struct. This follows modern kernel standards and also makes the system more secure. With this patch, thread_info is included in task_struct at an offset of 0 instead of being placed at the bottom of the kernel stack. Thus, the $tp register points to both thread_info and task_struct. To support this, introduce a per-CPU variable cpu_tasks to store the pointer to the current task_struct. This decouples the recovery of the $tp register from the stack pointer during exception entry. Then initialize cpu_tasks for the primary and secondary CPUs during arch-specific setup and SMP boot paths. To eliminate the dangerous windows during the early initialization where the cpu_tasks remains uninitialized, set_current() is invoked as early as possible in both setup_arch() (right after unwind_init) and start_secondary() (right after cpu_probe). This ensures the $tp recovery barrier is armed in case any early boot exceptions or kernel panics occur. Modify SAVE_SOME and handle_syscall to restore the $tp register from cpu_tasks, and also use the la_abs absolute addressing for cpu_tasks access in assembly to bypass the relocation limits within exception handling sections. By advancing the preservation of u0 in SAVE_SOME, reuse the PERCPU_BASE_KS value in u0 for the cpu_tasks calculation, effectively eliminating a duplicate csrrd instruction execution on SMP platforms. Update and to fully support the CONFIG_THREAD_INFO_IN_TASK feature. Remove the obsolete next_ti argument from __switch_to(), which shifts the remaining arguments ahead in the calling convention (sched_ra from a3 to a2, and sched_cfa from a4 to a3). Under the new configuration, __switch_to() now directly derives the thread pointer ($tp) from the next task_struct pointer in a1. To preserve the optimal and clean "move tp, a1" path for 64-bit kernels, the thread pointer ($tp) is assigned directly from a1 in the core path. For 32-bit kernels, where a1 carries a 2000-byte structural pointer bias at entry, an explicit adjustment "PTR_ADDI tp, tp, -TASK_STRUCT_OFFSET" is introduced at the function exit. In the context of __switch_to(), local interrupts are disabled, and the kernel is in a critical switching phase where handling any synchronous exception is practically impossible and prohibited. If any synchronous exception or watchpoint does trigger in this narrow window, it constitutes a fatal double fault and the kernel is expected to die/panic immediately anyway. Therefore, the temporary biased value in $tp is safe and acceptable here. Additionally, evaluate the stack lookup as a single load instruction "LONG_LPTR t0, a1, (TASK_STACK - TASK_STRUCT_OFFSET)", this perfectly satisfies both 32-bit and 64-bit kernels. Using the "next" pointer in a1 as the base register, rather than $tp, effectively unchains the data dependency (RAW hazard) from the preceding move instruction, maximizing the instruction-level parallelism and superscalar execution efficiency while naturally adapting the structural shift. With CONFIG_THREAD_INFO_IN_TASK enabled, the kernel stack life cycle is decoupled from task_struct and can be freed concurrently. Currently, show_stacktrace() reads raw stack data via __get_addr() and subsequently calls show_backtrace() to unwind the frame, without holding any reference to the target task's stack. If show_stacktrace() is called on a concurrently exiting task, it could attempt to read from a freed or reallocated kernel stack. This introduces a severe use-after-free (UAF) read risk or kernel panics. Wrap the entire stack inspection process inside show_stacktrace() with a try_get_task_stack() and put_task_stack() pair. This ensures the task stack remains pinned safely during both the raw stack data dump loop and the subsequent stack unwinding phase. Also, ensure that the task pointer is initialized to "current" early if it is NULL, so that try_get_task_stack() always operates on a valid task reference. Signed-off-by: Tiezhu Yang --- .../core/thread-info-in-task/arch-support.txt | 2 +- arch/loongarch/Kconfig | 1 + arch/loongarch/include/asm/current.h | 31 +++++++++++++++++++ arch/loongarch/include/asm/smp.h | 3 +- arch/loongarch/include/asm/stackframe.h | 9 ++++-- arch/loongarch/include/asm/switch_to.h | 6 ++-- arch/loongarch/include/asm/thread_info.h | 10 ------ arch/loongarch/kernel/asm-offsets.c | 6 ++-- arch/loongarch/kernel/entry.S | 7 +++-- arch/loongarch/kernel/head.S | 18 ++++++----- arch/loongarch/kernel/process.c | 2 ++ arch/loongarch/kernel/relocate.c | 2 +- arch/loongarch/kernel/setup.c | 1 + arch/loongarch/kernel/smp.c | 6 ++-- arch/loongarch/kernel/switch.S | 14 +++++---- arch/loongarch/kernel/traps.c | 8 +++++ 16 files changed, 88 insertions(+), 38 deletions(-) create mode 100644 arch/loongarch/include/asm/current.h diff --git a/Documentation/features/core/thread-info-in-task/arch-support.t= xt b/Documentation/features/core/thread-info-in-task/arch-support.txt index f3d744c76061..e26efdfbb6b4 100644 --- a/Documentation/features/core/thread-info-in-task/arch-support.txt +++ b/Documentation/features/core/thread-info-in-task/arch-support.txt @@ -12,7 +12,7 @@ | arm64: | ok | | csky: | TODO | | hexagon: | TODO | - | loongarch: | TODO | + | loongarch: | ok | | m68k: | TODO | | microblaze: | TODO | | mips: | TODO | diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig index 606597da46b8..cf8d3cf91814 100644 --- a/arch/loongarch/Kconfig +++ b/arch/loongarch/Kconfig @@ -210,6 +210,7 @@ config LOONGARCH select SYSCTL_ARCH_UNALIGN_NO_WARN select SYSCTL_EXCEPTION_TRACE select SWIOTLB if 64BIT + select THREAD_INFO_IN_TASK select TRACE_IRQFLAGS_SUPPORT select USE_PERCPU_NUMA_NODE_ID select USER_STACKTRACE_SUPPORT diff --git a/arch/loongarch/include/asm/current.h b/arch/loongarch/include/= asm/current.h new file mode 100644 index 000000000000..fa4fb7987075 --- /dev/null +++ b/arch/loongarch/include/asm/current.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __ASM_LOONGARCH_CURRENT_H +#define __ASM_LOONGARCH_CURRENT_H + +#include + +#ifndef __ASSEMBLER__ + +#include + +struct task_struct; + +DECLARE_PER_CPU(struct task_struct *, cpu_tasks); + +register struct task_struct *current_thread_pointer __asm__("$tp"); + +static __always_inline struct task_struct *get_current(void) +{ + return current_thread_pointer; +} + +#define current get_current() + +static __always_inline void set_current(struct task_struct *task) +{ + __this_cpu_write(cpu_tasks, task); +} + +#endif /* __ASSEMBLER__ */ + +#endif /* __ASM_LOONGARCH_CURRENT_H */ diff --git a/arch/loongarch/include/asm/smp.h b/arch/loongarch/include/asm/= smp.h index 3a47f52959a8..761cc0016df8 100644 --- a/arch/loongarch/include/asm/smp.h +++ b/arch/loongarch/include/asm/smp.h @@ -82,7 +82,8 @@ struct seq_file; =20 struct secondary_data { unsigned long stack; - unsigned long thread_info; + unsigned long task; + unsigned long offset; }; extern struct secondary_data cpuboot_data; =20 diff --git a/arch/loongarch/include/asm/stackframe.h b/arch/loongarch/inclu= de/asm/stackframe.h index ecc8e50fffa8..b031152e0fc8 100644 --- a/arch/loongarch/include/asm/stackframe.h +++ b/arch/loongarch/include/asm/stackframe.h @@ -191,10 +191,15 @@ andi t0, t0, 0x3 /* extract pplv bit */ beqz t0, 9f =20 - LONG_LI tp, ~_THREAD_MASK - and tp, tp, sp cfi_st u0, PT_R21, \docfi csrrd u0, PERCPU_BASE_KS + + la_abs t1, cpu_tasks +#ifdef CONFIG_SMP + LONG_ADD t1, t1, u0 +#endif + LONG_L tp, t1, 0 + 9: #ifdef CONFIG_KGDB li.w t0, CSR_CRMD_WE diff --git a/arch/loongarch/include/asm/switch_to.h b/arch/loongarch/includ= e/asm/switch_to.h index 5b225aff3ba2..07a4c5909779 100644 --- a/arch/loongarch/include/asm/switch_to.h +++ b/arch/loongarch/include/asm/switch_to.h @@ -15,7 +15,6 @@ struct task_struct; * __switch_to - switch execution of a task * @prev: The task previously executed. * @next: The task to begin executing. - * @next_ti: task_thread_info(next). * @sched_ra: __schedule return address. * @sched_cfa: __schedule call frame address. * @@ -23,7 +22,7 @@ struct task_struct; * the context of next. Returns prev. */ extern asmlinkage struct task_struct *__switch_to(struct task_struct *prev, - struct task_struct *next, struct thread_info *next_ti, + struct task_struct *next, void *sched_ra, void *sched_cfa); =20 /* @@ -37,7 +36,8 @@ do { \ lose_fpu_inatomic(1, prev); \ lose_lbt_inatomic(1, prev); \ hw_breakpoint_thread_switch(next); \ - (last) =3D __switch_to(prev, next, task_thread_info(next), \ + set_current(next); \ + (last) =3D __switch_to(prev, next, \ __builtin_return_address(0), __builtin_frame_address(0)); \ } while (0) =20 diff --git a/arch/loongarch/include/asm/thread_info.h b/arch/loongarch/incl= ude/asm/thread_info.h index 4d7117fcdc78..41eabe4fb647 100644 --- a/arch/loongarch/include/asm/thread_info.h +++ b/arch/loongarch/include/asm/thread_info.h @@ -22,7 +22,6 @@ * must also be changed */ struct thread_info { - struct task_struct *task; /* main task structure */ unsigned long flags; /* low level flags */ unsigned long tp_value; /* thread pointer */ __u32 cpu; /* current CPU */ @@ -37,20 +36,11 @@ struct thread_info { */ #define INIT_THREAD_INFO(tsk) \ { \ - .task =3D &tsk, \ .flags =3D _TIF_FIXADE, \ .cpu =3D 0, \ .preempt_count =3D INIT_PREEMPT_COUNT, \ } =20 -/* How to get the thread information struct from C. */ -register struct thread_info *__current_thread_info __asm__("$tp"); - -static inline struct thread_info *current_thread_info(void) -{ - return __current_thread_info; -} - register unsigned long current_stack_pointer __asm__("$sp"); =20 #endif /* !__ASSEMBLER__ */ diff --git a/arch/loongarch/kernel/asm-offsets.c b/arch/loongarch/kernel/as= m-offsets.c index 2cc953f113ac..453b176fa2d1 100644 --- a/arch/loongarch/kernel/asm-offsets.c +++ b/arch/loongarch/kernel/asm-offsets.c @@ -70,7 +70,7 @@ static void __used output_task_defines(void) { COMMENT("LoongArch task_struct offsets."); OFFSET(TASK_STATE, task_struct, __state); - OFFSET(TASK_THREAD_INFO, task_struct, stack); + OFFSET(TASK_STACK, task_struct, stack); OFFSET(TASK_FLAGS, task_struct, flags); OFFSET(TASK_MM, task_struct, mm); OFFSET(TASK_PID, task_struct, pid); @@ -84,7 +84,6 @@ static void __used output_task_defines(void) static void __used output_thread_info_defines(void) { COMMENT("LoongArch thread_info offsets."); - OFFSET(TI_TASK, thread_info, task); OFFSET(TI_FLAGS, thread_info, flags); OFFSET(TI_TP_VALUE, thread_info, tp_value); OFFSET(TI_CPU, thread_info, cpu); @@ -267,7 +266,8 @@ static void __used output_smpboot_defines(void) { COMMENT("Linux smp cpu boot offsets."); OFFSET(CPU_BOOT_STACK, secondary_data, stack); - OFFSET(CPU_BOOT_TINFO, secondary_data, thread_info); + OFFSET(CPU_BOOT_TASK, secondary_data, task); + OFFSET(CPU_BOOT_OFFSET, secondary_data, offset); BLANK(); } #endif diff --git a/arch/loongarch/kernel/entry.S b/arch/loongarch/kernel/entry.S index b53d333a7c42..53bce27f516b 100644 --- a/arch/loongarch/kernel/entry.S +++ b/arch/loongarch/kernel/entry.S @@ -67,8 +67,11 @@ SYM_CODE_START(handle_syscall) #endif =20 move u0, t0 - LONG_LI tp, ~_THREAD_MASK - and tp, tp, sp + la_abs t1, cpu_tasks +#ifdef CONFIG_SMP + LONG_ADD t1, t1, u0 +#endif + LONG_L tp, t1, 0 =20 move a0, sp bl do_syscall diff --git a/arch/loongarch/kernel/head.S b/arch/loongarch/kernel/head.S index 4eed7bc312a8..ec67faab907b 100644 --- a/arch/loongarch/kernel/head.S +++ b/arch/loongarch/kernel/head.S @@ -74,10 +74,11 @@ SYM_CODE_START(kernel_entry) # kernel entry point /* GPR21 used for percpu base (runtime), initialized as 0 */ move u0, zero =20 - la.pcrel tp, init_thread_union - /* Set the SP after an empty pt_regs. */ - PTR_LI sp, (_THREAD_SIZE - PT_SIZE) - PTR_ADD sp, sp, tp + la.pcrel tp, init_task + la.pcrel t0, init_stack + PTR_LI t1, _THREAD_SIZE + PTR_ADD t0, t0, t1 + PTR_ADDI sp, t0, -PT_SIZE set_saved_sp sp, t0, t1 =20 #ifdef CONFIG_RELOCATABLE @@ -86,8 +87,10 @@ SYM_CODE_START(kernel_entry) # kernel entry point =20 #ifdef CONFIG_RANDOMIZE_BASE /* Repoint the sp into the new kernel */ - PTR_LI sp, (_THREAD_SIZE - PT_SIZE) - PTR_ADD sp, sp, tp + LONG_LPTR t0, tp, TASK_STACK + PTR_LI t1, _THREAD_SIZE + PTR_ADD t0, t0, t1 + PTR_ADDI sp, t0, -PT_SIZE set_saved_sp sp, t0, t1 =20 /* Jump to the new kernel: new_pc =3D current_pc + random_offset */ @@ -128,7 +131,8 @@ SYM_CODE_START(smpboot_entry) #endif la.pcrel t0, cpuboot_data ld.d sp, t0, CPU_BOOT_STACK - ld.d tp, t0, CPU_BOOT_TINFO + ld.d tp, t0, CPU_BOOT_TASK + ld.d u0, t0, CPU_BOOT_OFFSET =20 bl start_secondary ASM_BUG() diff --git a/arch/loongarch/kernel/process.c b/arch/loongarch/kernel/proces= s.c index 5505fc355e1b..0116a7befab0 100644 --- a/arch/loongarch/kernel/process.c +++ b/arch/loongarch/kernel/process.c @@ -54,6 +54,8 @@ #include #include =20 +DEFINE_PER_CPU(struct task_struct *, cpu_tasks); + #ifdef CONFIG_STACKPROTECTOR #include unsigned long __stack_chk_guard __read_mostly; diff --git a/arch/loongarch/kernel/relocate.c b/arch/loongarch/kernel/reloc= ate.c index 4b61a9632a98..2a42874e5eb7 100644 --- a/arch/loongarch/kernel/relocate.c +++ b/arch/loongarch/kernel/relocate.c @@ -313,7 +313,7 @@ unsigned long __init relocate_kernel(void) reloc_offset +=3D random_offset; =20 /* The current thread is now within the relocated kernel */ - __current_thread_info =3D RELOCATED_KASLR(__current_thread_info); + current_thread_pointer =3D RELOCATED_KASLR(current_thread_pointer); =20 update_reloc_offset(&reloc_offset, random_offset); } diff --git a/arch/loongarch/kernel/setup.c b/arch/loongarch/kernel/setup.c index 839b23edee87..369262117c63 100644 --- a/arch/loongarch/kernel/setup.c +++ b/arch/loongarch/kernel/setup.c @@ -593,6 +593,7 @@ void __init setup_arch(char **cmdline_p) { cpu_probe(); unwind_init(); + set_current(current); =20 init_environ(); efi_init(); diff --git a/arch/loongarch/kernel/smp.c b/arch/loongarch/kernel/smp.c index 64a048f1b880..fd7b4abf0f3e 100644 --- a/arch/loongarch/kernel/smp.c +++ b/arch/loongarch/kernel/smp.c @@ -400,8 +400,9 @@ void loongson_boot_secondary(int cpu, struct task_struc= t *idle) pr_info("Booting CPU#%d...\n", cpu); =20 entry =3D __pa_symbol((unsigned long)&smpboot_entry); - cpuboot_data.stack =3D (unsigned long)__KSTK_TOS(idle); - cpuboot_data.thread_info =3D (unsigned long)task_thread_info(idle); + cpuboot_data.stack =3D (unsigned long)task_pt_regs(idle); + cpuboot_data.task =3D (unsigned long)idle; + cpuboot_data.offset =3D per_cpu_offset(cpu); =20 csr_mail_send(entry, cpu_logical_map(cpu), 0); =20 @@ -663,6 +664,7 @@ asmlinkage void start_secondary(void) set_my_cpu_offset(per_cpu_offset(cpu)); =20 cpu_probe(); + set_current(current); constant_clockevent_init(); loongson_init_secondary(); =20 diff --git a/arch/loongarch/kernel/switch.S b/arch/loongarch/kernel/switch.S index f377d8f5c51a..d6e0d05d6fd3 100644 --- a/arch/loongarch/kernel/switch.S +++ b/arch/loongarch/kernel/switch.S @@ -12,7 +12,7 @@ =20 /* * task_struct *__switch_to(task_struct *prev, task_struct *next, - * struct thread_info *next_ti, void *sched_ra, void *sched_cfa) + * void *sched_ra, void *sched_cfa) */ .align 5 SYM_FUNC_START(__switch_to) @@ -24,8 +24,8 @@ SYM_FUNC_START(__switch_to) LONG_SPTR t1, a0, (THREAD_CSRPRMD - TASK_STRUCT_OFFSET) =20 cpu_save_nonscratch a0 - LONG_SPTR a3, a0, (THREAD_SCHED_RA - TASK_STRUCT_OFFSET) - LONG_SPTR a4, a0, (THREAD_SCHED_CFA - TASK_STRUCT_OFFSET) + LONG_SPTR a2, a0, (THREAD_SCHED_RA - TASK_STRUCT_OFFSET) + LONG_SPTR a3, a0, (THREAD_SCHED_CFA - TASK_STRUCT_OFFSET) =20 #if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_SMP) la t7, __stack_chk_guard @@ -33,11 +33,12 @@ SYM_FUNC_START(__switch_to) LONG_SPTR t8, t7, 0 #endif =20 - move tp, a2 + move tp, a1 cpu_restore_nonscratch a1 =20 - li.w t0, _THREAD_SIZE - PTR_ADD t0, t0, tp + LONG_LPTR t0, a1, (TASK_STACK - TASK_STRUCT_OFFSET) + PTR_LI t1, _THREAD_SIZE + PTR_ADD t0, t0, t1 set_saved_sp t0, t1, t2 =20 LONG_LPTR t1, a1, (THREAD_CSRPRMD - TASK_STRUCT_OFFSET) @@ -45,6 +46,7 @@ SYM_FUNC_START(__switch_to) =20 #ifdef CONFIG_32BIT PTR_ADDI a0, a0, -TASK_STRUCT_OFFSET + PTR_ADDI tp, tp, -TASK_STRUCT_OFFSET #endif jr ra SYM_FUNC_END(__switch_to) diff --git a/arch/loongarch/kernel/traps.c b/arch/loongarch/kernel/traps.c index 5d49b742e3bf..776523747ea3 100644 --- a/arch/loongarch/kernel/traps.c +++ b/arch/loongarch/kernel/traps.c @@ -107,6 +107,12 @@ static void show_stacktrace(struct task_struct *task, unsigned long stackdata; unsigned long *sp =3D (unsigned long *)regs->regs[3]; =20 + if (!task) + task =3D current; + + if (!try_get_task_stack(task)) + return; + printk("%sStack :", loglvl); i =3D 0; while ((unsigned long) sp & (PAGE_SIZE - 1)) { @@ -129,6 +135,8 @@ static void show_stacktrace(struct task_struct *task, } pr_cont("\n"); show_backtrace(task, regs, loglvl, user); + + put_task_stack(task); } =20 void show_stack(struct task_struct *task, unsigned long *sp, const char *l= oglvl) --=20 2.42.0 From nobody Wed Jun 17 04:16:12 2026 Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by smtp.subspace.kernel.org (Postfix) with ESMTP id E8C861F151C; Fri, 12 Jun 2026 01:16:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=114.242.206.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781226986; cv=none; b=oUx/ZhvZ9V8ZhbKt0P3uLl7xe6oW5fjmkdFbPDQHKmXRkVAumemnZpusH+HU1MEAmB4qTNjHvqAmDQe0YnbjHNtN5HGxfneTP0m+xyj9ts9u4rvDSYUmXrve8gz6DVR/An6dpF0jJF+1sIy003Z5SPEM4dlPH2ILm+988gaeCJQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781226986; c=relaxed/simple; bh=Bo0BHYJ0tHSmpC59lQMtEt4KfHXhD8Eh07x0FPHBtV8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=RTw32kNYsELJIm+MuhCPwzRkYMw6sAJgdBtr/1A6sxZz9ASy0QMRz2HRZummn9YTJLh9XIbp4v35E5ppiREtZShKTd0OzM9kU0eV47sA9prDVCIQJyBLKTJ6DLZCgyV1EOIlHqgabmYQfsSqt8r4ng/pz86xfOMDM9Lvit2gQtQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=loongson.cn; spf=pass smtp.mailfrom=loongson.cn; arc=none smtp.client-ip=114.242.206.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=loongson.cn Received: from loongson.cn (unknown [113.200.148.30]) by gateway (Coremail) with SMTP id _____8BxzsDmXStquk0TAA--.27749S3; Fri, 12 Jun 2026 09:16:22 +0800 (CST) Received: from linux.localdomain (unknown [113.200.148.30]) by front1 (Coremail) with SMTP id qMiowJCxvsLgXStqTHCjAA--.47687S4; Fri, 12 Jun 2026 09:16:21 +0800 (CST) From: Tiezhu Yang To: Huacai Chen , Hengqi Chen Cc: loongarch@lists.linux.dev, bpf@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 2/3] LoongArch: BPF: Inline bpf_get_current_task{_btf}() helpers Date: Fri, 12 Jun 2026 09:16:15 +0800 Message-ID: <20260612011616.27771-3-yangtiezhu@loongson.cn> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20260612011616.27771-1-yangtiezhu@loongson.cn> References: <20260612011616.27771-1-yangtiezhu@loongson.cn> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qMiowJCxvsLgXStqTHCjAA--.47687S4 X-CM-SenderInfo: p1dqw3xlh2x3gn0dqz5rrqw2lrqou0/ X-Coremail-Antispam: 1Uk129KBj93XoW7tr43KFy8tF4DXw4DXryDXFc_yoW8KFyDpF 4UAr1Ykr4DX34ftrWxJw4DZr1ayaykGry7WFy5K3ySka1fXrnYqr1fK3W3JF95ArW8ZF1f Z39FyrsY9F1DAagCm3ZEXasCq-sJn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7ZEXa sCq-sGcSsGvfJ3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU 0xBIdaVrnRJUUUk0b4IE77IF4wAFF20E14v26r1j6r4UM7CY07I20VC2zVCF04k26cxKx2 IYs7xG6rWj6s0DM7CIcVAFz4kK6r126r13M28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48v e4kI8wA2z4x0Y4vE2Ix0cI8IcVAFwI0_Gr0_Xr1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI 0_Gr0_Cr1l84ACjcxK6I8E87Iv67AKxVW8JVWxJwA2z4x0Y4vEx4A2jsIEc7CjxVAFwI0_ Gr0_Gr1UM2AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6xkI12xvs2x26I8E6xACxx1l5I 8CrVACY4xI64kE6c02F40Ex7xfMcIj6xIIjxv20xvE14v26r1q6rW5McIj6I8E87Iv67AK xVW8JVWxJwAm72CE4IkC6x0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41l42xK82IYc2Ij64 vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s026x8G jcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r126r1DMIIYrxkI7VAKI48JMIIF0xvE2I x0cI8IcVAFwI0_Gr0_Xr1lIxAIcVC0I7IYx2IY6xkF7I0E14v26r4j6F4UMIIF0xvE42xK 8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVW8JVWxJwCI42IY6I8E87Iv6xkF7I 0E14v26r4j6r4UJbIYCTnIWIevJa73UjIFyTuYvjxUco7KUUUUU Content-Type: text/plain; charset="utf-8" The pointer to task_struct is always available in the $tp register, the calls to bpf_get_current_task() and bpf_get_current_task_btf() can be inlined into a single move instruction. (1) Here is the sample test.c: #include #include SEC("raw_tp/sys_enter") long test_task(void *ctx) { return (long)bpf_get_current_task(); } char _license[] SEC("license") =3D "GPL"; (2) Here are the test steps: sudo yum install libbpf-devel kernel-devel bpftool clang -target bpf -O2 -c test.c -o test.o sudo sysctl -w net.core.bpf_jit_enable=3D1 sudo bpftool prog show name test_task sudo rm -f /sys/fs/bpf/test_task sudo bpftool prog load test.o /sys/fs/bpf/test_task ID=3D$(sudo bpftool prog show pinned /sys/fs/bpf/test_task | grep -oE '^[= 0-9]+') sudo bpftool prog dump jited id $ID (3) Here are the test results: Before: 6 instructions ... 64: lu12i.w $t1, 1093 68: ori $t1, $t1, 3320 6c: lu32i.d $t1, 0 70: lu52i.d $t1, $t1, -1792 74: jirl $ra, $t1, 0 78: move $a5, $a0 ... After: 1 instruction ... 64: move $a5, $tp ... This is similar with commit 2bb138cb20a6 ("bpf, arm64: Inline bpf_get_current_task/_btf() helpers"). Signed-off-by: Tiezhu Yang --- arch/loongarch/net/bpf_jit.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c index 24913dc7f4e8..b93b67d22c26 100644 --- a/arch/loongarch/net/bpf_jit.c +++ b/arch/loongarch/net/bpf_jit.c @@ -1147,6 +1147,13 @@ static int build_insn(const struct bpf_insn *insn, s= truct jit_ctx *ctx, bool ext =20 /* function call */ case BPF_JMP | BPF_CALL: + /* Implement helper call to bpf_get_current_task/_btf() inline */ + if (insn->src_reg =3D=3D 0 && (insn->imm =3D=3D BPF_FUNC_get_current_tas= k || + insn->imm =3D=3D BPF_FUNC_get_current_task_btf)) { + move_reg(ctx, regmap[BPF_REG_0], LOONGARCH_GPR_TP); + break; + } + ret =3D bpf_jit_get_func_addr(ctx->prog, insn, extra_pass, &func_addr, &func_addr_fixed); if (ret < 0) @@ -2367,3 +2374,14 @@ bool bpf_jit_supports_subprog_tailcalls(void) { return true; } + +bool bpf_jit_inlines_helper_call(s32 imm) +{ + switch (imm) { + case BPF_FUNC_get_current_task: + case BPF_FUNC_get_current_task_btf: + return true; + default: + return false; + } +} --=20 2.42.0 From nobody Wed Jun 17 04:16:12 2026 Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by smtp.subspace.kernel.org (Postfix) with ESMTP id A795730566C; Fri, 12 Jun 2026 01:16:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=114.242.206.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781226986; cv=none; b=dsacEjxK0zBTu3vNCl51xbrvMbmfEFBIZOsEd0BFvKMCqBdT4XxceiDzihpQGxNkiw3vvVV2Y3yKF+YOETWj9ymO9GX8gSR7LbhvmwRZJMtGgdTt7prao55jEiiovzK1s6dnoR6XubnyffF8211/9NenL3yiSrwT1w/9XMPM1+o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781226986; c=relaxed/simple; bh=3nTdHJdjlXmAp/wNFCBcxKPU++qEyD5ygE8fXLT4UjY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=qmS4nVYv0IfEp2wsq2U3MdcPilusyBoD8DRkNOu0p7xuIjMezTbL2rrFSjnMRjrlLBD3Ong6SHXWtFsqUoBGOpRtUdDEUw5iGUUt5uavwP5ltrtmJpXYxjh4VvsN+5Fx2vYSs1Ss7EJX8LfXBknhoxstWQ2vh4l9Ut7iycekLs8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=loongson.cn; spf=pass smtp.mailfrom=loongson.cn; arc=none smtp.client-ip=114.242.206.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=loongson.cn Received: from loongson.cn (unknown [113.200.148.30]) by gateway (Coremail) with SMTP id _____8Cx3enmXStqvk0TAA--.51083S3; Fri, 12 Jun 2026 09:16:22 +0800 (CST) Received: from linux.localdomain (unknown [113.200.148.30]) by front1 (Coremail) with SMTP id qMiowJCxvsLgXStqTHCjAA--.47687S5; Fri, 12 Jun 2026 09:16:22 +0800 (CST) From: Tiezhu Yang To: Huacai Chen , Hengqi Chen Cc: loongarch@lists.linux.dev, bpf@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 3/3] LoongArch: BPF: Inline bpf_get_smp_processor_id() helper Date: Fri, 12 Jun 2026 09:16:16 +0800 Message-ID: <20260612011616.27771-4-yangtiezhu@loongson.cn> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20260612011616.27771-1-yangtiezhu@loongson.cn> References: <20260612011616.27771-1-yangtiezhu@loongson.cn> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qMiowJCxvsLgXStqTHCjAA--.47687S5 X-CM-SenderInfo: p1dqw3xlh2x3gn0dqz5rrqw2lrqou0/ X-Coremail-Antispam: 1Uk129KBj93XoW7CrykWw4UurW7JFW8ZF1xXrc_yoW5Jr1UpF 4UCrsIkr4DWa4FqFWxJr4kZryYqws5Wry3GFyYgayak3Z7Zry5tr1fKw13tFn5Ar409a4x Z390krsYkF4UXagCm3ZEXasCq-sJn29KB7ZKAUJUUUU5529EdanIXcx71UUUUU7KY7ZEXa sCq-sGcSsGvfJ3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU 0xBIdaVrnRJUUUk0b4IE77IF4wAFF20E14v26r1j6r4UM7CY07I20VC2zVCF04k26cxKx2 IYs7xG6rWj6s0DM7CIcVAFz4kK6r1q6r4UM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48v e4kI8wA2z4x0Y4vE2Ix0cI8IcVAFwI0_Gr0_Xr1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI 0_Gr0_Cr1l84ACjcxK6I8E87Iv67AKxVW8JVWxJwA2z4x0Y4vEx4A2jsIEc7CjxVAFwI0_ Gr0_Gr1UM2AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6xkI12xvs2x26I8E6xACxx1l5I 8CrVACY4xI64kE6c02F40Ex7xfMcIj6xIIjxv20xvE14v26r1q6rW5McIj6I8E87Iv67AK xVW8JVWxJwAm72CE4IkC6x0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41l42xK82IYc2Ij64 vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s026x8G jcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r126r1DMIIYrxkI7VAKI48JMIIF0xvE2I x0cI8IcVAFwI0_Gr0_Xr1lIxAIcVC0I7IYx2IY6xkF7I0E14v26r4j6F4UMIIF0xvE42xK 8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVW8JVWxJwCI42IY6I8E87Iv6xkF7I 0E14v26r4j6r4UJbIYCTnIWIevJa73UjIFyTuYvjxUoxR6UUUUU Content-Type: text/plain; charset="utf-8" The pointer to thread_info is always available in the $tp register, the call to bpf_get_smp_processor_id() can be inlined into a single load instruction. (1) Here is the sample test.c: #include #include SEC("raw_tp/sys_enter") int test_cpuid(void *ctx) { return bpf_get_smp_processor_id(); } char _license[] SEC("license") =3D "GPL"; (2) Here are the test steps: sudo yum install libbpf-devel kernel-devel bpftool clang -target bpf -O2 -c test.c -o test.o sudo sysctl -w net.core.bpf_jit_enable=3D1 sudo bpftool prog show name test_cpuid sudo rm -f /sys/fs/bpf/test_cpuid sudo bpftool prog load test.o /sys/fs/bpf/test_cpuid ID=3D$(sudo bpftool prog show pinned /sys/fs/bpf/test_cpuid | grep -oE '^= [0-9]+') sudo bpftool prog dump jited id $ID (3) Here are the test results: Before: 6 instructions ... 64: lu12i.w $t1, 1213 68: ori $t1, $t1, 1680 6c: lu32i.d $t1, 0 70: lu52i.d $t1, $t1, -1792 74: jirl $ra, $t1, 0 78: move $a5, $a0 ... After: 1 instruction ... 64: ld.wu $a5, $tp, 16 ... This is similar with commit 2ddec2c80b44 ("riscv, bpf: inline bpf_get_smp_processor_id()"). Signed-off-by: Tiezhu Yang --- arch/loongarch/net/bpf_jit.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c index b93b67d22c26..4f2493c549f1 100644 --- a/arch/loongarch/net/bpf_jit.c +++ b/arch/loongarch/net/bpf_jit.c @@ -5,6 +5,7 @@ * Copyright (C) 2022 Loongson Technology Corporation Limited */ #include +#include #include "bpf_jit.h" =20 #define LOONGARCH_MAX_REG_ARGS 8 @@ -1154,6 +1155,12 @@ static int build_insn(const struct bpf_insn *insn, s= truct jit_ctx *ctx, bool ext break; } =20 + /* Implement helper call to bpf_get_smp_processor_id() inline */ + if (insn->src_reg =3D=3D 0 && insn->imm =3D=3D BPF_FUNC_get_smp_processo= r_id) { + emit_insn(ctx, ldwu, regmap[BPF_REG_0], LOONGARCH_GPR_TP, TI_CPU); + break; + } + ret =3D bpf_jit_get_func_addr(ctx->prog, insn, extra_pass, &func_addr, &func_addr_fixed); if (ret < 0) @@ -2380,6 +2387,7 @@ bool bpf_jit_inlines_helper_call(s32 imm) switch (imm) { case BPF_FUNC_get_current_task: case BPF_FUNC_get_current_task_btf: + case BPF_FUNC_get_smp_processor_id: return true; default: return false; --=20 2.42.0