From c9ed75c153dac4dac249176cd33b43f2a0fed034 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Thu, 14 Apr 2005 05:55:34 +0000 Subject: [PATCH] If an I/O APIC returns 0xffffffff for its version register after we map it, assume it is bogus and return NULL instead of trying to parse it as an APIC. Inspired by: linux bug reports via njl --- sys/i386/i386/io_apic.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/sys/i386/i386/io_apic.c b/sys/i386/i386/io_apic.c index a403eebc68a9..b6c9446a7439 100644 --- a/sys/i386/i386/io_apic.c +++ b/sys/i386/i386/io_apic.c @@ -502,11 +502,20 @@ ioapic_create(uintptr_t addr, int32_t apic_id, int intbase) u_int numintr, i; uint32_t value; + /* Map the register window so we can access the device. */ apic = (ioapic_t *)pmap_mapdev(addr, IOAPIC_MEM_REGION); mtx_lock_spin(&icu_lock); - numintr = ((ioapic_read(apic, IOAPIC_VER) & IOART_VER_MAXREDIR) >> - MAXREDIRSHIFT) + 1; + value = ioapic_read(apic, IOAPIC_VER); mtx_unlock_spin(&icu_lock); + + /* If it's version register doesn't seem to work, punt. */ + if (value == 0xffffff) { + pmap_unmapdev(apic, IOAPIC_MEM_REGION); + return (NULL); + } + + /* Determine the number of vectors and set the APIC ID. */ + numintr = ((value & IOART_VER_MAXREDIR) >> MAXREDIRSHIFT) + 1; io = malloc(sizeof(struct ioapic) + numintr * sizeof(struct ioapic_intsrc), M_IOAPIC, M_WAITOK); io->io_pic = ioapic_template;