aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/fpu/signal.c
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2021-06-23 14:02:28 +0200
committerBorislav Petkov <bp@suse.de>2021-06-23 20:03:15 +0200
commitcdcec1b77001e7f2cd10dccfc6d9b6d5d3f1f3ea (patch)
tree597f46ea770941abca905178beebfdc7f4f8be20 /arch/x86/kernel/fpu/signal.c
parentx86/fpu/signal: Sanitize the xstate check on sigframe (diff)
downloadlinux-dev-cdcec1b77001e7f2cd10dccfc6d9b6d5d3f1f3ea.tar.xz
linux-dev-cdcec1b77001e7f2cd10dccfc6d9b6d5d3f1f3ea.zip
x86/fpu/signal: Sanitize copy_user_to_fpregs_zeroing()
Now that user_xfeatures is correctly set when xsave is enabled, remove the duplicated initialization of components. Rename the function while at it. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Borislav Petkov <bp@suse.de> Reviewed-by: Borislav Petkov <bp@suse.de> Link: https://lkml.kernel.org/r/20210623121457.377341297@linutronix.de
Diffstat (limited to 'arch/x86/kernel/fpu/signal.c')
-rw-r--r--arch/x86/kernel/fpu/signal.c36
1 files changed, 15 insertions, 21 deletions
diff --git a/arch/x86/kernel/fpu/signal.c b/arch/x86/kernel/fpu/signal.c
index d55241038871..a1a70134e1fe 100644
--- a/arch/x86/kernel/fpu/signal.c
+++ b/arch/x86/kernel/fpu/signal.c
@@ -251,33 +251,27 @@ sanitize_restored_user_xstate(union fpregs_state *state,
}
/*
- * Restore the extended state if present. Otherwise, restore the FP/SSE state.
+ * Restore the FPU state directly from the userspace signal frame.
*/
-static int copy_user_to_fpregs_zeroing(void __user *buf, u64 xbv, int fx_only)
+static int restore_fpregs_from_user(void __user *buf, u64 xrestore, bool fx_only)
{
- u64 init_bv;
- int r;
-
if (use_xsave()) {
- if (fx_only) {
- init_bv = xfeatures_mask_uabi() & ~XFEATURE_MASK_FPSSE;
+ u64 init_bv = xfeatures_mask_uabi() & ~xrestore;
+ int ret;
- r = fxrstor_from_user_sigframe(buf);
- if (!r)
- os_xrstor(&init_fpstate.xsave, init_bv);
- return r;
- } else {
- init_bv = xfeatures_mask_uabi() & ~xbv;
-
- r = xrstor_from_user_sigframe(buf, xbv);
- if (!r && unlikely(init_bv))
- os_xrstor(&init_fpstate.xsave, init_bv);
- return r;
- }
+ if (likely(!fx_only))
+ ret = xrstor_from_user_sigframe(buf, xrestore);
+ else
+ ret = fxrstor_from_user_sigframe(buf);
+
+ if (!ret && unlikely(init_bv))
+ os_xrstor(&init_fpstate.xsave, init_bv);
+ return ret;
} else if (use_fxsr()) {
return fxrstor_from_user_sigframe(buf);
- } else
+ } else {
return frstor_from_user_sigframe(buf);
+ }
}
static int __fpu_restore_sig(void __user *buf, void __user *buf_fx,
@@ -314,7 +308,7 @@ static int __fpu_restore_sig(void __user *buf, void __user *buf_fx,
*/
fpregs_lock();
pagefault_disable();
- ret = copy_user_to_fpregs_zeroing(buf_fx, user_xfeatures, fx_only);
+ ret = restore_fpregs_from_user(buf_fx, user_xfeatures, fx_only);
pagefault_enable();
if (!ret) {