apix mistakenly assumes the LAPIC is enabled
We have code in apix_regops.c:apix_enable_x2apic() that tries to enable the x2APIC (MSR mode). Unfortunately, this code assumes incorrectly that the APIC is already enabled in xAPIC (MMIO) mode:
wrmsr(REG_APIC_BASE_MSR, apic_base_msr);apic_base_msr = rdmsr(REG_APIC_BASE_MSR); apic_base_msr = apic_base_msr | (0x1 << X2APIC_ENABLE_BIT); wrmsr(REG_APIC_BASE_MSR, apic_base_msr);
The original Intel x2APIC specification states that the APIC comes up in xAPIC mode by default (that is, bits 11:10 of APIC_BASE_MSR) are 2b'10. Unfortunately, for reasons unknown and undocumented, AMD's implementation does not; the Milan B1 PPR specifically shows that these bits are 2b'00 at reset. Despite this pointless divergence, AMD did follow the Intel specification in that they also prohibit the transition from APIC disabled --> x2APIC mode. Therefore, we must check the current state of the APIC and ensure that when we wish to enable x2APIC mode, we always first enable the LAPIC if needed. Failing to do this results in a #GP and a panic. While it appears that most AMD PCs set up xAPIC mode in firmware prior to boot, we should not count on this; there is no specification guaranteeing it and in any case firmware is usually buggy. Making this universally correct will also allow sharing this code on machines without firmware.
No data to display