* [PATCH v1 1/1] x86/fred: Fix init_task thread stack pointer initialization
@ 2024-03-01 8:40 Xin Li (Intel)
2024-03-01 13:15 ` Brian Gerst
0 siblings, 1 reply; 5+ messages in thread
From: Xin Li (Intel) @ 2024-03-01 8:40 UTC (permalink / raw)
To: linux-kernel; +Cc: tglx, mingo, bp, dave.hansen, x86, hpa, brgerst
As TOP_OF_KERNEL_STACK_PADDING is defined as 0 on x86_64, no one noticed
it's missing in the calculation of the .sp field in INIT_THREAD until it
is defined to 16 with CONFIG_X86_FRED=y.
Subtract TOP_OF_KERNEL_STACK_PADDING from the .sp field of INIT_THREAD.
Fixes: 65c9cc9e2c14 ("x86/fred: Reserve space for the FRED stack frame")
Fixes: 3adee777ad0d ("x86/smpboot: Remove initial_stack on 64-bit")
Reported-by: kernel test robot <oliver.sang@intel.com>
Closes: https://lore.kernel.org/oe-lkp/202402262159.183c2a37-lkp@intel.com
Signed-off-by: Xin Li (Intel) <xin@zytor.com>
---
arch/x86/include/asm/processor.h | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 26620d7642a9..17fe81998ce4 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -664,8 +664,10 @@ static __always_inline void prefetchw(const void *x)
#else
extern unsigned long __end_init_task[];
-#define INIT_THREAD { \
- .sp = (unsigned long)&__end_init_task - sizeof(struct pt_regs), \
+#define INIT_THREAD { \
+ .sp = (unsigned long)&__end_init_task - \
+ TOP_OF_KERNEL_STACK_PADDING - \
+ sizeof(struct pt_regs), \
}
extern unsigned long KSTK_ESP(struct task_struct *task);
base-commit: e13841907b8fda0ae0ce1ec03684665f578416a8
--
2.44.0
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH v1 1/1] x86/fred: Fix init_task thread stack pointer initialization 2024-03-01 8:40 [PATCH v1 1/1] x86/fred: Fix init_task thread stack pointer initialization Xin Li (Intel) @ 2024-03-01 13:15 ` Brian Gerst 2024-03-02 4:17 ` Xin Li 0 siblings, 1 reply; 5+ messages in thread From: Brian Gerst @ 2024-03-01 13:15 UTC (permalink / raw) To: Xin Li (Intel); +Cc: linux-kernel, tglx, mingo, bp, dave.hansen, x86, hpa On Fri, Mar 1, 2024 at 3:41 AM Xin Li (Intel) <xin@zytor.com> wrote: > > As TOP_OF_KERNEL_STACK_PADDING is defined as 0 on x86_64, no one noticed > it's missing in the calculation of the .sp field in INIT_THREAD until it > is defined to 16 with CONFIG_X86_FRED=y. > > Subtract TOP_OF_KERNEL_STACK_PADDING from the .sp field of INIT_THREAD. > > Fixes: 65c9cc9e2c14 ("x86/fred: Reserve space for the FRED stack frame") > Fixes: 3adee777ad0d ("x86/smpboot: Remove initial_stack on 64-bit") > Reported-by: kernel test robot <oliver.sang@intel.com> > Closes: https://lore.kernel.org/oe-lkp/202402262159.183c2a37-lkp@intel.com > Signed-off-by: Xin Li (Intel) <xin@zytor.com> > --- > arch/x86/include/asm/processor.h | 6 ++++-- > 1 file changed, 4 insertions(+), 2 deletions(-) > > diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h > index 26620d7642a9..17fe81998ce4 100644 > --- a/arch/x86/include/asm/processor.h > +++ b/arch/x86/include/asm/processor.h > @@ -664,8 +664,10 @@ static __always_inline void prefetchw(const void *x) > #else > extern unsigned long __end_init_task[]; > > -#define INIT_THREAD { \ > - .sp = (unsigned long)&__end_init_task - sizeof(struct pt_regs), \ > +#define INIT_THREAD { \ > + .sp = (unsigned long)&__end_init_task - \ > + TOP_OF_KERNEL_STACK_PADDING - \ > + sizeof(struct pt_regs), \ > } > > extern unsigned long KSTK_ESP(struct task_struct *task); > There is another spot in head_64.S that also needs this offset: /* Set up the stack for verify_cpu() */ leaq (__end_init_task - PTREGS_SIZE)(%rip), %rsp Brian Gerst ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v1 1/1] x86/fred: Fix init_task thread stack pointer initialization 2024-03-01 13:15 ` Brian Gerst @ 2024-03-02 4:17 ` Xin Li 2024-03-02 13:20 ` Brian Gerst 0 siblings, 1 reply; 5+ messages in thread From: Xin Li @ 2024-03-02 4:17 UTC (permalink / raw) To: Brian Gerst; +Cc: linux-kernel, tglx, mingo, bp, dave.hansen, x86, hpa On 3/1/2024 5:15 AM, Brian Gerst wrote: > On Fri, Mar 1, 2024 at 3:41 AM Xin Li (Intel) <xin@zytor.com> wrote: > There is another spot in head_64.S that also needs this offset: I checked all references to __end_init_task before sending out this patch, and I doubt we need to make more similar changes. First of all, "movq TASK_threadsp(%rcx), %rsp" you added in 3adee777ad0d ("x86/smpboot: Remove initial_stack on 64-bit") is exactly what we need to set up %rsp for the init task. > /* Set up the stack for verify_cpu() */ > leaq (__end_init_task - PTREGS_SIZE)(%rip), %rsp As the comment says, it's a _temporary_ stack for calling verify_cpu() (but only for BSP, as APs use a different bring up stack), at which stage the concept of "task" has not formed. I'm thinking maybe it's better to do: /* Set up the stack for verify_cpu() */ leaq __end_init_task(%rip), %rsp Previously it was "leaq (__end_init_task - FRAME_SIZE)(%rip), %rsp", but the kernel unwinder goes up only to secondary_startup_64_no_verify() after the new way you introduced to set up %rsp for the init task, and it seems to me that there is no point to subtract FRAME_SIZE or PTREGS_SIZE. On the other hand, TOP_OF_KERNEL_STACK_PADDING is required for x86_32, but probably not for x86_64 (defined as 0 before FRED). The most important usage of TOP_OF_KERNEL_STACK_PADDING is to get the pt_regs pointer for a task, i.e., task_pt_regs(task), which assumes a fixed offset from the top of a task stack, but also limits the space that could be used by future hardware above the pt_regs structure. Thus I prefer to limit the usage of TOP_OF_KERNEL_STACK_PADDING on x86_64. Thanks! Xin ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v1 1/1] x86/fred: Fix init_task thread stack pointer initialization 2024-03-02 4:17 ` Xin Li @ 2024-03-02 13:20 ` Brian Gerst 2024-03-04 3:42 ` Xin Li 0 siblings, 1 reply; 5+ messages in thread From: Brian Gerst @ 2024-03-02 13:20 UTC (permalink / raw) To: Xin Li; +Cc: linux-kernel, tglx, mingo, bp, dave.hansen, x86, hpa On Fri, Mar 1, 2024 at 11:18 PM Xin Li <xin@zytor.com> wrote: > > On 3/1/2024 5:15 AM, Brian Gerst wrote: > > On Fri, Mar 1, 2024 at 3:41 AM Xin Li (Intel) <xin@zytor.com> wrote: > > There is another spot in head_64.S that also needs this offset: > > I checked all references to __end_init_task before sending out this > patch, and I doubt we need to make more similar changes. > > First of all, "movq TASK_threadsp(%rcx), %rsp" you added in > 3adee777ad0d ("x86/smpboot: Remove initial_stack on 64-bit") is exactly > what we need to set up %rsp for the init task. > > > /* Set up the stack for verify_cpu() */ > > leaq (__end_init_task - PTREGS_SIZE)(%rip), %rsp > > As the comment says, it's a _temporary_ stack for calling verify_cpu() > (but only for BSP, as APs use a different bring up stack), at which > stage the concept of "task" has not formed. I'm thinking maybe it's > better to do: > > /* Set up the stack for verify_cpu() */ > leaq __end_init_task(%rip), %rsp > > Previously it was "leaq (__end_init_task - FRAME_SIZE)(%rip), %rsp", > but the kernel unwinder goes up only to secondary_startup_64_no_verify() > after the new way you introduced to set up %rsp for the init task, and > it seems to me that there is no point to subtract FRAME_SIZE or > PTREGS_SIZE. > > On the other hand, TOP_OF_KERNEL_STACK_PADDING is required for x86_32, > but probably not for x86_64 (defined as 0 before FRED). The most > important usage of TOP_OF_KERNEL_STACK_PADDING is to get the pt_regs > pointer for a task, i.e., task_pt_regs(task), which assumes a fixed > offset from the top of a task stack, but also limits the space that > could be used by future hardware above the pt_regs structure. Thus I > prefer to limit the usage of TOP_OF_KERNEL_STACK_PADDING on x86_64. The point is to keep consistency with other kernel threads, which have the pt_regs area cleared (see copy_thread()). In particular, the CS field can't have junk in it or else user_mode(regs) could return the wrong result. So the stack needs to start below pt_regs, or we need to explicitly zero pt_regs later. Ideally, the load from thread->sp should just shift RSP by phys_base, pointing to the same memory location in the virtual mapping. Brian Gerst ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v1 1/1] x86/fred: Fix init_task thread stack pointer initialization 2024-03-02 13:20 ` Brian Gerst @ 2024-03-04 3:42 ` Xin Li 0 siblings, 0 replies; 5+ messages in thread From: Xin Li @ 2024-03-04 3:42 UTC (permalink / raw) To: Brian Gerst; +Cc: linux-kernel, tglx, mingo, bp, dave.hansen, x86, hpa On 3/2/2024 5:20 AM, Brian Gerst wrote: > On Fri, Mar 1, 2024 at 11:18 PM Xin Li <xin@zytor.com> wrote: >> >> On 3/1/2024 5:15 AM, Brian Gerst wrote: >>> On Fri, Mar 1, 2024 at 3:41 AM Xin Li (Intel) <xin@zytor.com> wrote: >>> There is another spot in head_64.S that also needs this offset: >> >> I checked all references to __end_init_task before sending out this >> patch, and I doubt we need to make more similar changes. >> >> First of all, "movq TASK_threadsp(%rcx), %rsp" you added in >> 3adee777ad0d ("x86/smpboot: Remove initial_stack on 64-bit") is exactly >> what we need to set up %rsp for the init task. >> >>> /* Set up the stack for verify_cpu() */ >>> leaq (__end_init_task - PTREGS_SIZE)(%rip), %rsp >> >> As the comment says, it's a _temporary_ stack for calling verify_cpu() >> (but only for BSP, as APs use a different bring up stack), at which >> stage the concept of "task" has not formed. I'm thinking maybe it's >> better to do: >> >> /* Set up the stack for verify_cpu() */ >> leaq __end_init_task(%rip), %rsp >> >> Previously it was "leaq (__end_init_task - FRAME_SIZE)(%rip), %rsp", >> but the kernel unwinder goes up only to secondary_startup_64_no_verify() >> after the new way you introduced to set up %rsp for the init task, and >> it seems to me that there is no point to subtract FRAME_SIZE or >> PTREGS_SIZE. >> >> On the other hand, TOP_OF_KERNEL_STACK_PADDING is required for x86_32, >> but probably not for x86_64 (defined as 0 before FRED). The most >> important usage of TOP_OF_KERNEL_STACK_PADDING is to get the pt_regs >> pointer for a task, i.e., task_pt_regs(task), which assumes a fixed >> offset from the top of a task stack, but also limits the space that >> could be used by future hardware above the pt_regs structure. Thus I >> prefer to limit the usage of TOP_OF_KERNEL_STACK_PADDING on x86_64. > > The point is to keep consistency with other kernel threads, which have > the pt_regs area cleared (see copy_thread()). In particular, the CS > field can't have junk in it or else user_mode(regs) could return the > wrong result. So the stack needs to start below pt_regs, or we need > to explicitly zero pt_regs later. Okay, I will add TOP_OF_KERNEL_STACK_PADDING to the spot in arch/x86/kernel/head_64.S, plus another spot in arch/x86/xen/xen-head.S. However, I still think it would be better to not have TOP_OF_KERNEL_STACK_PADDING in these spots, instead we should explicitly zero pt_regs later; any *implicit* protocol is NOT welcome. I will find a timer later to check with the x86 maintainers :) > Ideally, the load from thread->sp should just shift RSP by phys_base, > pointing to the same memory location in the virtual mapping. I prefer to do this explicitly as what's done now; it may be easier to understand for future kernel developers. Thanks! Xin ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2024-03-04 3:43 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2024-03-01 8:40 [PATCH v1 1/1] x86/fred: Fix init_task thread stack pointer initialization Xin Li (Intel) 2024-03-01 13:15 ` Brian Gerst 2024-03-02 4:17 ` Xin Li 2024-03-02 13:20 ` Brian Gerst 2024-03-04 3:42 ` Xin Li
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®