diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/acpi/actbl2.h | 15 | ||||
-rw-r--r-- | include/linux/dmar.h | 82 | ||||
-rw-r--r-- | include/linux/intel-iommu.h | 1 | ||||
-rw-r--r-- | include/linux/iova.h | 2 |
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 | ||
451 | struct acpi_dmar_pci_path { | 453 | struct 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 | |||
514 | struct 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 | ||
29 | struct acpi_dmar_header; | 31 | struct acpi_dmar_header; |
30 | 32 | ||
@@ -34,13 +36,19 @@ struct acpi_dmar_header; | |||
34 | 36 | ||
35 | struct intel_iommu; | 37 | struct intel_iommu; |
36 | 38 | ||
39 | struct 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 |
38 | extern struct acpi_table_header *dmar_tbl; | 46 | extern struct acpi_table_header *dmar_tbl; |
39 | struct dmar_drhd_unit { | 47 | struct 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 | ||
59 | struct 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 | |||
68 | extern struct rw_semaphore dmar_global_lock; | ||
51 | extern struct list_head dmar_drhd_units; | 69 | extern 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 | ||
86 | static 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 | |||
68 | extern int dmar_table_init(void); | 101 | extern int dmar_table_init(void); |
69 | extern int dmar_dev_scope_init(void); | 102 | extern int dmar_dev_scope_init(void); |
70 | extern int dmar_parse_dev_scope(void *start, void *end, int *cnt, | 103 | extern 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); |
72 | extern void dmar_free_dev_scope(struct pci_dev ***devices, int *cnt); | 105 | extern void *dmar_alloc_dev_scope(void *start, void *end, int *cnt); |
73 | 106 | extern void dmar_free_dev_scope(struct dmar_dev_scope **devices, int *cnt); | |
107 | extern 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); | ||
111 | extern 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 */ |
75 | extern int detect_intel_iommu(void); | 115 | extern int detect_intel_iommu(void); |
76 | extern int enable_drhd_fault_handling(void); | 116 | extern int enable_drhd_fault_handling(void); |
77 | #else | 117 | #else |
118 | struct dmar_pci_notify_info; | ||
78 | static inline int detect_intel_iommu(void) | 119 | static 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 |
140 | extern int iommu_detected, no_iommu; | 181 | extern int iommu_detected, no_iommu; |
141 | extern struct list_head dmar_rmrr_units; | ||
142 | struct 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 | |||
154 | struct 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 | |||
162 | int dmar_parse_rmrr_atsr_dev(void); | ||
163 | extern int dmar_parse_one_rmrr(struct acpi_dmar_header *header); | 182 | extern int dmar_parse_one_rmrr(struct acpi_dmar_header *header); |
164 | extern int dmar_parse_one_atsr(struct acpi_dmar_header *header); | 183 | extern int dmar_parse_one_atsr(struct acpi_dmar_header *header); |
184 | extern int dmar_iommu_notify_scope_dev(struct dmar_pci_notify_info *info); | ||
165 | extern int intel_iommu_init(void); | 185 | extern int intel_iommu_init(void); |
166 | #else /* !CONFIG_INTEL_IOMMU: */ | 186 | #else /* !CONFIG_INTEL_IOMMU: */ |
167 | static inline int intel_iommu_init(void) { return -ENODEV; } | 187 | static 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 | } |
176 | static inline int dmar_parse_rmrr_atsr_dev(void) | 196 | static 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); | |||
47 | void init_iova_domain(struct iova_domain *iovad, unsigned long pfn_32bit); | 47 | void init_iova_domain(struct iova_domain *iovad, unsigned long pfn_32bit); |
48 | struct iova *find_iova(struct iova_domain *iovad, unsigned long pfn); | 48 | struct iova *find_iova(struct iova_domain *iovad, unsigned long pfn); |
49 | void put_iova_domain(struct iova_domain *iovad); | 49 | void put_iova_domain(struct iova_domain *iovad); |
50 | struct 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 |