Re: [PATCH v1 1/3] LoongArch: Implement CONFIG_THREAD_INFO_IN_TASK
From: bot+bpf-ci
Date: Mon Jun 08 2026 - 07:19:23 EST
> diff --git a/arch/loongarch/kernel/switch.S b/arch/loongarch/kernel/switch.S
> index f377d8f5c51a..33a10221d73a 100644
> --- a/arch/loongarch/kernel/switch.S
> +++ b/arch/loongarch/kernel/switch.S
> @@ -12,7 +12,7 @@
>
> /*
> * 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)
For context, the 32-bit path biases a1 at function entry:
arch/loongarch/kernel/switch.S:__switch_to() {
#ifdef CONFIG_32BIT
PTR_ADDI a0, a0, TASK_STRUCT_OFFSET
PTR_ADDI a1, a1, TASK_STRUCT_OFFSET
#endif
...
}
so on 32-bit a1 holds (task_struct + TASK_STRUCT_OFFSET). This bias lets the
THREAD_* field accesses encoded as (FIELD - TASK_STRUCT_OFFSET) fit the 12-bit
signed load/store immediate range.
> @@ -33,11 +33,12 @@ SYM_FUNC_START(__switch_to)
> LONG_SPTR t8, t7, 0
> #endif
>
> - move tp, a2
> + move tp, a1
> cpu_restore_nonscratch a1
On 32-bit, does this leave $tp biased by TASK_STRUCT_OFFSET?
The old code set $tp from a2 (next_ti), which was an unbiased thread_info
pointer. The new code sets $tp from a1, and on 32-bit a1 was biased by
+TASK_STRUCT_OFFSET at entry. a0 is un-biased before return:
arch/loongarch/kernel/switch.S:__switch_to() {
...
#ifdef CONFIG_32BIT
PTR_ADDI a0, a0, -TASK_STRUCT_OFFSET
#endif
jr ra
}
but a1 is never un-biased, so $tp would hold (task_struct + TASK_STRUCT_OFFSET).
Under THREAD_INFO_IN_TASK, get_current() reads $tp directly as the raw
task_struct pointer with no offset compensation:
arch/loongarch/include/asm/current.h {
register struct task_struct *current_thread_pointer __asm__("$tp");
static __always_inline struct task_struct *get_current(void)
{
return current_thread_pointer;
}
}
The exception-entry paths (SAVE_SOME and handle_syscall) restore $tp from
cpu_tasks, which set_current() populates with the raw, unbiased task pointer:
arch/loongarch/include/asm/switch_to.h:set_current() {
__this_cpu_write(cpu_tasks, task);
...
}
so everywhere except the scheduler path $tp holds the raw task_struct.
After __switch_to() returns into __schedule(), would every current->field
access on 32-bit then dereference (task_struct + TASK_STRUCT_OFFSET) until the
next exception entry reloads $tp from cpu_tasks?
The commit message says the patch "correctly neutralizes the structural
pointer bias on 32-bit platforms while cleanly falling back to 0 on 64-bit
systems." That appears to apply to the new
LONG_LPTR t0, tp, (TASK_STACK - TASK_STRUCT_OFFSET)
load, but the move tp, a1 itself still stores the biased pointer into the live
current-task register.
THREAD_INFO_IN_TASK is selected unconditionally for LoongArch (no if 64BIT in
arch/loongarch/Kconfig), and CONFIG_32BIT (LA32R/LA32S) is a selectable kernel
type, so the 32-bit path is real, supported code.
Would something like
move tp, a1
#ifdef CONFIG_32BIT
PTR_ADDI tp, tp, -TASK_STRUCT_OFFSET
#endif
be needed here, or some other un-biasing of $tp on 32-bit?
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/27132522999