x86/fpu: Check CPU-provided sizes against struct declarations
We now have C structures defined for each of the XSAVE state components that we support. This patch adds checks during our verification pass to ensure that the CPU-provided data enumerated in CPUID leaves matches our C structures. If not, we warn and dump all the XSAVE CPUID leaves. Note: this *actually* found an inconsistency with the MPX 'bndcsr' state. The hardware pads it out differently from our C structures. This patch caught it and warned. 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/20150902233131.A8DB36DA@viggo.jf.intel.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
parent
e6e888f96b
commit
ef78f2a4bf
|
@ -432,6 +432,49 @@ static void __xstate_dump_leaves(void)
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
#define XCHECK_SZ(sz, nr, nr_macro, __struct) do { \
|
||||
if ((nr == nr_macro) && \
|
||||
WARN_ONCE(sz != sizeof(__struct), \
|
||||
"%s: struct is %zu bytes, cpu state %d bytes\n", \
|
||||
__stringify(nr_macro), sizeof(__struct), sz)) { \
|
||||
__xstate_dump_leaves(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* We have a C struct for each 'xstate'. We need to ensure
|
||||
* that our software representation matches what the CPU
|
||||
* tells us about the state's size.
|
||||
*/
|
||||
static void check_xstate_against_struct(int nr)
|
||||
{
|
||||
/*
|
||||
* Ask the CPU for the size of the state.
|
||||
*/
|
||||
int sz = xfeature_size(nr);
|
||||
/*
|
||||
* Match each CPU state with the corresponding software
|
||||
* structure.
|
||||
*/
|
||||
XCHECK_SZ(sz, nr, XFEATURE_YMM, struct ymmh_struct);
|
||||
XCHECK_SZ(sz, nr, XFEATURE_BNDREGS, struct mpx_bndreg_state);
|
||||
XCHECK_SZ(sz, nr, XFEATURE_BNDCSR, struct mpx_bndcsr_state);
|
||||
XCHECK_SZ(sz, nr, XFEATURE_OPMASK, struct avx_512_opmask_state);
|
||||
XCHECK_SZ(sz, nr, XFEATURE_ZMM_Hi256, struct avx_512_zmm_uppers_state);
|
||||
XCHECK_SZ(sz, nr, XFEATURE_Hi16_ZMM, struct avx_512_hi16_state);
|
||||
|
||||
/*
|
||||
* Make *SURE* to add any feature numbers in below if
|
||||
* there are "holes" in the xsave state component
|
||||
* numbers.
|
||||
*/
|
||||
if ((nr < XFEATURE_YMM) ||
|
||||
(nr >= XFEATURE_MAX)) {
|
||||
WARN_ONCE(1, "no structure for xstate: %d\n", nr);
|
||||
XSTATE_WARN_ON(1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This essentially double-checks what the cpu told us about
|
||||
* how large the XSAVE buffer needs to be. We are recalculating
|
||||
|
@ -445,6 +488,8 @@ static void do_extra_xstate_size_checks(void)
|
|||
for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) {
|
||||
if (!xfeature_enabled(i))
|
||||
continue;
|
||||
|
||||
check_xstate_against_struct(i);
|
||||
/*
|
||||
* Supervisor state components can be managed only by
|
||||
* XSAVES, which is compacted-format only.
|
||||
|
|
Loading…
Reference in New Issue