On Thu, Jan 05, 2017 at 01:23:55AM +0000, Eric Joyner wrote: > I started off with a snapshot of 12-CURRENT, but I got a kernel panic on > boot that complained about a duplicate local APIC ID. For now, disabling > Hyper Threading gets rid of that panic. I think there's a KASSERT that > wasn't getting hit on my 11.0-RELEASE install. This is because 11.0 has INVARIANTS disabled in the GENERIC kernel config. Do you mean this one KASSERT(la->la_enabled == 0, ("Duplicate local APIC ID %u", apic_id)); ? This is most likely to out of bounds accesses to the array. Please revert the modification I suggested in previous mail, i.e. return to the stock HEAD, and use this one instead. You would also need to bump MAXCPU in your kernel config. If this works out, the patch still requires more work to get rid of that dozen of statically sized arrays. But more likely, the patch requires some debugging. diff --git a/sys/x86/acpica/madt.c b/sys/x86/acpica/madt.c index 959530c0d89..4509bc4a2f2 100644 --- a/sys/x86/acpica/madt.c +++ b/sys/x86/acpica/madt.c _at__at_ -135,7 +135,7 _at__at_ madt_setup_local(void) vm_paddr_t dmartbl_physaddr; const char *reason; char *hw_vendor; - u_int p[4]; + u_int p[4], i; int user_x2apic; bool bios_x2apic; _at__at_ -216,6 +216,11 _at__at_ madt_setup_local(void) (int)sizeof(madt->Header.OemId), madt->Header.OemId, (int)sizeof(madt->Header.OemTableId), madt->Header.OemTableId); + if (!x2apic_mode) { + for (i = xAPIC_MAX_APIC_ID; i < MAX_APIC_ID; i++) + lapic_ignore(i); + } + /* * We ignore 64-bit local APIC override entries. Should we * perhaps emit a warning here if we find one? _at__at_ -242,7 +247,7 _at__at_ madt_setup_io(void) panic("Using MADT but ACPI doesn't work"); } - ioapics = malloc(sizeof(*ioapics) * (MAX_APIC_ID + 1), M_MADT, + ioapics = malloc(sizeof(*ioapics) * (xAPIC_MAX_APIC_ID + 1), M_MADT, M_WAITOK | M_ZERO); /* First, we run through adding I/O APIC's. */ _at__at_ -269,7 +274,7 _at__at_ madt_setup_io(void) } /* Third, we register all the I/O APIC's. */ - for (i = 0; i <= MAX_APIC_ID; i++) + for (i = 0; i <= xAPIC_MAX_APIC_ID; i++) if (ioapics[i].io_apic != NULL) ioapic_register(ioapics[i].io_apic); _at__at_ -365,7 +370,7 _at__at_ madt_parse_apics(ACPI_SUBTABLE_HEADER *entry, void *arg __unused) "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 > xAPIC_MAX_APIC_ID) panic("%s: I/O APIC ID %u too high", __func__, apic->Id); if (ioapics[apic->Id].io_apic != NULL) diff --git a/sys/x86/include/apicvar.h b/sys/x86/include/apicvar.h index 09c3a638df8..b65c4a8c913 100644 --- a/sys/x86/include/apicvar.h +++ b/sys/x86/include/apicvar.h _at__at_ -74,8 +74,9 _at__at_ * I/O device! */ -#define MAX_APIC_ID 0xfe -#define APIC_ID_ALL 0xff +#define xAPIC_MAX_APIC_ID 0xfe +#define MAX_APIC_ID 0x200 +#define APIC_ID_ALL 0xffffffff /* I/O Interrupts are used for external devices such as ISA, PCI, etc. */ #define APIC_IO_INTS (IDT_IO_INTS + 16) _at__at_ -204,6 +205,7 _at__at_ int ioapic_set_smi(void *cookie, u_int pin); */ struct apic_ops { void (*create)(u_int, int); + void (*ignore)(u_int); void (*init)(vm_paddr_t); void (*xapic_mode)(void); bool (*is_x2apic)(void); _at__at_ -256,6 +258,13 _at__at_ lapic_create(u_int apic_id, int boot_cpu) } static inline void +lapic_ignore(u_int apic_id) +{ + + apic_ops.ignore(apic_id); +} + +static inline void lapic_init(vm_paddr_t addr) { diff --git a/sys/x86/include/x86_smp.h b/sys/x86/include/x86_smp.h index 84a0eba25bc..0cf4ef234e4 100644 --- a/sys/x86/include/x86_smp.h +++ b/sys/x86/include/x86_smp.h _at__at_ -78,6 +78,7 _at__at_ inthand_t /* functions in x86_mp.c */ void assign_cpu_ids(void); void cpu_add(u_int apic_id, char boot_cpu); +void cpu_ignore(u_int apic_id); void cpustop_handler(void); void cpususpend_handler(void); void init_secondary_tail(void); diff --git a/sys/x86/x86/local_apic.c b/sys/x86/x86/local_apic.c index 1b1547de780..163f5e4b66f 100644 --- a/sys/x86/x86/local_apic.c +++ b/sys/x86/x86/local_apic.c _at__at_ -298,6 +298,7 _at__at_ struct pic lapic_pic = { .pic_resume = lapic_resume }; /* Forward declarations for apic_ops */ static void native_lapic_create(u_int apic_id, int boot_cpu); +static void native_lapic_ignore(u_int apic_id); static void native_lapic_init(vm_paddr_t addr); static void native_lapic_xapic_mode(void); static void native_lapic_setup(int boot); _at__at_ -337,6 +338,7 _at__at_ static void native_lapic_ipi_free(int vector); struct apic_ops apic_ops = { .create = native_lapic_create, + .ignore = native_lapic_ignore, .init = native_lapic_init, .xapic_mode = native_lapic_xapic_mode, .is_x2apic = native_lapic_is_x2apic, _at__at_ -602,6 +604,18 _at__at_ native_lapic_create(u_int apic_id, int boot_cpu) #endif } +static void +native_lapic_ignore(u_int apic_id) +{ + + if (!lapics[apic_id].la_present) + return; + lapics[apic_id].la_present = 0; +#ifdef SMP + cpu_ignore(apic_id); +#endif +} + /* * Dump contents of local APIC registers */ diff --git a/sys/x86/x86/mp_x86.c b/sys/x86/x86/mp_x86.c index 56653ee7470..d3a4a09ceaa 100644 --- a/sys/x86/x86/mp_x86.c +++ b/sys/x86/x86/mp_x86.c _at__at_ -136,6 +136,8 _at__at_ volatile int aps_ready = 0; struct cpu_info cpu_info[MAX_APIC_ID + 1]; int apic_cpuids[MAX_APIC_ID + 1]; int cpu_apic_ids[MAXCPU]; +_Static_assert(MAXCPU <= MAX_APIC_ID, + "MAXCPU cannot be larger that MAX_APIC_ID"); /* Holds pending bitmap based IPIs per CPU */ volatile u_int cpu_ipi_pending[MAXCPU]; _at__at_ -794,12 +796,12 _at__at_ cpu_add(u_int apic_id, char boot_cpu) 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 %d 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; _at__at_ -809,11 +811,24 _at__at_ cpu_add(u_int apic_id, char boot_cpu) mp_maxid = mp_ncpus - 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"); } void +cpu_ignore(u_int apic_id) +{ + + KASSERT(cpu_info[apic_id].cpu_present == 1, ("CPU %u not added", + apic_id)); + KASSERT(cpu_info[apic_id].cpu_bsp == 0, ("Cannot ignore BSP %u", + apic_id)); + cpu_info[apic_id].cpu_present = 0; + if (bootverbose) + printf("SMP: Ignoring CPU %u\n", apic_id); +} + +void cpu_mp_setmaxid(void) {Received on Thu Jan 05 2017 - 10:48:15 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:41:09 UTC