[kvm-unit-tests PATCH] x86: apic: test self-IPI in xAPIC mode

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

 



Add self-IPI checks for both xAPIC and x2APIC explicitly as two separate
tests.  Both tests try to set up their respective mode (xAPIC or x2APIC)
and reset the mode to what was enabled before. If x2APIC is unsupported,
the x2APIC test is just skipped.

There was already a self-IPI test, test_self_ipi, that used x2APIC mode
if supported, and xAPIC otherwise.  This happened because test_self_ipi
used whatever mode was enabled before, and test_enable_x2apic (which
runs before) tries to enable x2APIC mode but falls back to legacy xAPIC
mode when x2APIC is unsupported.

Tested the case where x2apic is unsupported with:
./x86-run ./x86/apic.flat -smp 2 -cpu qemu64,-x2apic

Signed-off-by: Ricardo Koller <ricarkol@xxxxxxxxxx>
Reviewed-by: Jim Mattson <jmattson@xxxxxxxxxx>
Reviewed-by: Peter Shier <pshier@xxxxxxxxxx>
---
 x86/apic.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 48 insertions(+), 2 deletions(-)

diff --git a/x86/apic.c b/x86/apic.c
index a7681fea836c7..735022b7891f5 100644
--- a/x86/apic.c
+++ b/x86/apic.c
@@ -266,7 +266,7 @@ static void self_ipi_isr(isr_regs_t *regs)
     eoi();
 }
 
-static void test_self_ipi(void)
+static void __test_self_ipi(void)
 {
     u64 start = rdtsc();
     int vec = 0xf1;
@@ -279,8 +279,53 @@ static void test_self_ipi(void)
     do {
         pause();
     } while (rdtsc() - start < 1000000000 && ipi_count == 0);
+}
+
+static void test_self_ipi_xapic(void)
+{
+    u64 orig_apicbase = rdmsr(MSR_IA32_APICBASE);
+
+    report_prefix_push("self_ipi_xapic");
+
+    /* Reset to xAPIC mode. */
+    reset_apic();
+    report((rdmsr(MSR_IA32_APICBASE) & (APIC_EN | APIC_EXTD)) == APIC_EN,
+           "Local apic enabled in xAPIC mode");
 
+    ipi_count = 0;
+    __test_self_ipi();
     report(ipi_count == 1, "self ipi");
+
+    /* Enable x2APIC mode if it was already enabled. */
+    if (orig_apicbase & APIC_EXTD)
+        enable_x2apic();
+
+    report_prefix_pop();
+}
+
+static void test_self_ipi_x2apic(void)
+{
+    u64 orig_apicbase = rdmsr(MSR_IA32_APICBASE);
+
+    report_prefix_push("self_ipi_x2apic");
+
+    if (enable_x2apic()) {
+        report((rdmsr(MSR_IA32_APICBASE) & (APIC_EN | APIC_EXTD)) ==
+               (APIC_EN | APIC_EXTD),
+               "Local apic enabled in x2APIC mode");
+
+        ipi_count = 0;
+        __test_self_ipi();
+        report(ipi_count == 1, "self ipi");
+
+        /* Reset to xAPIC mode unless x2APIC was already enabled. */
+        if (!(orig_apicbase & APIC_EXTD))
+            reset_apic();
+    } else {
+        report_skip("x2apic not detected");
+    }
+
+    report_prefix_pop();
 }
 
 volatile int nmi_counter_private, nmi_counter, nmi_hlt_counter, sti_loop_active;
@@ -657,7 +702,8 @@ int main(void)
     test_enable_x2apic();
     test_apicbase();
 
-    test_self_ipi();
+    test_self_ipi_xapic();
+    test_self_ipi_x2apic();
     test_physical_broadcast();
     if (test_device_enabled())
         test_pv_ipi();
-- 
2.29.1.341.ge80a0c044ae-goog




[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