]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
x86/fpu: Remove init_task FPU state dependencies, add debugging warning for PF_KTHREA...
authorIngo Molnar <mingo@kernel.org>
Wed, 9 Apr 2025 21:11:26 +0000 (23:11 +0200)
committerIngo Molnar <mingo@kernel.org>
Mon, 14 Apr 2025 06:18:29 +0000 (08:18 +0200)
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
arch/x86/include/asm/processor.h
arch/x86/kernel/fpu/core.c
arch/x86/kernel/fpu/init.c
arch/x86/kernel/fpu/xstate.c
arch/x86/kernel/vmlinux.lds.S

index b7f7c9c83409824a85208f7713fe3cd04307cdf7..eaa7214d69536fd822449d9621745151e30121c6 100644 (file)
@@ -516,7 +516,11 @@ struct thread_struct {
 #endif
 };
 
-#define x86_task_fpu(task)     ((struct fpu *)((void *)(task) + sizeof(*(task))))
+#ifdef CONFIG_X86_DEBUG_FPU
+extern struct fpu *x86_task_fpu(struct task_struct *task);
+#else
+# define x86_task_fpu(task)    ((struct fpu *)((void *)(task) + sizeof(*(task))))
+#endif
 
 /*
  * X86 doesn't need any embedded-FPU-struct quirks:
index 4a2193892e5d9db97d37ab961071600772bd486c..4d1a205b7ce2af0fe67b5506e37cd387b60d6d5e 100644 (file)
@@ -51,6 +51,16 @@ static DEFINE_PER_CPU(bool, in_kernel_fpu);
  */
 DEFINE_PER_CPU(struct fpu *, fpu_fpregs_owner_ctx);
 
+#ifdef CONFIG_X86_DEBUG_FPU
+struct fpu *x86_task_fpu(struct task_struct *task)
+{
+       if (WARN_ON_ONCE(task->flags & PF_KTHREAD))
+               return NULL;
+
+       return (void *)task + sizeof(*task);
+}
+#endif
+
 /*
  * Can we use the FPU in kernel mode with the
  * whole "kernel_fpu_begin/end()" sequence?
@@ -599,11 +609,9 @@ int fpu_clone(struct task_struct *dst, unsigned long clone_flags, bool minimal,
         *
         * This is safe because task_struct size is a multiple of cacheline size.
         */
-       struct fpu *src_fpu = x86_task_fpu(current);
-       struct fpu *dst_fpu = x86_task_fpu(dst);
+       struct fpu *dst_fpu = (void *)dst + sizeof(*dst);
 
        BUILD_BUG_ON(sizeof(*dst) % SMP_CACHE_BYTES != 0);
-       BUG_ON(!src_fpu);
 
        /* The new task's FPU state cannot be valid in the hardware. */
        dst_fpu->last_cpu = -1;
@@ -666,7 +674,6 @@ int fpu_clone(struct task_struct *dst, unsigned long clone_flags, bool minimal,
        if (update_fpu_shstk(dst, ssp))
                return 1;
 
-       trace_x86_fpu_copy_src(src_fpu);
        trace_x86_fpu_copy_dst(dst_fpu);
 
        return 0;
index da41a1d2c40f40a0d17d4c8490a6eecc64d897fb..16b6611634c3854fe78e2ffe08cf78b3e2ddf33c 100644 (file)
@@ -38,7 +38,7 @@ static void fpu__init_cpu_generic(void)
        /* Flush out any pending x87 state: */
 #ifdef CONFIG_MATH_EMULATION
        if (!boot_cpu_has(X86_FEATURE_FPU))
-               fpstate_init_soft(&x86_task_fpu(current)->fpstate->regs.soft);
+               ;
        else
 #endif
                asm volatile ("fninit");
@@ -207,7 +207,6 @@ static void __init fpu__init_system_xstate_size_legacy(void)
        fpu_kernel_cfg.default_size = size;
        fpu_user_cfg.max_size = size;
        fpu_user_cfg.default_size = size;
-       fpstate_reset(x86_task_fpu(current));
 }
 
 /*
index 253da5aec9150f7e45e39982d8f7f98f3dd34de3..4c771b9bd270bb1fa6e47ae0e309c6eba911dbd2 100644 (file)
@@ -870,9 +870,6 @@ void __init fpu__init_system_xstate(unsigned int legacy_size)
        if (err)
                goto out_disable;
 
-       /* Reset the state for the current task */
-       fpstate_reset(x86_task_fpu(current));
-
        /*
         * Update info used for ptrace frames; use standard-format size and no
         * supervisor xstates:
index d9ca2d1754dafc3d01f34b46af1eb8f183373b8b..ccdc45e5b75961711580f62cb2a73f48c1c433c5 100644 (file)
@@ -181,10 +181,6 @@ SECTIONS
                /* equivalent to task_pt_regs(&init_task) */
                __top_init_kernel_stack = __end_init_stack - TOP_OF_KERNEL_STACK_PADDING - PTREGS_SIZE;
 
-               __x86_init_fpu_begin = .;
-               . = __x86_init_fpu_begin + 128*PAGE_SIZE;
-               __x86_init_fpu_end = .;
-
 #ifdef CONFIG_X86_32
                /* 32 bit has nosave before _edata */
                NOSAVE_DATA