Commit edd1e598 authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

Merge tag 'kvm-x86-selftests-6.13' of https://github.com/kvm-x86/linux into HEAD

KVM selftests changes for 6.13

 - Enable XFAM-based features by default for all selftests VMs, which will
   allow removing the "no AVX" restriction.
parents c59de141 89f88698
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -20,7 +20,6 @@
#define SLEEPING_THREAD_NUM (1 << 4)
#define FORK_NUM (1ULL << 9)
#define DELAY_US_MAX 2000
#define GUEST_CODE_PIO_PORT 4

sem_t *sem;

+5 −0
Original line number Diff line number Diff line
@@ -1049,6 +1049,11 @@ static inline void vcpu_set_cpuid(struct kvm_vcpu *vcpu)
	vcpu_ioctl(vcpu, KVM_GET_CPUID2, vcpu->cpuid);
}

static inline void vcpu_get_cpuid(struct kvm_vcpu *vcpu)
{
	vcpu_ioctl(vcpu, KVM_GET_CPUID2, vcpu->cpuid);
}

void vcpu_set_cpuid_property(struct kvm_vcpu *vcpu,
			     struct kvm_x86_cpu_property property,
			     uint32_t value);
+24 −0
Original line number Diff line number Diff line
@@ -506,6 +506,8 @@ static void vcpu_init_sregs(struct kvm_vm *vm, struct kvm_vcpu *vcpu)

	sregs.cr0 = X86_CR0_PE | X86_CR0_NE | X86_CR0_PG;
	sregs.cr4 |= X86_CR4_PAE | X86_CR4_OSFXSR;
	if (kvm_cpu_has(X86_FEATURE_XSAVE))
		sregs.cr4 |= X86_CR4_OSXSAVE;
	sregs.efer |= (EFER_LME | EFER_LMA | EFER_NX);

	kvm_seg_set_unusable(&sregs.ldt);
@@ -519,6 +521,20 @@ static void vcpu_init_sregs(struct kvm_vm *vm, struct kvm_vcpu *vcpu)
	vcpu_sregs_set(vcpu, &sregs);
}

static void vcpu_init_xcrs(struct kvm_vm *vm, struct kvm_vcpu *vcpu)
{
	struct kvm_xcrs xcrs = {
		.nr_xcrs = 1,
		.xcrs[0].xcr = 0,
		.xcrs[0].value = kvm_cpu_supported_xcr0(),
	};

	if (!kvm_cpu_has(X86_FEATURE_XSAVE))
		return;

	vcpu_xcrs_set(vcpu, &xcrs);
}

static void set_idt_entry(struct kvm_vm *vm, int vector, unsigned long addr,
			  int dpl, unsigned short selector)
{
@@ -675,6 +691,7 @@ struct kvm_vcpu *vm_arch_vcpu_add(struct kvm_vm *vm, uint32_t vcpu_id)
	vcpu = __vm_vcpu_add(vm, vcpu_id);
	vcpu_init_cpuid(vcpu, kvm_get_supported_cpuid());
	vcpu_init_sregs(vm, vcpu);
	vcpu_init_xcrs(vm, vcpu);

	/* Setup guest general purpose registers */
	vcpu_regs_get(vcpu, &regs);
@@ -686,6 +703,13 @@ struct kvm_vcpu *vm_arch_vcpu_add(struct kvm_vm *vm, uint32_t vcpu_id)
	mp_state.mp_state = 0;
	vcpu_mp_state_set(vcpu, &mp_state);

	/*
	 * Refresh CPUID after setting SREGS and XCR0, so that KVM's "runtime"
	 * updates to guest CPUID, e.g. for OSXSAVE and XSAVE state size, are
	 * reflected into selftests' vCPU CPUID cache, i.e. so that the cache
	 * is consistent with vCPU state.
	 */
	vcpu_get_cpuid(vcpu);
	return vcpu;
}

+4 −19
Original line number Diff line number Diff line
@@ -86,6 +86,8 @@ static inline void __xsavec(struct xstate *xstate, uint64_t rfbm)

static void check_xtile_info(void)
{
	GUEST_ASSERT((xgetbv(0) & XFEATURE_MASK_XTILE) == XFEATURE_MASK_XTILE);

	GUEST_ASSERT(this_cpu_has_p(X86_PROPERTY_XSTATE_MAX_SIZE_XCR0));
	GUEST_ASSERT(this_cpu_property(X86_PROPERTY_XSTATE_MAX_SIZE_XCR0) <= XSAVE_SIZE);

@@ -122,29 +124,12 @@ static void set_tilecfg(struct tile_config *cfg)
	}
}

static void init_regs(void)
{
	uint64_t cr4, xcr0;

	GUEST_ASSERT(this_cpu_has(X86_FEATURE_XSAVE));

	/* turn on CR4.OSXSAVE */
	cr4 = get_cr4();
	cr4 |= X86_CR4_OSXSAVE;
	set_cr4(cr4);
	GUEST_ASSERT(this_cpu_has(X86_FEATURE_OSXSAVE));

	xcr0 = xgetbv(0);
	xcr0 |= XFEATURE_MASK_XTILE;
	xsetbv(0x0, xcr0);
	GUEST_ASSERT((xgetbv(0) & XFEATURE_MASK_XTILE) == XFEATURE_MASK_XTILE);
}

static void __attribute__((__flatten__)) guest_code(struct tile_config *amx_cfg,
						    struct tile_data *tiledata,
						    struct xstate *xstate)
{
	init_regs();
	GUEST_ASSERT(this_cpu_has(X86_FEATURE_XSAVE) &&
		     this_cpu_has(X86_FEATURE_OSXSAVE));
	check_xtile_info();
	GUEST_SYNC(1);

+43 −26
Original line number Diff line number Diff line
@@ -12,17 +12,16 @@
#include "kvm_util.h"
#include "processor.h"

/* CPUIDs known to differ */
struct cpuid_mask {
	union {
		struct {
	u32 function;
	u32 index;
} mangled_cpuids[] = {
	/*
	 * These entries depend on the vCPU's XCR0 register and IA32_XSS MSR,
	 * which are not controlled for by this test.
	 */
	{.function = 0xd, .index = 0},
	{.function = 0xd, .index = 1},
			u32 eax;
			u32 ebx;
			u32 ecx;
			u32 edx;
		};
		u32 regs[4];
	};
};

static void test_guest_cpuids(struct kvm_cpuid2 *guest_cpuid)
@@ -56,17 +55,29 @@ static void guest_main(struct kvm_cpuid2 *guest_cpuid)
	GUEST_DONE();
}

static bool is_cpuid_mangled(const struct kvm_cpuid_entry2 *entrie)
static struct cpuid_mask get_const_cpuid_mask(const struct kvm_cpuid_entry2 *entry)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(mangled_cpuids); i++) {
		if (mangled_cpuids[i].function == entrie->function &&
		    mangled_cpuids[i].index == entrie->index)
			return true;
	struct cpuid_mask mask;

	memset(&mask, 0xff, sizeof(mask));

	switch (entry->function) {
	case 0x1:
		mask.regs[X86_FEATURE_OSXSAVE.reg] &= ~BIT(X86_FEATURE_OSXSAVE.bit);
		break;
	case 0x7:
		mask.regs[X86_FEATURE_OSPKE.reg] &= ~BIT(X86_FEATURE_OSPKE.bit);
		break;
	case 0xd:
		/*
		 * CPUID.0xD.{0,1}.EBX enumerate XSAVE size based on the current
		 * XCR0 and IA32_XSS MSR values.
		 */
		if (entry->index < 2)
			mask.ebx = 0;
		break;
	}

	return false;
	return mask;
}

static void compare_cpuids(const struct kvm_cpuid2 *cpuid1,
@@ -79,6 +90,8 @@ static void compare_cpuids(const struct kvm_cpuid2 *cpuid1,
		    "CPUID nent mismatch: %d vs. %d", cpuid1->nent, cpuid2->nent);

	for (i = 0; i < cpuid1->nent; i++) {
		struct cpuid_mask mask;

		e1 = &cpuid1->entries[i];
		e2 = &cpuid2->entries[i];

@@ -88,15 +101,19 @@ static void compare_cpuids(const struct kvm_cpuid2 *cpuid1,
			    i, e1->function, e1->index, e1->flags,
			    e2->function, e2->index, e2->flags);

		if (is_cpuid_mangled(e1))
			continue;
		/* Mask off dynamic bits, e.g. OSXSAVE, when comparing entries. */
		mask = get_const_cpuid_mask(e1);

		TEST_ASSERT(e1->eax == e2->eax && e1->ebx == e2->ebx &&
			    e1->ecx == e2->ecx && e1->edx == e2->edx,
		TEST_ASSERT((e1->eax & mask.eax) == (e2->eax & mask.eax) &&
			    (e1->ebx & mask.ebx) == (e2->ebx & mask.ebx) &&
			    (e1->ecx & mask.ecx) == (e2->ecx & mask.ecx) &&
			    (e1->edx & mask.edx) == (e2->edx & mask.edx),
			    "CPUID 0x%x.%x differ: 0x%x:0x%x:0x%x:0x%x vs 0x%x:0x%x:0x%x:0x%x",
			    e1->function, e1->index,
			    e1->eax, e1->ebx, e1->ecx, e1->edx,
			    e2->eax, e2->ebx, e2->ecx, e2->edx);
			    e1->eax & mask.eax, e1->ebx & mask.ebx,
			    e1->ecx & mask.ecx, e1->edx & mask.edx,
			    e2->eax & mask.eax, e2->ebx & mask.ebx,
			    e2->ecx & mask.ecx, e2->edx & mask.edx);
	}
}

Loading