Skip to content

Commit 22aafe3

Browse files
author
Ingo Molnar
committed
x86/fpu: Remove init_task FPU state dependencies, add debugging warning for PF_KTHREAD tasks
init_task's FPU state initialization was a bit of a hack: __x86_init_fpu_begin = .; . = __x86_init_fpu_begin + 128*PAGE_SIZE; __x86_init_fpu_end = .; But the init task isn't supposed to be using the FPU context in any case, so remove the hack and add in some debug warnings. As Linus noted in the discussion, the init task (and other PF_KTHREAD tasks) *can* use the FPU via kernel_fpu_begin()/_end(), but they don't need the context area because their FPU use is not preemptible or reentrant, and they don't return to user-space. Signed-off-by: Ingo Molnar <mingo@kernel.org> Cc: Andy Lutomirski <luto@kernel.org> Cc: Brian Gerst <brgerst@gmail.com> Cc: Chang S. Bae <chang.seok.bae@intel.com> Cc: Fenghua Yu <fenghua.yu@intel.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Uros Bizjak <ubizjak@gmail.com> Link: https://lore.kernel.org/r/20250409211127.3544993-8-mingo@kernel.org
1 parent c360bdc commit 22aafe3

File tree

5 files changed

+17
-14
lines changed

5 files changed

+17
-14
lines changed

arch/x86/include/asm/processor.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,11 @@ struct thread_struct {
516516
#endif
517517
};
518518

519-
#define x86_task_fpu(task) ((struct fpu *)((void *)(task) + sizeof(*(task))))
519+
#ifdef CONFIG_X86_DEBUG_FPU
520+
extern struct fpu *x86_task_fpu(struct task_struct *task);
521+
#else
522+
# define x86_task_fpu(task) ((struct fpu *)((void *)(task) + sizeof(*(task))))
523+
#endif
520524

521525
/*
522526
* X86 doesn't need any embedded-FPU-struct quirks:

arch/x86/kernel/fpu/core.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,16 @@ static DEFINE_PER_CPU(bool, in_kernel_fpu);
5151
*/
5252
DEFINE_PER_CPU(struct fpu *, fpu_fpregs_owner_ctx);
5353

54+
#ifdef CONFIG_X86_DEBUG_FPU
55+
struct fpu *x86_task_fpu(struct task_struct *task)
56+
{
57+
if (WARN_ON_ONCE(task->flags & PF_KTHREAD))
58+
return NULL;
59+
60+
return (void *)task + sizeof(*task);
61+
}
62+
#endif
63+
5464
/*
5565
* Can we use the FPU in kernel mode with the
5666
* whole "kernel_fpu_begin/end()" sequence?
@@ -599,11 +609,9 @@ int fpu_clone(struct task_struct *dst, unsigned long clone_flags, bool minimal,
599609
*
600610
* This is safe because task_struct size is a multiple of cacheline size.
601611
*/
602-
struct fpu *src_fpu = x86_task_fpu(current);
603-
struct fpu *dst_fpu = x86_task_fpu(dst);
612+
struct fpu *dst_fpu = (void *)dst + sizeof(*dst);
604613

605614
BUILD_BUG_ON(sizeof(*dst) % SMP_CACHE_BYTES != 0);
606-
BUG_ON(!src_fpu);
607615

608616
/* The new task's FPU state cannot be valid in the hardware. */
609617
dst_fpu->last_cpu = -1;
@@ -666,7 +674,6 @@ int fpu_clone(struct task_struct *dst, unsigned long clone_flags, bool minimal,
666674
if (update_fpu_shstk(dst, ssp))
667675
return 1;
668676

669-
trace_x86_fpu_copy_src(src_fpu);
670677
trace_x86_fpu_copy_dst(dst_fpu);
671678

672679
return 0;

arch/x86/kernel/fpu/init.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ static void fpu__init_cpu_generic(void)
3838
/* Flush out any pending x87 state: */
3939
#ifdef CONFIG_MATH_EMULATION
4040
if (!boot_cpu_has(X86_FEATURE_FPU))
41-
fpstate_init_soft(&x86_task_fpu(current)->fpstate->regs.soft);
41+
;
4242
else
4343
#endif
4444
asm volatile ("fninit");
@@ -207,7 +207,6 @@ static void __init fpu__init_system_xstate_size_legacy(void)
207207
fpu_kernel_cfg.default_size = size;
208208
fpu_user_cfg.max_size = size;
209209
fpu_user_cfg.default_size = size;
210-
fpstate_reset(x86_task_fpu(current));
211210
}
212211

213212
/*

arch/x86/kernel/fpu/xstate.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -870,9 +870,6 @@ void __init fpu__init_system_xstate(unsigned int legacy_size)
870870
if (err)
871871
goto out_disable;
872872

873-
/* Reset the state for the current task */
874-
fpstate_reset(x86_task_fpu(current));
875-
876873
/*
877874
* Update info used for ptrace frames; use standard-format size and no
878875
* supervisor xstates:

arch/x86/kernel/vmlinux.lds.S

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -181,10 +181,6 @@ SECTIONS
181181
/* equivalent to task_pt_regs(&init_task) */
182182
__top_init_kernel_stack = __end_init_stack - TOP_OF_KERNEL_STACK_PADDING - PTREGS_SIZE;
183183

184-
__x86_init_fpu_begin = .;
185-
. = __x86_init_fpu_begin + 128*PAGE_SIZE;
186-
__x86_init_fpu_end = .;
187-
188184
#ifdef CONFIG_X86_32
189185
/* 32 bit has nosave before _edata */
190186
NOSAVE_DATA

0 commit comments

Comments
 (0)