Index: head/sys/x86/acpica/madt.c =================================================================== --- head/sys/x86/acpica/madt.c +++ head/sys/x86/acpica/madt.c @@ -212,6 +212,14 @@ } } + /* + * Truncate max_apic_id if not in x2APIC mode. Some structures + * will already be allocated with the previous max_apic_id, but + * at least we can prevent wasting more memory elsewhere. + */ + if (!x2apic_mode) + max_apic_id = min(max_apic_id, xAPIC_MAX_APIC_ID); + madt = pmap_mapbios(madt_physaddr, madt_length); lapics = malloc(sizeof(*lapics) * (max_apic_id + 1), M_MADT, M_WAITOK | M_ZERO); @@ -250,7 +258,7 @@ panic("Using MADT but ACPI doesn't work"); } - ioapics = malloc(sizeof(*ioapics) * (MAX_APIC_ID + 1), M_MADT, + ioapics = malloc(sizeof(*ioapics) * (IOAPIC_MAX_ID + 1), M_MADT, M_WAITOK | M_ZERO); /* First, we run through adding I/O APIC's. */ @@ -277,7 +285,7 @@ } /* Third, we register all the I/O APIC's. */ - for (i = 0; i <= MAX_APIC_ID; i++) + for (i = 0; i <= IOAPIC_MAX_ID; i++) if (ioapics[i].io_apic != NULL) ioapic_register(ioapics[i].io_apic); @@ -408,7 +416,7 @@ "MADT: Found IO APIC ID %u, Interrupt %u at %p\n", apic->Id, apic->GlobalIrqBase, (void *)(uintptr_t)apic->Address); - if (apic->Id > MAX_APIC_ID) + if (apic->Id > IOAPIC_MAX_ID) panic("%s: I/O APIC ID %u too high", __func__, apic->Id); if (ioapics[apic->Id].io_apic != NULL) @@ -501,7 +509,7 @@ int i, best; best = -1; - for (i = 0; i <= MAX_APIC_ID; i++) { + for (i = 0; i <= IOAPIC_MAX_ID; i++) { if (ioapics[i].io_apic == NULL || ioapics[i].io_vector > intr) continue; Index: head/sys/x86/include/apicvar.h =================================================================== --- head/sys/x86/include/apicvar.h +++ head/sys/x86/include/apicvar.h @@ -74,8 +74,12 @@ * I/O device! */ -#define MAX_APIC_ID 0xfe -#define APIC_ID_ALL 0xff +#define xAPIC_MAX_APIC_ID 0xfe +#define xAPIC_ID_ALL 0xff +#define MAX_APIC_ID 0x200 +#define APIC_ID_ALL 0xffffffff + +#define IOAPIC_MAX_ID xAPIC_MAX_APIC_ID /* I/O Interrupts are used for external devices such as ISA, PCI, etc. */ #define APIC_IO_INTS (IDT_IO_INTS + 16) Index: head/sys/x86/x86/mp_x86.c =================================================================== --- head/sys/x86/x86/mp_x86.c +++ head/sys/x86/x86/mp_x86.c @@ -137,6 +137,10 @@ struct cpu_info *cpu_info; int *apic_cpuids; int cpu_apic_ids[MAXCPU]; +_Static_assert(MAXCPU <= MAX_APIC_ID, + "MAXCPU cannot be larger that MAX_APIC_ID"); +_Static_assert(xAPIC_MAX_APIC_ID <= MAX_APIC_ID, + "xAPIC_MAX_APIC_ID cannot be larger that MAX_APIC_ID"); /* Holds pending bitmap based IPIs per CPU */ volatile u_int cpu_ipi_pending[MAXCPU]; @@ -830,18 +834,18 @@ panic("SMP: APIC ID %d too high", apic_id); return; } - KASSERT(cpu_info[apic_id].cpu_present == 0, ("CPU %d added twice", + KASSERT(cpu_info[apic_id].cpu_present == 0, ("CPU %u added twice", apic_id)); cpu_info[apic_id].cpu_present = 1; if (boot_cpu) { KASSERT(boot_cpu_id == -1, - ("CPU %d claims to be BSP, but CPU %d already is", apic_id, + ("CPU %u claims to be BSP, but CPU %u already is", apic_id, boot_cpu_id)); boot_cpu_id = apic_id; cpu_info[apic_id].cpu_bsp = 1; } if (bootverbose) - printf("SMP: Added CPU %d (%s)\n", apic_id, boot_cpu ? "BSP" : + printf("SMP: Added CPU %u (%s)\n", apic_id, boot_cpu ? "BSP" : "AP"); } Index: head/sys/x86/x86/mptable.c =================================================================== --- head/sys/x86/x86/mptable.c +++ head/sys/x86/x86/mptable.c @@ -159,7 +159,7 @@ static mpfps_t mpfps; static mpcth_t mpct; static ext_entry_ptr mpet; -static void *ioapics[MAX_APIC_ID + 1]; +static void *ioapics[IOAPIC_MAX_ID + 1]; static bus_datum *busses; static int mptable_nioapics, mptable_nbusses, mptable_maxbusid; static int pci0 = -1; @@ -393,7 +393,7 @@ mptable_parse_ints(); /* Fourth, we register all the I/O APIC's. */ - for (i = 0; i <= MAX_APIC_ID; i++) + for (i = 0; i <= IOAPIC_MAX_ID; i++) if (ioapics[i] != NULL) ioapic_register(ioapics[i]); @@ -589,7 +589,7 @@ apic = (io_apic_entry_ptr)entry; if (!(apic->apic_flags & IOAPICENTRY_FLAG_EN)) break; - if (apic->apic_id > MAX_APIC_ID) + if (apic->apic_id > IOAPIC_MAX_ID) panic("%s: I/O APIC ID %d too high", __func__, apic->apic_id); if (ioapics[apic->apic_id] != NULL) @@ -736,7 +736,7 @@ return; } } - if (apic_id > MAX_APIC_ID) { + if (apic_id > IOAPIC_MAX_ID) { printf("MPTable: Ignoring interrupt entry for ioapic%d\n", intr->dst_apic_id); return;