| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
- From: Thomas Lamprecht <[email protected]>
- Date: Wed, 3 Apr 2019 18:41:50 +0200
- Subject: [PATCH] x86/fpu: backport copy_kernel_to_XYZ_err helpers
- MIME-Version: 1.0
- Content-Type: text/plain; charset=UTF-8
- Content-Transfer-Encoding: 8bit
- partial cherry-pick from upstream 5.2 "86/fpu: Restore from kernel
- memory on the 64-bit path too"
- commit 926b21f37b072ae4c117052de45a975c6d468fec
- Author: Sebastian Andrzej Siewior <[email protected]>
- Namely, only backport the added helpers, none of the semantic changes.
- relevant parts of the original commit message:
- > In order to avoid that mess, copy the FPU state from userland, validate
- > it and then load it. The copy_kernel_…() helpers are basically just
- > like the old helpers except that they operate on kernel memory and the
- > fault handler just sets the error value and the caller handles it.
- Link: https://lkml.kernel.org/r/[email protected]
- (partial cherry picked from commit 926b21f37b072ae4c117052de45a975c6d468fec)
- Signed-off-by: Thomas Lamprecht <[email protected]>
- ---
- arch/x86/include/asm/fpu/internal.h | 43 +++++++++++++++++++++++++++++
- 1 file changed, 43 insertions(+)
- diff --git a/arch/x86/include/asm/fpu/internal.h b/arch/x86/include/asm/fpu/internal.h
- index fa2c93cb42a2..f3193ab0a2fb 100644
- --- a/arch/x86/include/asm/fpu/internal.h
- +++ b/arch/x86/include/asm/fpu/internal.h
- @@ -122,6 +122,21 @@ extern void fpstate_sanitize_xstate(struct fpu *fpu);
- err; \
- })
-
- +#define kernel_insn_err(insn, output, input...) \
- +({ \
- + int err; \
- + asm volatile("1:" #insn "\n\t" \
- + "2:\n" \
- + ".section .fixup,\"ax\"\n" \
- + "3: movl $-1,%[err]\n" \
- + " jmp 2b\n" \
- + ".previous\n" \
- + _ASM_EXTABLE(1b, 3b) \
- + : [err] "=r" (err), output \
- + : "0"(0), input); \
- + err; \
- +})
- +
- #define kernel_insn(insn, output, input...) \
- asm volatile("1:" #insn "\n\t" \
- "2:\n" \
- @@ -158,6 +173,14 @@ static inline void copy_kernel_to_fxregs(struct fxregs_state *fx)
- }
- }
-
- +static inline int copy_kernel_to_fxregs_err(struct fxregs_state *fx)
- +{
- + if (IS_ENABLED(CONFIG_X86_32))
- + return kernel_insn_err(fxrstor %[fx], "=m" (*fx), [fx] "m" (*fx));
- + else
- + return kernel_insn_err(fxrstorq %[fx], "=m" (*fx), [fx] "m" (*fx));
- +}
- +
- static inline int copy_user_to_fxregs(struct fxregs_state __user *fx)
- {
- if (IS_ENABLED(CONFIG_X86_32))
- @@ -175,6 +198,11 @@ static inline void copy_kernel_to_fregs(struct fregs_state *fx)
- kernel_insn(frstor %[fx], "=m" (*fx), [fx] "m" (*fx));
- }
-
- +static inline int copy_kernel_to_fregs_err(struct fregs_state *fx)
- +{
- + return kernel_insn_err(frstor %[fx], "=m" (*fx), [fx] "m" (*fx));
- +}
- +
- static inline int copy_user_to_fregs(struct fregs_state __user *fx)
- {
- return user_insn(frstor %[fx], "=m" (*fx), [fx] "m" (*fx));
- @@ -400,6 +428,21 @@ static inline int copy_user_to_xregs(struct xregs_state __user *buf, u64 mask)
- return err;
- }
-
- +/*
- + * Restore xstate from kernel space xsave area, return an error code instead of
- + * an exception.
- + */
- +static inline int copy_kernel_to_xregs_err(struct xregs_state *xstate, u64 mask)
- +{
- + u32 lmask = mask;
- + u32 hmask = mask >> 32;
- + int err;
- +
- + XSTATE_OP(XRSTOR, xstate, lmask, hmask, err);
- +
- + return err;
- +}
- +
- /*
- * These must be called with preempt disabled. Returns
- * 'true' if the FPU state is still intact and we can
|