summaryrefslogtreecommitdiffstats
path: root/sys/x86
diff options
context:
space:
mode:
authoravg <avg@FreeBSD.org>2012-12-01 18:16:14 +0000
committeravg <avg@FreeBSD.org>2012-12-01 18:16:14 +0000
commit39d9709f4f963d0a536eb85f006176ce54db1cd9 (patch)
tree11a80a0abd53a942a7bc1a48bf228c5a4e8cdf9f /sys/x86
parent71c0a498878d5543bd4eaee74cb83189e862fe52 (diff)
downloadFreeBSD-src-39d9709f4f963d0a536eb85f006176ce54db1cd9.zip
FreeBSD-src-39d9709f4f963d0a536eb85f006176ce54db1cd9.tar.gz
ioapic_program_intpin: program high bits before low bits
Programming the low bits has a side-effect if unmasking the pin if it is not disabled. So if an interrupt was pending then it would be delivered with the correct new vector but to the incorrect old LAPIC. This fix could be made clearer by preserving the mask bit while programming the low bits and then explicitly resetting the mask bit after all the programming is done. Probability to trip over the fixed bug could be increased by bootverbose because printing of the interrupt information in ioapic_assign_cpu lengthened the time window during which an interrupt could arrive while a pin is masked. Reported by: Andreas Longwitz <longwitz@incore.de> Tested by: Andreas Longwitz <longwitz@incore.de> MFC after: 12 days
Diffstat (limited to 'sys/x86')
-rw-r--r--sys/x86/x86/io_apic.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/sys/x86/x86/io_apic.c b/sys/x86/x86/io_apic.c
index e72a636..4df27c2 100644
--- a/sys/x86/x86/io_apic.c
+++ b/sys/x86/x86/io_apic.c
@@ -311,12 +311,12 @@ ioapic_program_intpin(struct ioapic_intsrc *intpin)
}
/* Write the values to the APIC. */
- intpin->io_lowreg = low;
- ioapic_write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin), low);
value = ioapic_read(io->io_addr, IOAPIC_REDTBL_HI(intpin->io_intpin));
value &= ~IOART_DEST;
value |= high;
ioapic_write(io->io_addr, IOAPIC_REDTBL_HI(intpin->io_intpin), value);
+ intpin->io_lowreg = low;
+ ioapic_write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin), low);
}
static int
OpenPOWER on IntegriCloud