x86/apic: Don't access the APIC when disabling x2APIC

With 'iommu=off' on the kernel command line and x2APIC enabled by the BIOS
the code which disables the x2APIC triggers an unchecked MSR access error:

RDMSR from 0x802 at rIP: 0xffffffff94079992 (native_apic_msr_read+0x12/0x50)

This is happens because default_acpi_madt_oem_check() selects an x2APIC
driver before the x2APIC is disabled.

When the x2APIC is disabled because interrupt remapping cannot be enabled
due to 'iommu=off' on the command line, x2apic_disable() invokes
apic_set_fixmap() which in turn tries to read the APIC ID. This triggers
the MSR warning because x2APIC is disabled, but the APIC driver is still
x2APIC based.

Prevent that by adding an argument to apic_set_fixmap() which makes the
APIC ID read out conditional and set it to false from the x2APIC disable
path. That's correct as the APIC ID has already been read out during early
discovery.

Fixes: d10a904435fa ("x86/apic: Consolidate boot_cpu_physical_apicid initialization sites")
Reported-by: Adrian Huang <ahuang12@lenovo.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Tested-by: Adrian Huang <ahuang12@lenovo.com>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/875xw5t6r7.ffs@tglx

authored by Thomas Gleixner and committed by Ingo Molnar 720a22fd 400fea4b

Changed files
+11 -5
arch
x86
kernel
apic
+11 -5
arch/x86/kernel/apic/apic.c
··· 1771 1771 __x2apic_enable(); 1772 1772 } 1773 1773 1774 - static __init void apic_set_fixmap(void); 1774 + static __init void apic_set_fixmap(bool read_apic); 1775 1775 1776 1776 static __init void x2apic_disable(void) 1777 1777 { ··· 1793 1793 } 1794 1794 1795 1795 __x2apic_disable(); 1796 - apic_set_fixmap(); 1796 + /* 1797 + * Don't reread the APIC ID as it was already done from 1798 + * check_x2apic() and the APIC driver still is a x2APIC variant, 1799 + * which fails to do the read after x2APIC was disabled. 1800 + */ 1801 + apic_set_fixmap(false); 1797 1802 } 1798 1803 1799 1804 static __init void x2apic_enable(void) ··· 2062 2057 } 2063 2058 } 2064 2059 2065 - static __init void apic_set_fixmap(void) 2060 + static __init void apic_set_fixmap(bool read_apic) 2066 2061 { 2067 2062 set_fixmap_nocache(FIX_APIC_BASE, mp_lapic_addr); 2068 2063 apic_mmio_base = APIC_BASE; 2069 2064 apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%16lx)\n", 2070 2065 apic_mmio_base, mp_lapic_addr); 2071 - apic_read_boot_cpu_id(false); 2066 + if (read_apic) 2067 + apic_read_boot_cpu_id(false); 2072 2068 } 2073 2069 2074 2070 void __init register_lapic_address(unsigned long address) ··· 2079 2073 mp_lapic_addr = address; 2080 2074 2081 2075 if (!x2apic_mode) 2082 - apic_set_fixmap(); 2076 + apic_set_fixmap(true); 2083 2077 } 2084 2078 2085 2079 /*