[patch V3 12/20] x86/fpu/signal: Move header zeroing out of xsave_to_user_sigframe()
From: Thomas Gleixner
Date: Wed Sep 08 2021 - 09:30:24 EST
There is no reason to have the header zeroing in the pagefault disabled
region. Do it upfront once.
Signed-off-by: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
---
arch/x86/include/asm/fpu/internal.h | 17 ++++++-----------
arch/x86/kernel/fpu/signal.c | 12 ++++++++++++
2 files changed, 18 insertions(+), 11 deletions(-)
--- a/arch/x86/include/asm/fpu/internal.h
+++ b/arch/x86/include/asm/fpu/internal.h
@@ -349,9 +349,12 @@ static inline void os_xrstor(struct xreg
* We don't use modified optimization because xrstor/xrstors might track
* a different application.
*
- * We don't use compacted format xsave area for
- * backward compatibility for old applications which don't understand
- * compacted format of xsave area.
+ * We don't use compacted format xsave area for backward compatibility for
+ * old applications which don't understand the compacted format of the
+ * xsave area.
+ *
+ * The caller has to zero buf::header before calling this because XSAVE*
+ * does not touch the reserved fields in the header.
*/
static inline int xsave_to_user_sigframe(struct xregs_state __user *buf)
{
@@ -365,14 +368,6 @@ static inline int xsave_to_user_sigframe
u32 hmask = mask >> 32;
int err;
- /*
- * Clear the xsave header first, so that reserved fields are
- * initialized to zero.
- */
- err = __clear_user(&buf->header, sizeof(buf->header));
- if (unlikely(err))
- return -EFAULT;
-
stac();
XSTATE_OP(XSAVE, buf, lmask, hmask, err);
clac();
--- a/arch/x86/kernel/fpu/signal.c
+++ b/arch/x86/kernel/fpu/signal.c
@@ -189,6 +189,18 @@ int copy_fpstate_to_sigframe(void __user
if (!access_ok(buf, size))
return -EACCES;
+
+ if (use_xsave()) {
+ struct xregs_state __user *xbuf = buf_fx;
+
+ /*
+ * Clear the xsave header first, so that reserved fields are
+ * initialized to zero.
+ */
+ ret = __clear_user(&xbuf->header, sizeof(xbuf->header));
+ if (unlikely(ret))
+ return ret;
+ }
retry:
/*
* Load the FPU registers if they are not valid for the current task.