1*669ebabbSIngo Molnar #ifndef __ASM_X86_XSAVE_H 2*669ebabbSIngo Molnar #define __ASM_X86_XSAVE_H 3*669ebabbSIngo Molnar 4*669ebabbSIngo Molnar #include <linux/types.h> 5*669ebabbSIngo Molnar #include <asm/processor.h> 6*669ebabbSIngo Molnar 7*669ebabbSIngo Molnar #define XSTATE_CPUID 0x0000000d 8*669ebabbSIngo Molnar 9*669ebabbSIngo Molnar #define XSTATE_FP 0x1 10*669ebabbSIngo Molnar #define XSTATE_SSE 0x2 11*669ebabbSIngo Molnar #define XSTATE_YMM 0x4 12*669ebabbSIngo Molnar #define XSTATE_BNDREGS 0x8 13*669ebabbSIngo Molnar #define XSTATE_BNDCSR 0x10 14*669ebabbSIngo Molnar #define XSTATE_OPMASK 0x20 15*669ebabbSIngo Molnar #define XSTATE_ZMM_Hi256 0x40 16*669ebabbSIngo Molnar #define XSTATE_Hi16_ZMM 0x80 17*669ebabbSIngo Molnar 18*669ebabbSIngo Molnar /* The highest xstate bit above (of XSTATE_Hi16_ZMM): */ 19*669ebabbSIngo Molnar #define XFEATURES_NR_MAX 8 20*669ebabbSIngo Molnar 21*669ebabbSIngo Molnar #define XSTATE_FPSSE (XSTATE_FP | XSTATE_SSE) 22*669ebabbSIngo Molnar #define XSTATE_AVX512 (XSTATE_OPMASK | XSTATE_ZMM_Hi256 | XSTATE_Hi16_ZMM) 23*669ebabbSIngo Molnar /* Bit 63 of XCR0 is reserved for future expansion */ 24*669ebabbSIngo Molnar #define XSTATE_EXTEND_MASK (~(XSTATE_FPSSE | (1ULL << 63))) 25*669ebabbSIngo Molnar 26*669ebabbSIngo Molnar #define FXSAVE_SIZE 512 27*669ebabbSIngo Molnar 28*669ebabbSIngo Molnar #define XSAVE_HDR_SIZE 64 29*669ebabbSIngo Molnar #define XSAVE_HDR_OFFSET FXSAVE_SIZE 30*669ebabbSIngo Molnar 31*669ebabbSIngo Molnar #define XSAVE_YMM_SIZE 256 32*669ebabbSIngo Molnar #define XSAVE_YMM_OFFSET (XSAVE_HDR_SIZE + XSAVE_HDR_OFFSET) 33*669ebabbSIngo Molnar 34*669ebabbSIngo Molnar /* Supported features which support lazy state saving */ 35*669ebabbSIngo Molnar #define XSTATE_LAZY (XSTATE_FP | XSTATE_SSE | XSTATE_YMM \ 36*669ebabbSIngo Molnar | XSTATE_OPMASK | XSTATE_ZMM_Hi256 | XSTATE_Hi16_ZMM) 37*669ebabbSIngo Molnar 38*669ebabbSIngo Molnar /* Supported features which require eager state saving */ 39*669ebabbSIngo Molnar #define XSTATE_EAGER (XSTATE_BNDREGS | XSTATE_BNDCSR) 40*669ebabbSIngo Molnar 41*669ebabbSIngo Molnar /* All currently supported features */ 42*669ebabbSIngo Molnar #define XCNTXT_MASK (XSTATE_LAZY | XSTATE_EAGER) 43*669ebabbSIngo Molnar 44*669ebabbSIngo Molnar #ifdef CONFIG_X86_64 45*669ebabbSIngo Molnar #define REX_PREFIX "0x48, " 46*669ebabbSIngo Molnar #else 47*669ebabbSIngo Molnar #define REX_PREFIX 48*669ebabbSIngo Molnar #endif 49*669ebabbSIngo Molnar 50*669ebabbSIngo Molnar extern unsigned int xstate_size; 51*669ebabbSIngo Molnar extern u64 xfeatures_mask; 52*669ebabbSIngo Molnar extern u64 xstate_fx_sw_bytes[USER_XSTATE_FX_SW_WORDS]; 53*669ebabbSIngo Molnar extern struct xsave_struct init_xstate_ctx; 54*669ebabbSIngo Molnar 55*669ebabbSIngo Molnar extern void update_regset_xstate_info(unsigned int size, u64 xstate_mask); 56*669ebabbSIngo Molnar 57*669ebabbSIngo Molnar /* These macros all use (%edi)/(%rdi) as the single memory argument. */ 58*669ebabbSIngo Molnar #define XSAVE ".byte " REX_PREFIX "0x0f,0xae,0x27" 59*669ebabbSIngo Molnar #define XSAVEOPT ".byte " REX_PREFIX "0x0f,0xae,0x37" 60*669ebabbSIngo Molnar #define XSAVES ".byte " REX_PREFIX "0x0f,0xc7,0x2f" 61*669ebabbSIngo Molnar #define XRSTOR ".byte " REX_PREFIX "0x0f,0xae,0x2f" 62*669ebabbSIngo Molnar #define XRSTORS ".byte " REX_PREFIX "0x0f,0xc7,0x1f" 63*669ebabbSIngo Molnar 64*669ebabbSIngo Molnar #define xstate_fault ".section .fixup,\"ax\"\n" \ 65*669ebabbSIngo Molnar "3: movl $-1,%[err]\n" \ 66*669ebabbSIngo Molnar " jmp 2b\n" \ 67*669ebabbSIngo Molnar ".previous\n" \ 68*669ebabbSIngo Molnar _ASM_EXTABLE(1b, 3b) \ 69*669ebabbSIngo Molnar : [err] "=r" (err) 70*669ebabbSIngo Molnar 71*669ebabbSIngo Molnar /* 72*669ebabbSIngo Molnar * This function is called only during boot time when x86 caps are not set 73*669ebabbSIngo Molnar * up and alternative can not be used yet. 74*669ebabbSIngo Molnar */ 75*669ebabbSIngo Molnar static inline int xsave_state_booting(struct xsave_struct *fx) 76*669ebabbSIngo Molnar { 77*669ebabbSIngo Molnar u64 mask = -1; 78*669ebabbSIngo Molnar u32 lmask = mask; 79*669ebabbSIngo Molnar u32 hmask = mask >> 32; 80*669ebabbSIngo Molnar int err = 0; 81*669ebabbSIngo Molnar 82*669ebabbSIngo Molnar WARN_ON(system_state != SYSTEM_BOOTING); 83*669ebabbSIngo Molnar 84*669ebabbSIngo Molnar if (boot_cpu_has(X86_FEATURE_XSAVES)) 85*669ebabbSIngo Molnar asm volatile("1:"XSAVES"\n\t" 86*669ebabbSIngo Molnar "2:\n\t" 87*669ebabbSIngo Molnar xstate_fault 88*669ebabbSIngo Molnar : "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask) 89*669ebabbSIngo Molnar : "memory"); 90*669ebabbSIngo Molnar else 91*669ebabbSIngo Molnar asm volatile("1:"XSAVE"\n\t" 92*669ebabbSIngo Molnar "2:\n\t" 93*669ebabbSIngo Molnar xstate_fault 94*669ebabbSIngo Molnar : "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask) 95*669ebabbSIngo Molnar : "memory"); 96*669ebabbSIngo Molnar return err; 97*669ebabbSIngo Molnar } 98*669ebabbSIngo Molnar 99*669ebabbSIngo Molnar /* 100*669ebabbSIngo Molnar * This function is called only during boot time when x86 caps are not set 101*669ebabbSIngo Molnar * up and alternative can not be used yet. 102*669ebabbSIngo Molnar */ 103*669ebabbSIngo Molnar static inline int xrstor_state_booting(struct xsave_struct *fx, u64 mask) 104*669ebabbSIngo Molnar { 105*669ebabbSIngo Molnar u32 lmask = mask; 106*669ebabbSIngo Molnar u32 hmask = mask >> 32; 107*669ebabbSIngo Molnar int err = 0; 108*669ebabbSIngo Molnar 109*669ebabbSIngo Molnar WARN_ON(system_state != SYSTEM_BOOTING); 110*669ebabbSIngo Molnar 111*669ebabbSIngo Molnar if (boot_cpu_has(X86_FEATURE_XSAVES)) 112*669ebabbSIngo Molnar asm volatile("1:"XRSTORS"\n\t" 113*669ebabbSIngo Molnar "2:\n\t" 114*669ebabbSIngo Molnar xstate_fault 115*669ebabbSIngo Molnar : "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask) 116*669ebabbSIngo Molnar : "memory"); 117*669ebabbSIngo Molnar else 118*669ebabbSIngo Molnar asm volatile("1:"XRSTOR"\n\t" 119*669ebabbSIngo Molnar "2:\n\t" 120*669ebabbSIngo Molnar xstate_fault 121*669ebabbSIngo Molnar : "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask) 122*669ebabbSIngo Molnar : "memory"); 123*669ebabbSIngo Molnar return err; 124*669ebabbSIngo Molnar } 125*669ebabbSIngo Molnar 126*669ebabbSIngo Molnar /* 127*669ebabbSIngo Molnar * Save processor xstate to xsave area. 128*669ebabbSIngo Molnar */ 129*669ebabbSIngo Molnar static inline int xsave_state(struct xsave_struct *fx) 130*669ebabbSIngo Molnar { 131*669ebabbSIngo Molnar u64 mask = -1; 132*669ebabbSIngo Molnar u32 lmask = mask; 133*669ebabbSIngo Molnar u32 hmask = mask >> 32; 134*669ebabbSIngo Molnar int err = 0; 135*669ebabbSIngo Molnar 136*669ebabbSIngo Molnar WARN_ON(system_state == SYSTEM_BOOTING); 137*669ebabbSIngo Molnar 138*669ebabbSIngo Molnar /* 139*669ebabbSIngo Molnar * If xsaves is enabled, xsaves replaces xsaveopt because 140*669ebabbSIngo Molnar * it supports compact format and supervisor states in addition to 141*669ebabbSIngo Molnar * modified optimization in xsaveopt. 142*669ebabbSIngo Molnar * 143*669ebabbSIngo Molnar * Otherwise, if xsaveopt is enabled, xsaveopt replaces xsave 144*669ebabbSIngo Molnar * because xsaveopt supports modified optimization which is not 145*669ebabbSIngo Molnar * supported by xsave. 146*669ebabbSIngo Molnar * 147*669ebabbSIngo Molnar * If none of xsaves and xsaveopt is enabled, use xsave. 148*669ebabbSIngo Molnar */ 149*669ebabbSIngo Molnar alternative_input_2( 150*669ebabbSIngo Molnar "1:"XSAVE, 151*669ebabbSIngo Molnar XSAVEOPT, 152*669ebabbSIngo Molnar X86_FEATURE_XSAVEOPT, 153*669ebabbSIngo Molnar XSAVES, 154*669ebabbSIngo Molnar X86_FEATURE_XSAVES, 155*669ebabbSIngo Molnar [fx] "D" (fx), "a" (lmask), "d" (hmask) : 156*669ebabbSIngo Molnar "memory"); 157*669ebabbSIngo Molnar asm volatile("2:\n\t" 158*669ebabbSIngo Molnar xstate_fault 159*669ebabbSIngo Molnar : "0" (0) 160*669ebabbSIngo Molnar : "memory"); 161*669ebabbSIngo Molnar 162*669ebabbSIngo Molnar return err; 163*669ebabbSIngo Molnar } 164*669ebabbSIngo Molnar 165*669ebabbSIngo Molnar /* 166*669ebabbSIngo Molnar * Restore processor xstate from xsave area. 167*669ebabbSIngo Molnar */ 168*669ebabbSIngo Molnar static inline int xrstor_state(struct xsave_struct *fx, u64 mask) 169*669ebabbSIngo Molnar { 170*669ebabbSIngo Molnar int err = 0; 171*669ebabbSIngo Molnar u32 lmask = mask; 172*669ebabbSIngo Molnar u32 hmask = mask >> 32; 173*669ebabbSIngo Molnar 174*669ebabbSIngo Molnar /* 175*669ebabbSIngo Molnar * Use xrstors to restore context if it is enabled. xrstors supports 176*669ebabbSIngo Molnar * compacted format of xsave area which is not supported by xrstor. 177*669ebabbSIngo Molnar */ 178*669ebabbSIngo Molnar alternative_input( 179*669ebabbSIngo Molnar "1: " XRSTOR, 180*669ebabbSIngo Molnar XRSTORS, 181*669ebabbSIngo Molnar X86_FEATURE_XSAVES, 182*669ebabbSIngo Molnar "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask) 183*669ebabbSIngo Molnar : "memory"); 184*669ebabbSIngo Molnar 185*669ebabbSIngo Molnar asm volatile("2:\n" 186*669ebabbSIngo Molnar xstate_fault 187*669ebabbSIngo Molnar : "0" (0) 188*669ebabbSIngo Molnar : "memory"); 189*669ebabbSIngo Molnar 190*669ebabbSIngo Molnar return err; 191*669ebabbSIngo Molnar } 192*669ebabbSIngo Molnar 193*669ebabbSIngo Molnar /* 194*669ebabbSIngo Molnar * Restore xstate context for new process during context switch. 195*669ebabbSIngo Molnar */ 196*669ebabbSIngo Molnar static inline int fpu_xrstor_checking(struct xsave_struct *fx) 197*669ebabbSIngo Molnar { 198*669ebabbSIngo Molnar return xrstor_state(fx, -1); 199*669ebabbSIngo Molnar } 200*669ebabbSIngo Molnar 201*669ebabbSIngo Molnar /* 202*669ebabbSIngo Molnar * Save xstate to user space xsave area. 203*669ebabbSIngo Molnar * 204*669ebabbSIngo Molnar * We don't use modified optimization because xrstor/xrstors might track 205*669ebabbSIngo Molnar * a different application. 206*669ebabbSIngo Molnar * 207*669ebabbSIngo Molnar * We don't use compacted format xsave area for 208*669ebabbSIngo Molnar * backward compatibility for old applications which don't understand 209*669ebabbSIngo Molnar * compacted format of xsave area. 210*669ebabbSIngo Molnar */ 211*669ebabbSIngo Molnar static inline int xsave_user(struct xsave_struct __user *buf) 212*669ebabbSIngo Molnar { 213*669ebabbSIngo Molnar int err; 214*669ebabbSIngo Molnar 215*669ebabbSIngo Molnar /* 216*669ebabbSIngo Molnar * Clear the xsave header first, so that reserved fields are 217*669ebabbSIngo Molnar * initialized to zero. 218*669ebabbSIngo Molnar */ 219*669ebabbSIngo Molnar err = __clear_user(&buf->header, sizeof(buf->header)); 220*669ebabbSIngo Molnar if (unlikely(err)) 221*669ebabbSIngo Molnar return -EFAULT; 222*669ebabbSIngo Molnar 223*669ebabbSIngo Molnar __asm__ __volatile__(ASM_STAC "\n" 224*669ebabbSIngo Molnar "1:"XSAVE"\n" 225*669ebabbSIngo Molnar "2: " ASM_CLAC "\n" 226*669ebabbSIngo Molnar xstate_fault 227*669ebabbSIngo Molnar : "D" (buf), "a" (-1), "d" (-1), "0" (0) 228*669ebabbSIngo Molnar : "memory"); 229*669ebabbSIngo Molnar return err; 230*669ebabbSIngo Molnar } 231*669ebabbSIngo Molnar 232*669ebabbSIngo Molnar /* 233*669ebabbSIngo Molnar * Restore xstate from user space xsave area. 234*669ebabbSIngo Molnar */ 235*669ebabbSIngo Molnar static inline int xrestore_user(struct xsave_struct __user *buf, u64 mask) 236*669ebabbSIngo Molnar { 237*669ebabbSIngo Molnar int err = 0; 238*669ebabbSIngo Molnar struct xsave_struct *xstate = ((__force struct xsave_struct *)buf); 239*669ebabbSIngo Molnar u32 lmask = mask; 240*669ebabbSIngo Molnar u32 hmask = mask >> 32; 241*669ebabbSIngo Molnar 242*669ebabbSIngo Molnar __asm__ __volatile__(ASM_STAC "\n" 243*669ebabbSIngo Molnar "1:"XRSTOR"\n" 244*669ebabbSIngo Molnar "2: " ASM_CLAC "\n" 245*669ebabbSIngo Molnar xstate_fault 246*669ebabbSIngo Molnar : "D" (xstate), "a" (lmask), "d" (hmask), "0" (0) 247*669ebabbSIngo Molnar : "memory"); /* memory required? */ 248*669ebabbSIngo Molnar return err; 249*669ebabbSIngo Molnar } 250*669ebabbSIngo Molnar 251*669ebabbSIngo Molnar void *get_xsave_addr(struct xsave_struct *xsave, int xstate); 252*669ebabbSIngo Molnar void setup_xstate_comp(void); 253*669ebabbSIngo Molnar 254*669ebabbSIngo Molnar #endif 255