diff options
author | Dave Hansen <dave.hansen@linux.intel.com> | 2015-09-02 19:31:29 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2015-09-14 06:22:00 -0400 |
commit | 1126cb4535c4ff172c37a412a6bd25d6b47a1901 (patch) | |
tree | 1202fea28c6e6dc88ba85b9801b3289251c94251 | |
parent | 633d54c47a5bedfb42f10e6a63eeeebd35abdb4c (diff) |
x86/fpu/mpx: Rework MPX 'xstate' types
MPX includes two separate "extended state components". There is
no real need to have an 'mpx_struct' because we never really
manage the states together.
We also separate out the actual data in 'mpx_bndcsr_state' from
the padding. We will shortly be checking the state sizes
against our structures and need them to match. For consistency,
we also ensure to prefix these types with 'mpx_'.
Lastly, we add some comments to mirror some of the descriptions
in the Intel documents (SDM) of the various state components.
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Tim Chen <tim.c.chen@linux.intel.com>
Cc: dave@sr71.net
Cc: linux-kernel@vger.kernel.org
Link: http://lkml.kernel.org/r/20150902233129.384B73EB@viggo.jf.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r-- | arch/x86/include/asm/fpu/types.h | 29 | ||||
-rw-r--r-- | arch/x86/include/asm/trace/mpx.h | 7 | ||||
-rw-r--r-- | arch/x86/kernel/traps.c | 2 | ||||
-rw-r--r-- | arch/x86/mm/mpx.c | 9 |
4 files changed, 33 insertions, 14 deletions
diff --git a/arch/x86/include/asm/fpu/types.h b/arch/x86/include/asm/fpu/types.h index 9f579305dd11..4d8c2009b94e 100644 --- a/arch/x86/include/asm/fpu/types.h +++ b/arch/x86/include/asm/fpu/types.h | |||
@@ -141,20 +141,37 @@ struct ymmh_struct { | |||
141 | }; | 141 | }; |
142 | 142 | ||
143 | /* Intel MPX support: */ | 143 | /* Intel MPX support: */ |
144 | struct bndreg { | 144 | |
145 | struct mpx_bndreg { | ||
145 | u64 lower_bound; | 146 | u64 lower_bound; |
146 | u64 upper_bound; | 147 | u64 upper_bound; |
147 | } __packed; | 148 | } __packed; |
149 | /* | ||
150 | * State component 3 is used for the 4 128-bit bounds registers | ||
151 | */ | ||
152 | struct mpx_bndreg_state { | ||
153 | struct mpx_bndreg bndreg[4]; | ||
154 | } __packed; | ||
148 | 155 | ||
149 | struct bndcsr { | 156 | /* |
157 | * State component 4 is used for the 64-bit user-mode MPX | ||
158 | * configuration register BNDCFGU and the 64-bit MPX status | ||
159 | * register BNDSTATUS. We call the pair "BNDCSR". | ||
160 | */ | ||
161 | struct mpx_bndcsr { | ||
150 | u64 bndcfgu; | 162 | u64 bndcfgu; |
151 | u64 bndstatus; | 163 | u64 bndstatus; |
152 | } __packed; | 164 | } __packed; |
153 | 165 | ||
154 | struct mpx_struct { | 166 | /* |
155 | struct bndreg bndreg[4]; | 167 | * The BNDCSR state is padded out to be 64-bytes in size. |
156 | struct bndcsr bndcsr; | 168 | */ |
157 | }; | 169 | struct mpx_bndcsr_state { |
170 | union { | ||
171 | struct mpx_bndcsr bndcsr; | ||
172 | u8 pad_to_64_bytes[64]; | ||
173 | }; | ||
174 | } __packed; | ||
158 | 175 | ||
159 | struct xstate_header { | 176 | struct xstate_header { |
160 | u64 xfeatures; | 177 | u64 xfeatures; |
diff --git a/arch/x86/include/asm/trace/mpx.h b/arch/x86/include/asm/trace/mpx.h index 173dd3ba108c..0f492fc50bce 100644 --- a/arch/x86/include/asm/trace/mpx.h +++ b/arch/x86/include/asm/trace/mpx.h | |||
@@ -11,7 +11,7 @@ | |||
11 | TRACE_EVENT(mpx_bounds_register_exception, | 11 | TRACE_EVENT(mpx_bounds_register_exception, |
12 | 12 | ||
13 | TP_PROTO(void *addr_referenced, | 13 | TP_PROTO(void *addr_referenced, |
14 | const struct bndreg *bndreg), | 14 | const struct mpx_bndreg *bndreg), |
15 | TP_ARGS(addr_referenced, bndreg), | 15 | TP_ARGS(addr_referenced, bndreg), |
16 | 16 | ||
17 | TP_STRUCT__entry( | 17 | TP_STRUCT__entry( |
@@ -44,7 +44,7 @@ TRACE_EVENT(mpx_bounds_register_exception, | |||
44 | 44 | ||
45 | TRACE_EVENT(bounds_exception_mpx, | 45 | TRACE_EVENT(bounds_exception_mpx, |
46 | 46 | ||
47 | TP_PROTO(const struct bndcsr *bndcsr), | 47 | TP_PROTO(const struct mpx_bndcsr *bndcsr), |
48 | TP_ARGS(bndcsr), | 48 | TP_ARGS(bndcsr), |
49 | 49 | ||
50 | TP_STRUCT__entry( | 50 | TP_STRUCT__entry( |
@@ -116,7 +116,8 @@ TRACE_EVENT(mpx_new_bounds_table, | |||
116 | /* | 116 | /* |
117 | * This gets used outside of MPX-specific code, so we need a stub. | 117 | * This gets used outside of MPX-specific code, so we need a stub. |
118 | */ | 118 | */ |
119 | static inline void trace_bounds_exception_mpx(const struct bndcsr *bndcsr) | 119 | static inline |
120 | void trace_bounds_exception_mpx(const struct mpx_bndcsr *bndcsr) | ||
120 | { | 121 | { |
121 | } | 122 | } |
122 | 123 | ||
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 0cd2ac5c0f28..ade185a46b1d 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c | |||
@@ -361,7 +361,7 @@ dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code) | |||
361 | 361 | ||
362 | dotraplinkage void do_bounds(struct pt_regs *regs, long error_code) | 362 | dotraplinkage void do_bounds(struct pt_regs *regs, long error_code) |
363 | { | 363 | { |
364 | const struct bndcsr *bndcsr; | 364 | const struct mpx_bndcsr *bndcsr; |
365 | siginfo_t *info; | 365 | siginfo_t *info; |
366 | 366 | ||
367 | RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU"); | 367 | RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU"); |
diff --git a/arch/x86/mm/mpx.c b/arch/x86/mm/mpx.c index f35fc9c6ed50..b0ae85f90f10 100644 --- a/arch/x86/mm/mpx.c +++ b/arch/x86/mm/mpx.c | |||
@@ -237,7 +237,8 @@ bad_opcode: | |||
237 | */ | 237 | */ |
238 | siginfo_t *mpx_generate_siginfo(struct pt_regs *regs) | 238 | siginfo_t *mpx_generate_siginfo(struct pt_regs *regs) |
239 | { | 239 | { |
240 | const struct bndreg *bndregs, *bndreg; | 240 | const struct mpx_bndreg_state *bndregs; |
241 | const struct mpx_bndreg *bndreg; | ||
241 | siginfo_t *info = NULL; | 242 | siginfo_t *info = NULL; |
242 | struct insn insn; | 243 | struct insn insn; |
243 | uint8_t bndregno; | 244 | uint8_t bndregno; |
@@ -264,7 +265,7 @@ siginfo_t *mpx_generate_siginfo(struct pt_regs *regs) | |||
264 | goto err_out; | 265 | goto err_out; |
265 | } | 266 | } |
266 | /* now go select the individual register in the set of 4 */ | 267 | /* now go select the individual register in the set of 4 */ |
267 | bndreg = &bndregs[bndregno]; | 268 | bndreg = &bndregs->bndreg[bndregno]; |
268 | 269 | ||
269 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 270 | info = kzalloc(sizeof(*info), GFP_KERNEL); |
270 | if (!info) { | 271 | if (!info) { |
@@ -306,7 +307,7 @@ err_out: | |||
306 | 307 | ||
307 | static __user void *mpx_get_bounds_dir(void) | 308 | static __user void *mpx_get_bounds_dir(void) |
308 | { | 309 | { |
309 | const struct bndcsr *bndcsr; | 310 | const struct mpx_bndcsr *bndcsr; |
310 | 311 | ||
311 | if (!cpu_feature_enabled(X86_FEATURE_MPX)) | 312 | if (!cpu_feature_enabled(X86_FEATURE_MPX)) |
312 | return MPX_INVALID_BOUNDS_DIR; | 313 | return MPX_INVALID_BOUNDS_DIR; |
@@ -489,7 +490,7 @@ out_unmap: | |||
489 | static int do_mpx_bt_fault(void) | 490 | static int do_mpx_bt_fault(void) |
490 | { | 491 | { |
491 | unsigned long bd_entry, bd_base; | 492 | unsigned long bd_entry, bd_base; |
492 | const struct bndcsr *bndcsr; | 493 | const struct mpx_bndcsr *bndcsr; |
493 | struct mm_struct *mm = current->mm; | 494 | struct mm_struct *mm = current->mm; |
494 | 495 | ||
495 | bndcsr = get_xsave_field_ptr(XFEATURE_MASK_BNDCSR); | 496 | bndcsr = get_xsave_field_ptr(XFEATURE_MASK_BNDCSR); |