aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/io_apic_64.c
diff options
context:
space:
mode:
authorKeshavamurthy, Anil S <anil.s.keshavamurthy@intel.com>2007-10-21 19:41:54 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-22 11:13:19 -0400
commit3460a6d9cef9ac2aa997da7eff7ff1c8291b361c (patch)
tree3cf7eb916456d781d2edb135f9069f7c94d10085 /arch/x86/kernel/io_apic_64.c
parent7d3b03ce7bff9d39ebaee1bb8de1968c4434b883 (diff)
Intel IOMMU: DMAR fault handling support
MSI interrupt handler registrations and fault handling support for Intel-IOMMU hadrware. This patch enables the MSI interrupts for the DMA remapping units and in the interrupt handler read the fault cause and outputs the same on to the console. Signed-off-by: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com> Cc: Andi Kleen <ak@suse.de> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Muli Ben-Yehuda <muli@il.ibm.com> Cc: "Siddha, Suresh B" <suresh.b.siddha@intel.com> Cc: Arjan van de Ven <arjan@infradead.org> Cc: Ashok Raj <ashok.raj@intel.com> Cc: "David S. Miller" <davem@davemloft.net> Cc: Christoph Lameter <clameter@sgi.com> Cc: Greg KH <greg@kroah.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/x86/kernel/io_apic_64.c')
-rw-r--r--arch/x86/kernel/io_apic_64.c59
1 files changed, 58 insertions, 1 deletions
diff --git a/arch/x86/kernel/io_apic_64.c b/arch/x86/kernel/io_apic_64.c
index b3c2d268d708..953328b55a30 100644
--- a/arch/x86/kernel/io_apic_64.c
+++ b/arch/x86/kernel/io_apic_64.c
@@ -31,6 +31,7 @@
31#include <linux/sysdev.h> 31#include <linux/sysdev.h>
32#include <linux/msi.h> 32#include <linux/msi.h>
33#include <linux/htirq.h> 33#include <linux/htirq.h>
34#include <linux/dmar.h>
34#ifdef CONFIG_ACPI 35#ifdef CONFIG_ACPI
35#include <acpi/acpi_bus.h> 36#include <acpi/acpi_bus.h>
36#endif 37#endif
@@ -2031,8 +2032,64 @@ void arch_teardown_msi_irq(unsigned int irq)
2031 destroy_irq(irq); 2032 destroy_irq(irq);
2032} 2033}
2033 2034
2034#endif /* CONFIG_PCI_MSI */ 2035#ifdef CONFIG_DMAR
2036#ifdef CONFIG_SMP
2037static void dmar_msi_set_affinity(unsigned int irq, cpumask_t mask)
2038{
2039 struct irq_cfg *cfg = irq_cfg + irq;
2040 struct msi_msg msg;
2041 unsigned int dest;
2042 cpumask_t tmp;
2043
2044 cpus_and(tmp, mask, cpu_online_map);
2045 if (cpus_empty(tmp))
2046 return;
2047
2048 if (assign_irq_vector(irq, mask))
2049 return;
2050
2051 cpus_and(tmp, cfg->domain, mask);
2052 dest = cpu_mask_to_apicid(tmp);
2053
2054 dmar_msi_read(irq, &msg);
2055
2056 msg.data &= ~MSI_DATA_VECTOR_MASK;
2057 msg.data |= MSI_DATA_VECTOR(cfg->vector);
2058 msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
2059 msg.address_lo |= MSI_ADDR_DEST_ID(dest);
2060
2061 dmar_msi_write(irq, &msg);
2062 irq_desc[irq].affinity = mask;
2063}
2064#endif /* CONFIG_SMP */
2065
2066struct irq_chip dmar_msi_type = {
2067 .name = "DMAR_MSI",
2068 .unmask = dmar_msi_unmask,
2069 .mask = dmar_msi_mask,
2070 .ack = ack_apic_edge,
2071#ifdef CONFIG_SMP
2072 .set_affinity = dmar_msi_set_affinity,
2073#endif
2074 .retrigger = ioapic_retrigger_irq,
2075};
2076
2077int arch_setup_dmar_msi(unsigned int irq)
2078{
2079 int ret;
2080 struct msi_msg msg;
2081
2082 ret = msi_compose_msg(NULL, irq, &msg);
2083 if (ret < 0)
2084 return ret;
2085 dmar_msi_write(irq, &msg);
2086 set_irq_chip_and_handler_name(irq, &dmar_msi_type, handle_edge_irq,
2087 "edge");
2088 return 0;
2089}
2090#endif
2035 2091
2092#endif /* CONFIG_PCI_MSI */
2036/* 2093/*
2037 * Hypertransport interrupt support 2094 * Hypertransport interrupt support
2038 */ 2095 */