Pull IOMMU fixes from David Woodhouse: "Two minor fixes. The first fixes the assignment of SR-IOV virtual functions to the correct IOMMU unit, and the second fixes the excessively large (and physically contiguous) PASID tables used with SVM" * git://git.infradead.org/intel-iommu: iommu/vt-d: Fix PASID table allocation iommu/vt-d: Fix IOMMU lookup for SR-IOV Virtual Functions
Unified · Split
| @@ -338,7 +338,9 @@ static int dmar_pci_bus_notifier(struct notifier_block *nb, · 337 unmodified lines | ||
| 338 | 338 | struct pci_dev *pdev = to_pci_dev(data); |
| 339 | 339 | struct dmar_pci_notify_info *info; |
| 340 | 340 | |
| 341 | − /* Only care about add/remove events for physical functions */ | |
| 341 | + /* Only care about add/remove events for physical functions. | |
| 342 | + * For VFs we actually do the lookup based on the corresponding | |
| 343 | + * PF in device_to_iommu() anyway. */ | |
| 342 | 344 | if (pdev->is_virtfn) |
| 343 | 345 | return NOTIFY_DONE; |
| 344 | 346 | if (action != BUS_NOTIFY_ADD_DEVICE && |
| @@ -892,7 +892,13 @@ static struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devf · 891 unmodified lines | ||
| 892 | 892 | return NULL; |
| 893 | 893 | |
| 894 | 894 | if (dev_is_pci(dev)) { |
| 895 | + struct pci_dev *pf_pdev; | |
| 896 | + | |
| 895 | 897 | pdev = to_pci_dev(dev); |
| 898 | + /* VFs aren't listed in scope tables; we need to look up | |
| 899 | + * the PF instead to find the IOMMU. */ | |
| 900 | + pf_pdev = pci_physfn(pdev); | |
| 901 | + dev = &pf_pdev->dev; | |
| 896 | 902 | segment = pci_domain_nr(pdev->bus); |
| 897 | 903 | } else if (has_acpi_companion(dev)) |
| 898 | 904 | dev = &ACPI_COMPANION(dev)->dev; |
| @@ -905,6 +911,13 @@ static struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devf · 6 unmodified lines | ||
| 905 | 911 | for_each_active_dev_scope(drhd->devices, |
| 906 | 912 | drhd->devices_cnt, i, tmp) { |
| 907 | 913 | if (tmp == dev) { |
| 914 | + /* For a VF use its original BDF# not that of the PF | |
| 915 | + * which we used for the IOMMU lookup. Strictly speaking | |
| 916 | + * we could do this for all PCI devices; we only need to | |
| 917 | + * get the BDF# from the scope table for ACPI matches. */ | |
| 918 | + if (pdev->is_virtfn) | |
| 919 | + goto got_pdev; | |
| 920 | + | |
| 908 | 921 | *bus = drhd->devices[i].bus; |
| 909 | 922 | *devfn = drhd->devices[i].devfn; |
| 910 | 923 | goto out; |
| @@ -39,10 +39,18 @@ int intel_svm_alloc_pasid_tables(struct intel_iommu *iommu) · 38 unmodified lines | ||
| 39 | 39 | struct page *pages; |
| 40 | 40 | int order; |
| 41 | 41 | |
| 42 | − order = ecap_pss(iommu->ecap) + 7 - PAGE_SHIFT; | |
| 43 | − if (order < 0) | |
| 44 | − order = 0; | |
| 45 | − | |
| 42 | + /* Start at 2 because it's defined as 2^(1+PSS) */ | |
| 43 | + iommu->pasid_max = 2 << ecap_pss(iommu->ecap); | |
| 44 | + | |
| 45 | + /* Eventually I'm promised we will get a multi-level PASID table | |
| 46 | + * and it won't have to be physically contiguous. Until then, | |
| 47 | + * limit the size because 8MiB contiguous allocations can be hard | |
| 48 | + * to come by. The limit of 0x20000, which is 1MiB for each of | |
| 49 | + * the PASID and PASID-state tables, is somewhat arbitrary. */ | |
| 50 | + if (iommu->pasid_max > 0x20000) | |
| 51 | + iommu->pasid_max = 0x20000; | |
| 52 | + | |
| 53 | + order = get_order(sizeof(struct pasid_entry) * iommu->pasid_max); | |
| 46 | 54 | pages = alloc_pages(GFP_KERNEL | __GFP_ZERO, order); |
| 47 | 55 | if (!pages) { |
| 48 | 56 | pr_warn("IOMMU: %s: Failed to allocate PASID table\n", |
| @@ -53,6 +61,8 @@ int intel_svm_alloc_pasid_tables(struct intel_iommu *iommu) · 4 unmodified lines | ||
| 53 | 61 | pr_info("%s: Allocated order %d PASID table.\n", iommu->name, order); |
| 54 | 62 | |
| 55 | 63 | if (ecap_dis(iommu->ecap)) { |
| 64 | + /* Just making it explicit... */ | |
| 65 | + BUILD_BUG_ON(sizeof(struct pasid_entry) != sizeof(struct pasid_state_entry)); | |
| 56 | 66 | pages = alloc_pages(GFP_KERNEL | __GFP_ZERO, order); |
| 57 | 67 | if (pages) |
| 58 | 68 | iommu->pasid_state_table = page_address(pages); |
| @@ -68,11 +78,7 @@ int intel_svm_alloc_pasid_tables(struct intel_iommu *iommu) · 9 unmodified lines | ||
| 68 | 78 | |
| 69 | 79 | int intel_svm_free_pasid_tables(struct intel_iommu *iommu) |
| 70 | 80 | { |
| 71 | − int order; | |
| 72 | − | |
| 73 | − order = ecap_pss(iommu->ecap) + 7 - PAGE_SHIFT; | |
| 74 | − if (order < 0) | |
| 75 | − order = 0; | |
| 81 | + int order = get_order(sizeof(struct pasid_entry) * iommu->pasid_max); | |
| 76 | 82 | |
| 77 | 83 | if (iommu->pasid_table) { |
| 78 | 84 | free_pages((unsigned long)iommu->pasid_table, order); |
| @@ -371,8 +377,8 @@ int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, struct svm_dev_ · 292 unmodified lines | ||
| 371 | 377 | } |
| 372 | 378 | svm->iommu = iommu; |
| 373 | 379 | |
| 374 | − if (pasid_max > 2 << ecap_pss(iommu->ecap)) | |
| 375 | − pasid_max = 2 << ecap_pss(iommu->ecap); | |
| 380 | + if (pasid_max > iommu->pasid_max) | |
| 381 | + pasid_max = iommu->pasid_max; | |
| 376 | 382 | |
| 377 | 383 | /* Do not use PASID 0 in caching mode (virtualised IOMMU) */ |
| 378 | 384 | ret = idr_alloc(&iommu->pasid_idr, svm, |
| @@ -429,6 +429,7 @@ struct intel_iommu { · 428 unmodified lines | ||
| 429 | 429 | struct page_req_dsc *prq; |
| 430 | 430 | unsigned char prq_name[16]; /* Name for PRQ interrupt */ |
| 431 | 431 | struct idr pasid_idr; |
| 432 | + u32 pasid_max; | |
| 432 | 433 | #endif |
| 433 | 434 | struct q_inval *qi; /* Queued invalidation info */ |
| 434 | 435 | u32 *iommu_state; /* Store iommu states between suspend and resume.*/ |