diff options
author | jeff <jeff@FreeBSD.org> | 2009-02-21 23:15:34 +0000 |
---|---|---|
committer | jeff <jeff@FreeBSD.org> | 2009-02-21 23:15:34 +0000 |
commit | f9e60653c3321a67bddec27a97c8c496ab838d54 (patch) | |
tree | f54a64e1a7df22435032053ba1c743ee0f9d7fec /sys | |
parent | 96ec4168f2218b750f2e2abc983bf68587558543 (diff) | |
download | FreeBSD-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.c | 8 | ||||
-rw-r--r-- | sys/i386/i386/local_apic.c | 8 |
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); |