summaryrefslogtreecommitdiff
path: root/arch/x86/kernel/fpu/signal.c
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2021-06-23 15:01:51 +0300
committerBorislav Petkov <bp@suse.de>2021-06-23 18:53:31 +0300
commit1f3171252dc586745bb548d48f3bcedfea34b58d (patch)
treeecd2505dd43d3255d2a49498e1312fbd3d0162c4 /arch/x86/kernel/fpu/signal.c
parent9fe8a6f5eed8fff6b2d7dbc99b911334e311732d (diff)
downloadlinux-1f3171252dc586745bb548d48f3bcedfea34b58d.tar.xz
x86/fpu: Get rid of copy_supervisor_to_kernel()
If the fast path of restoring the FPU state on sigreturn fails or is not taken and the current task's FPU is active then the FPU has to be deactivated for the slow path to allow a safe update of the tasks FPU memory state. With supervisor states enabled, this requires to save the supervisor state in the memory state first. Supervisor states require XSAVES so saving only the supervisor state requires to reshuffle the memory buffer because XSAVES uses the compacted format and therefore stores the supervisor states at the beginning of the memory state. That's just an overengineered optimization. Get rid of it and save the full state for this case. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Borislav Petkov <bp@suse.de> Reviewed-by: Andy Lutomirski <luto@kernel.org> Reviewed-by: Borislav Petkov <bp@suse.de> Link: https://lkml.kernel.org/r/20210623121453.734561971@linutronix.de
Diffstat (limited to 'arch/x86/kernel/fpu/signal.c')
-rw-r--r--arch/x86/kernel/fpu/signal.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/arch/x86/kernel/fpu/signal.c b/arch/x86/kernel/fpu/signal.c
index 888c8e0d2ff1..501059579066 100644
--- a/arch/x86/kernel/fpu/signal.c
+++ b/arch/x86/kernel/fpu/signal.c
@@ -401,15 +401,18 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size)
* the optimisation).
*/
fpregs_lock();
-
if (!test_thread_flag(TIF_NEED_FPU_LOAD)) {
-
/*
- * Supervisor states are not modified by user space input. Save
- * current supervisor states first and invalidate the FPU regs.
+ * If supervisor states are available then save the
+ * hardware state in current's fpstate so that the
+ * supervisor state is preserved. Save the full state for
+ * simplicity. There is no point in optimizing this by only
+ * saving the supervisor states and then shuffle them to
+ * the right place in memory. This is the slow path and the
+ * above XRSTOR failed or ia32_fxstate is true. Shrug.
*/
if (xfeatures_mask_supervisor())
- copy_supervisor_to_kernel(&fpu->state.xsave);
+ copy_xregs_to_kernel(&fpu->state.xsave);
set_thread_flag(TIF_NEED_FPU_LOAD);
}
__fpu_invalidate_fpregs_state(fpu);