--- /dev/null
+From efa165504943f2128d50f63de0c02faf6dcceb0d Mon Sep 17 00:00:00 2001
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Wed, 9 Jun 2021 21:18:00 +0200
+Subject: x86/fpu: Reset state for all signal restore failures
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+commit efa165504943f2128d50f63de0c02faf6dcceb0d upstream.
+
+If access_ok() or fpregs_soft_set() fails in __fpu__restore_sig() then the
+function just returns but does not clear the FPU state as it does for all
+other fatal failures.
+
+Clear the FPU state for these failures as well.
+
+Fixes: 72a671ced66d ("x86, fpu: Unify signal handling code paths for x86 and x86_64 kernels")
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Cc: stable@vger.kernel.org
+Link: https://lkml.kernel.org/r/87mtryyhhz.ffs@nanos.tec.linutronix.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kernel/fpu/signal.c | 31 ++++++++++++++++++++-----------
+ 1 file changed, 20 insertions(+), 11 deletions(-)
+
+--- a/arch/x86/kernel/fpu/signal.c
++++ b/arch/x86/kernel/fpu/signal.c
+@@ -272,6 +272,7 @@ static int __fpu__restore_sig(void __use
+ int state_size = fpu_kernel_xstate_size;
+ u64 xfeatures = 0;
+ int fx_only = 0;
++ int ret = 0;
+
+ ia32_fxstate &= (IS_ENABLED(CONFIG_X86_32) ||
+ IS_ENABLED(CONFIG_IA32_EMULATION));
+@@ -281,15 +282,21 @@ static int __fpu__restore_sig(void __use
+ return 0;
+ }
+
+- if (!access_ok(VERIFY_READ, buf, size))
+- return -EACCES;
++ if (!access_ok(VERIFY_READ, buf, size)) {
++ ret = -EACCES;
++ goto out_err;
++ }
+
+ fpu__initialize(fpu);
+
+- if (!static_cpu_has(X86_FEATURE_FPU))
+- return fpregs_soft_set(current, NULL,
+- 0, sizeof(struct user_i387_ia32_struct),
+- NULL, buf) != 0;
++ if (!static_cpu_has(X86_FEATURE_FPU)) {
++ ret = fpregs_soft_set(current, NULL,
++ 0, sizeof(struct user_i387_ia32_struct),
++ NULL, buf) != 0;
++ if (ret)
++ goto out_err;
++ return 0;
++ }
+
+ if (use_xsave()) {
+ struct _fpx_sw_bytes fx_sw_user;
+@@ -349,6 +356,7 @@ static int __fpu__restore_sig(void __use
+ fpu__restore(fpu);
+ local_bh_enable();
+
++ /* Failure is already handled */
+ return err;
+ } else {
+ /*
+@@ -356,13 +364,14 @@ static int __fpu__restore_sig(void __use
+ * state to the registers directly (with exceptions handled).
+ */
+ user_fpu_begin();
+- if (copy_user_to_fpregs_zeroing(buf_fx, xfeatures, fx_only)) {
+- fpu__clear(fpu);
+- return -1;
+- }
++ if (!copy_user_to_fpregs_zeroing(buf_fx, xfeatures, fx_only))
++ return 0;
++ ret = -1;
+ }
+
+- return 0;
++out_err:
++ fpu__clear(fpu);
++ return ret;
+ }
+
+ static inline int xstate_sigframe_size(void)