Index: sys/x86/acpica/madt.c =================================================================== --- sys/x86/acpica/madt.c +++ sys/x86/acpica/madt.c @@ -83,6 +83,8 @@ static int madt_probe_cpus(void); static void madt_probe_cpus_handler(ACPI_SUBTABLE_HEADER *entry, void *arg __unused); +static void madt_setup_cpus_handler(ACPI_SUBTABLE_HEADER *entry, + void *arg __unused); static void madt_register(void *dummy); static int madt_setup_local(void); static int madt_setup_io(void); @@ -140,6 +142,7 @@ bool bios_x2apic; madt = pmap_mapbios(madt_physaddr, madt_length); + madt_walk_table(madt_setup_cpus_handler, NULL); if ((cpu_feature2 & CPUID2_X2APIC) != 0) { reason = NULL; @@ -302,6 +305,19 @@ } static void +madt_parse_cpu(unsigned int apic_id, unsigned int flags) +{ + + if (!(flags & ACPI_MADT_ENABLED) || mp_ncpus == MAXCPU || + apic_id > MAX_APIC_ID) + return; + + mp_ncpus++; + mp_maxid = mp_ncpus - 1; + max_apic_id = max(apic_id, max_apic_id); +} + +static void madt_add_cpu(u_int acpi_id, u_int apic_id, u_int flags) { struct lapic_info *la; @@ -338,6 +354,24 @@ switch (entry->Type) { case ACPI_MADT_TYPE_LOCAL_APIC: proc = (ACPI_MADT_LOCAL_APIC *)entry; + madt_parse_cpu(proc->Id, proc->LapicFlags); + break; + case ACPI_MADT_TYPE_LOCAL_X2APIC: + x2apic = (ACPI_MADT_LOCAL_X2APIC *)entry; + madt_parse_cpu(x2apic->LocalApicId, x2apic->LapicFlags); + break; + } +} + +static void +madt_setup_cpus_handler(ACPI_SUBTABLE_HEADER *entry, void *arg) +{ + ACPI_MADT_LOCAL_APIC *proc; + ACPI_MADT_LOCAL_X2APIC *x2apic; + + switch (entry->Type) { + case ACPI_MADT_TYPE_LOCAL_APIC: + proc = (ACPI_MADT_LOCAL_APIC *)entry; madt_add_cpu(proc->ProcessorId, proc->Id, proc->LapicFlags); break; case ACPI_MADT_TYPE_LOCAL_X2APIC: Index: sys/x86/include/apicvar.h =================================================================== --- sys/x86/include/apicvar.h +++ sys/x86/include/apicvar.h @@ -175,6 +175,8 @@ SLIST_ENTRY(apic_enumerator) apic_next; }; +extern unsigned int max_apic_id; + inthand_t IDTVEC(apic_isr1), IDTVEC(apic_isr2), IDTVEC(apic_isr3), IDTVEC(apic_isr4), IDTVEC(apic_isr5), IDTVEC(apic_isr6), Index: sys/x86/x86/local_apic.c =================================================================== --- sys/x86/x86/local_apic.c +++ sys/x86/x86/local_apic.c @@ -184,6 +184,7 @@ #ifdef SMP static uint64_t lapic_ipi_wait_mult; #endif +unsigned int max_apic_id; SYSCTL_NODE(_hw, OID_AUTO, apic, CTLFLAG_RD, 0, "APIC options"); SYSCTL_INT(_hw_apic, OID_AUTO, x2apic_mode, CTLFLAG_RD, &x2apic_mode, 0, ""); Index: sys/x86/x86/mp_x86.c =================================================================== --- sys/x86/x86/mp_x86.c +++ sys/x86/x86/mp_x86.c @@ -825,10 +825,6 @@ boot_cpu_id = apic_id; cpu_info[apic_id].cpu_bsp = 1; } - if (mp_ncpus < MAXCPU) { - mp_ncpus++; - mp_maxid = mp_ncpus - 1; - } if (bootverbose) printf("SMP: Added CPU %d (%s)\n", apic_id, boot_cpu ? "BSP" : "AP"); Index: sys/x86/x86/mptable.c =================================================================== --- sys/x86/x86/mptable.c +++ sys/x86/x86/mptable.c @@ -191,6 +191,7 @@ static int mptable_probe(void); static int mptable_probe_cpus(void); static void mptable_probe_cpus_handler(u_char *entry, void *arg __unused); +static void mptable_setup_cpus_handler(u_char *entry, void *arg __unused); static void mptable_register(void *dummy); static int mptable_setup_local(void); static int mptable_setup_io(void); @@ -329,14 +330,11 @@ /* Is this a pre-defined config? */ if (mpfps->config_type != 0) { - lapic_create(0, 1); - lapic_create(1, 0); + mp_ncpus = 2; + mp_maxid = 1; + max_apic_id = 1; } else { - cpu_mask = 0; mptable_walk_table(mptable_probe_cpus_handler, &cpu_mask); -#ifdef MPTABLE_FORCE_HTT - mptable_hyperthread_fixup(cpu_mask); -#endif } return (0); } @@ -352,9 +350,17 @@ /* Is this a pre-defined config? */ printf("MPTable: <"); if (mpfps->config_type != 0) { + lapic_create(0, 1); + lapic_create(1, 0); addr = DEFAULT_APIC_BASE; printf("Default Configuration %d", mpfps->config_type); + } else { + cpu_mask = 0; + mptable_walk_table(mptable_setup_cpus_handler, &cpu_mask); +#ifdef MPTABLE_FORCE_HTT + mptable_hyperthread_fixup(cpu_mask); +#endif addr = mpct->apic_address; printf("%.*s %.*s", (int)sizeof(mpct->oem_id), mpct->oem_id, (int)sizeof(mpct->product_id), mpct->product_id); @@ -466,6 +472,25 @@ mptable_probe_cpus_handler(u_char *entry, void *arg) { proc_entry_ptr proc; + + switch (*entry) { + case MPCT_ENTRY_PROCESSOR: + proc = (proc_entry_ptr)entry; + if (proc->cpu_flags & PROCENTRY_FLAG_EN && + proc->apic_id < MAX_LAPIC_ID && mp_ncpus < MAXCPU) { + mp_ncpus++; + mp_maxid = mp_ncpus - 1; + max_apic_id = max(max_apic_id, proc->apic_id); + } + break; + } +} + + +static void +mptable_setup_cpus_handler(u_char *entry, void *arg) +{ + proc_entry_ptr proc; u_int *cpu_mask; switch (*entry) { Index: sys/x86/xen/pvcpu_enum.c =================================================================== --- sys/x86/xen/pvcpu_enum.c +++ sys/x86/xen/pvcpu_enum.c @@ -151,11 +151,12 @@ #ifdef SMP int i, ret; - for (i = 0; i < MAXCPU; i++) { + for (i = 0; i < MAXCPU && (i * 2) < MAX_APIC_ID; i++) { ret = HYPERVISOR_vcpu_op(VCPUOP_is_up, i, NULL); - if (ret >= 0) - lapic_create((i * 2), (i == 0)); + mp_ncpus = min(mp_ncpus + 1, MAXCPU); } + mp_maxid = mp_ncpus - 1; + max_apic_id = mp_ncpus * 2; #endif return (0); } @@ -166,6 +167,16 @@ static int xenpv_setup_local(void) { +#ifdef SMP + int i, ret; + + for (i = 0; i < MAXCPU && (i * 2) < MAX_APIC_ID; i++) { + ret = HYPERVISOR_vcpu_op(VCPUOP_is_up, i, NULL); + if (ret >= 0) + lapic_create((i * 2), (i == 0)); + } +#endif + PCPU_SET(vcpu_id, 0); lapic_init(0); return (0);