summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorjeff <jeff@FreeBSD.org>2009-02-21 23:15:34 +0000
committerjeff <jeff@FreeBSD.org>2009-02-21 23:15:34 +0000
commitf9e60653c3321a67bddec27a97c8c496ab838d54 (patch)
treef54a64e1a7df22435032053ba1c743ee0f9d7fec /sys
parent96ec4168f2218b750f2e2abc983bf68587558543 (diff)
downloadFreeBSD-src-f9e60653c3321a67bddec27a97c8c496ab838d54.zip
FreeBSD-src-f9e60653c3321a67bddec27a97c8c496ab838d54.tar.gz
- Resolve an issue where we may clear an idt while an interrupt on a
different cpu is still assigned to that vector by never clearing idt entries. This was only provided as a debugging feature and the bugs are caught by other means. - Drop the sched lock when rebinding to reassign an interrupt vector to a new cpu so that pending interrupts have a chance to be delivered before removing the old vector. Discussed with: tegge, jhb
Diffstat (limited to 'sys')
-rw-r--r--sys/amd64/amd64/local_apic.c8
-rw-r--r--sys/i386/i386/local_apic.c8
2 files changed, 16 insertions, 0 deletions
diff --git a/sys/amd64/amd64/local_apic.c b/sys/amd64/amd64/local_apic.c
index 40e4a06..3e68a02 100644
--- a/sys/amd64/amd64/local_apic.c
+++ b/sys/amd64/amd64/local_apic.c
@@ -900,7 +900,13 @@ apic_disable_vector(u_int apic_id, u_int vector)
KASSERT(vector != IDT_SYSCALL, ("Attempt to overwrite syscall entry"));
KASSERT(ioint_handlers[vector / 32] != NULL,
("No ISR handler for vector %u", vector));
+#ifdef notyet
+ /*
+ * We can not currently clear the idt entry because other cpus
+ * may have a valid vector at this offset.
+ */
setidt(vector, &IDTVEC(rsvd), SDT_SYSIGT, SEL_KPL, 0);
+#endif
}
/* Release an APIC vector when it's no longer in use. */
@@ -924,9 +930,11 @@ apic_free_vector(u_int apic_id, u_int vector, u_int irq)
if (sched_is_bound(td))
panic("apic_free_vector: Thread already bound.\n");
sched_bind(td, apic_cpuid(apic_id));
+ thread_unlock(td);
mtx_lock_spin(&icu_lock);
lapics[apic_id].la_ioint_irqs[vector - APIC_IO_INTS] = 0;
mtx_unlock_spin(&icu_lock);
+ thread_lock(td);
sched_unbind(td);
thread_unlock(td);
diff --git a/sys/i386/i386/local_apic.c b/sys/i386/i386/local_apic.c
index f543e68..dc97c05 100644
--- a/sys/i386/i386/local_apic.c
+++ b/sys/i386/i386/local_apic.c
@@ -903,8 +903,14 @@ apic_disable_vector(u_int apic_id, u_int vector)
KASSERT(vector != IDT_SYSCALL, ("Attempt to overwrite syscall entry"));
KASSERT(ioint_handlers[vector / 32] != NULL,
("No ISR handler for vector %u", vector));
+#ifdef notyet
+ /*
+ * We can not currently clear the idt entry because other cpus
+ * may have a valid vector at this offset.
+ */
setidt(vector, &IDTVEC(rsvd), SDT_SYS386TGT, SEL_KPL,
GSEL(GCODE_SEL, SEL_KPL));
+#endif
}
/* Release an APIC vector when it's no longer in use. */
@@ -928,9 +934,11 @@ apic_free_vector(u_int apic_id, u_int vector, u_int irq)
if (sched_is_bound(td))
panic("apic_free_vector: Thread already bound.\n");
sched_bind(td, apic_cpuid(apic_id));
+ thread_unlock(td);
mtx_lock_spin(&icu_lock);
lapics[apic_id].la_ioint_irqs[vector - APIC_IO_INTS] = 0;
mtx_unlock_spin(&icu_lock);
+ thread_lock(td);
sched_unbind(td);
thread_unlock(td);
OpenPOWER on IntegriCloud