Commit 8fe09d6a authored by Sean Christopherson's avatar Sean Christopherson
Browse files

KVM: selftests: Set input function/index in raw CPUID helper(s)



Set the function/index for CPUID in the helper instead of relying on the
caller to do so.  In addition to reducing the risk of consuming an
uninitialized ECX, having the function/index embedded in the call makes
it easier to understand what is being checked.

Signed-off-by: default avatarSean Christopherson <seanjc@google.com>
Link: https://lore.kernel.org/r/20220614200707.3315957-32-seanjc@google.com
parent 813e38cd
Loading
Loading
Loading
Loading
+13 −3
Original line number Diff line number Diff line
@@ -404,10 +404,13 @@ static inline void outl(uint16_t port, uint32_t value)
	__asm__ __volatile__("outl %%eax, %%dx" : : "d"(port), "a"(value));
}

static inline void cpuid(uint32_t *eax, uint32_t *ebx,
static inline void __cpuid(uint32_t function, uint32_t index,
			   uint32_t *eax, uint32_t *ebx,
			   uint32_t *ecx, uint32_t *edx)
{
	/* ecx is often an input as well as an output. */
	*eax = function;
	*ecx = index;

	asm volatile("cpuid"
	    : "=a" (*eax),
	      "=b" (*ebx),
@@ -417,6 +420,13 @@ static inline void cpuid(uint32_t *eax, uint32_t *ebx,
	    : "memory");
}

static inline void cpuid(uint32_t function,
			 uint32_t *eax, uint32_t *ebx,
			 uint32_t *ecx, uint32_t *edx)
{
	return __cpuid(function, 0, eax, ebx, ecx, edx);
}

#define SET_XMM(__var, __xmm) \
	asm volatile("movq %0, %%"#__xmm : : "r"(__var) : #__xmm)

+4 −9
Original line number Diff line number Diff line
@@ -1301,9 +1301,7 @@ unsigned long vm_compute_max_gfn(struct kvm_vm *vm)

	/* Before family 17h, the HyperTransport area is just below 1T.  */
	ht_gfn = (1 << 28) - num_ht_pages;
	eax = 1;
	ecx = 0;
	cpuid(&eax, &ebx, &ecx, &edx);
	cpuid(1, &eax, &ebx, &ecx, &edx);
	if (x86_family(eax) < 0x17)
		goto done;

@@ -1312,18 +1310,15 @@ unsigned long vm_compute_max_gfn(struct kvm_vm *vm)
	 * reduced due to SME by bits 11:6 of CPUID[0x8000001f].EBX.  Use
	 * the old conservative value if MAXPHYADDR is not enumerated.
	 */
	eax = 0x80000000;
	cpuid(&eax, &ebx, &ecx, &edx);
	cpuid(0x80000000, &eax, &ebx, &ecx, &edx);
	max_ext_leaf = eax;
	if (max_ext_leaf < 0x80000008)
		goto done;

	eax = 0x80000008;
	cpuid(&eax, &ebx, &ecx, &edx);
	cpuid(0x80000008, &eax, &ebx, &ecx, &edx);
	max_pfn = (1ULL << ((eax & 0xff) - vm->page_shift)) - 1;
	if (max_ext_leaf >= 0x8000001f) {
		eax = 0x8000001f;
		cpuid(&eax, &ebx, &ecx, &edx);
		cpuid(0x8000001f, &eax, &ebx, &ecx, &edx);
		max_pfn >>= (ebx >> 6) & 0x3f;
	}

+4 −15
Original line number Diff line number Diff line
@@ -122,9 +122,7 @@ static inline void check_cpuid_xsave(void)
{
	uint32_t eax, ebx, ecx, edx;

	eax = 1;
	ecx = 0;
	cpuid(&eax, &ebx, &ecx, &edx);
	cpuid(1, &eax, &ebx, &ecx, &edx);
	if (!(ecx & CPUID_XSAVE))
		GUEST_ASSERT(!"cpuid: no CPU xsave support!");
	if (!(ecx & CPUID_OSXSAVE))
@@ -140,10 +138,7 @@ static bool enum_xtile_config(void)
{
	u32 eax, ebx, ecx, edx;

	eax = TILE_CPUID;
	ecx = TILE_PALETTE_CPUID_SUBLEAVE;

	cpuid(&eax, &ebx, &ecx, &edx);
	__cpuid(TILE_CPUID, TILE_PALETTE_CPUID_SUBLEAVE, &eax, &ebx, &ecx, &edx);
	if (!eax || !ebx || !ecx)
		return false;

@@ -165,10 +160,7 @@ static bool enum_xsave_tile(void)
{
	u32 eax, ebx, ecx, edx;

	eax = XSTATE_CPUID;
	ecx = XFEATURE_XTILEDATA;

	cpuid(&eax, &ebx, &ecx, &edx);
	__cpuid(XSTATE_CPUID, XFEATURE_XTILEDATA, &eax, &ebx, &ecx, &edx);
	if (!eax || !ebx)
		return false;

@@ -183,10 +175,7 @@ static bool check_xsave_size(void)
	u32 eax, ebx, ecx, edx;
	bool valid = false;

	eax = XSTATE_CPUID;
	ecx = XSTATE_USER_STATE_SUBLEAVE;

	cpuid(&eax, &ebx, &ecx, &edx);
	__cpuid(XSTATE_CPUID, XSTATE_USER_STATE_SUBLEAVE, &eax, &ebx, &ecx, &edx);
	if (ebx && ebx <= XSAVE_SIZE)
		valid = true;

+5 −6
Original line number Diff line number Diff line
@@ -31,10 +31,9 @@ static void test_guest_cpuids(struct kvm_cpuid2 *guest_cpuid)
	u32 eax, ebx, ecx, edx;

	for (i = 0; i < guest_cpuid->nent; i++) {
		eax = guest_cpuid->entries[i].function;
		ecx = guest_cpuid->entries[i].index;

		cpuid(&eax, &ebx, &ecx, &edx);
		__cpuid(guest_cpuid->entries[i].function,
			guest_cpuid->entries[i].index,
			&eax, &ebx, &ecx, &edx);

		GUEST_ASSERT(eax == guest_cpuid->entries[i].eax &&
			     ebx == guest_cpuid->entries[i].ebx &&
@@ -46,9 +45,9 @@ static void test_guest_cpuids(struct kvm_cpuid2 *guest_cpuid)

static void test_cpuid_40000000(struct kvm_cpuid2 *guest_cpuid)
{
	u32 eax = 0x40000000, ebx, ecx = 0, edx;
	u32 eax, ebx, ecx, edx;

	cpuid(&eax, &ebx, &ecx, &edx);
	cpuid(0x40000000, &eax, &ebx, &ecx, &edx);

	GUEST_ASSERT(eax == 0x40000001);
}