tools/testing/selftests/kvm/x86/msrs_test.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/kvm/x86/msrs_test.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/kvm/x86/msrs_test.c
Extension
.c
Size
14435 bytes
Lines
490
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct kvm_msr {
	const struct kvm_x86_cpu_feature feature;
	const struct kvm_x86_cpu_feature feature2;
	const char *name;
	const u64 reset_val;
	const u64 write_val;
	const u64 rsvd_val;
	const u32 index;
	const bool is_kvm_defined;
};

#define ____MSR_TEST(msr, str, val, rsvd, reset, feat, f2, is_kvm)	\
{									\
	.index = msr,							\
	.name = str,							\
	.write_val = val,						\
	.rsvd_val = rsvd,						\
	.reset_val = reset,						\
	.feature = X86_FEATURE_ ##feat,					\
	.feature2 = X86_FEATURE_ ##f2,					\
	.is_kvm_defined = is_kvm,					\
}

#define __MSR_TEST(msr, str, val, rsvd, reset, feat)			\
	____MSR_TEST(msr, str, val, rsvd, reset, feat, feat, false)

#define MSR_TEST_NON_ZERO(msr, val, rsvd, reset, feat)			\
	__MSR_TEST(msr, #msr, val, rsvd, reset, feat)

#define MSR_TEST(msr, val, rsvd, feat)					\
	__MSR_TEST(msr, #msr, val, rsvd, 0, feat)

#define MSR_TEST2(msr, val, rsvd, feat, f2)				\
	____MSR_TEST(msr, #msr, val, rsvd, 0, feat, f2, false)

/*
 * Note, use a page aligned value for the canonical value so that the value
 * is compatible with MSRs that use bits 11:0 for things other than addresses.
 */
static const u64 canonical_val = 0x123456789000ull;

/*
 * Arbitrary value with bits set in every byte, but not all bits set.  This is
 * also a non-canonical value, but that's coincidental (any 64-bit value with
 * an alternating 0s/1s pattern will be non-canonical).
 */
static const u64 u64_val = 0xaaaa5555aaaa5555ull;

#define MSR_TEST_CANONICAL(msr, feat)					\
	__MSR_TEST(msr, #msr, canonical_val, NONCANONICAL, 0, feat)

#define MSR_TEST_KVM(msr, val, rsvd, feat)				\
	____MSR_TEST(KVM_REG_ ##msr, #msr, val, rsvd, 0, feat, feat, true)

/*
 * The main struct must be scoped to a function due to the use of structures to
 * define features.  For the global structure, allocate enough space for the
 * foreseeable future without getting too ridiculous, to minimize maintenance
 * costs (bumping the array size every time an MSR is added is really annoying).
 */
static struct kvm_msr msrs[128];
static int idx;

static bool ignore_unsupported_msrs;

static u64 fixup_rdmsr_val(u32 msr, u64 want)
{
	/*
	 * AMD CPUs drop bits 63:32 on some MSRs that Intel CPUs support.  KVM
	 * is supposed to emulate that behavior based on guest vendor model
	 * (which is the same as the host vendor model for this test).
	 */
	if (!host_cpu_is_amd_compatible)
		return want;

	switch (msr) {
	case MSR_IA32_SYSENTER_ESP:
	case MSR_IA32_SYSENTER_EIP:
	case MSR_TSC_AUX:
		return want & GENMASK_ULL(31, 0);
	default:
		return want;
	}
}

static void __rdmsr(u32 msr, u64 want)
{
	u64 val;
	u8 vec;

Annotation

Implementation Notes