aboutsummaryrefslogtreecommitdiffstats
path: root/xen/include/asm-x86/io_apic.h
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-12-16 12:32:35 +0000
committerKeir Fraser <keir.fraser@citrix.com>2009-12-16 12:32:35 +0000
commit142a10c6c8d52689e9770e5f61bcce7b4af9095a (patch)
treed84b26d6af6904672180889c8bfbba411ac75699 /xen/include/asm-x86/io_apic.h
parent5a396b13fd70696a6e62eca387d4e4b51dbb6853 (diff)
downloadxen-142a10c6c8d52689e9770e5f61bcce7b4af9095a.tar.gz
xen-142a10c6c8d52689e9770e5f61bcce7b4af9095a.tar.bz2
xen-142a10c6c8d52689e9770e5f61bcce7b4af9095a.zip
iommu: Actually clear IO-APIC pins on boot and shutdown when used with an IOMMU
When booted with iommu=on, io_apic_read/write functions call into the interrupt remapping code to update the IRTEs. Unfortunately, on boot and shutdown, we really want clear_IO_APIC() to sanitize the actual IOAPIC RTE, and not just the bits that are active when interrupt remapping is enabled. This is particularly a problem on older versions of Xen which used the IOAPIC RTE as the canonical source for the IRTE index. In that case, clear_IO_APIC() actually causes whatever happens to be stored in the RTEs to be used as an IRTE index, which can come back and bite us in ioapic_guest_write() if we attempt to remove an interrupt that didn't actually exist. Current upstream appears less susceptible to errors since the IRTE index is stored in an array, but it's still a good idea to sanitize the IOAPIC state. Signed-off-by: Alex Williamson <alex.williamson@hp.com> Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
Diffstat (limited to 'xen/include/asm-x86/io_apic.h')
-rw-r--r--xen/include/asm-x86/io_apic.h16
1 files changed, 13 insertions, 3 deletions
diff --git a/xen/include/asm-x86/io_apic.h b/xen/include/asm-x86/io_apic.h
index e47ee0c168..d546380435 100644
--- a/xen/include/asm-x86/io_apic.h
+++ b/xen/include/asm-x86/io_apic.h
@@ -131,20 +131,30 @@ extern struct mpc_config_ioapic mp_ioapics[MAX_IO_APICS];
/* Only need to remap ioapic RTE (reg: 10~3Fh) */
#define ioapic_reg_remapped(reg) (iommu_enabled && ((reg) >= 0x10))
+static inline unsigned int __io_apic_read(unsigned int apic, unsigned int reg)
+{
+ *IO_APIC_BASE(apic) = reg;
+ return *(IO_APIC_BASE(apic)+4);
+}
+
static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg)
{
if (ioapic_reg_remapped(reg))
return iommu_read_apic_from_ire(apic, reg);
+ return __io_apic_read(apic, reg);
+}
+
+static inline void __io_apic_write(unsigned int apic, unsigned int reg, unsigned int value)
+{
*IO_APIC_BASE(apic) = reg;
- return *(IO_APIC_BASE(apic)+4);
+ *(IO_APIC_BASE(apic)+4) = value;
}
static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned int value)
{
if (ioapic_reg_remapped(reg))
return iommu_update_ire_from_apic(apic, reg, value);
- *IO_APIC_BASE(apic) = reg;
- *(IO_APIC_BASE(apic)+4) = value;
+ __io_apic_write(apic, reg, value);
}
static inline void io_apic_eoi(unsigned int apic, unsigned int vector)