Skip to content

Commit 81287ad

Browse files
KAGA-KOKOhansendc
authored andcommitted
x86/apic: Sanitize APIC address setup
Convert places which just write mp_lapic_addr and let them register the local APIC address directly instead of relying on magic other code to do so. Add a WARN_ON() into register_lapic_address() which is raised when register_lapic_address() is invoked more than once during boot. Signed-off-by: Thomas Gleixner <[email protected]> Signed-off-by: Dave Hansen <[email protected]> Acked-by: Peter Zijlstra (Intel) <[email protected]> Tested-by: Michael Kelley <[email protected]> Tested-by: Sohil Mehta <[email protected]> Tested-by: Juergen Gross <[email protected]> # Xen PV (dom0 and unpriv. guest)
1 parent 5a88f35 commit 81287ad

File tree

3 files changed

+12
-29
lines changed

3 files changed

+12
-29
lines changed

arch/x86/include/asm/mpspec.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ extern DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BUSSES);
4141

4242
extern unsigned int boot_cpu_physical_apicid;
4343
extern u8 boot_cpu_apic_version;
44-
extern unsigned long mp_lapic_addr;
4544

4645
#ifdef CONFIG_X86_LOCAL_APIC
4746
extern int smp_found_config;

arch/x86/kernel/apic/apic.c

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ static __init int setup_apicpmtimer(char *s)
172172
__setup("apicpmtimer", setup_apicpmtimer);
173173
#endif
174174

175-
unsigned long mp_lapic_addr __ro_after_init;
175+
static unsigned long mp_lapic_addr __ro_after_init;
176176
bool apic_is_disabled __ro_after_init;
177177
/* Disable local APIC timer from the kernel commandline or via dmi quirk */
178178
static int disable_apic_timer __initdata;
@@ -2009,12 +2009,12 @@ static bool __init detect_init_APIC(void)
20092009
return false;
20102010
}
20112011

2012-
mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
2012+
register_lapic_address(APIC_DEFAULT_PHYS_BASE);
20132013
return true;
20142014
}
20152015
#else
20162016

2017-
static bool __init apic_verify(void)
2017+
static bool __init apic_verify(unsigned long addr)
20182018
{
20192019
u32 features, h, l;
20202020

@@ -2028,15 +2028,15 @@ static bool __init apic_verify(void)
20282028
return false;
20292029
}
20302030
set_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC);
2031-
mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
20322031

20332032
/* The BIOS may have set up the APIC at some other address */
20342033
if (boot_cpu_data.x86 >= 6) {
20352034
rdmsr(MSR_IA32_APICBASE, l, h);
20362035
if (l & MSR_IA32_APICBASE_ENABLE)
2037-
mp_lapic_addr = l & MSR_IA32_APICBASE_BASE;
2036+
addr = l & MSR_IA32_APICBASE_BASE;
20382037
}
20392038

2039+
register_lapic_address(addr);
20402040
pr_info("Found and enabled local APIC!\n");
20412041
return true;
20422042
}
@@ -2063,7 +2063,7 @@ bool __init apic_force_enable(unsigned long addr)
20632063
enabled_via_apicbase = 1;
20642064
}
20652065
}
2066-
return apic_verify();
2066+
return apic_verify(addr);
20672067
}
20682068

20692069
/*
@@ -2105,7 +2105,7 @@ static bool __init detect_init_APIC(void)
21052105
if (!apic_force_enable(APIC_DEFAULT_PHYS_BASE))
21062106
return false;
21072107
} else {
2108-
if (!apic_verify())
2108+
if (!apic_verify(APIC_DEFAULT_PHYS_BASE))
21092109
return false;
21102110
}
21112111

@@ -2130,34 +2130,25 @@ void __init init_apic_mappings(void)
21302130
if (x2apic_mode)
21312131
return;
21322132

2133-
/* If no local APIC can be found return early */
21342133
if (!smp_found_config && !detect_init_APIC()) {
2135-
/* lets NOP'ify apic operations */
21362134
pr_info("APIC: disable apic facility\n");
21372135
apic_disable();
2138-
} else {
2139-
apic_phys = mp_lapic_addr;
2140-
2141-
/*
2142-
* If the system has ACPI MADT tables or MP info, the LAPIC
2143-
* address is already registered.
2144-
*/
2145-
if (!acpi_lapic && !smp_found_config)
2146-
register_lapic_address(apic_phys);
21472136
}
21482137
}
21492138

21502139
static __init void apic_set_fixmap(void)
21512140
{
21522141
set_fixmap_nocache(FIX_APIC_BASE, mp_lapic_addr);
2153-
apic_mmio_base = APIC_BASE;
2142+
apic_phys = apic_mmio_base = APIC_BASE;
21542143
apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%16lx)\n",
21552144
apic_mmio_base, mp_lapic_addr);
21562145
apic_read_boot_cpu_id(false);
21572146
}
21582147

21592148
void __init register_lapic_address(unsigned long address)
21602149
{
2150+
/* This should only happen once */
2151+
WARN_ON_ONCE(mp_lapic_addr);
21612152
mp_lapic_addr = address;
21622153

21632154
if (!x2apic_mode)

arch/x86/kernel/mpparse.c

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -374,11 +374,6 @@ static inline void __init construct_default_ISA_mptable(int mpc_default_type)
374374
int linttypes[2] = { mp_ExtINT, mp_NMI };
375375
int i;
376376

377-
/*
378-
* local APIC has default address
379-
*/
380-
mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
381-
382377
/*
383378
* 2 CPUs, numbered 0 & 1.
384379
*/
@@ -520,10 +515,8 @@ void __init default_get_smp_config(unsigned int early)
520515
*/
521516
if (mpf->feature1) {
522517
if (early) {
523-
/*
524-
* local APIC has default address
525-
*/
526-
mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
518+
/* Local APIC has default address */
519+
register_lapic_address(APIC_DEFAULT_PHYS_BASE);
527520
goto out;
528521
}
529522

0 commit comments

Comments
 (0)