KVM: selftests: Add helpers for safe and safe+forced RDMSR, RDPMC, and XGETBV
Add helpers for safe and safe-with-forced-emulations versions of RDMSR, RDPMC, and XGETBV. Use macro shenanigans to eliminate the rather large amount of boilerplate needed to get values in and out of registers. Tested-by: Dapeng Mi <dapeng1.mi@linux.intel.com> Link: https://lore.kernel.org/r/20240109230250.424295-29-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com>
This commit is contained in:
@@ -1216,21 +1216,35 @@ void vm_install_exception_handler(struct kvm_vm *vm, int vector,
|
||||
vector; \
|
||||
})
|
||||
|
||||
static inline uint8_t rdmsr_safe(uint32_t msr, uint64_t *val)
|
||||
{
|
||||
uint64_t error_code;
|
||||
uint8_t vector;
|
||||
uint32_t a, d;
|
||||
|
||||
asm volatile(KVM_ASM_SAFE("rdmsr")
|
||||
: "=a"(a), "=d"(d), KVM_ASM_SAFE_OUTPUTS(vector, error_code)
|
||||
: "c"(msr)
|
||||
: KVM_ASM_SAFE_CLOBBERS);
|
||||
|
||||
*val = (uint64_t)a | ((uint64_t)d << 32);
|
||||
return vector;
|
||||
#define BUILD_READ_U64_SAFE_HELPER(insn, _fep, _FEP) \
|
||||
static inline uint8_t insn##_safe ##_fep(uint32_t idx, uint64_t *val) \
|
||||
{ \
|
||||
uint64_t error_code; \
|
||||
uint8_t vector; \
|
||||
uint32_t a, d; \
|
||||
\
|
||||
asm volatile(KVM_ASM_SAFE##_FEP(#insn) \
|
||||
: "=a"(a), "=d"(d), \
|
||||
KVM_ASM_SAFE_OUTPUTS(vector, error_code) \
|
||||
: "c"(idx) \
|
||||
: KVM_ASM_SAFE_CLOBBERS); \
|
||||
\
|
||||
*val = (uint64_t)a | ((uint64_t)d << 32); \
|
||||
return vector; \
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate {insn}_safe() and {insn}_safe_fep() helpers for instructions that
|
||||
* use ECX as in input index, and EDX:EAX as a 64-bit output.
|
||||
*/
|
||||
#define BUILD_READ_U64_SAFE_HELPERS(insn) \
|
||||
BUILD_READ_U64_SAFE_HELPER(insn, , ) \
|
||||
BUILD_READ_U64_SAFE_HELPER(insn, _fep, _FEP) \
|
||||
|
||||
BUILD_READ_U64_SAFE_HELPERS(rdmsr)
|
||||
BUILD_READ_U64_SAFE_HELPERS(rdpmc)
|
||||
BUILD_READ_U64_SAFE_HELPERS(xgetbv)
|
||||
|
||||
static inline uint8_t wrmsr_safe(uint32_t msr, uint64_t val)
|
||||
{
|
||||
return kvm_asm_safe("wrmsr", "a"(val & -1u), "d"(val >> 32), "c"(msr));
|
||||
|
||||
Reference in New Issue
Block a user