[RFC PATCH 2/2] KVM: selftests: APIC_ID must be correctly updated when disabling x2apic

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Make sure the APIC_ID is correctly shifted in the right bit positions
when disabling x2APIC via KVM_SET_MSRS.

Signed-off-by: Emanuele Giuseppe Esposito <eesposit@xxxxxxxxxx>
---
 .../selftests/kvm/x86_64/xapic_state_test.c   | 64 +++++++++++++++++++
 1 file changed, 64 insertions(+)

diff --git a/tools/testing/selftests/kvm/x86_64/xapic_state_test.c b/tools/testing/selftests/kvm/x86_64/xapic_state_test.c
index d7d37dae3eeb..6ebda7162a25 100644
--- a/tools/testing/selftests/kvm/x86_64/xapic_state_test.c
+++ b/tools/testing/selftests/kvm/x86_64/xapic_state_test.c
@@ -132,6 +132,62 @@ static void test_icr(struct xapic_vcpu *x)
 	__test_icr(x, -1ull & ~APIC_DM_FIXED_MASK);
 }
 
+static void _test_lapic_id(struct kvm_vcpu *vcpu, bool x2apic_enabled,
+			   int expected_id)
+{
+	struct kvm_lapic_state xapic;
+
+	vcpu_ioctl(vcpu, KVM_GET_LAPIC, &xapic);
+	if (x2apic_enabled)
+		ASSERT_EQ(xapic.regs[APIC_ID], expected_id);
+	else
+		ASSERT_EQ(xapic.regs[0x23], expected_id);
+
+}
+
+static void test_apic_id(struct kvm_vcpu *vcpu, int id)
+{
+	int ret;
+	struct {
+		struct kvm_msrs info;
+		struct kvm_msr_entry entries[1];
+	} msr_data = {
+		.info.nmsrs = 1,
+		.entries[0].index = MSR_IA32_APICBASE,
+	};
+
+	/* vcpu is initialized with xAPIC enabled */
+	ret = __vcpu_ioctl(vcpu, KVM_GET_MSRS, &msr_data.info);
+	TEST_ASSERT(ret == 1, __KVM_IOCTL_ERROR("__vcpu_ioctl", ret));
+	ASSERT_EQ(msr_data.entries[0].data & MSR_IA32_APICBASE_ENABLE,
+		  MSR_IA32_APICBASE_ENABLE);
+	ASSERT_EQ(msr_data.entries[0].data & X2APIC_ENABLE, 0);
+	_test_lapic_id(vcpu, false, id);
+
+	/* enable x2APIC */
+	msr_data.entries[0].data |= X2APIC_ENABLE;
+	ret = __vcpu_ioctl(vcpu, KVM_SET_MSRS, &msr_data.info);
+	TEST_ASSERT(ret == 1, __KVM_IOCTL_ERROR("__vcpu_ioctl", ret));
+	ASSERT_EQ(msr_data.entries[0].data & MSR_IA32_APICBASE_ENABLE,
+		  MSR_IA32_APICBASE_ENABLE);
+	ASSERT_EQ(msr_data.entries[0].data & X2APIC_ENABLE, X2APIC_ENABLE);
+	_test_lapic_id(vcpu, true, id);
+
+	/*
+	 * Check that disabling x2APIC correctly updates the APIC ID to the
+	 * xAPIC format.
+	 */
+	msr_data.entries[0].data ^= X2APIC_ENABLE;
+	ret = __vcpu_ioctl(vcpu, KVM_SET_MSRS, &msr_data.info);
+	TEST_ASSERT(ret == 1, __KVM_IOCTL_ERROR("__vcpu_ioctl", ret));
+	ASSERT_EQ(msr_data.entries[0].data & MSR_IA32_APICBASE_ENABLE,
+		  MSR_IA32_APICBASE_ENABLE);
+	ASSERT_EQ(msr_data.entries[0].data & X2APIC_ENABLE, 0);
+	_test_lapic_id(vcpu, false, id);
+}
+
+#define NCPUS 3
+
 int main(int argc, char *argv[])
 {
 	struct xapic_vcpu x = {
@@ -139,6 +195,14 @@ int main(int argc, char *argv[])
 		.is_x2apic = true,
 	};
 	struct kvm_vm *vm;
+	struct kvm_vcpu *vcpus[NCPUS] = { 0 };
+	int i;
+
+	vm = vm_create_with_vcpus(NCPUS, NULL, vcpus);
+	vm_enable_cap(vm, KVM_CAP_X2APIC_API, KVM_X2APIC_API_USE_32BIT_IDS);
+	for (i = 0; i < NCPUS; i++)
+		test_apic_id(vcpus[i], i);
+	kvm_vm_free(vm);
 
 	vm = vm_create_with_one_vcpu(&x.vcpu, x2apic_guest_code);
 	test_icr(&x);
-- 
2.31.1




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux