]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/suse-2.6.27.39/patches.arch/x2APIC_PATCH_06_of_41_ad3ad3f6a2caebf56869b83b69e23eb9fa5e0ab6
Fix oinkmaster patch.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.arch / x2APIC_PATCH_06_of_41_ad3ad3f6a2caebf56869b83b69e23eb9fa5e0ab6
CommitLineData
2cb7cef9
BS
1From: Suresh Siddha <suresh.b.siddha@intel.com>
2Subject: x64, x2apic/intr-remap: parse ioapic scope under vt-d structures
3References: fate #303948 and fate #303984
4Patch-Mainline: queued for .28
5Commit-ID: ad3ad3f6a2caebf56869b83b69e23eb9fa5e0ab6
6
7Signed-off-by: Thomas Renninger <trenn@suse.de>
8
9Parse the vt-d device scope structures to find the mapping between IO-APICs
10and the interrupt remapping hardware units.
11
12This will be used later for enabling Interrupt-remapping for IOAPIC devices.
13
14Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
15Cc: akpm@linux-foundation.org
16Cc: arjan@linux.intel.com
17Cc: andi@firstfloor.org
18Cc: ebiederm@xmission.com
19Cc: jbarnes@virtuousgeek.org
20Cc: steiner@sgi.com
21Signed-off-by: Ingo Molnar <mingo@elte.hu>
22
23---
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(+)
31
32Index: 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
39
40+obj-$(CONFIG_INTR_REMAP) += dmar.o intr_remapping.o
41+
42 #
43 # Some architectures use the generic PCI setup functions
44 #
45Index: 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)
50 }
51 #endif
52
53+#ifdef CONFIG_INTR_REMAP
54+ parse_ioapics_under_ir();
55+#endif
56 return 0;
57 }
58
59Index: 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)
69
70
71 /* IOTLB_REG */
72Index: linux-2.6.26/drivers/pci/intr_remapping.c
73===================================================================
74--- /dev/null
75+++ linux-2.6.26/drivers/pci/intr_remapping.c
76@@ -0,0 +1,70 @@
77+#include <linux/dmar.h>
78+#include <asm/io_apic.h>
79+#include "intel-iommu.h"
80+#include "intr_remapping.h"
81+
82+static struct ioapic_scope ir_ioapic[MAX_IO_APICS];
83+static int ir_ioapic_num;
84+
85+static int ir_parse_ioapic_scope(struct acpi_dmar_header *header,
86+ struct intel_iommu *iommu)
87+{
88+ struct acpi_dmar_hardware_unit *drhd;
89+ struct acpi_dmar_device_scope *scope;
90+ void *start, *end;
91+
92+ drhd = (struct acpi_dmar_hardware_unit *)header;
93+
94+ start = (void *)(drhd + 1);
95+ end = ((void *)drhd) + header->length;
96+
97+ while (start < end) {
98+ scope = start;
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");
102+ return -1;
103+ }
104+
105+ printk(KERN_INFO "IOAPIC id %d under DRHD base"
106+ " 0x%Lx\n", scope->enumeration_id,
107+ drhd->address);
108+
109+ ir_ioapic[ir_ioapic_num].iommu = iommu;
110+ ir_ioapic[ir_ioapic_num].id = scope->enumeration_id;
111+ ir_ioapic_num++;
112+ }
113+ start += scope->length;
114+ }
115+
116+ return 0;
117+}
118+
119+/*
120+ * Finds the assocaition between IOAPIC's and its Interrupt-remapping
121+ * hardware unit.
122+ */
123+int __init parse_ioapics_under_ir(void)
124+{
125+ struct dmar_drhd_unit *drhd;
126+ int ir_supported = 0;
127+
128+ for_each_drhd_unit(drhd) {
129+ struct intel_iommu *iommu = drhd->iommu;
130+
131+ if (ecap_ir_support(iommu->ecap)) {
132+ if (ir_parse_ioapic_scope(drhd->hdr, iommu))
133+ return -1;
134+
135+ ir_supported = 1;
136+ }
137+ }
138+
139+ if (ir_supported && ir_ioapic_num != nr_ioapics) {
140+ printk(KERN_WARNING
141+ "Not all IO-APIC's listed under remapping hardware\n");
142+ return -1;
143+ }
144+
145+ return ir_supported;
146+}
147Index: linux-2.6.26/drivers/pci/intr_remapping.h
148===================================================================
149--- /dev/null
150+++ linux-2.6.26/drivers/pci/intr_remapping.h
151@@ -0,0 +1,6 @@
152+#include "intel-iommu.h"
153+
154+struct ioapic_scope {
155+ struct intel_iommu *iommu;
156+ unsigned int id;
157+};
158Index: 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);
167
168 extern struct list_head dmar_drhd_units;
169 extern struct list_head dmar_rmrr_units;