Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Dave Hansen and committed by
Ingo Molnar
1126cb45 633d54c4

+33 -14
+23 -6
arch/x86/include/asm/fpu/types.h
··· 141 141 }; 142 142 143 143 /* Intel MPX support: */ 144 - struct bndreg { 144 + 145 + struct mpx_bndreg { 145 146 u64 lower_bound; 146 147 u64 upper_bound; 147 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 162 u64 bndcfgu; 151 163 u64 bndstatus; 152 164 } __packed; 153 165 154 - struct mpx_struct { 155 - struct bndreg bndreg[4]; 156 - struct bndcsr bndcsr; 157 - }; 166 + /* 167 + * The BNDCSR state is padded out to be 64-bytes in size. 168 + */ 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 176 struct xstate_header { 160 177 u64 xfeatures;
+4 -3
arch/x86/include/asm/trace/mpx.h
··· 11 11 TRACE_EVENT(mpx_bounds_register_exception, 12 12 13 13 TP_PROTO(void *addr_referenced, 14 - const struct bndreg *bndreg), 14 + const struct mpx_bndreg *bndreg), 15 15 TP_ARGS(addr_referenced, bndreg), 16 16 17 17 TP_STRUCT__entry( ··· 44 44 45 45 TRACE_EVENT(bounds_exception_mpx, 46 46 47 - TP_PROTO(const struct bndcsr *bndcsr), 47 + TP_PROTO(const struct mpx_bndcsr *bndcsr), 48 48 TP_ARGS(bndcsr), 49 49 50 50 TP_STRUCT__entry( ··· 116 116 /* 117 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
+1 -1
arch/x86/kernel/traps.c
··· 361 361 362 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 365 siginfo_t *info; 366 366 367 367 RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU");
+5 -4
arch/x86/mm/mpx.c
··· 237 237 */ 238 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 242 siginfo_t *info = NULL; 242 243 struct insn insn; 243 244 uint8_t bndregno; ··· 265 264 goto err_out; 266 265 } 267 266 /* now go select the individual register in the set of 4 */ 268 - bndreg = &bndregs[bndregno]; 267 + bndreg = &bndregs->bndreg[bndregno]; 269 268 270 269 info = kzalloc(sizeof(*info), GFP_KERNEL); 271 270 if (!info) { ··· 307 306 308 307 static __user void *mpx_get_bounds_dir(void) 309 308 { 310 - const struct bndcsr *bndcsr; 309 + const struct mpx_bndcsr *bndcsr; 311 310 312 311 if (!cpu_feature_enabled(X86_FEATURE_MPX)) 313 312 return MPX_INVALID_BOUNDS_DIR; ··· 490 489 static int do_mpx_bt_fault(void) 491 490 { 492 491 unsigned long bd_entry, bd_base; 493 - const struct bndcsr *bndcsr; 492 + const struct mpx_bndcsr *bndcsr; 494 493 struct mm_struct *mm = current->mm; 495 494 496 495 bndcsr = get_xsave_field_ptr(XFEATURE_MASK_BNDCSR);