x86/apic: Fix x2apic enablement without interrupt remapping
[ Upstream commit 26573a97746c7a99f394f9d398ce91a8853b3b89 ] Currently, Linux as a hypervisor guest will enable x2apic only if there are no CPUs present at boot time with an APIC ID above 255. Hotplugging a CPU later with a higher APIC ID would result in a CPU which cannot be targeted by external interrupts. Add a filter in x2apic_apic_id_valid() which can be used to prevent such CPUs from coming online, and allow x2apic to be enabled even if they are present at boot time. Fixes: ce69a784504 ("x86/apic: Enable x2APIC without interrupt remapping under KVM") Signed-off-by: David Woodhouse <dwmw@amazon.co.uk> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Link: https://lore.kernel.org/r/20201024213535.443185-2-dwmw2@infradead.org Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
b7ec74246c
commit
a3ec54b95c
@ -259,6 +259,7 @@ static inline u64 native_x2apic_icr_read(void)
|
||||
|
||||
extern int x2apic_mode;
|
||||
extern int x2apic_phys;
|
||||
extern void __init x2apic_set_max_apicid(u32 apicid);
|
||||
extern void __init check_x2apic(void);
|
||||
extern void x2apic_setup(void);
|
||||
static inline int x2apic_enabled(void)
|
||||
|
@ -1886,20 +1886,22 @@ static __init void try_to_enable_x2apic(int remap_mode)
|
||||
return;
|
||||
|
||||
if (remap_mode != IRQ_REMAP_X2APIC_MODE) {
|
||||
/* IR is required if there is APIC ID > 255 even when running
|
||||
* under KVM
|
||||
/*
|
||||
* Using X2APIC without IR is not architecturally supported
|
||||
* on bare metal but may be supported in guests.
|
||||
*/
|
||||
if (max_physical_apicid > 255 ||
|
||||
!x86_init.hyper.x2apic_available()) {
|
||||
if (!x86_init.hyper.x2apic_available()) {
|
||||
pr_info("x2apic: IRQ remapping doesn't support X2APIC mode\n");
|
||||
x2apic_disable();
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* without IR all CPUs can be addressed by IOAPIC/MSI
|
||||
* only in physical mode
|
||||
* Without IR, all CPUs can be addressed by IOAPIC/MSI only
|
||||
* in physical mode, and CPUs with an APIC ID that cannnot
|
||||
* be addressed must not be brought online.
|
||||
*/
|
||||
x2apic_set_max_apicid(255);
|
||||
x2apic_phys = 1;
|
||||
}
|
||||
x2apic_enable();
|
||||
|
@ -8,6 +8,12 @@
|
||||
int x2apic_phys;
|
||||
|
||||
static struct apic apic_x2apic_phys;
|
||||
static u32 x2apic_max_apicid __ro_after_init;
|
||||
|
||||
void __init x2apic_set_max_apicid(u32 apicid)
|
||||
{
|
||||
x2apic_max_apicid = apicid;
|
||||
}
|
||||
|
||||
static int __init set_x2apic_phys_mode(char *arg)
|
||||
{
|
||||
@ -98,6 +104,9 @@ static int x2apic_phys_probe(void)
|
||||
/* Common x2apic functions, also used by x2apic_cluster */
|
||||
int x2apic_apic_id_valid(u32 apicid)
|
||||
{
|
||||
if (x2apic_max_apicid && apicid > x2apic_max_apicid)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user