Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

iommu/vt-d: Change scope lists to struct device, bus, devfn

It's not only for PCI devices any more, and the scope information for an
ACPI device provides the bus and devfn so that has to be stored here too.

It is the device pointer itself which needs to be protected with RCU,
so the __rcu annotation follows it into the definition of struct
dmar_dev_scope, since we're no longer just passing arrays of device
pointers around.

Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>

+59 -43
+22 -19
drivers/iommu/dmar.c
··· 97 97 if (*cnt == 0) 98 98 return NULL; 99 99 100 - return kcalloc(*cnt, sizeof(struct pci_dev *), GFP_KERNEL); 100 + return kcalloc(*cnt, sizeof(struct dmar_dev_scope), GFP_KERNEL); 101 101 } 102 102 103 - void dmar_free_dev_scope(struct pci_dev __rcu ***devices, int *cnt) 103 + void dmar_free_dev_scope(struct dmar_dev_scope **devices, int *cnt) 104 104 { 105 105 int i; 106 - struct pci_dev *tmp_dev; 106 + struct device *tmp_dev; 107 107 108 108 if (*devices && *cnt) { 109 109 for_each_active_dev_scope(*devices, *cnt, i, tmp_dev) 110 - pci_dev_put(tmp_dev); 110 + put_device(tmp_dev); 111 111 kfree(*devices); 112 112 } 113 113 ··· 191 191 /* Return: > 0 if match found, 0 if no match found, < 0 if error happens */ 192 192 int dmar_insert_dev_scope(struct dmar_pci_notify_info *info, 193 193 void *start, void*end, u16 segment, 194 - struct pci_dev __rcu **devices, int devices_cnt) 194 + struct dmar_dev_scope *devices, 195 + int devices_cnt) 195 196 { 196 197 int i, level; 197 - struct pci_dev *tmp, *dev = info->dev; 198 + struct device *tmp, *dev = &info->dev->dev; 198 199 struct acpi_dmar_device_scope *scope; 199 200 struct acpi_dmar_pci_path *path; 200 201 ··· 214 213 continue; 215 214 216 215 if ((scope->entry_type == ACPI_DMAR_SCOPE_TYPE_ENDPOINT) ^ 217 - (dev->hdr_type == PCI_HEADER_TYPE_NORMAL)) { 216 + (info->dev->hdr_type == PCI_HEADER_TYPE_NORMAL)) { 218 217 pr_warn("Device scope type does not match for %s\n", 219 - pci_name(dev)); 218 + pci_name(info->dev)); 220 219 return -EINVAL; 221 220 } 222 221 223 222 for_each_dev_scope(devices, devices_cnt, i, tmp) 224 223 if (tmp == NULL) { 225 - rcu_assign_pointer(devices[i], 226 - pci_dev_get(dev)); 224 + devices[i].bus = info->dev->bus->number; 225 + devices[i].devfn = info->dev->devfn; 226 + rcu_assign_pointer(devices[i].dev, 227 + get_device(dev)); 227 228 return 1; 228 229 } 229 230 BUG_ON(i >= devices_cnt); ··· 235 232 } 236 233 237 234 int dmar_remove_dev_scope(struct dmar_pci_notify_info *info, u16 segment, 238 - struct pci_dev __rcu **devices, int count) 235 + struct dmar_dev_scope *devices, int count) 239 236 { 240 237 int index; 241 - struct pci_dev *tmp; 238 + struct device *tmp; 242 239 243 240 if (info->seg != segment) 244 241 return 0; 245 242 246 243 for_each_active_dev_scope(devices, count, index, tmp) 247 - if (tmp == info->dev) { 248 - rcu_assign_pointer(devices[index], NULL); 244 + if (tmp == &info->dev->dev) { 245 + rcu_assign_pointer(devices[index].dev, NULL); 249 246 synchronize_rcu(); 250 - pci_dev_put(tmp); 247 + put_device(tmp); 251 248 return 1; 252 249 } 253 250 ··· 565 562 return ret; 566 563 } 567 564 568 - static int dmar_pci_device_match(struct pci_dev __rcu *devices[], int cnt, 569 - struct pci_dev *dev) 565 + static int dmar_pci_device_match(struct dmar_dev_scope devices[], 566 + int cnt, struct pci_dev *dev) 570 567 { 571 568 int index; 572 - struct pci_dev *tmp; 569 + struct device *tmp; 573 570 574 571 while (dev) { 575 572 for_each_active_dev_scope(devices, cnt, index, tmp) 576 - if (dev == tmp) 573 + if (dev_is_pci(tmp) && dev == to_pci_dev(tmp)) 577 574 return 1; 578 575 579 576 /* Check our parent */
+25 -18
drivers/iommu/intel-iommu.c
··· 382 382 struct acpi_dmar_header *hdr; /* ACPI header */ 383 383 u64 base_address; /* reserved base address*/ 384 384 u64 end_address; /* reserved end address */ 385 - struct pci_dev __rcu **devices; /* target devices */ 385 + struct dmar_dev_scope *devices; /* target devices */ 386 386 int devices_cnt; /* target device count */ 387 387 }; 388 388 389 389 struct dmar_atsr_unit { 390 390 struct list_head list; /* list of ATSR units */ 391 391 struct acpi_dmar_header *hdr; /* ACPI header */ 392 - struct pci_dev __rcu **devices; /* target devices */ 392 + struct dmar_dev_scope *devices; /* target devices */ 393 393 int devices_cnt; /* target device count */ 394 394 u8 include_all:1; /* include all ports */ 395 395 }; ··· 669 669 { 670 670 struct dmar_drhd_unit *drhd = NULL; 671 671 struct intel_iommu *iommu; 672 - struct pci_dev *dev; 672 + struct device *dev; 673 + struct pci_dev *pdev; 673 674 int i; 674 675 675 676 rcu_read_lock(); ··· 680 679 681 680 for_each_active_dev_scope(drhd->devices, 682 681 drhd->devices_cnt, i, dev) { 683 - if (dev->bus->number == bus && dev->devfn == devfn) 682 + if (!dev_is_pci(dev)) 683 + continue; 684 + pdev = to_pci_dev(dev); 685 + if (pdev->bus->number == bus && pdev->devfn == devfn) 684 686 goto out; 685 - if (dev->subordinate && 686 - dev->subordinate->number <= bus && 687 - dev->subordinate->busn_res.end >= bus) 687 + if (pdev->subordinate && 688 + pdev->subordinate->number <= bus && 689 + pdev->subordinate->busn_res.end >= bus) 688 690 goto out; 689 691 } 690 692 ··· 2483 2479 static bool device_has_rmrr(struct pci_dev *dev) 2484 2480 { 2485 2481 struct dmar_rmrr_unit *rmrr; 2486 - struct pci_dev *tmp; 2482 + struct device *tmp; 2487 2483 int i; 2488 2484 2489 2485 rcu_read_lock(); ··· 2494 2490 */ 2495 2491 for_each_active_dev_scope(rmrr->devices, 2496 2492 rmrr->devices_cnt, i, tmp) 2497 - if (tmp == dev) { 2493 + if (tmp == &dev->dev) { 2498 2494 rcu_read_unlock(); 2499 2495 return true; 2500 2496 } ··· 2606 2602 { 2607 2603 struct dmar_drhd_unit *drhd; 2608 2604 struct dmar_rmrr_unit *rmrr; 2609 - struct pci_dev *pdev; 2605 + struct device *dev; 2610 2606 struct intel_iommu *iommu; 2611 2607 int i, ret; 2612 2608 ··· 2750 2746 for_each_rmrr_units(rmrr) { 2751 2747 /* some BIOS lists non-exist devices in DMAR table. */ 2752 2748 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt, 2753 - i, pdev) { 2754 - ret = iommu_prepare_rmrr_dev(rmrr, pdev); 2749 + i, dev) { 2750 + if (!dev_is_pci(dev)) 2751 + continue; 2752 + ret = iommu_prepare_rmrr_dev(rmrr, to_pci_dev(dev)); 2755 2753 if (ret) 2756 2754 printk(KERN_ERR 2757 2755 "IOMMU: mapping reserved region failed\n"); ··· 3440 3434 static void __init init_no_remapping_devices(void) 3441 3435 { 3442 3436 struct dmar_drhd_unit *drhd; 3443 - struct pci_dev *dev; 3437 + struct device *dev; 3444 3438 int i; 3445 3439 3446 3440 for_each_drhd_unit(drhd) { ··· 3448 3442 for_each_active_dev_scope(drhd->devices, 3449 3443 drhd->devices_cnt, i, dev) 3450 3444 break; 3451 - /* ignore DMAR unit if no pci devices exist */ 3445 + /* ignore DMAR unit if no devices exist */ 3452 3446 if (i == drhd->devices_cnt) 3453 3447 drhd->ignored = 1; 3454 3448 } ··· 3460 3454 3461 3455 for_each_active_dev_scope(drhd->devices, 3462 3456 drhd->devices_cnt, i, dev) 3463 - if (!IS_GFX_DEVICE(dev)) 3457 + if (!dev_is_pci(dev) || !IS_GFX_DEVICE(to_pci_dev(dev))) 3464 3458 break; 3465 3459 if (i < drhd->devices_cnt) 3466 3460 continue; ··· 3473 3467 drhd->ignored = 1; 3474 3468 for_each_active_dev_scope(drhd->devices, 3475 3469 drhd->devices_cnt, i, dev) 3476 - dev->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO; 3470 + dev->archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO; 3477 3471 } 3478 3472 } 3479 3473 } ··· 3697 3691 { 3698 3692 int i, ret = 1; 3699 3693 struct pci_bus *bus; 3700 - struct pci_dev *bridge = NULL, *tmp; 3694 + struct pci_dev *bridge = NULL; 3695 + struct device *tmp; 3701 3696 struct acpi_dmar_atsr *atsr; 3702 3697 struct dmar_atsr_unit *atsru; 3703 3698 ··· 3721 3714 continue; 3722 3715 3723 3716 for_each_dev_scope(atsru->devices, atsru->devices_cnt, i, tmp) 3724 - if (tmp == bridge) 3717 + if (tmp == &bridge->dev) 3725 3718 goto out; 3726 3719 3727 3720 if (atsru->include_all)
+12 -6
include/linux/dmar.h
··· 36 36 37 37 struct intel_iommu; 38 38 39 + struct dmar_dev_scope { 40 + struct device __rcu *dev; 41 + u8 bus; 42 + u8 devfn; 43 + }; 44 + 39 45 #ifdef CONFIG_DMAR_TABLE 40 46 extern struct acpi_table_header *dmar_tbl; 41 47 struct dmar_drhd_unit { 42 48 struct list_head list; /* list of drhd units */ 43 49 struct acpi_dmar_header *hdr; /* ACPI header */ 44 50 u64 reg_base_addr; /* register base address*/ 45 - struct pci_dev __rcu **devices;/* target device array */ 51 + struct dmar_dev_scope *devices;/* target device array */ 46 52 int devices_cnt; /* target device count */ 47 53 u16 segment; /* PCI domain */ 48 54 u8 ignored:1; /* ignore drhd */ ··· 92 86 #define dmar_rcu_dereference(p) rcu_dereference_check((p), dmar_rcu_check()) 93 87 94 88 #define for_each_dev_scope(a, c, p, d) \ 95 - for ((p) = 0; ((d) = (p) < (c) ? dmar_rcu_dereference((a)[(p)]) : \ 89 + for ((p) = 0; ((d) = (p) < (c) ? dmar_rcu_dereference((a)[(p)].dev) : \ 96 90 NULL, (p) < (c)); (p)++) 97 91 98 92 #define for_each_active_dev_scope(a, c, p, d) \ ··· 101 95 extern int dmar_table_init(void); 102 96 extern int dmar_dev_scope_init(void); 103 97 extern int dmar_parse_dev_scope(void *start, void *end, int *cnt, 104 - struct pci_dev ***devices, u16 segment); 98 + struct dmar_dev_scope **devices, u16 segment); 105 99 extern void *dmar_alloc_dev_scope(void *start, void *end, int *cnt); 106 - extern void dmar_free_dev_scope(struct pci_dev __rcu ***devices, int *cnt); 100 + extern void dmar_free_dev_scope(struct dmar_dev_scope **devices, int *cnt); 107 101 extern int dmar_insert_dev_scope(struct dmar_pci_notify_info *info, 108 102 void *start, void*end, u16 segment, 109 - struct pci_dev __rcu **devices, 103 + struct dmar_dev_scope *devices, 110 104 int devices_cnt); 111 105 extern int dmar_remove_dev_scope(struct dmar_pci_notify_info *info, 112 - u16 segment, struct pci_dev __rcu **devices, 106 + u16 segment, struct dmar_dev_scope *devices, 113 107 int count); 114 108 /* Intel IOMMU detection */ 115 109 extern int detect_intel_iommu(void);