Commit b5e66df3 authored by Sean Christopherson's avatar Sean Christopherson
Browse files

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: default avatarDapeng Mi <dapeng1.mi@linux.intel.com>
Link: https://lore.kernel.org/r/20240109230250.424295-29-seanjc@google.com


Signed-off-by: default avatarSean Christopherson <seanjc@google.com>
parent ab3b6a7d
Loading
Loading
Loading
Loading
+26 −12
Original line number Diff line number Diff line
@@ -1216,20 +1216,34 @@ 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;
#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;							\
}

	asm volatile(KVM_ASM_SAFE("rdmsr")
		     : "=a"(a), "=d"(d), KVM_ASM_SAFE_OUTPUTS(vector, error_code)
		     : "c"(msr)
		     : KVM_ASM_SAFE_CLOBBERS);
/*
 * 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)			\

	*val = (uint64_t)a | ((uint64_t)d << 32);
	return vector;
}
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)
{