1 From: Suresh Siddha <suresh.b.siddha@intel.com>
2 Subject: x64, x2apic/intr-remap: parse ioapic scope under vt-d structures
3 References: fate #303948 and fate #303984
4 Patch-Mainline: queued for .28
5 Commit-ID: ad3ad3f6a2caebf56869b83b69e23eb9fa5e0ab6
7 Signed-off-by: Thomas Renninger <trenn@suse.de>
9 Parse the vt-d device scope structures to find the mapping between IO-APICs
10 and the interrupt remapping hardware units.
12 This will be used later for enabling Interrupt-remapping for IOAPIC devices.
14 Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
15 Cc: akpm@linux-foundation.org
16 Cc: arjan@linux.intel.com
17 Cc: andi@firstfloor.org
18 Cc: ebiederm@xmission.com
19 Cc: jbarnes@virtuousgeek.org
21 Signed-off-by: Ingo Molnar <mingo@elte.hu>
24 drivers/pci/Makefile | 2 +
25 drivers/pci/dmar.c | 3 +
26 drivers/pci/intel-iommu.h | 2 +
27 drivers/pci/intr_remapping.c | 70 +++++++++++++++++++++++++++++++++++++++++++
28 drivers/pci/intr_remapping.h | 6 +++
29 include/linux/dmar.h | 1
30 6 files changed, 84 insertions(+)
32 Index: linux-2.6.26/drivers/pci/Makefile
33 ===================================================================
34 --- linux-2.6.26.orig/drivers/pci/Makefile
35 +++ linux-2.6.26/drivers/pci/Makefile
36 @@ -26,6 +26,8 @@ obj-$(CONFIG_HT_IRQ) += htirq.o
37 # Build Intel IOMMU support
38 obj-$(CONFIG_DMAR) += dmar.o iova.o intel-iommu.o
40 +obj-$(CONFIG_INTR_REMAP) += dmar.o intr_remapping.o
43 # Some architectures use the generic PCI setup functions
45 Index: linux-2.6.26/drivers/pci/dmar.c
46 ===================================================================
47 --- linux-2.6.26.orig/drivers/pci/dmar.c
48 +++ linux-2.6.26/drivers/pci/dmar.c
49 @@ -425,6 +425,9 @@ int __init dmar_table_init(void)
53 +#ifdef CONFIG_INTR_REMAP
54 + parse_ioapics_under_ir();
59 Index: linux-2.6.26/drivers/pci/intel-iommu.h
60 ===================================================================
61 --- linux-2.6.26.orig/drivers/pci/intel-iommu.h
62 +++ linux-2.6.26/drivers/pci/intel-iommu.h
63 @@ -114,6 +114,8 @@ static inline void dmar_writeq(void __io
64 #define ecap_max_iotlb_offset(e) \
65 (ecap_iotlb_offset(e) + ecap_niotlb_iunits(e) * 16)
66 #define ecap_coherent(e) ((e) & 0x1)
67 +#define ecap_eim_support(e) ((e >> 4) & 0x1)
68 +#define ecap_ir_support(e) ((e >> 3) & 0x1)
72 Index: linux-2.6.26/drivers/pci/intr_remapping.c
73 ===================================================================
75 +++ linux-2.6.26/drivers/pci/intr_remapping.c
77 +#include <linux/dmar.h>
78 +#include <asm/io_apic.h>
79 +#include "intel-iommu.h"
80 +#include "intr_remapping.h"
82 +static struct ioapic_scope ir_ioapic[MAX_IO_APICS];
83 +static int ir_ioapic_num;
85 +static int ir_parse_ioapic_scope(struct acpi_dmar_header *header,
86 + struct intel_iommu *iommu)
88 + struct acpi_dmar_hardware_unit *drhd;
89 + struct acpi_dmar_device_scope *scope;
92 + drhd = (struct acpi_dmar_hardware_unit *)header;
94 + start = (void *)(drhd + 1);
95 + end = ((void *)drhd) + header->length;
97 + while (start < end) {
99 + if (scope->entry_type == ACPI_DMAR_SCOPE_TYPE_IOAPIC) {
100 + if (ir_ioapic_num == MAX_IO_APICS) {
101 + printk(KERN_WARNING "Exceeded Max IO APICS\n");
105 + printk(KERN_INFO "IOAPIC id %d under DRHD base"
106 + " 0x%Lx\n", scope->enumeration_id,
109 + ir_ioapic[ir_ioapic_num].iommu = iommu;
110 + ir_ioapic[ir_ioapic_num].id = scope->enumeration_id;
113 + start += scope->length;
120 + * Finds the assocaition between IOAPIC's and its Interrupt-remapping
123 +int __init parse_ioapics_under_ir(void)
125 + struct dmar_drhd_unit *drhd;
126 + int ir_supported = 0;
128 + for_each_drhd_unit(drhd) {
129 + struct intel_iommu *iommu = drhd->iommu;
131 + if (ecap_ir_support(iommu->ecap)) {
132 + if (ir_parse_ioapic_scope(drhd->hdr, iommu))
139 + if (ir_supported && ir_ioapic_num != nr_ioapics) {
140 + printk(KERN_WARNING
141 + "Not all IO-APIC's listed under remapping hardware\n");
145 + return ir_supported;
147 Index: linux-2.6.26/drivers/pci/intr_remapping.h
148 ===================================================================
150 +++ linux-2.6.26/drivers/pci/intr_remapping.h
152 +#include "intel-iommu.h"
154 +struct ioapic_scope {
155 + struct intel_iommu *iommu;
158 Index: linux-2.6.26/include/linux/dmar.h
159 ===================================================================
160 --- linux-2.6.26.orig/include/linux/dmar.h
161 +++ linux-2.6.26/include/linux/dmar.h
162 @@ -47,6 +47,7 @@ extern int intel_iommu_init(void);
163 extern int dmar_table_init(void);
164 extern int early_dmar_detect(void);
165 extern int dmar_dev_scope_init(void);
166 +extern int parse_ioapics_under_ir(void);
168 extern struct list_head dmar_drhd_units;
169 extern struct list_head dmar_rmrr_units;