[kvm-unit-tests PATCH 1/2] x86: apic: Play nice with x2APIC being enabled when getting "pre-boot" ID

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

 



Retrieve the "pre-boot" APIC ID via the x2APIC interface if x2APIC is
enabled instead of assuming that the APIC is always in xAPIC mode.   EFI
has a catch-22 where it needs the APID ID to initialize the per-vCPU
GS.base, but calling reset_apic() = >disable_apic() needs GS.base to be
correctly initialized in order to set the correct APIC ops.  Play nice
with either xAPIC or x2APIC so that EFI can be used for SMP tests, in
particular the SVM INIT-SIPI tests which send APs back through the boot
sequence while x2APIC is enabled.

Alternatively, disabling x2APIC and updating the APIC ops could be split,
but there's no obvious advantage in doing so.  Retrieving the pre-boot
APIC ID isn't a hot path, i.e. the cost of the RDMSR is likely negligible,
and letting callers force xAPIC without updating the ops isn't any less
fragile.

Signed-off-by: Sean Christopherson <seanjc@xxxxxxxxxx>
---
 lib/x86/apic.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/lib/x86/apic.c b/lib/x86/apic.c
index 5d4c776..eed93fa 100644
--- a/lib/x86/apic.c
+++ b/lib/x86/apic.c
@@ -56,11 +56,6 @@ static uint32_t xapic_id(void)
 	return xapic_read(APIC_ID) >> 24;
 }
 
-uint32_t pre_boot_apic_id(void)
-{
-	return xapic_id();
-}
-
 static const struct apic_ops xapic_ops = {
 	.reg_read = xapic_read,
 	.reg_write = xapic_write,
@@ -165,6 +160,15 @@ int enable_x2apic(void)
 	}
 }
 
+uint32_t pre_boot_apic_id(void)
+{
+	u32 msr_lo, msr_hi;
+
+	asm ("rdmsr" : "=a"(msr_lo), "=d"(msr_hi) : "c"(MSR_IA32_APICBASE));
+
+	return (msr_lo & APIC_EXTD) ? x2apic_id() : xapic_id();
+}
+
 void disable_apic(void)
 {
 	wrmsr(MSR_IA32_APICBASE, rdmsr(MSR_IA32_APICBASE) & ~(APIC_EN | APIC_EXTD));
-- 
2.37.1.359.gd136c6c3e2-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