svn commit: r330959 - stable/10/sys/x86/x86
Marius Strobl
marius at FreeBSD.org
Wed Mar 14 23:59:53 UTC 2018
Author: marius
Date: Wed Mar 14 23:59:52 2018
New Revision: 330959
URL: https://svnweb.freebsd.org/changeset/base/330959
Log:
MFC: 327314
With the advent of interrupt remapping, Intel has repurposed bit 11
(now: Interrupt_Index[15]) and assigned the previously reserved bits
55:48 (Interrupt_Index[14:0] goes into 63:49 while Destination Field
used 63:56 and bit 48 now is Interrupt_Format) in the IO redirection
tables (see the VT-d specification, "5.1.5.1 I/OxAPIC Programming").
Thus, when not using interrupt remapping, ensure that all previously
reserved bits in the high part of the RTEs are zero instead of doing
a read-modify-write for their Destination Field bits only.
Otherwise, on machines based on Apollo Lake and its derivatives such
as Denverton, typically some of the previously preserved bits remain
set after boot when not employing interrupt remapping. The result is
that INTx interrupts are not getting delivered.
Note: With an AMD IOMMU, interrupt remapping apparently bypasses the
IO APIC altogether.
Submitted by: loos (modulo comment)
Reviewed by: jhb (modulo comment)
Modified:
stable/10/sys/x86/x86/io_apic.c
Directory Properties:
stable/10/ (props changed)
Modified: stable/10/sys/x86/x86/io_apic.c
==============================================================================
--- stable/10/sys/x86/x86/io_apic.c Wed Mar 14 23:59:50 2018 (r330958)
+++ stable/10/sys/x86/x86/io_apic.c Wed Mar 14 23:59:52 2018 (r330959)
@@ -252,7 +252,7 @@ static void
ioapic_program_intpin(struct ioapic_intsrc *intpin)
{
struct ioapic *io = (struct ioapic *)intpin->io_intsrc.is_pic;
- uint32_t low, high, value;
+ uint32_t low, high;
/*
* If a pin is completely invalid or if it is valid but hasn't
@@ -270,7 +270,11 @@ ioapic_program_intpin(struct ioapic_intsrc *intpin)
return;
}
- /* Set the destination. */
+ /*
+ * Set the destination. Note that with Intel interrupt remapping,
+ * the previously reserved bits 55:48 now have a purpose so ensure
+ * these are zero.
+ */
low = IOART_DESTPHY;
high = intpin->io_cpu << APIC_ID_SHIFT;
@@ -308,10 +312,7 @@ ioapic_program_intpin(struct ioapic_intsrc *intpin)
}
/* Write the values to the APIC. */
- 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);
+ ioapic_write(io->io_addr, IOAPIC_REDTBL_HI(intpin->io_intpin), high);
intpin->io_lowreg = low;
ioapic_write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin), low);
}
More information about the svn-src-all
mailing list