@@ -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)
@@ -1841,14 +1841,24 @@ 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
+ /*
+ * If there are APIC IDs above 255, they cannot be used
+ * without interrupt remapping. In a virtual machine, but
+ * not on bare metal, X2APIC can be used anyway. In the
+ * case where BIOS has enabled X2APIC, don't disable it
+ * just because there are APIC IDs that can't be used.
+ * They couldn't be used if the kernel falls back to XAPIC
+ * anyway.
*/
if (max_physical_apicid > 255 ||
!x86_init.hyper.x2apic_available()) {
pr_info("x2apic: IRQ remapping doesn't support X2APIC mode\n");
- x2apic_disable();
- return;
+ if (!x2apic_mode) {
+ x2apic_disable();
+ return;
+ }
+
+ x2apic_set_max_apicid(255);
}
/*
@@ -8,6 +8,12 @@
int x2apic_phys;
static struct apic apic_x2apic_phys;
+static u32 x2apic_max_apicid;
+
+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;
}