diff options
Diffstat (limited to 'arch/x86/include/asm/xsave.h')
| -rw-r--r-- | arch/x86/include/asm/xsave.h | 33 |
1 files changed, 18 insertions, 15 deletions
diff --git a/arch/x86/include/asm/xsave.h b/arch/x86/include/asm/xsave.h index 8b75824e41dd..0d1523146545 100644 --- a/arch/x86/include/asm/xsave.h +++ b/arch/x86/include/asm/xsave.h | |||
| @@ -145,6 +145,16 @@ static inline int fpu_xrstor_checking(struct xsave_struct *fx) | |||
| 145 | return xrstor_state(fx, -1); | 145 | return xrstor_state(fx, -1); |
| 146 | } | 146 | } |
| 147 | 147 | ||
| 148 | /* | ||
| 149 | * Save xstate to user space xsave area. | ||
| 150 | * | ||
| 151 | * We don't use modified optimization because xrstor/xrstors might track | ||
| 152 | * a different application. | ||
| 153 | * | ||
| 154 | * We don't use compacted format xsave area for | ||
| 155 | * backward compatibility for old applications which don't understand | ||
| 156 | * compacted format of xsave area. | ||
| 157 | */ | ||
| 148 | static inline int xsave_user(struct xsave_struct __user *buf) | 158 | static inline int xsave_user(struct xsave_struct __user *buf) |
| 149 | { | 159 | { |
| 150 | int err; | 160 | int err; |
| @@ -158,35 +168,28 @@ static inline int xsave_user(struct xsave_struct __user *buf) | |||
| 158 | return -EFAULT; | 168 | return -EFAULT; |
| 159 | 169 | ||
| 160 | __asm__ __volatile__(ASM_STAC "\n" | 170 | __asm__ __volatile__(ASM_STAC "\n" |
| 161 | "1: .byte " REX_PREFIX "0x0f,0xae,0x27\n" | 171 | "1:"XSAVE"\n" |
| 162 | "2: " ASM_CLAC "\n" | 172 | "2: " ASM_CLAC "\n" |
| 163 | ".section .fixup,\"ax\"\n" | 173 | xstate_fault |
| 164 | "3: movl $-1,%[err]\n" | ||
| 165 | " jmp 2b\n" | ||
| 166 | ".previous\n" | ||
| 167 | _ASM_EXTABLE(1b,3b) | ||
| 168 | : [err] "=r" (err) | ||
| 169 | : "D" (buf), "a" (-1), "d" (-1), "0" (0) | 174 | : "D" (buf), "a" (-1), "d" (-1), "0" (0) |
| 170 | : "memory"); | 175 | : "memory"); |
| 171 | return err; | 176 | return err; |
| 172 | } | 177 | } |
| 173 | 178 | ||
| 179 | /* | ||
| 180 | * Restore xstate from user space xsave area. | ||
| 181 | */ | ||
| 174 | static inline int xrestore_user(struct xsave_struct __user *buf, u64 mask) | 182 | static inline int xrestore_user(struct xsave_struct __user *buf, u64 mask) |
| 175 | { | 183 | { |
| 176 | int err; | 184 | int err = 0; |
| 177 | struct xsave_struct *xstate = ((__force struct xsave_struct *)buf); | 185 | struct xsave_struct *xstate = ((__force struct xsave_struct *)buf); |
| 178 | u32 lmask = mask; | 186 | u32 lmask = mask; |
| 179 | u32 hmask = mask >> 32; | 187 | u32 hmask = mask >> 32; |
| 180 | 188 | ||
| 181 | __asm__ __volatile__(ASM_STAC "\n" | 189 | __asm__ __volatile__(ASM_STAC "\n" |
| 182 | "1: .byte " REX_PREFIX "0x0f,0xae,0x2f\n" | 190 | "1:"XRSTOR"\n" |
| 183 | "2: " ASM_CLAC "\n" | 191 | "2: " ASM_CLAC "\n" |
| 184 | ".section .fixup,\"ax\"\n" | 192 | xstate_fault |
| 185 | "3: movl $-1,%[err]\n" | ||
| 186 | " jmp 2b\n" | ||
| 187 | ".previous\n" | ||
| 188 | _ASM_EXTABLE(1b,3b) | ||
| 189 | : [err] "=r" (err) | ||
| 190 | : "D" (xstate), "a" (lmask), "d" (hmask), "0" (0) | 193 | : "D" (xstate), "a" (lmask), "d" (hmask), "0" (0) |
| 191 | : "memory"); /* memory required? */ | 194 | : "memory"); /* memory required? */ |
| 192 | return err; | 195 | return err; |
