123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- /* SPDX-License-Identifier: GPL-2.0 */
- #ifndef __X86_KERNEL_FPU_LEGACY_H
- #define __X86_KERNEL_FPU_LEGACY_H
- #include <asm/fpu/types.h>
- extern unsigned int mxcsr_feature_mask;
- static inline void ldmxcsr(u32 mxcsr)
- {
- asm volatile("ldmxcsr %0" :: "m" (mxcsr));
- }
- /*
- * Returns 0 on success or the trap number when the operation raises an
- * exception.
- */
- #define user_insn(insn, output, input...) \
- ({ \
- int err; \
- \
- might_fault(); \
- \
- asm volatile(ASM_STAC "\n" \
- "1: " #insn "\n" \
- "2: " ASM_CLAC "\n" \
- _ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_FAULT_MCE_SAFE) \
- : [err] "=a" (err), output \
- : "0"(0), input); \
- err; \
- })
- #define kernel_insn_err(insn, output, input...) \
- ({ \
- int err; \
- asm volatile("1:" #insn "\n\t" \
- "2:\n" \
- _ASM_EXTABLE_TYPE_REG(1b, 2b, EX_TYPE_EFAULT_REG, %[err]) \
- : [err] "=r" (err), output \
- : "0"(0), input); \
- err; \
- })
- #define kernel_insn(insn, output, input...) \
- asm volatile("1:" #insn "\n\t" \
- "2:\n" \
- _ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_FPU_RESTORE) \
- : output : input)
- static inline int fnsave_to_user_sigframe(struct fregs_state __user *fx)
- {
- return user_insn(fnsave %[fx]; fwait, [fx] "=m" (*fx), "m" (*fx));
- }
- static inline int fxsave_to_user_sigframe(struct fxregs_state __user *fx)
- {
- if (IS_ENABLED(CONFIG_X86_32))
- return user_insn(fxsave %[fx], [fx] "=m" (*fx), "m" (*fx));
- else
- return user_insn(fxsaveq %[fx], [fx] "=m" (*fx), "m" (*fx));
- }
- static inline void fxrstor(struct fxregs_state *fx)
- {
- if (IS_ENABLED(CONFIG_X86_32))
- kernel_insn(fxrstor %[fx], "=m" (*fx), [fx] "m" (*fx));
- else
- kernel_insn(fxrstorq %[fx], "=m" (*fx), [fx] "m" (*fx));
- }
- static inline int fxrstor_safe(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 fxrstor_from_user_sigframe(struct fxregs_state __user *fx)
- {
- if (IS_ENABLED(CONFIG_X86_32))
- return user_insn(fxrstor %[fx], "=m" (*fx), [fx] "m" (*fx));
- else
- return user_insn(fxrstorq %[fx], "=m" (*fx), [fx] "m" (*fx));
- }
- static inline void frstor(struct fregs_state *fx)
- {
- kernel_insn(frstor %[fx], "=m" (*fx), [fx] "m" (*fx));
- }
- static inline int frstor_safe(struct fregs_state *fx)
- {
- return kernel_insn_err(frstor %[fx], "=m" (*fx), [fx] "m" (*fx));
- }
- static inline int frstor_from_user_sigframe(struct fregs_state __user *fx)
- {
- return user_insn(frstor %[fx], "=m" (*fx), [fx] "m" (*fx));
- }
- static inline void fxsave(struct fxregs_state *fx)
- {
- if (IS_ENABLED(CONFIG_X86_32))
- asm volatile( "fxsave %[fx]" : [fx] "=m" (*fx));
- else
- asm volatile("fxsaveq %[fx]" : [fx] "=m" (*fx));
- }
- #endif
|