On 29/10/20 23:56, Ricardo Koller wrote: > 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(); > Queued, thanks. Paolo