Move the "safe" helpers for XSETBV and XGETBV to processor.h, and convert them to use asm_safe() and other common macros as appropriate. Signed-off-by: Sean Christopherson <seanjc@xxxxxxxxxx> --- lib/x86/processor.h | 22 +++++++++++++++++++--- x86/xsave.c | 31 +++---------------------------- 2 files changed, 22 insertions(+), 31 deletions(-) diff --git a/lib/x86/processor.h b/lib/x86/processor.h index 243eacde..54f3bdbb 100644 --- a/lib/x86/processor.h +++ b/lib/x86/processor.h @@ -430,6 +430,14 @@ static inline void wrmsr(u32 index, u64 val) vector; \ }) +#define wrreg64_safe(insn, index, val) \ +({ \ + uint32_t eax = (val), edx = (val) >> 32; \ + \ + asm_safe(insn, "a" (eax), "d" (edx), "c" (index)); \ +}) + + static inline int rdmsr_safe(u32 index, uint64_t *val) { return rdreg64_safe("rdmsr", index, val); @@ -437,9 +445,7 @@ static inline int rdmsr_safe(u32 index, uint64_t *val) static inline int wrmsr_safe(u32 index, u64 val) { - u32 a = val, d = val >> 32; - - return asm_safe("wrmsr", "a"(a), "d"(d), "c"(index)); + return wrreg64_safe("wrmsr", index, val); } static inline int rdpmc_safe(u32 index, uint64_t *val) @@ -457,6 +463,16 @@ static inline uint64_t rdpmc(uint32_t index) return val; } +static inline int xgetbv_safe(u32 index, u64 *result) +{ + return rdreg64_safe(".byte 0x0f,0x01,0xd0", index, result); +} + +static inline int xsetbv_safe(u32 index, u64 value) +{ + return wrreg64_safe(".byte 0x0f,0x01,0xd1", index, value); +} + static inline int write_cr0_safe(ulong val) { return asm_safe("mov %0,%%cr0", "r" (val)); diff --git a/x86/xsave.c b/x86/xsave.c index 39a55d66..5d80f245 100644 --- a/x86/xsave.c +++ b/x86/xsave.c @@ -8,31 +8,6 @@ #define uint64_t unsigned long long #endif -static int xgetbv_checking(u32 index, u64 *result) -{ - u32 eax, edx; - - asm volatile(ASM_TRY("1f") - ".byte 0x0f,0x01,0xd0\n\t" /* xgetbv */ - "1:" - : "=a" (eax), "=d" (edx) - : "c" (index)); - *result = eax + ((u64)edx << 32); - return exception_vector(); -} - -static int xsetbv_safe(u32 index, u64 value) -{ - u32 eax = value; - u32 edx = value >> 32; - - asm volatile(ASM_TRY("1f") - ".byte 0x0f,0x01,0xd1\n\t" /* xsetbv */ - "1:" - : : "a" (eax), "d" (edx), "c" (index)); - return exception_vector(); -} - static uint64_t get_supported_xcr0(void) { struct cpuid r; @@ -78,7 +53,7 @@ static void test_xsave(void) test_bits = XSTATE_FP | XSTATE_SSE; report(xsetbv_safe(XCR_XFEATURE_ENABLED_MASK, test_bits) == 0, "\t\txsetbv(XCR_XFEATURE_ENABLED_MASK, XSTATE_FP | XSTATE_SSE)"); - report(xgetbv_checking(XCR_XFEATURE_ENABLED_MASK, &xcr0) == 0, + report(xgetbv_safe(XCR_XFEATURE_ENABLED_MASK, &xcr0) == 0, " xgetbv(XCR_XFEATURE_ENABLED_MASK)"); printf("\tIllegal tests\n"); @@ -123,7 +98,7 @@ static void test_xsave(void) "\t\txsetbv(XCR_XFEATURE_ENABLED_MASK, XSTATE_FP | XSTATE_SSE) - expect #UD"); printf("\tIllegal tests:\n"); - report(xgetbv_checking(XCR_XFEATURE_ENABLED_MASK, &xcr0) == UD_VECTOR, + report(xgetbv_safe(XCR_XFEATURE_ENABLED_MASK, &xcr0) == UD_VECTOR, "\txgetbv(XCR_XFEATURE_ENABLED_MASK) - expect #UD"); } @@ -141,7 +116,7 @@ static void test_no_xsave(void) report(write_cr4_safe(cr4 | X86_CR4_OSXSAVE) == GP_VECTOR, "Set OSXSAVE in CR4 - expect #GP"); - report(xgetbv_checking(XCR_XFEATURE_ENABLED_MASK, &xcr0) == UD_VECTOR, + report(xgetbv_safe(XCR_XFEATURE_ENABLED_MASK, &xcr0) == UD_VECTOR, "Execute xgetbv - expect #UD"); report(xsetbv_safe(XCR_XFEATURE_ENABLED_MASK, 0x3) == UD_VECTOR, -- 2.40.0.348.gf938b09366-goog