aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu/dmar.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/iommu/dmar.c')
-rw-r--r--drivers/iommu/dmar.c513
1 files changed, 389 insertions, 124 deletions
diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
index 158156543410..f445c10df8df 100644
--- a/drivers/iommu/dmar.c
+++ b/drivers/iommu/dmar.c
@@ -43,14 +43,24 @@
43 43
44#include "irq_remapping.h" 44#include "irq_remapping.h"
45 45
46/* No locks are needed as DMA remapping hardware unit 46/*
47 * list is constructed at boot time and hotplug of 47 * Assumptions:
48 * these units are not supported by the architecture. 48 * 1) The hotplug framework guarentees that DMAR unit will be hot-added
49 * before IO devices managed by that unit.
50 * 2) The hotplug framework guarantees that DMAR unit will be hot-removed
51 * after IO devices managed by that unit.
52 * 3) Hotplug events are rare.
53 *
54 * Locking rules for DMA and interrupt remapping related global data structures:
55 * 1) Use dmar_global_lock in process context
56 * 2) Use RCU in interrupt context
49 */ 57 */
58DECLARE_RWSEM(dmar_global_lock);
50LIST_HEAD(dmar_drhd_units); 59LIST_HEAD(dmar_drhd_units);
51 60
52struct acpi_table_header * __initdata dmar_tbl; 61struct acpi_table_header * __initdata dmar_tbl;
53static acpi_size dmar_tbl_size; 62static acpi_size dmar_tbl_size;
63static int dmar_dev_scope_status = 1;
54 64
55static int alloc_iommu(struct dmar_drhd_unit *drhd); 65static int alloc_iommu(struct dmar_drhd_unit *drhd);
56static void free_iommu(struct intel_iommu *iommu); 66static void free_iommu(struct intel_iommu *iommu);
@@ -62,73 +72,20 @@ static void __init dmar_register_drhd_unit(struct dmar_drhd_unit *drhd)
62 * the very end. 72 * the very end.
63 */ 73 */
64 if (drhd->include_all) 74 if (drhd->include_all)
65 list_add_tail(&drhd->list, &dmar_drhd_units); 75 list_add_tail_rcu(&drhd->list, &dmar_drhd_units);
66 else 76 else
67 list_add(&drhd->list, &dmar_drhd_units); 77 list_add_rcu(&drhd->list, &dmar_drhd_units);
68} 78}
69 79
70static int __init dmar_parse_one_dev_scope(struct acpi_dmar_device_scope *scope, 80void *dmar_alloc_dev_scope(void *start, void *end, int *cnt)
71 struct pci_dev **dev, u16 segment)
72{
73 struct pci_bus *bus;
74 struct pci_dev *pdev = NULL;
75 struct acpi_dmar_pci_path *path;
76 int count;
77
78 bus = pci_find_bus(segment, scope->bus);
79 path = (struct acpi_dmar_pci_path *)(scope + 1);
80 count = (scope->length - sizeof(struct acpi_dmar_device_scope))
81 / sizeof(struct acpi_dmar_pci_path);
82
83 while (count) {
84 if (pdev)
85 pci_dev_put(pdev);
86 /*
87 * Some BIOSes list non-exist devices in DMAR table, just
88 * ignore it
89 */
90 if (!bus) {
91 pr_warn("Device scope bus [%d] not found\n", scope->bus);
92 break;
93 }
94 pdev = pci_get_slot(bus, PCI_DEVFN(path->device, path->function));
95 if (!pdev) {
96 /* warning will be printed below */
97 break;
98 }
99 path ++;
100 count --;
101 bus = pdev->subordinate;
102 }
103 if (!pdev) {
104 pr_warn("Device scope device [%04x:%02x:%02x.%02x] not found\n",
105 segment, scope->bus, path->device, path->function);
106 return 0;
107 }
108 if ((scope->entry_type == ACPI_DMAR_SCOPE_TYPE_ENDPOINT && \
109 pdev->subordinate) || (scope->entry_type == \
110 ACPI_DMAR_SCOPE_TYPE_BRIDGE && !pdev->subordinate)) {
111 pci_dev_put(pdev);
112 pr_warn("Device scope type does not match for %s\n",
113 pci_name(pdev));
114 return -EINVAL;
115 }
116 *dev = pdev;
117 return 0;
118}
119
120int __init dmar_parse_dev_scope(void *start, void *end, int *cnt,
121 struct pci_dev ***devices, u16 segment)
122{ 81{
123 struct acpi_dmar_device_scope *scope; 82 struct acpi_dmar_device_scope *scope;
124 void * tmp = start;
125 int index;
126 int ret;
127 83
128 *cnt = 0; 84 *cnt = 0;
129 while (start < end) { 85 while (start < end) {
130 scope = start; 86 scope = start;
131 if (scope->entry_type == ACPI_DMAR_SCOPE_TYPE_ENDPOINT || 87 if (scope->entry_type == ACPI_DMAR_SCOPE_TYPE_ACPI ||
88 scope->entry_type == ACPI_DMAR_SCOPE_TYPE_ENDPOINT ||
132 scope->entry_type == ACPI_DMAR_SCOPE_TYPE_BRIDGE) 89 scope->entry_type == ACPI_DMAR_SCOPE_TYPE_BRIDGE)
133 (*cnt)++; 90 (*cnt)++;
134 else if (scope->entry_type != ACPI_DMAR_SCOPE_TYPE_IOAPIC && 91 else if (scope->entry_type != ACPI_DMAR_SCOPE_TYPE_IOAPIC &&
@@ -138,43 +95,236 @@ int __init dmar_parse_dev_scope(void *start, void *end, int *cnt,
138 start += scope->length; 95 start += scope->length;
139 } 96 }
140 if (*cnt == 0) 97 if (*cnt == 0)
141 return 0; 98 return NULL;
142 99
143 *devices = kcalloc(*cnt, sizeof(struct pci_dev *), GFP_KERNEL); 100 return kcalloc(*cnt, sizeof(struct dmar_dev_scope), GFP_KERNEL);
144 if (!*devices) 101}
145 return -ENOMEM;
146 102
147 start = tmp; 103void dmar_free_dev_scope(struct dmar_dev_scope **devices, int *cnt)
148 index = 0; 104{
149 while (start < end) { 105 int i;
106 struct device *tmp_dev;
107
108 if (*devices && *cnt) {
109 for_each_active_dev_scope(*devices, *cnt, i, tmp_dev)
110 put_device(tmp_dev);
111 kfree(*devices);
112 }
113
114 *devices = NULL;
115 *cnt = 0;
116}
117
118/* Optimize out kzalloc()/kfree() for normal cases */
119static char dmar_pci_notify_info_buf[64];
120
121static struct dmar_pci_notify_info *
122dmar_alloc_pci_notify_info(struct pci_dev *dev, unsigned long event)
123{
124 int level = 0;
125 size_t size;
126 struct pci_dev *tmp;
127 struct dmar_pci_notify_info *info;
128
129 BUG_ON(dev->is_virtfn);
130
131 /* Only generate path[] for device addition event */
132 if (event == BUS_NOTIFY_ADD_DEVICE)
133 for (tmp = dev; tmp; tmp = tmp->bus->self)
134 level++;
135
136 size = sizeof(*info) + level * sizeof(struct acpi_dmar_pci_path);
137 if (size <= sizeof(dmar_pci_notify_info_buf)) {
138 info = (struct dmar_pci_notify_info *)dmar_pci_notify_info_buf;
139 } else {
140 info = kzalloc(size, GFP_KERNEL);
141 if (!info) {
142 pr_warn("Out of memory when allocating notify_info "
143 "for %s.\n", pci_name(dev));
144 if (dmar_dev_scope_status == 0)
145 dmar_dev_scope_status = -ENOMEM;
146 return NULL;
147 }
148 }
149
150 info->event = event;
151 info->dev = dev;
152 info->seg = pci_domain_nr(dev->bus);
153 info->level = level;
154 if (event == BUS_NOTIFY_ADD_DEVICE) {
155 for (tmp = dev, level--; tmp; tmp = tmp->bus->self) {
156 info->path[level].device = PCI_SLOT(tmp->devfn);
157 info->path[level].function = PCI_FUNC(tmp->devfn);
158 if (pci_is_root_bus(tmp->bus))
159 info->bus = tmp->bus->number;
160 }
161 }
162
163 return info;
164}
165
166static inline void dmar_free_pci_notify_info(struct dmar_pci_notify_info *info)
167{
168 if ((void *)info != dmar_pci_notify_info_buf)
169 kfree(info);
170}
171
172static bool dmar_match_pci_path(struct dmar_pci_notify_info *info, int bus,
173 struct acpi_dmar_pci_path *path, int count)
174{
175 int i;
176
177 if (info->bus != bus)
178 return false;
179 if (info->level != count)
180 return false;
181
182 for (i = 0; i < count; i++) {
183 if (path[i].device != info->path[i].device ||
184 path[i].function != info->path[i].function)
185 return false;
186 }
187
188 return true;
189}
190
191/* Return: > 0 if match found, 0 if no match found, < 0 if error happens */
192int dmar_insert_dev_scope(struct dmar_pci_notify_info *info,
193 void *start, void*end, u16 segment,
194 struct dmar_dev_scope *devices,
195 int devices_cnt)
196{
197 int i, level;
198 struct device *tmp, *dev = &info->dev->dev;
199 struct acpi_dmar_device_scope *scope;
200 struct acpi_dmar_pci_path *path;
201
202 if (segment != info->seg)
203 return 0;
204
205 for (; start < end; start += scope->length) {
150 scope = start; 206 scope = start;
151 if (scope->entry_type == ACPI_DMAR_SCOPE_TYPE_ENDPOINT || 207 if (scope->entry_type != ACPI_DMAR_SCOPE_TYPE_ENDPOINT &&
152 scope->entry_type == ACPI_DMAR_SCOPE_TYPE_BRIDGE) { 208 scope->entry_type != ACPI_DMAR_SCOPE_TYPE_BRIDGE)
153 ret = dmar_parse_one_dev_scope(scope, 209 continue;
154 &(*devices)[index], segment); 210
155 if (ret) { 211 path = (struct acpi_dmar_pci_path *)(scope + 1);
156 dmar_free_dev_scope(devices, cnt); 212 level = (scope->length - sizeof(*scope)) / sizeof(*path);
157 return ret; 213 if (!dmar_match_pci_path(info, scope->bus, path, level))
158 } 214 continue;
159 index ++; 215
216 if ((scope->entry_type == ACPI_DMAR_SCOPE_TYPE_ENDPOINT) ^
217 (info->dev->hdr_type == PCI_HEADER_TYPE_NORMAL)) {
218 pr_warn("Device scope type does not match for %s\n",
219 pci_name(info->dev));
220 return -EINVAL;
160 } 221 }
161 start += scope->length; 222
223 for_each_dev_scope(devices, devices_cnt, i, tmp)
224 if (tmp == NULL) {
225 devices[i].bus = info->dev->bus->number;
226 devices[i].devfn = info->dev->devfn;
227 rcu_assign_pointer(devices[i].dev,
228 get_device(dev));
229 return 1;
230 }
231 BUG_ON(i >= devices_cnt);
162 } 232 }
163 233
164 return 0; 234 return 0;
165} 235}
166 236
167void dmar_free_dev_scope(struct pci_dev ***devices, int *cnt) 237int dmar_remove_dev_scope(struct dmar_pci_notify_info *info, u16 segment,
238 struct dmar_dev_scope *devices, int count)
168{ 239{
169 if (*devices && *cnt) { 240 int index;
170 while (--*cnt >= 0) 241 struct device *tmp;
171 pci_dev_put((*devices)[*cnt]); 242
172 kfree(*devices); 243 if (info->seg != segment)
173 *devices = NULL; 244 return 0;
174 *cnt = 0; 245
246 for_each_active_dev_scope(devices, count, index, tmp)
247 if (tmp == &info->dev->dev) {
248 rcu_assign_pointer(devices[index].dev, NULL);
249 synchronize_rcu();
250 put_device(tmp);
251 return 1;
252 }
253
254 return 0;
255}
256
257static int dmar_pci_bus_add_dev(struct dmar_pci_notify_info *info)
258{
259 int ret = 0;
260 struct dmar_drhd_unit *dmaru;
261 struct acpi_dmar_hardware_unit *drhd;
262
263 for_each_drhd_unit(dmaru) {
264 if (dmaru->include_all)
265 continue;
266
267 drhd = container_of(dmaru->hdr,
268 struct acpi_dmar_hardware_unit, header);
269 ret = dmar_insert_dev_scope(info, (void *)(drhd + 1),
270 ((void *)drhd) + drhd->header.length,
271 dmaru->segment,
272 dmaru->devices, dmaru->devices_cnt);
273 if (ret != 0)
274 break;
175 } 275 }
276 if (ret >= 0)
277 ret = dmar_iommu_notify_scope_dev(info);
278 if (ret < 0 && dmar_dev_scope_status == 0)
279 dmar_dev_scope_status = ret;
280
281 return ret;
176} 282}
177 283
284static void dmar_pci_bus_del_dev(struct dmar_pci_notify_info *info)
285{
286 struct dmar_drhd_unit *dmaru;
287
288 for_each_drhd_unit(dmaru)
289 if (dmar_remove_dev_scope(info, dmaru->segment,
290 dmaru->devices, dmaru->devices_cnt))
291 break;
292 dmar_iommu_notify_scope_dev(info);
293}
294
295static int dmar_pci_bus_notifier(struct notifier_block *nb,
296 unsigned long action, void *data)
297{
298 struct pci_dev *pdev = to_pci_dev(data);
299 struct dmar_pci_notify_info *info;
300
301 /* Only care about add/remove events for physical functions */
302 if (pdev->is_virtfn)
303 return NOTIFY_DONE;
304 if (action != BUS_NOTIFY_ADD_DEVICE && action != BUS_NOTIFY_DEL_DEVICE)
305 return NOTIFY_DONE;
306
307 info = dmar_alloc_pci_notify_info(pdev, action);
308 if (!info)
309 return NOTIFY_DONE;
310
311 down_write(&dmar_global_lock);
312 if (action == BUS_NOTIFY_ADD_DEVICE)
313 dmar_pci_bus_add_dev(info);
314 else if (action == BUS_NOTIFY_DEL_DEVICE)
315 dmar_pci_bus_del_dev(info);
316 up_write(&dmar_global_lock);
317
318 dmar_free_pci_notify_info(info);
319
320 return NOTIFY_OK;
321}
322
323static struct notifier_block dmar_pci_bus_nb = {
324 .notifier_call = dmar_pci_bus_notifier,
325 .priority = INT_MIN,
326};
327
178/** 328/**
179 * dmar_parse_one_drhd - parses exactly one DMA remapping hardware definition 329 * dmar_parse_one_drhd - parses exactly one DMA remapping hardware definition
180 * structure which uniquely represent one DMA remapping hardware unit 330 * structure which uniquely represent one DMA remapping hardware unit
@@ -196,9 +346,18 @@ dmar_parse_one_drhd(struct acpi_dmar_header *header)
196 dmaru->reg_base_addr = drhd->address; 346 dmaru->reg_base_addr = drhd->address;
197 dmaru->segment = drhd->segment; 347 dmaru->segment = drhd->segment;
198 dmaru->include_all = drhd->flags & 0x1; /* BIT0: INCLUDE_ALL */ 348 dmaru->include_all = drhd->flags & 0x1; /* BIT0: INCLUDE_ALL */
349 dmaru->devices = dmar_alloc_dev_scope((void *)(drhd + 1),
350 ((void *)drhd) + drhd->header.length,
351 &dmaru->devices_cnt);
352 if (dmaru->devices_cnt && dmaru->devices == NULL) {
353 kfree(dmaru);
354 return -ENOMEM;
355 }
199 356
200 ret = alloc_iommu(dmaru); 357 ret = alloc_iommu(dmaru);
201 if (ret) { 358 if (ret) {
359 dmar_free_dev_scope(&dmaru->devices,
360 &dmaru->devices_cnt);
202 kfree(dmaru); 361 kfree(dmaru);
203 return ret; 362 return ret;
204 } 363 }
@@ -215,19 +374,24 @@ static void dmar_free_drhd(struct dmar_drhd_unit *dmaru)
215 kfree(dmaru); 374 kfree(dmaru);
216} 375}
217 376
218static int __init dmar_parse_dev(struct dmar_drhd_unit *dmaru) 377static int __init dmar_parse_one_andd(struct acpi_dmar_header *header)
219{ 378{
220 struct acpi_dmar_hardware_unit *drhd; 379 struct acpi_dmar_andd *andd = (void *)header;
221 380
222 drhd = (struct acpi_dmar_hardware_unit *) dmaru->hdr; 381 /* Check for NUL termination within the designated length */
223 382 if (strnlen(andd->object_name, header->length - 8) == header->length - 8) {
224 if (dmaru->include_all) 383 WARN_TAINT(1, TAINT_FIRMWARE_WORKAROUND,
225 return 0; 384 "Your BIOS is broken; ANDD object name is not NUL-terminated\n"
385 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
386 dmi_get_system_info(DMI_BIOS_VENDOR),
387 dmi_get_system_info(DMI_BIOS_VERSION),
388 dmi_get_system_info(DMI_PRODUCT_VERSION));
389 return -EINVAL;
390 }
391 pr_info("ANDD device: %x name: %s\n", andd->device_number,
392 andd->object_name);
226 393
227 return dmar_parse_dev_scope((void *)(drhd + 1), 394 return 0;
228 ((void *)drhd) + drhd->header.length,
229 &dmaru->devices_cnt, &dmaru->devices,
230 drhd->segment);
231} 395}
232 396
233#ifdef CONFIG_ACPI_NUMA 397#ifdef CONFIG_ACPI_NUMA
@@ -293,6 +457,10 @@ dmar_table_print_dmar_entry(struct acpi_dmar_header *header)
293 (unsigned long long)rhsa->base_address, 457 (unsigned long long)rhsa->base_address,
294 rhsa->proximity_domain); 458 rhsa->proximity_domain);
295 break; 459 break;
460 case ACPI_DMAR_TYPE_ANDD:
461 /* We don't print this here because we need to sanity-check
462 it first. So print it in dmar_parse_one_andd() instead. */
463 break;
296 } 464 }
297} 465}
298 466
@@ -378,6 +546,9 @@ parse_dmar_table(void)
378 ret = dmar_parse_one_rhsa(entry_header); 546 ret = dmar_parse_one_rhsa(entry_header);
379#endif 547#endif
380 break; 548 break;
549 case ACPI_DMAR_TYPE_ANDD:
550 ret = dmar_parse_one_andd(entry_header);
551 break;
381 default: 552 default:
382 pr_warn("Unknown DMAR structure type %d\n", 553 pr_warn("Unknown DMAR structure type %d\n",
383 entry_header->type); 554 entry_header->type);
@@ -394,14 +565,15 @@ parse_dmar_table(void)
394 return ret; 565 return ret;
395} 566}
396 567
397static int dmar_pci_device_match(struct pci_dev *devices[], int cnt, 568static int dmar_pci_device_match(struct dmar_dev_scope devices[],
398 struct pci_dev *dev) 569 int cnt, struct pci_dev *dev)
399{ 570{
400 int index; 571 int index;
572 struct device *tmp;
401 573
402 while (dev) { 574 while (dev) {
403 for (index = 0; index < cnt; index++) 575 for_each_active_dev_scope(devices, cnt, index, tmp)
404 if (dev == devices[index]) 576 if (dev_is_pci(tmp) && dev == to_pci_dev(tmp))
405 return 1; 577 return 1;
406 578
407 /* Check our parent */ 579 /* Check our parent */
@@ -414,11 +586,12 @@ static int dmar_pci_device_match(struct pci_dev *devices[], int cnt,
414struct dmar_drhd_unit * 586struct dmar_drhd_unit *
415dmar_find_matched_drhd_unit(struct pci_dev *dev) 587dmar_find_matched_drhd_unit(struct pci_dev *dev)
416{ 588{
417 struct dmar_drhd_unit *dmaru = NULL; 589 struct dmar_drhd_unit *dmaru;
418 struct acpi_dmar_hardware_unit *drhd; 590 struct acpi_dmar_hardware_unit *drhd;
419 591
420 dev = pci_physfn(dev); 592 dev = pci_physfn(dev);
421 593
594 rcu_read_lock();
422 for_each_drhd_unit(dmaru) { 595 for_each_drhd_unit(dmaru) {
423 drhd = container_of(dmaru->hdr, 596 drhd = container_of(dmaru->hdr,
424 struct acpi_dmar_hardware_unit, 597 struct acpi_dmar_hardware_unit,
@@ -426,44 +599,128 @@ dmar_find_matched_drhd_unit(struct pci_dev *dev)
426 599
427 if (dmaru->include_all && 600 if (dmaru->include_all &&
428 drhd->segment == pci_domain_nr(dev->bus)) 601 drhd->segment == pci_domain_nr(dev->bus))
429 return dmaru; 602 goto out;
430 603
431 if (dmar_pci_device_match(dmaru->devices, 604 if (dmar_pci_device_match(dmaru->devices,
432 dmaru->devices_cnt, dev)) 605 dmaru->devices_cnt, dev))
433 return dmaru; 606 goto out;
434 } 607 }
608 dmaru = NULL;
609out:
610 rcu_read_unlock();
435 611
436 return NULL; 612 return dmaru;
437} 613}
438 614
439int __init dmar_dev_scope_init(void) 615static void __init dmar_acpi_insert_dev_scope(u8 device_number,
616 struct acpi_device *adev)
440{ 617{
441 static int dmar_dev_scope_initialized; 618 struct dmar_drhd_unit *dmaru;
442 struct dmar_drhd_unit *drhd; 619 struct acpi_dmar_hardware_unit *drhd;
443 int ret = -ENODEV; 620 struct acpi_dmar_device_scope *scope;
444 621 struct device *tmp;
445 if (dmar_dev_scope_initialized) 622 int i;
446 return dmar_dev_scope_initialized; 623 struct acpi_dmar_pci_path *path;
447 624
448 if (list_empty(&dmar_drhd_units)) 625 for_each_drhd_unit(dmaru) {
449 goto fail; 626 drhd = container_of(dmaru->hdr,
627 struct acpi_dmar_hardware_unit,
628 header);
450 629
451 list_for_each_entry(drhd, &dmar_drhd_units, list) { 630 for (scope = (void *)(drhd + 1);
452 ret = dmar_parse_dev(drhd); 631 (unsigned long)scope < ((unsigned long)drhd) + drhd->header.length;
453 if (ret) 632 scope = ((void *)scope) + scope->length) {
454 goto fail; 633 if (scope->entry_type != ACPI_DMAR_SCOPE_TYPE_ACPI)
634 continue;
635 if (scope->enumeration_id != device_number)
636 continue;
637
638 path = (void *)(scope + 1);
639 pr_info("ACPI device \"%s\" under DMAR at %llx as %02x:%02x.%d\n",
640 dev_name(&adev->dev), dmaru->reg_base_addr,
641 scope->bus, path->device, path->function);
642 for_each_dev_scope(dmaru->devices, dmaru->devices_cnt, i, tmp)
643 if (tmp == NULL) {
644 dmaru->devices[i].bus = scope->bus;
645 dmaru->devices[i].devfn = PCI_DEVFN(path->device,
646 path->function);
647 rcu_assign_pointer(dmaru->devices[i].dev,
648 get_device(&adev->dev));
649 return;
650 }
651 BUG_ON(i >= dmaru->devices_cnt);
652 }
455 } 653 }
654 pr_warn("No IOMMU scope found for ANDD enumeration ID %d (%s)\n",
655 device_number, dev_name(&adev->dev));
656}
456 657
457 ret = dmar_parse_rmrr_atsr_dev(); 658static int __init dmar_acpi_dev_scope_init(void)
458 if (ret) 659{
459 goto fail; 660 struct acpi_dmar_andd *andd;
661
662 if (dmar_tbl == NULL)
663 return -ENODEV;
460 664
461 dmar_dev_scope_initialized = 1; 665 for (andd = (void *)dmar_tbl + sizeof(struct acpi_table_dmar);
666 ((unsigned long)andd) < ((unsigned long)dmar_tbl) + dmar_tbl->length;
667 andd = ((void *)andd) + andd->header.length) {
668 if (andd->header.type == ACPI_DMAR_TYPE_ANDD) {
669 acpi_handle h;
670 struct acpi_device *adev;
671
672 if (!ACPI_SUCCESS(acpi_get_handle(ACPI_ROOT_OBJECT,
673 andd->object_name,
674 &h))) {
675 pr_err("Failed to find handle for ACPI object %s\n",
676 andd->object_name);
677 continue;
678 }
679 acpi_bus_get_device(h, &adev);
680 if (!adev) {
681 pr_err("Failed to get device for ACPI object %s\n",
682 andd->object_name);
683 continue;
684 }
685 dmar_acpi_insert_dev_scope(andd->device_number, adev);
686 }
687 }
462 return 0; 688 return 0;
689}
463 690
464fail: 691int __init dmar_dev_scope_init(void)
465 dmar_dev_scope_initialized = ret; 692{
466 return ret; 693 struct pci_dev *dev = NULL;
694 struct dmar_pci_notify_info *info;
695
696 if (dmar_dev_scope_status != 1)
697 return dmar_dev_scope_status;
698
699 if (list_empty(&dmar_drhd_units)) {
700 dmar_dev_scope_status = -ENODEV;
701 } else {
702 dmar_dev_scope_status = 0;
703
704 dmar_acpi_dev_scope_init();
705
706 for_each_pci_dev(dev) {
707 if (dev->is_virtfn)
708 continue;
709
710 info = dmar_alloc_pci_notify_info(dev,
711 BUS_NOTIFY_ADD_DEVICE);
712 if (!info) {
713 return dmar_dev_scope_status;
714 } else {
715 dmar_pci_bus_add_dev(info);
716 dmar_free_pci_notify_info(info);
717 }
718 }
719
720 bus_register_notifier(&pci_bus_type, &dmar_pci_bus_nb);
721 }
722
723 return dmar_dev_scope_status;
467} 724}
468 725
469 726
@@ -557,6 +814,7 @@ int __init detect_intel_iommu(void)
557{ 814{
558 int ret; 815 int ret;
559 816
817 down_write(&dmar_global_lock);
560 ret = dmar_table_detect(); 818 ret = dmar_table_detect();
561 if (ret) 819 if (ret)
562 ret = check_zero_address(); 820 ret = check_zero_address();
@@ -574,6 +832,7 @@ int __init detect_intel_iommu(void)
574 } 832 }
575 early_acpi_os_unmap_memory((void __iomem *)dmar_tbl, dmar_tbl_size); 833 early_acpi_os_unmap_memory((void __iomem *)dmar_tbl, dmar_tbl_size);
576 dmar_tbl = NULL; 834 dmar_tbl = NULL;
835 up_write(&dmar_global_lock);
577 836
578 return ret ? 1 : -ENODEV; 837 return ret ? 1 : -ENODEV;
579} 838}
@@ -696,6 +955,7 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd)
696 } 955 }
697 iommu->agaw = agaw; 956 iommu->agaw = agaw;
698 iommu->msagaw = msagaw; 957 iommu->msagaw = msagaw;
958 iommu->segment = drhd->segment;
699 959
700 iommu->node = -1; 960 iommu->node = -1;
701 961
@@ -1386,10 +1646,15 @@ static int __init dmar_free_unused_resources(void)
1386 if (irq_remapping_enabled || intel_iommu_enabled) 1646 if (irq_remapping_enabled || intel_iommu_enabled)
1387 return 0; 1647 return 0;
1388 1648
1649 if (dmar_dev_scope_status != 1 && !list_empty(&dmar_drhd_units))
1650 bus_unregister_notifier(&pci_bus_type, &dmar_pci_bus_nb);
1651
1652 down_write(&dmar_global_lock);
1389 list_for_each_entry_safe(dmaru, dmaru_n, &dmar_drhd_units, list) { 1653 list_for_each_entry_safe(dmaru, dmaru_n, &dmar_drhd_units, list) {
1390 list_del(&dmaru->list); 1654 list_del(&dmaru->list);
1391 dmar_free_drhd(dmaru); 1655 dmar_free_drhd(dmaru);
1392 } 1656 }
1657 up_write(&dmar_global_lock);
1393 1658
1394 return 0; 1659 return 0;
1395} 1660}