From 1295ca1d26b84932b69f876ac432ce07133c7881 Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Thu, 9 Nov 2017 12:09:06 +0000 Subject: [PATCH] x86: Split out new msr.h header Move the {rd,wr}msr wrappers from lib.h and bitfield unions from msr-index.h to here, leaving msr-index.h to be purely name definitions. Correct an XFT typo in the msr-index.h header guards, and include msr.h in arch/xtf.h to avoid tests needing to include msr-index.h manually Signed-off-by: Andrew Cooper --- arch/x86/include/arch/lib.h | 48 +----------- arch/x86/include/arch/msr-index.h | 39 ++-------- arch/x86/include/arch/msr.h | 120 ++++++++++++++++++++++++++++++ arch/x86/include/arch/xtf.h | 1 + tests/cpuid-faulting/main.c | 1 - tests/invlpg/main.c | 1 - tests/lbr-tsx-vmentry/main.c | 2 - tests/vvmx/test.h | 1 - tests/xsa-193/main.c | 2 - tests/xsa-204/main.c | 1 - 10 files changed, 130 insertions(+), 86 deletions(-) create mode 100644 arch/x86/include/arch/msr.h diff --git a/arch/x86/include/arch/lib.h b/arch/x86/include/arch/lib.h index 82eb7da..6714bdc 100644 --- a/arch/x86/include/arch/lib.h +++ b/arch/x86/include/arch/lib.h @@ -5,53 +5,7 @@ #include #include #include - -static inline uint64_t rdmsr(uint32_t idx) -{ - uint32_t lo, hi; - - asm volatile("rdmsr": "=a" (lo), "=d" (hi): "c" (idx)); - - return (((uint64_t)hi) << 32) | lo; -} - -static inline bool rdmsr_safe(uint32_t idx, uint64_t *val) -{ - uint32_t lo, hi, new_idx; - - asm volatile("1: rdmsr; 2:" - _ASM_EXTABLE_HANDLER(1b, 2b, ex_rdmsr_safe) - : "=a" (lo), "=d" (hi), "=c" (new_idx) - : "c" (idx), "X" (ex_rdmsr_safe)); - - bool fault = idx != new_idx; - - if ( !fault ) - *val = (((uint64_t)hi) << 32) | lo; - - return fault; -} - -static inline void wrmsr(uint32_t idx, uint64_t val) -{ - asm volatile ("wrmsr": - : "c" (idx), "a" ((uint32_t)val), - "d" ((uint32_t)(val >> 32))); -} - -static inline bool wrmsr_safe(uint32_t idx, uint64_t val) -{ - uint32_t new_idx; - - asm volatile ("1: wrmsr; 2:" - _ASM_EXTABLE_HANDLER(1b, 2b, ex_wrmsr_safe) - : "=c" (new_idx) - : "c" (idx), "a" ((uint32_t)val), - "d" ((uint32_t)(val >> 32)), - "X" (ex_wrmsr_safe)); - - return idx != new_idx; -} +#include static inline void cpuid(uint32_t leaf, uint32_t *eax, uint32_t *ebx, diff --git a/arch/x86/include/arch/msr-index.h b/arch/x86/include/arch/msr-index.h index d5cf57f..6e7e144 100644 --- a/arch/x86/include/arch/msr-index.h +++ b/arch/x86/include/arch/msr-index.h @@ -1,5 +1,10 @@ -#ifndef XFT_X86_MSR_INDEX_H -#define XFT_X86_MSR_INDEX_H +/** + * @file arch/x86/include/arch/msr.h + * + * Model Specific Register mnemonics and bit definitions. + */ +#ifndef XTF_X86_MSR_INDEX_H +#define XTF_X86_MSR_INDEX_H #include @@ -66,35 +71,7 @@ #define MSR_GS_BASE 0xc0000101 #define MSR_SHADOW_GS_BASE 0xc0000102 -#ifndef __ASSEMBLY__ -#include - -typedef union msr_feature_control { - uint64_t raw; - struct { - bool lock:1, - vmxon_inside_smx:1, - vmxon_outside_smx:1; - }; -} msr_feature_control_t; - -typedef union msr_vmx_basic { - uint64_t raw; - struct { - uint32_t vmcs_rev_id:31; - bool mbz:1; - uint32_t vmcs_size:13; - uint32_t :3; - bool paddr_32bit:1; - bool smm_dual:1; - uint32_t vmcs_mem_type:4; - bool inouts_exit_info:1; - bool true_ctls:1; - }; -} msr_vmx_basic_t; - -#endif /* !__ASSEMBLY__ */ -#endif /* XFT_X86_MSR_INDEX_H */ +#endif /* XTF_X86_MSR_INDEX_H */ /* * Local variables: diff --git a/arch/x86/include/arch/msr.h b/arch/x86/include/arch/msr.h new file mode 100644 index 0000000..3c58eaf --- /dev/null +++ b/arch/x86/include/arch/msr.h @@ -0,0 +1,120 @@ +/** + * @file arch/x86/include/arch/msr.h + * + * Misc C-level infrastructure for MSRs. + */ +#ifndef XTF_X86_MSR_H +#define XTF_X86_MSR_H + +#include +#include + +#include + +#include + +/** + * Thin wrapper around an `rdmsr` instruction. May crash with @#GP[0]. + */ +static inline uint64_t rdmsr(uint32_t idx) +{ + uint32_t lo, hi; + + asm volatile ("rdmsr": "=a" (lo), "=d" (hi): "c" (idx)); + + return (((uint64_t)hi) << 32) | lo; +} + +/** + * Wrapper around `rdmsr` which safely catches @#GP[0]. + * + * @param idx MSR to read + * @param [out] val Value, if no fault occurred. + * @return boolean indicating whether the read faulted. + */ +static inline bool rdmsr_safe(uint32_t idx, uint64_t *val) +{ + uint32_t lo, hi, new_idx; + + asm volatile ("1: rdmsr; 2:" + _ASM_EXTABLE_HANDLER(1b, 2b, ex_rdmsr_safe) + : "=a" (lo), "=d" (hi), "=c" (new_idx) + : "c" (idx), "X" (ex_rdmsr_safe)); + + bool fault = idx != new_idx; + + if ( !fault ) + *val = (((uint64_t)hi) << 32) | lo; + + return fault; +} + +/** + * Thin wrapper around an `wrmsr` instruction. May crash with @#GP[0]. + */ +static inline void wrmsr(uint32_t idx, uint64_t val) +{ + asm volatile ("wrmsr": + : "c" (idx), "a" ((uint32_t)val), + "d" ((uint32_t)(val >> 32))); +} + +/** + * Wrapper around `wrmsr` which safely catches @#GP[0]. + * + * @param idx MSR to write + * @param val Value to write + * @return boolean indicating whether the write faulted. + */ +static inline bool wrmsr_safe(uint32_t idx, uint64_t val) +{ + uint32_t new_idx; + + asm volatile ("1: wrmsr; 2:" + _ASM_EXTABLE_HANDLER(1b, 2b, ex_wrmsr_safe) + : "=c" (new_idx) + : "c" (idx), "a" ((uint32_t)val), + "d" ((uint32_t)(val >> 32)), + "X" (ex_wrmsr_safe)); + + return idx != new_idx; +} + +/* + * Types wrapping MSR content. + */ +typedef union msr_feature_control { + uint64_t raw; + struct { + bool lock:1, + vmxon_inside_smx:1, + vmxon_outside_smx:1; + }; +} msr_feature_control_t; + +typedef union msr_vmx_basic { + uint64_t raw; + struct { + uint32_t vmcs_rev_id:31; + bool mbz:1; + uint32_t vmcs_size:13; + uint32_t :3; + bool paddr_32bit:1; + bool smm_dual:1; + uint32_t vmcs_mem_type:4; + bool inouts_exit_info:1; + bool true_ctls:1; + }; +} msr_vmx_basic_t; + +#endif /* XTF_X86_MSR_H */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/arch/x86/include/arch/xtf.h b/arch/x86/include/arch/xtf.h index c1f028a..f860b32 100644 --- a/arch/x86/include/arch/xtf.h +++ b/arch/x86/include/arch/xtf.h @@ -3,6 +3,7 @@ #include #include +#include extern char _end[]; diff --git a/tests/cpuid-faulting/main.c b/tests/cpuid-faulting/main.c index 23fa6ca..3bab8fa 100644 --- a/tests/cpuid-faulting/main.c +++ b/tests/cpuid-faulting/main.c @@ -22,7 +22,6 @@ #include #include -#include #include const char test_title[] = "Guest CPUID Faulting support"; diff --git a/tests/invlpg/main.c b/tests/invlpg/main.c index c62c92e..2e5c519 100644 --- a/tests/invlpg/main.c +++ b/tests/invlpg/main.c @@ -84,7 +84,6 @@ #include #include -#include #include const char test_title[] = "Invlpg tests"; diff --git a/tests/lbr-tsx-vmentry/main.c b/tests/lbr-tsx-vmentry/main.c index 734e9cd..75f8059 100644 --- a/tests/lbr-tsx-vmentry/main.c +++ b/tests/lbr-tsx-vmentry/main.c @@ -34,8 +34,6 @@ */ #include -#include - const char test_title[] = "LBR/TSX VMentry failure test"; static void int3_stub(void) diff --git a/tests/vvmx/test.h b/tests/vvmx/test.h index 0e32ce5..5d9664f 100644 --- a/tests/vvmx/test.h +++ b/tests/vvmx/test.h @@ -3,7 +3,6 @@ #include -#include #include /* diff --git a/tests/xsa-193/main.c b/tests/xsa-193/main.c index e93c67c..312f520 100644 --- a/tests/xsa-193/main.c +++ b/tests/xsa-193/main.c @@ -19,8 +19,6 @@ */ #include -#include - const char test_title[] = "XSA-193 PoC"; void test_main(void) diff --git a/tests/xsa-204/main.c b/tests/xsa-204/main.c index 6618aa3..3d1406f 100644 --- a/tests/xsa-204/main.c +++ b/tests/xsa-204/main.c @@ -21,7 +21,6 @@ */ #include -#include #include bool test_needs_fep = true; -- 2.39.5