Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef __X86_KERNEL_FPU_LEGACY_H
0003 #define __X86_KERNEL_FPU_LEGACY_H
0004 
0005 #include <asm/fpu/types.h>
0006 
0007 extern unsigned int mxcsr_feature_mask;
0008 
0009 static inline void ldmxcsr(u32 mxcsr)
0010 {
0011     asm volatile("ldmxcsr %0" :: "m" (mxcsr));
0012 }
0013 
0014 /*
0015  * Returns 0 on success or the trap number when the operation raises an
0016  * exception.
0017  */
0018 #define user_insn(insn, output, input...)               \
0019 ({                                  \
0020     int err;                            \
0021                                     \
0022     might_fault();                          \
0023                                     \
0024     asm volatile(ASM_STAC "\n"                  \
0025              "1: " #insn "\n"                   \
0026              "2: " ASM_CLAC "\n"                \
0027              _ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_FAULT_MCE_SAFE)  \
0028              : [err] "=a" (err), output             \
0029              : "0"(0), input);                  \
0030     err;                                \
0031 })
0032 
0033 #define kernel_insn_err(insn, output, input...)             \
0034 ({                                  \
0035     int err;                            \
0036     asm volatile("1:" #insn "\n\t"                  \
0037              "2:\n"                     \
0038              _ASM_EXTABLE_TYPE_REG(1b, 2b, EX_TYPE_EFAULT_REG, %[err]) \
0039              : [err] "=r" (err), output             \
0040              : "0"(0), input);                  \
0041     err;                                \
0042 })
0043 
0044 #define kernel_insn(insn, output, input...)             \
0045     asm volatile("1:" #insn "\n\t"                  \
0046              "2:\n"                     \
0047              _ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_FPU_RESTORE) \
0048              : output : input)
0049 
0050 static inline int fnsave_to_user_sigframe(struct fregs_state __user *fx)
0051 {
0052     return user_insn(fnsave %[fx]; fwait,  [fx] "=m" (*fx), "m" (*fx));
0053 }
0054 
0055 static inline int fxsave_to_user_sigframe(struct fxregs_state __user *fx)
0056 {
0057     if (IS_ENABLED(CONFIG_X86_32))
0058         return user_insn(fxsave %[fx], [fx] "=m" (*fx), "m" (*fx));
0059     else
0060         return user_insn(fxsaveq %[fx], [fx] "=m" (*fx), "m" (*fx));
0061 
0062 }
0063 
0064 static inline void fxrstor(struct fxregs_state *fx)
0065 {
0066     if (IS_ENABLED(CONFIG_X86_32))
0067         kernel_insn(fxrstor %[fx], "=m" (*fx), [fx] "m" (*fx));
0068     else
0069         kernel_insn(fxrstorq %[fx], "=m" (*fx), [fx] "m" (*fx));
0070 }
0071 
0072 static inline int fxrstor_safe(struct fxregs_state *fx)
0073 {
0074     if (IS_ENABLED(CONFIG_X86_32))
0075         return kernel_insn_err(fxrstor %[fx], "=m" (*fx), [fx] "m" (*fx));
0076     else
0077         return kernel_insn_err(fxrstorq %[fx], "=m" (*fx), [fx] "m" (*fx));
0078 }
0079 
0080 static inline int fxrstor_from_user_sigframe(struct fxregs_state __user *fx)
0081 {
0082     if (IS_ENABLED(CONFIG_X86_32))
0083         return user_insn(fxrstor %[fx], "=m" (*fx), [fx] "m" (*fx));
0084     else
0085         return user_insn(fxrstorq %[fx], "=m" (*fx), [fx] "m" (*fx));
0086 }
0087 
0088 static inline void frstor(struct fregs_state *fx)
0089 {
0090     kernel_insn(frstor %[fx], "=m" (*fx), [fx] "m" (*fx));
0091 }
0092 
0093 static inline int frstor_safe(struct fregs_state *fx)
0094 {
0095     return kernel_insn_err(frstor %[fx], "=m" (*fx), [fx] "m" (*fx));
0096 }
0097 
0098 static inline int frstor_from_user_sigframe(struct fregs_state __user *fx)
0099 {
0100     return user_insn(frstor %[fx], "=m" (*fx), [fx] "m" (*fx));
0101 }
0102 
0103 static inline void fxsave(struct fxregs_state *fx)
0104 {
0105     if (IS_ENABLED(CONFIG_X86_32))
0106         asm volatile( "fxsave %[fx]" : [fx] "=m" (*fx));
0107     else
0108         asm volatile("fxsaveq %[fx]" : [fx] "=m" (*fx));
0109 }
0110 
0111 #endif