--- sys/platform/pc64/acpica/acpi_fadt.c +++ sys/platform/pc64/acpica/acpi_fadt.c @@ -198,12 +198,26 @@ acpi_sci_test(const struct acpi_sci_mode *mode) last_cnt = get_interrupt_counter(acpi_sci_irq, 0); machintr_legacy_intr_config(acpi_sci_irq, mode->sci_trig, mode->sci_pola); + /* + * NOTE: register_int() returns NULL without panicing if the + * interrupt is already exclusively owned by another handler + * (e.g. a FADT whose SciInterrupt names the 8254 "clk" irq, + * which is registered INTR_EXCL|INTR_CLOCK long before acpi0 + * attaches). In that case never unregister the NULL descriptor, + * leave the line's trigger mode alone, and disable the SCI. + */ sci_desc = register_int(acpi_sci_irq, acpi_sci_dummy_intr, NULL, "sci", NULL, INTR_EXCL | INTR_CLOCK | INTR_NOPOLL | INTR_MPSAFE | INTR_NOENTROPY, 0); + if (sci_desc == NULL) { + kprintf("ACPI FADT: SCI irq %d is not available, disable\n", + acpi_sci_irq); + acpi_sci_irq = -1; + return TRUE; + } DELAY(100 * 1000); unregister_int(sci_desc, 0); --- sys/kern/kern_intr.c +++ sys/kern/kern_intr.c @@ -420,6 +420,10 @@ unregister_int(void *id, int cpuid) KKASSERT(cpuid >= 0 && cpuid < ncpus); + if (id == NULL) /* defense in depth: register_int() may + * legally fail and return NULL */ + return; + intr = ((intrec_t)id)->intr; if (intr < 0 || intr >= MAX_INTS)