summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2014-07-06 21:36:56 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2014-07-06 21:36:56 +0000
commit04973b34883aa97ea758c43ff34fe127c512cbb3 (patch)
tree160a46a8fcd965652ae20ffccfd02d450f78653f /sys
parent768be5765618406c96134203b588b282437a7226 (diff)
If we find a bogus interrupt (undefined polarity or trigger) don't panic but
print a message and ignore the interrupt. There are BIOSen out there with random garbage in NMI entries for the non-BP CPUs.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/acpi/acpimadt.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/sys/dev/acpi/acpimadt.c b/sys/dev/acpi/acpimadt.c
index 1fc2e64aebf..fb879305f7e 100644
--- a/sys/dev/acpi/acpimadt.c
+++ b/sys/dev/acpi/acpimadt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpimadt.c,v 1.27 2014/05/18 20:16:29 mlarkin Exp $ */
+/* $OpenBSD: acpimadt.c,v 1.28 2014/07/06 21:36:55 kettenis Exp $ */
/*
* Copyright (c) 2006 Mark Kettenis <kettenis@openbsd.org>
*
@@ -54,7 +54,7 @@ struct cfdriver acpimadt_cd = {
};
int acpimadt_validate(struct acpi_madt *);
-void acpimadt_cfg_intr(int, u_int32_t *);
+int acpimadt_cfg_intr(int, u_int32_t *);
int acpimadt_print(void *, const char *);
int
@@ -150,7 +150,7 @@ acpimadt_validate(struct acpi_madt *madt)
struct mp_bus acpimadt_busses[256];
struct mp_bus acpimadt_isa_bus;
-void
+int
acpimadt_cfg_intr(int flags, u_int32_t *redir)
{
int mpspo = (flags >> MPS_INTPO_SHIFT) & MPS_INTPO_MASK;
@@ -166,7 +166,7 @@ acpimadt_cfg_intr(int flags, u_int32_t *redir)
*redir |= IOAPIC_REDLO_ACTLO;
break;
default:
- panic("unknown MPS interrupt polarity %d", mpspo);
+ return (0);
}
*redir |= (IOAPIC_REDLO_DEL_LOPRI << IOAPIC_REDLO_DEL_SHIFT);
@@ -180,8 +180,10 @@ acpimadt_cfg_intr(int flags, u_int32_t *redir)
*redir &= ~IOAPIC_REDLO_LEVEL;
break;
default:
- panic("unknown MPS interrupt trigger %d", mpstrig);
+ return (0);
}
+
+ return (1);
}
static u_int8_t lapic_map[256];
@@ -325,7 +327,12 @@ acpimadt_attach(struct device *parent, struct device *self, void *aux)
map->bus_pin = entry->madt_override.source;
map->flags = entry->madt_override.flags;
- acpimadt_cfg_intr(entry->madt_override.flags, &map->redir);
+ if (!acpimadt_cfg_intr(entry->madt_override.flags, &map->redir)) {
+ printf("%s: bogus override for pin %d\n",
+ self->dv_xname, pin);
+ free(map, M_DEVBUF);
+ break;
+ }
map->ioapic_ih = APIC_INT_VIA_APIC |
((apic->sc_apicid << APIC_INT_APIC_SHIFT) |
@@ -351,7 +358,13 @@ acpimadt_attach(struct device *parent, struct device *self, void *aux)
map->ioapic_pin = pin;
map->flags = entry->madt_lapic_nmi.flags;
- acpimadt_cfg_intr(entry->madt_lapic_nmi.flags, &map->redir);
+ if (!acpimadt_cfg_intr(entry->madt_lapic_nmi.flags, &map->redir)) {
+ printf("%s: bogus nmi for apid %d\n",
+ self->dv_xname, map->cpu_id);
+ mp_nintrs--;
+ break;
+ }
+
map->redir &= ~IOAPIC_REDLO_DEL_MASK;
map->redir |= (IOAPIC_REDLO_DEL_NMI << IOAPIC_REDLO_DEL_SHIFT);
break;