aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/acpi/actbl2.h15
-rw-r--r--include/linux/dmar.h82
-rw-r--r--include/linux/intel-iommu.h1
-rw-r--r--include/linux/iova.h2
4 files changed, 67 insertions, 33 deletions
diff --git a/include/acpi/actbl2.h b/include/acpi/actbl2.h
index 094a906a0e98..da5b057d775d 100644
--- a/include/acpi/actbl2.h
+++ b/include/acpi/actbl2.h
@@ -424,7 +424,8 @@ enum acpi_dmar_type {
424 ACPI_DMAR_TYPE_RESERVED_MEMORY = 1, 424 ACPI_DMAR_TYPE_RESERVED_MEMORY = 1,
425 ACPI_DMAR_TYPE_ATSR = 2, 425 ACPI_DMAR_TYPE_ATSR = 2,
426 ACPI_DMAR_HARDWARE_AFFINITY = 3, 426 ACPI_DMAR_HARDWARE_AFFINITY = 3,
427 ACPI_DMAR_TYPE_RESERVED = 4 /* 4 and greater are reserved */ 427 ACPI_DMAR_TYPE_ANDD = 4,
428 ACPI_DMAR_TYPE_RESERVED = 5 /* 5 and greater are reserved */
428}; 429};
429 430
430/* DMAR Device Scope structure */ 431/* DMAR Device Scope structure */
@@ -445,7 +446,8 @@ enum acpi_dmar_scope_type {
445 ACPI_DMAR_SCOPE_TYPE_BRIDGE = 2, 446 ACPI_DMAR_SCOPE_TYPE_BRIDGE = 2,
446 ACPI_DMAR_SCOPE_TYPE_IOAPIC = 3, 447 ACPI_DMAR_SCOPE_TYPE_IOAPIC = 3,
447 ACPI_DMAR_SCOPE_TYPE_HPET = 4, 448 ACPI_DMAR_SCOPE_TYPE_HPET = 4,
448 ACPI_DMAR_SCOPE_TYPE_RESERVED = 5 /* 5 and greater are reserved */ 449 ACPI_DMAR_SCOPE_TYPE_ACPI = 5,
450 ACPI_DMAR_SCOPE_TYPE_RESERVED = 6 /* 6 and greater are reserved */
449}; 451};
450 452
451struct acpi_dmar_pci_path { 453struct acpi_dmar_pci_path {
@@ -507,6 +509,15 @@ struct acpi_dmar_rhsa {
507 u32 proximity_domain; 509 u32 proximity_domain;
508}; 510};
509 511
512/* 4: ACPI Namespace Device Declaration Structure */
513
514struct acpi_dmar_andd {
515 struct acpi_dmar_header header;
516 u8 reserved[3];
517 u8 device_number;
518 u8 object_name[];
519};
520
510/******************************************************************************* 521/*******************************************************************************
511 * 522 *
512 * HPET - High Precision Event Timer table 523 * HPET - High Precision Event Timer table
diff --git a/include/linux/dmar.h b/include/linux/dmar.h
index eccb0c0c6cf6..23c8db129560 100644
--- a/include/linux/dmar.h
+++ b/include/linux/dmar.h
@@ -25,6 +25,8 @@
25#include <linux/types.h> 25#include <linux/types.h>
26#include <linux/msi.h> 26#include <linux/msi.h>
27#include <linux/irqreturn.h> 27#include <linux/irqreturn.h>
28#include <linux/rwsem.h>
29#include <linux/rcupdate.h>
28 30
29struct acpi_dmar_header; 31struct acpi_dmar_header;
30 32
@@ -34,13 +36,19 @@ struct acpi_dmar_header;
34 36
35struct intel_iommu; 37struct intel_iommu;
36 38
39struct dmar_dev_scope {
40 struct device __rcu *dev;
41 u8 bus;
42 u8 devfn;
43};
44
37#ifdef CONFIG_DMAR_TABLE 45#ifdef CONFIG_DMAR_TABLE
38extern struct acpi_table_header *dmar_tbl; 46extern struct acpi_table_header *dmar_tbl;
39struct dmar_drhd_unit { 47struct dmar_drhd_unit {
40 struct list_head list; /* list of drhd units */ 48 struct list_head list; /* list of drhd units */
41 struct acpi_dmar_header *hdr; /* ACPI header */ 49 struct acpi_dmar_header *hdr; /* ACPI header */
42 u64 reg_base_addr; /* register base address*/ 50 u64 reg_base_addr; /* register base address*/
43 struct pci_dev **devices; /* target device array */ 51 struct dmar_dev_scope *devices;/* target device array */
44 int devices_cnt; /* target device count */ 52 int devices_cnt; /* target device count */
45 u16 segment; /* PCI domain */ 53 u16 segment; /* PCI domain */
46 u8 ignored:1; /* ignore drhd */ 54 u8 ignored:1; /* ignore drhd */
@@ -48,33 +56,66 @@ struct dmar_drhd_unit {
48 struct intel_iommu *iommu; 56 struct intel_iommu *iommu;
49}; 57};
50 58
59struct dmar_pci_notify_info {
60 struct pci_dev *dev;
61 unsigned long event;
62 int bus;
63 u16 seg;
64 u16 level;
65 struct acpi_dmar_pci_path path[];
66} __attribute__((packed));
67
68extern struct rw_semaphore dmar_global_lock;
51extern struct list_head dmar_drhd_units; 69extern struct list_head dmar_drhd_units;
52 70
53#define for_each_drhd_unit(drhd) \ 71#define for_each_drhd_unit(drhd) \
54 list_for_each_entry(drhd, &dmar_drhd_units, list) 72 list_for_each_entry_rcu(drhd, &dmar_drhd_units, list)
55 73
56#define for_each_active_drhd_unit(drhd) \ 74#define for_each_active_drhd_unit(drhd) \
57 list_for_each_entry(drhd, &dmar_drhd_units, list) \ 75 list_for_each_entry_rcu(drhd, &dmar_drhd_units, list) \
58 if (drhd->ignored) {} else 76 if (drhd->ignored) {} else
59 77
60#define for_each_active_iommu(i, drhd) \ 78#define for_each_active_iommu(i, drhd) \
61 list_for_each_entry(drhd, &dmar_drhd_units, list) \ 79 list_for_each_entry_rcu(drhd, &dmar_drhd_units, list) \
62 if (i=drhd->iommu, drhd->ignored) {} else 80 if (i=drhd->iommu, drhd->ignored) {} else
63 81
64#define for_each_iommu(i, drhd) \ 82#define for_each_iommu(i, drhd) \
65 list_for_each_entry(drhd, &dmar_drhd_units, list) \ 83 list_for_each_entry_rcu(drhd, &dmar_drhd_units, list) \
66 if (i=drhd->iommu, 0) {} else 84 if (i=drhd->iommu, 0) {} else
67 85
86static inline bool dmar_rcu_check(void)
87{
88 return rwsem_is_locked(&dmar_global_lock) ||
89 system_state == SYSTEM_BOOTING;
90}
91
92#define dmar_rcu_dereference(p) rcu_dereference_check((p), dmar_rcu_check())
93
94#define for_each_dev_scope(a, c, p, d) \
95 for ((p) = 0; ((d) = (p) < (c) ? dmar_rcu_dereference((a)[(p)].dev) : \
96 NULL, (p) < (c)); (p)++)
97
98#define for_each_active_dev_scope(a, c, p, d) \
99 for_each_dev_scope((a), (c), (p), (d)) if (!(d)) { continue; } else
100
68extern int dmar_table_init(void); 101extern int dmar_table_init(void);
69extern int dmar_dev_scope_init(void); 102extern int dmar_dev_scope_init(void);
70extern int dmar_parse_dev_scope(void *start, void *end, int *cnt, 103extern int dmar_parse_dev_scope(void *start, void *end, int *cnt,
71 struct pci_dev ***devices, u16 segment); 104 struct dmar_dev_scope **devices, u16 segment);
72extern void dmar_free_dev_scope(struct pci_dev ***devices, int *cnt); 105extern void *dmar_alloc_dev_scope(void *start, void *end, int *cnt);
73 106extern void dmar_free_dev_scope(struct dmar_dev_scope **devices, int *cnt);
107extern int dmar_insert_dev_scope(struct dmar_pci_notify_info *info,
108 void *start, void*end, u16 segment,
109 struct dmar_dev_scope *devices,
110 int devices_cnt);
111extern int dmar_remove_dev_scope(struct dmar_pci_notify_info *info,
112 u16 segment, struct dmar_dev_scope *devices,
113 int count);
74/* Intel IOMMU detection */ 114/* Intel IOMMU detection */
75extern int detect_intel_iommu(void); 115extern int detect_intel_iommu(void);
76extern int enable_drhd_fault_handling(void); 116extern int enable_drhd_fault_handling(void);
77#else 117#else
118struct dmar_pci_notify_info;
78static inline int detect_intel_iommu(void) 119static inline int detect_intel_iommu(void)
79{ 120{
80 return -ENODEV; 121 return -ENODEV;
@@ -138,30 +179,9 @@ extern int arch_setup_dmar_msi(unsigned int irq);
138 179
139#ifdef CONFIG_INTEL_IOMMU 180#ifdef CONFIG_INTEL_IOMMU
140extern int iommu_detected, no_iommu; 181extern int iommu_detected, no_iommu;
141extern struct list_head dmar_rmrr_units;
142struct dmar_rmrr_unit {
143 struct list_head list; /* list of rmrr units */
144 struct acpi_dmar_header *hdr; /* ACPI header */
145 u64 base_address; /* reserved base address*/
146 u64 end_address; /* reserved end address */
147 struct pci_dev **devices; /* target devices */
148 int devices_cnt; /* target device count */
149};
150
151#define for_each_rmrr_units(rmrr) \
152 list_for_each_entry(rmrr, &dmar_rmrr_units, list)
153
154struct dmar_atsr_unit {
155 struct list_head list; /* list of ATSR units */
156 struct acpi_dmar_header *hdr; /* ACPI header */
157 struct pci_dev **devices; /* target devices */
158 int devices_cnt; /* target device count */
159 u8 include_all:1; /* include all ports */
160};
161
162int dmar_parse_rmrr_atsr_dev(void);
163extern int dmar_parse_one_rmrr(struct acpi_dmar_header *header); 182extern int dmar_parse_one_rmrr(struct acpi_dmar_header *header);
164extern int dmar_parse_one_atsr(struct acpi_dmar_header *header); 183extern int dmar_parse_one_atsr(struct acpi_dmar_header *header);
184extern int dmar_iommu_notify_scope_dev(struct dmar_pci_notify_info *info);
165extern int intel_iommu_init(void); 185extern int intel_iommu_init(void);
166#else /* !CONFIG_INTEL_IOMMU: */ 186#else /* !CONFIG_INTEL_IOMMU: */
167static inline int intel_iommu_init(void) { return -ENODEV; } 187static inline int intel_iommu_init(void) { return -ENODEV; }
@@ -173,7 +193,7 @@ static inline int dmar_parse_one_atsr(struct acpi_dmar_header *header)
173{ 193{
174 return 0; 194 return 0;
175} 195}
176static inline int dmar_parse_rmrr_atsr_dev(void) 196static inline int dmar_iommu_notify_scope_dev(struct dmar_pci_notify_info *info)
177{ 197{
178 return 0; 198 return 0;
179} 199}
diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h
index 2c4bed593b32..0a2da5188217 100644
--- a/include/linux/intel-iommu.h
+++ b/include/linux/intel-iommu.h
@@ -319,6 +319,7 @@ struct intel_iommu {
319 int agaw; /* agaw of this iommu */ 319 int agaw; /* agaw of this iommu */
320 int msagaw; /* max sagaw of this iommu */ 320 int msagaw; /* max sagaw of this iommu */
321 unsigned int irq; 321 unsigned int irq;
322 u16 segment; /* PCI segment# */
322 unsigned char name[13]; /* Device Name */ 323 unsigned char name[13]; /* Device Name */
323 324
324#ifdef CONFIG_INTEL_IOMMU 325#ifdef CONFIG_INTEL_IOMMU
diff --git a/include/linux/iova.h b/include/linux/iova.h
index 76a0759e88ec..3277f4711349 100644
--- a/include/linux/iova.h
+++ b/include/linux/iova.h
@@ -47,5 +47,7 @@ void copy_reserved_iova(struct iova_domain *from, struct iova_domain *to);
47void init_iova_domain(struct iova_domain *iovad, unsigned long pfn_32bit); 47void init_iova_domain(struct iova_domain *iovad, unsigned long pfn_32bit);
48struct iova *find_iova(struct iova_domain *iovad, unsigned long pfn); 48struct iova *find_iova(struct iova_domain *iovad, unsigned long pfn);
49void put_iova_domain(struct iova_domain *iovad); 49void put_iova_domain(struct iova_domain *iovad);
50struct iova *split_and_remove_iova(struct iova_domain *iovad,
51 struct iova *iova, unsigned long pfn_lo, unsigned long pfn_hi);
50 52
51#endif 53#endif