diff options
| -rw-r--r-- | arch/x86/include/asm/i387.h | 9 | ||||
| -rw-r--r-- | arch/x86/include/asm/xsave.h | 10 | ||||
| -rw-r--r-- | arch/x86/kernel/xsave.c | 12 |
3 files changed, 21 insertions, 10 deletions
diff --git a/arch/x86/include/asm/i387.h b/arch/x86/include/asm/i387.h index c991b3a7b904..0f1cf5d53dd8 100644 --- a/arch/x86/include/asm/i387.h +++ b/arch/x86/include/asm/i387.h | |||
| @@ -127,6 +127,15 @@ static inline int fxsave_user(struct i387_fxsave_struct __user *fx) | |||
| 127 | { | 127 | { |
| 128 | int err; | 128 | int err; |
| 129 | 129 | ||
| 130 | /* | ||
| 131 | * Clear the bytes not touched by the fxsave and reserved | ||
| 132 | * for the SW usage. | ||
| 133 | */ | ||
| 134 | err = __clear_user(&fx->sw_reserved, | ||
| 135 | sizeof(struct _fpx_sw_bytes)); | ||
| 136 | if (unlikely(err)) | ||
| 137 | return -EFAULT; | ||
| 138 | |||
| 130 | asm volatile("1: rex64/fxsave (%[fx])\n\t" | 139 | asm volatile("1: rex64/fxsave (%[fx])\n\t" |
| 131 | "2:\n" | 140 | "2:\n" |
| 132 | ".section .fixup,\"ax\"\n" | 141 | ".section .fixup,\"ax\"\n" |
diff --git a/arch/x86/include/asm/xsave.h b/arch/x86/include/asm/xsave.h index 2c4390cae228..30dfc81804d5 100644 --- a/arch/x86/include/asm/xsave.h +++ b/arch/x86/include/asm/xsave.h | |||
| @@ -59,6 +59,16 @@ static inline int fpu_xrstor_checking(struct fpu *fpu) | |||
| 59 | static inline int xsave_user(struct xsave_struct __user *buf) | 59 | static inline int xsave_user(struct xsave_struct __user *buf) |
| 60 | { | 60 | { |
| 61 | int err; | 61 | int err; |
| 62 | |||
| 63 | /* | ||
| 64 | * Clear the xsave header first, so that reserved fields are | ||
| 65 | * initialized to zero. | ||
| 66 | */ | ||
| 67 | err = __clear_user(&buf->xsave_hdr, | ||
| 68 | sizeof(struct xsave_hdr_struct)); | ||
| 69 | if (unlikely(err)) | ||
| 70 | return -EFAULT; | ||
| 71 | |||
| 62 | __asm__ __volatile__("1: .byte " REX_PREFIX "0x0f,0xae,0x27\n" | 72 | __asm__ __volatile__("1: .byte " REX_PREFIX "0x0f,0xae,0x27\n" |
| 63 | "2:\n" | 73 | "2:\n" |
| 64 | ".section .fixup,\"ax\"\n" | 74 | ".section .fixup,\"ax\"\n" |
diff --git a/arch/x86/kernel/xsave.c b/arch/x86/kernel/xsave.c index 37e68fc5e24a..6e73db1b7b4e 100644 --- a/arch/x86/kernel/xsave.c +++ b/arch/x86/kernel/xsave.c | |||
| @@ -91,14 +91,6 @@ int save_i387_xstate(void __user *buf) | |||
| 91 | return 0; | 91 | return 0; |
| 92 | 92 | ||
| 93 | if (task_thread_info(tsk)->status & TS_USEDFPU) { | 93 | if (task_thread_info(tsk)->status & TS_USEDFPU) { |
| 94 | /* | ||
| 95 | * Start with clearing the user buffer. This will present a | ||
| 96 | * clean context for the bytes not touched by the fxsave/xsave. | ||
| 97 | */ | ||
| 98 | err = __clear_user(buf, sig_xstate_size); | ||
| 99 | if (err) | ||
| 100 | return err; | ||
| 101 | |||
| 102 | if (use_xsave()) | 94 | if (use_xsave()) |
| 103 | err = xsave_user(buf); | 95 | err = xsave_user(buf); |
| 104 | else | 96 | else |
| @@ -184,8 +176,8 @@ static int restore_user_xstate(void __user *buf) | |||
| 184 | * init the state skipped by the user. | 176 | * init the state skipped by the user. |
| 185 | */ | 177 | */ |
| 186 | mask = pcntxt_mask & ~mask; | 178 | mask = pcntxt_mask & ~mask; |
| 187 | 179 | if (unlikely(mask)) | |
| 188 | xrstor_state(init_xstate_buf, mask); | 180 | xrstor_state(init_xstate_buf, mask); |
| 189 | 181 | ||
| 190 | return 0; | 182 | return 0; |
| 191 | 183 | ||
