]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/suse-2.6.27.39/patches.arch/x2APIC_PATCH_01_of_41_e61d98d8dad0048619bb138b0ff996422ffae53b
Imported linux-2.6.27.39 suse/xen patches.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.arch / x2APIC_PATCH_01_of_41_e61d98d8dad0048619bb138b0ff996422ffae53b
CommitLineData
2cb7cef9
BS
1From: Suresh Siddha <suresh.b.siddha@intel.com>
2Subject: x64, x2apic/intr-remap: Intel vt-d, IOMMU code reorganization
3References: fate #303948 and fate #303984
4Patch-Mainline: queued for .28
5Commit-ID: e61d98d8dad0048619bb138b0ff996422ffae53b
6
7Signed-off-by: Thomas Renninger <trenn@suse.de>
8
9code reorganization of the generic Intel vt-d parsing related routines and linux
10iommu routines specific to Intel vt-d.
11
12drivers/pci/dmar.c now contains the generic vt-d parsing related routines
13drivers/pci/intel_iommu.c contains the iommu routines specific to vt-d
14
15Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
16Cc: akpm@linux-foundation.org
17Cc: arjan@linux.intel.com
18Cc: andi@firstfloor.org
19Cc: ebiederm@xmission.com
20Cc: jbarnes@virtuousgeek.org
21Cc: steiner@sgi.com
22Signed-off-by: Ingo Molnar <mingo@elte.hu>
23
24---
25 drivers/pci/dma_remapping.h | 155 +++++++++++++++++++++++++++++++++++++++++
26 drivers/pci/dmar.c | 90 ++++++++++++++++++++++++
27 drivers/pci/intel-iommu.c | 92 ++----------------------
28 drivers/pci/intel-iommu.h | 163 +++-----------------------------------------
29 4 files changed, 264 insertions(+), 236 deletions(-)
30
31--- a/drivers/pci/dmar.c
32+++ b/drivers/pci/dmar.c
33@@ -19,9 +19,11 @@
34 * Author: Shaohua Li <shaohua.li@intel.com>
35 * Author: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
36 *
37- * This file implements early detection/parsing of DMA Remapping Devices
38+ * This file implements early detection/parsing of Remapping Devices
39 * reported to OS through BIOS via DMA remapping reporting (DMAR) ACPI
40 * tables.
41+ *
42+ * These routines are used by both DMA-remapping and Interrupt-remapping
43 */
44
45 #include <linux/pci.h>
46@@ -300,6 +302,37 @@ parse_dmar_table(void)
47 return ret;
48 }
49
50+int dmar_pci_device_match(struct pci_dev *devices[], int cnt,
51+ struct pci_dev *dev)
52+{
53+ int index;
54+
55+ while (dev) {
56+ for (index = 0; index < cnt; index++)
57+ if (dev == devices[index])
58+ return 1;
59+
60+ /* Check our parent */
61+ dev = dev->bus->self;
62+ }
63+
64+ return 0;
65+}
66+
67+struct dmar_drhd_unit *
68+dmar_find_matched_drhd_unit(struct pci_dev *dev)
69+{
70+ struct dmar_drhd_unit *drhd = NULL;
71+
72+ list_for_each_entry(drhd, &dmar_drhd_units, list) {
73+ if (drhd->include_all || dmar_pci_device_match(drhd->devices,
74+ drhd->devices_cnt, dev))
75+ return drhd;
76+ }
77+
78+ return NULL;
79+}
80+
81
82 int __init dmar_table_init(void)
83 {
84@@ -341,3 +374,58 @@ int __init early_dmar_detect(void)
85
86 return (ACPI_SUCCESS(status) ? 1 : 0);
87 }
88+
89+struct intel_iommu *alloc_iommu(struct intel_iommu *iommu,
90+ struct dmar_drhd_unit *drhd)
91+{
92+ int map_size;
93+ u32 ver;
94+
95+ iommu->reg = ioremap(drhd->reg_base_addr, PAGE_SIZE_4K);
96+ if (!iommu->reg) {
97+ printk(KERN_ERR "IOMMU: can't map the region\n");
98+ goto error;
99+ }
100+ iommu->cap = dmar_readq(iommu->reg + DMAR_CAP_REG);
101+ iommu->ecap = dmar_readq(iommu->reg + DMAR_ECAP_REG);
102+
103+ /* the registers might be more than one page */
104+ map_size = max_t(int, ecap_max_iotlb_offset(iommu->ecap),
105+ cap_max_fault_reg_offset(iommu->cap));
106+ map_size = PAGE_ALIGN_4K(map_size);
107+ if (map_size > PAGE_SIZE_4K) {
108+ iounmap(iommu->reg);
109+ iommu->reg = ioremap(drhd->reg_base_addr, map_size);
110+ if (!iommu->reg) {
111+ printk(KERN_ERR "IOMMU: can't map the region\n");
112+ goto error;
113+ }
114+ }
115+
116+ ver = readl(iommu->reg + DMAR_VER_REG);
117+ pr_debug("IOMMU %llx: ver %d:%d cap %llx ecap %llx\n",
118+ drhd->reg_base_addr, DMAR_VER_MAJOR(ver), DMAR_VER_MINOR(ver),
119+ iommu->cap, iommu->ecap);
120+
121+ spin_lock_init(&iommu->register_lock);
122+
123+ drhd->iommu = iommu;
124+ return iommu;
125+error:
126+ kfree(iommu);
127+ return NULL;
128+}
129+
130+void free_iommu(struct intel_iommu *iommu)
131+{
132+ if (!iommu)
133+ return;
134+
135+#ifdef CONFIG_DMAR
136+ free_dmar_iommu(iommu);
137+#endif
138+
139+ if (iommu->reg)
140+ iounmap(iommu->reg);
141+ kfree(iommu);
142+}
143--- /dev/null
144+++ b/drivers/pci/dma_remapping.h
145@@ -0,0 +1,155 @@
146+#ifndef _DMA_REMAPPING_H
147+#define _DMA_REMAPPING_H
148+
149+/*
150+ * We need a fixed PAGE_SIZE of 4K irrespective of
151+ * arch PAGE_SIZE for IOMMU page tables.
152+ */
153+#define PAGE_SHIFT_4K (12)
154+#define PAGE_SIZE_4K (1UL << PAGE_SHIFT_4K)
155+#define PAGE_MASK_4K (((u64)-1) << PAGE_SHIFT_4K)
156+#define PAGE_ALIGN_4K(addr) (((addr) + PAGE_SIZE_4K - 1) & PAGE_MASK_4K)
157+
158+#define IOVA_PFN(addr) ((addr) >> PAGE_SHIFT_4K)
159+#define DMA_32BIT_PFN IOVA_PFN(DMA_32BIT_MASK)
160+#define DMA_64BIT_PFN IOVA_PFN(DMA_64BIT_MASK)
161+
162+
163+/*
164+ * 0: Present
165+ * 1-11: Reserved
166+ * 12-63: Context Ptr (12 - (haw-1))
167+ * 64-127: Reserved
168+ */
169+struct root_entry {
170+ u64 val;
171+ u64 rsvd1;
172+};
173+#define ROOT_ENTRY_NR (PAGE_SIZE_4K/sizeof(struct root_entry))
174+static inline bool root_present(struct root_entry *root)
175+{
176+ return (root->val & 1);
177+}
178+static inline void set_root_present(struct root_entry *root)
179+{
180+ root->val |= 1;
181+}
182+static inline void set_root_value(struct root_entry *root, unsigned long value)
183+{
184+ root->val |= value & PAGE_MASK_4K;
185+}
186+
187+struct context_entry;
188+static inline struct context_entry *
189+get_context_addr_from_root(struct root_entry *root)
190+{
191+ return (struct context_entry *)
192+ (root_present(root)?phys_to_virt(
193+ root->val & PAGE_MASK_4K):
194+ NULL);
195+}
196+
197+/*
198+ * low 64 bits:
199+ * 0: present
200+ * 1: fault processing disable
201+ * 2-3: translation type
202+ * 12-63: address space root
203+ * high 64 bits:
204+ * 0-2: address width
205+ * 3-6: aval
206+ * 8-23: domain id
207+ */
208+struct context_entry {
209+ u64 lo;
210+ u64 hi;
211+};
212+#define context_present(c) ((c).lo & 1)
213+#define context_fault_disable(c) (((c).lo >> 1) & 1)
214+#define context_translation_type(c) (((c).lo >> 2) & 3)
215+#define context_address_root(c) ((c).lo & PAGE_MASK_4K)
216+#define context_address_width(c) ((c).hi & 7)
217+#define context_domain_id(c) (((c).hi >> 8) & ((1 << 16) - 1))
218+
219+#define context_set_present(c) do {(c).lo |= 1;} while (0)
220+#define context_set_fault_enable(c) \
221+ do {(c).lo &= (((u64)-1) << 2) | 1;} while (0)
222+#define context_set_translation_type(c, val) \
223+ do { \
224+ (c).lo &= (((u64)-1) << 4) | 3; \
225+ (c).lo |= ((val) & 3) << 2; \
226+ } while (0)
227+#define CONTEXT_TT_MULTI_LEVEL 0
228+#define context_set_address_root(c, val) \
229+ do {(c).lo |= (val) & PAGE_MASK_4K;} while (0)
230+#define context_set_address_width(c, val) do {(c).hi |= (val) & 7;} while (0)
231+#define context_set_domain_id(c, val) \
232+ do {(c).hi |= ((val) & ((1 << 16) - 1)) << 8;} while (0)
233+#define context_clear_entry(c) do {(c).lo = 0; (c).hi = 0;} while (0)
234+
235+/*
236+ * 0: readable
237+ * 1: writable
238+ * 2-6: reserved
239+ * 7: super page
240+ * 8-11: available
241+ * 12-63: Host physcial address
242+ */
243+struct dma_pte {
244+ u64 val;
245+};
246+#define dma_clear_pte(p) do {(p).val = 0;} while (0)
247+
248+#define DMA_PTE_READ (1)
249+#define DMA_PTE_WRITE (2)
250+
251+#define dma_set_pte_readable(p) do {(p).val |= DMA_PTE_READ;} while (0)
252+#define dma_set_pte_writable(p) do {(p).val |= DMA_PTE_WRITE;} while (0)
253+#define dma_set_pte_prot(p, prot) \
254+ do {(p).val = ((p).val & ~3) | ((prot) & 3); } while (0)
255+#define dma_pte_addr(p) ((p).val & PAGE_MASK_4K)
256+#define dma_set_pte_addr(p, addr) do {\
257+ (p).val |= ((addr) & PAGE_MASK_4K); } while (0)
258+#define dma_pte_present(p) (((p).val & 3) != 0)
259+
260+struct intel_iommu;
261+
262+struct dmar_domain {
263+ int id; /* domain id */
264+ struct intel_iommu *iommu; /* back pointer to owning iommu */
265+
266+ struct list_head devices; /* all devices' list */
267+ struct iova_domain iovad; /* iova's that belong to this domain */
268+
269+ struct dma_pte *pgd; /* virtual address */
270+ spinlock_t mapping_lock; /* page table lock */
271+ int gaw; /* max guest address width */
272+
273+ /* adjusted guest address width, 0 is level 2 30-bit */
274+ int agaw;
275+
276+#define DOMAIN_FLAG_MULTIPLE_DEVICES 1
277+ int flags;
278+};
279+
280+/* PCI domain-device relationship */
281+struct device_domain_info {
282+ struct list_head link; /* link to domain siblings */
283+ struct list_head global; /* link to global list */
284+ u8 bus; /* PCI bus numer */
285+ u8 devfn; /* PCI devfn number */
286+ struct pci_dev *dev; /* it's NULL for PCIE-to-PCI bridge */
287+ struct dmar_domain *domain; /* pointer to domain */
288+};
289+
290+extern int init_dmars(void);
291+extern void free_dmar_iommu(struct intel_iommu *iommu);
292+
293+#ifndef CONFIG_DMAR_GFX_WA
294+static inline void iommu_prepare_gfx_mapping(void)
295+{
296+ return;
297+}
298+#endif /* !CONFIG_DMAR_GFX_WA */
299+
300+#endif
301--- a/drivers/pci/intel-iommu.c
302+++ b/drivers/pci/intel-iommu.c
303@@ -992,6 +992,8 @@ static int iommu_init_domains(struct int
304 return -ENOMEM;
305 }
306
307+ spin_lock_init(&iommu->lock);
308+
309 /*
310 * if Caching mode is set, then invalid translations are tagged
311 * with domainid 0. Hence we need to pre-allocate it.
312@@ -1000,62 +1002,15 @@ static int iommu_init_domains(struct int
313 set_bit(0, iommu->domain_ids);
314 return 0;
315 }
316-static struct intel_iommu *alloc_iommu(struct intel_iommu *iommu,
317- struct dmar_drhd_unit *drhd)
318-{
319- int ret;
320- int map_size;
321- u32 ver;
322-
323- iommu->reg = ioremap(drhd->reg_base_addr, PAGE_SIZE_4K);
324- if (!iommu->reg) {
325- printk(KERN_ERR "IOMMU: can't map the region\n");
326- goto error;
327- }
328- iommu->cap = dmar_readq(iommu->reg + DMAR_CAP_REG);
329- iommu->ecap = dmar_readq(iommu->reg + DMAR_ECAP_REG);
330-
331- /* the registers might be more than one page */
332- map_size = max_t(int, ecap_max_iotlb_offset(iommu->ecap),
333- cap_max_fault_reg_offset(iommu->cap));
334- map_size = PAGE_ALIGN_4K(map_size);
335- if (map_size > PAGE_SIZE_4K) {
336- iounmap(iommu->reg);
337- iommu->reg = ioremap(drhd->reg_base_addr, map_size);
338- if (!iommu->reg) {
339- printk(KERN_ERR "IOMMU: can't map the region\n");
340- goto error;
341- }
342- }
343
344- ver = readl(iommu->reg + DMAR_VER_REG);
345- pr_debug("IOMMU %llx: ver %d:%d cap %llx ecap %llx\n",
346- drhd->reg_base_addr, DMAR_VER_MAJOR(ver), DMAR_VER_MINOR(ver),
347- iommu->cap, iommu->ecap);
348- ret = iommu_init_domains(iommu);
349- if (ret)
350- goto error_unmap;
351- spin_lock_init(&iommu->lock);
352- spin_lock_init(&iommu->register_lock);
353-
354- drhd->iommu = iommu;
355- return iommu;
356-error_unmap:
357- iounmap(iommu->reg);
358-error:
359- kfree(iommu);
360- return NULL;
361-}
362
363 static void domain_exit(struct dmar_domain *domain);
364-static void free_iommu(struct intel_iommu *iommu)
365+
366+void free_dmar_iommu(struct intel_iommu *iommu)
367 {
368 struct dmar_domain *domain;
369 int i;
370
371- if (!iommu)
372- return;
373-
374 i = find_first_bit(iommu->domain_ids, cap_ndoms(iommu->cap));
375 for (; i < cap_ndoms(iommu->cap); ) {
376 domain = iommu->domains[i];
377@@ -1080,10 +1035,6 @@ static void free_iommu(struct intel_iomm
378
379 /* free context mapping */
380 free_context_table(iommu);
381-
382- if (iommu->reg)
383- iounmap(iommu->reg);
384- kfree(iommu);
385 }
386
387 static struct dmar_domain * iommu_alloc_domain(struct intel_iommu *iommu)
388@@ -1428,37 +1379,6 @@ find_domain(struct pci_dev *pdev)
389 return NULL;
390 }
391
392-static int dmar_pci_device_match(struct pci_dev *devices[], int cnt,
393- struct pci_dev *dev)
394-{
395- int index;
396-
397- while (dev) {
398- for (index = 0; index < cnt; index++)
399- if (dev == devices[index])
400- return 1;
401-
402- /* Check our parent */
403- dev = dev->bus->self;
404- }
405-
406- return 0;
407-}
408-
409-static struct dmar_drhd_unit *
410-dmar_find_matched_drhd_unit(struct pci_dev *dev)
411-{
412- struct dmar_drhd_unit *drhd = NULL;
413-
414- list_for_each_entry(drhd, &dmar_drhd_units, list) {
415- if (drhd->include_all || dmar_pci_device_match(drhd->devices,
416- drhd->devices_cnt, dev))
417- return drhd;
418- }
419-
420- return NULL;
421-}
422-
423 /* domain is initialized */
424 static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw)
425 {
426@@ -1765,6 +1685,10 @@ int __init init_dmars(void)
427 goto error;
428 }
429
430+ ret = iommu_init_domains(iommu);
431+ if (ret)
432+ goto error;
433+
434 /*
435 * TBD:
436 * we could share the same root & context tables
437--- a/drivers/pci/intel-iommu.h
438+++ b/drivers/pci/intel-iommu.h
439@@ -27,19 +27,7 @@
440 #include <linux/sysdev.h>
441 #include "iova.h"
442 #include <linux/io.h>
443-
444-/*
445- * We need a fixed PAGE_SIZE of 4K irrespective of
446- * arch PAGE_SIZE for IOMMU page tables.
447- */
448-#define PAGE_SHIFT_4K (12)
449-#define PAGE_SIZE_4K (1UL << PAGE_SHIFT_4K)
450-#define PAGE_MASK_4K (((u64)-1) << PAGE_SHIFT_4K)
451-#define PAGE_ALIGN_4K(addr) (((addr) + PAGE_SIZE_4K - 1) & PAGE_MASK_4K)
452-
453-#define IOVA_PFN(addr) ((addr) >> PAGE_SHIFT_4K)
454-#define DMA_32BIT_PFN IOVA_PFN(DMA_32BIT_MASK)
455-#define DMA_64BIT_PFN IOVA_PFN(DMA_64BIT_MASK)
456+#include "dma_remapping.h"
457
458 /*
459 * Intel IOMMU register specification per version 1.0 public spec.
460@@ -187,158 +175,31 @@ static inline void dmar_writeq(void __io
461 #define dma_frcd_source_id(c) (c & 0xffff)
462 #define dma_frcd_page_addr(d) (d & (((u64)-1) << 12)) /* low 64 bit */
463
464-/*
465- * 0: Present
466- * 1-11: Reserved
467- * 12-63: Context Ptr (12 - (haw-1))
468- * 64-127: Reserved
469- */
470-struct root_entry {
471- u64 val;
472- u64 rsvd1;
473-};
474-#define ROOT_ENTRY_NR (PAGE_SIZE_4K/sizeof(struct root_entry))
475-static inline bool root_present(struct root_entry *root)
476-{
477- return (root->val & 1);
478-}
479-static inline void set_root_present(struct root_entry *root)
480-{
481- root->val |= 1;
482-}
483-static inline void set_root_value(struct root_entry *root, unsigned long value)
484-{
485- root->val |= value & PAGE_MASK_4K;
486-}
487-
488-struct context_entry;
489-static inline struct context_entry *
490-get_context_addr_from_root(struct root_entry *root)
491-{
492- return (struct context_entry *)
493- (root_present(root)?phys_to_virt(
494- root->val & PAGE_MASK_4K):
495- NULL);
496-}
497-
498-/*
499- * low 64 bits:
500- * 0: present
501- * 1: fault processing disable
502- * 2-3: translation type
503- * 12-63: address space root
504- * high 64 bits:
505- * 0-2: address width
506- * 3-6: aval
507- * 8-23: domain id
508- */
509-struct context_entry {
510- u64 lo;
511- u64 hi;
512-};
513-#define context_present(c) ((c).lo & 1)
514-#define context_fault_disable(c) (((c).lo >> 1) & 1)
515-#define context_translation_type(c) (((c).lo >> 2) & 3)
516-#define context_address_root(c) ((c).lo & PAGE_MASK_4K)
517-#define context_address_width(c) ((c).hi & 7)
518-#define context_domain_id(c) (((c).hi >> 8) & ((1 << 16) - 1))
519-
520-#define context_set_present(c) do {(c).lo |= 1;} while (0)
521-#define context_set_fault_enable(c) \
522- do {(c).lo &= (((u64)-1) << 2) | 1;} while (0)
523-#define context_set_translation_type(c, val) \
524- do { \
525- (c).lo &= (((u64)-1) << 4) | 3; \
526- (c).lo |= ((val) & 3) << 2; \
527- } while (0)
528-#define CONTEXT_TT_MULTI_LEVEL 0
529-#define context_set_address_root(c, val) \
530- do {(c).lo |= (val) & PAGE_MASK_4K;} while (0)
531-#define context_set_address_width(c, val) do {(c).hi |= (val) & 7;} while (0)
532-#define context_set_domain_id(c, val) \
533- do {(c).hi |= ((val) & ((1 << 16) - 1)) << 8;} while (0)
534-#define context_clear_entry(c) do {(c).lo = 0; (c).hi = 0;} while (0)
535-
536-/*
537- * 0: readable
538- * 1: writable
539- * 2-6: reserved
540- * 7: super page
541- * 8-11: available
542- * 12-63: Host physcial address
543- */
544-struct dma_pte {
545- u64 val;
546-};
547-#define dma_clear_pte(p) do {(p).val = 0;} while (0)
548-
549-#define DMA_PTE_READ (1)
550-#define DMA_PTE_WRITE (2)
551-
552-#define dma_set_pte_readable(p) do {(p).val |= DMA_PTE_READ;} while (0)
553-#define dma_set_pte_writable(p) do {(p).val |= DMA_PTE_WRITE;} while (0)
554-#define dma_set_pte_prot(p, prot) \
555- do {(p).val = ((p).val & ~3) | ((prot) & 3); } while (0)
556-#define dma_pte_addr(p) ((p).val & PAGE_MASK_4K)
557-#define dma_set_pte_addr(p, addr) do {\
558- (p).val |= ((addr) & PAGE_MASK_4K); } while (0)
559-#define dma_pte_present(p) (((p).val & 3) != 0)
560-
561-struct intel_iommu;
562-
563-struct dmar_domain {
564- int id; /* domain id */
565- struct intel_iommu *iommu; /* back pointer to owning iommu */
566-
567- struct list_head devices; /* all devices' list */
568- struct iova_domain iovad; /* iova's that belong to this domain */
569-
570- struct dma_pte *pgd; /* virtual address */
571- spinlock_t mapping_lock; /* page table lock */
572- int gaw; /* max guest address width */
573-
574- /* adjusted guest address width, 0 is level 2 30-bit */
575- int agaw;
576-
577-#define DOMAIN_FLAG_MULTIPLE_DEVICES 1
578- int flags;
579-};
580-
581-/* PCI domain-device relationship */
582-struct device_domain_info {
583- struct list_head link; /* link to domain siblings */
584- struct list_head global; /* link to global list */
585- u8 bus; /* PCI bus numer */
586- u8 devfn; /* PCI devfn number */
587- struct pci_dev *dev; /* it's NULL for PCIE-to-PCI bridge */
588- struct dmar_domain *domain; /* pointer to domain */
589-};
590-
591-extern int init_dmars(void);
592-
593 struct intel_iommu {
594 void __iomem *reg; /* Pointer to hardware regs, virtual addr */
595 u64 cap;
596 u64 ecap;
597- unsigned long *domain_ids; /* bitmap of domains */
598- struct dmar_domain **domains; /* ptr to domains */
599 int seg;
600 u32 gcmd; /* Holds TE, EAFL. Don't need SRTP, SFL, WBF */
601- spinlock_t lock; /* protect context, domain ids */
602 spinlock_t register_lock; /* protect register handling */
603+
604+#ifdef CONFIG_DMAR
605+ unsigned long *domain_ids; /* bitmap of domains */
606+ struct dmar_domain **domains; /* ptr to domains */
607+ spinlock_t lock; /* protect context, domain ids */
608 struct root_entry *root_entry; /* virtual address */
609
610 unsigned int irq;
611 unsigned char name[7]; /* Device Name */
612 struct msi_msg saved_msg;
613 struct sys_device sysdev;
614+#endif
615 };
616
617-#ifndef CONFIG_DMAR_GFX_WA
618-static inline void iommu_prepare_gfx_mapping(void)
619-{
620- return;
621-}
622-#endif /* !CONFIG_DMAR_GFX_WA */
623+extern struct dmar_drhd_unit * dmar_find_matched_drhd_unit(struct pci_dev *dev);
624+
625+extern struct intel_iommu *alloc_iommu(struct intel_iommu *iommu,
626+ struct dmar_drhd_unit *drhd);
627+extern void free_iommu(struct intel_iommu *iommu);
628
629 #endif