diff options
| author | Christoph Hellwig <hch@lst.de> | 2019-06-04 13:54:12 -0400 |
|---|---|---|
| committer | Borislav Petkov <bp@suse.de> | 2019-06-13 14:57:49 -0400 |
| commit | 8d3289f2fa1e0c7e2f72c7352f1efb75d2ad7c76 (patch) | |
| tree | d785c183839b1f28213f9061a94a4462c9681483 | |
| parent | 71ab8323cc357c68985a2d6fc6cfc22b1dbbc1c3 (diff) | |
x86/fpu: Don't use current->mm to check for a kthread
current->mm can be non-NULL if a kthread calls use_mm(). Check for
PF_KTHREAD instead to decide when to store user mode FP state.
Fixes: 2722146eb784 ("x86/fpu: Remove fpu->initialized")
Reported-by: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Borislav Petkov <bp@suse.de>
Acked-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: Aubrey Li <aubrey.li@intel.com>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jann Horn <jannh@google.com>
Cc: Nicolai Stange <nstange@suse.de>
Cc: Rik van Riel <riel@surriel.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: x86-ml <x86@kernel.org>
Link: https://lkml.kernel.org/r/20190604175411.GA27477@lst.de
| -rw-r--r-- | arch/x86/include/asm/fpu/internal.h | 6 | ||||
| -rw-r--r-- | arch/x86/kernel/fpu/core.c | 2 |
2 files changed, 4 insertions, 4 deletions
diff --git a/arch/x86/include/asm/fpu/internal.h b/arch/x86/include/asm/fpu/internal.h index 9e27fa05a7ae..4c95c365058a 100644 --- a/arch/x86/include/asm/fpu/internal.h +++ b/arch/x86/include/asm/fpu/internal.h | |||
| @@ -536,7 +536,7 @@ static inline void __fpregs_load_activate(void) | |||
| 536 | struct fpu *fpu = ¤t->thread.fpu; | 536 | struct fpu *fpu = ¤t->thread.fpu; |
| 537 | int cpu = smp_processor_id(); | 537 | int cpu = smp_processor_id(); |
| 538 | 538 | ||
| 539 | if (WARN_ON_ONCE(current->mm == NULL)) | 539 | if (WARN_ON_ONCE(current->flags & PF_KTHREAD)) |
| 540 | return; | 540 | return; |
| 541 | 541 | ||
| 542 | if (!fpregs_state_valid(fpu, cpu)) { | 542 | if (!fpregs_state_valid(fpu, cpu)) { |
| @@ -567,11 +567,11 @@ static inline void __fpregs_load_activate(void) | |||
| 567 | * otherwise. | 567 | * otherwise. |
| 568 | * | 568 | * |
| 569 | * The FPU context is only stored/restored for a user task and | 569 | * The FPU context is only stored/restored for a user task and |
| 570 | * ->mm is used to distinguish between kernel and user threads. | 570 | * PF_KTHREAD is used to distinguish between kernel and user threads. |
| 571 | */ | 571 | */ |
| 572 | static inline void switch_fpu_prepare(struct fpu *old_fpu, int cpu) | 572 | static inline void switch_fpu_prepare(struct fpu *old_fpu, int cpu) |
| 573 | { | 573 | { |
| 574 | if (static_cpu_has(X86_FEATURE_FPU) && current->mm) { | 574 | if (static_cpu_has(X86_FEATURE_FPU) && !(current->flags & PF_KTHREAD)) { |
| 575 | if (!copy_fpregs_to_fpstate(old_fpu)) | 575 | if (!copy_fpregs_to_fpstate(old_fpu)) |
| 576 | old_fpu->last_cpu = -1; | 576 | old_fpu->last_cpu = -1; |
| 577 | else | 577 | else |
diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c index 466fca686fb9..649fbc3fcf9f 100644 --- a/arch/x86/kernel/fpu/core.c +++ b/arch/x86/kernel/fpu/core.c | |||
| @@ -102,7 +102,7 @@ static void __kernel_fpu_begin(void) | |||
| 102 | 102 | ||
| 103 | kernel_fpu_disable(); | 103 | kernel_fpu_disable(); |
| 104 | 104 | ||
| 105 | if (current->mm) { | 105 | if (!(current->flags & PF_KTHREAD)) { |
| 106 | if (!test_thread_flag(TIF_NEED_FPU_LOAD)) { | 106 | if (!test_thread_flag(TIF_NEED_FPU_LOAD)) { |
| 107 | set_thread_flag(TIF_NEED_FPU_LOAD); | 107 | set_thread_flag(TIF_NEED_FPU_LOAD); |
| 108 | /* | 108 | /* |
