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 | struct pci_dev *pdev = to_pci_dev(data); | 338 | struct pci_dev *pdev = to_pci_dev(data); |
| 339 | struct dmar_pci_notify_info *info; | 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 | if (pdev->is_virtfn) | 344 | if (pdev->is_virtfn) |
| 343 | return NOTIFY_DONE; | 345 | return NOTIFY_DONE; |
| 344 | if (action != BUS_NOTIFY_ADD_DEVICE && | 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 | return NULL; | 892 | return NULL; |
| 893 | 893 | ||
| 894 | if (dev_is_pci(dev)) { | 894 | if (dev_is_pci(dev)) { |
| 895 | struct pci_dev *pf_pdev; | ||
| 896 | |||
| 895 | pdev = to_pci_dev(dev); | 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 | segment = pci_domain_nr(pdev->bus); | 902 | segment = pci_domain_nr(pdev->bus); |
| 897 | } else if (has_acpi_companion(dev)) | 903 | } else if (has_acpi_companion(dev)) |
| 898 | dev = &ACPI_COMPANION(dev)->dev; | 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 | for_each_active_dev_scope(drhd->devices, | 911 | for_each_active_dev_scope(drhd->devices, |
| 906 | drhd->devices_cnt, i, tmp) { | 912 | drhd->devices_cnt, i, tmp) { |
| 907 | if (tmp == dev) { | 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 | *bus = drhd->devices[i].bus; | 921 | *bus = drhd->devices[i].bus; |
| 909 | *devfn = drhd->devices[i].devfn; | 922 | *devfn = drhd->devices[i].devfn; |
| 910 | goto out; | 923 | goto out; |
| @@ -39,10 +39,18 @@ int intel_svm_alloc_pasid_tables(struct intel_iommu *iommu) · 38 unmodified lines | |||
| 39 | struct page *pages; | 39 | struct page *pages; |
| 40 | int order; | 40 | int order; |
| 41 | 41 | ||
| 42 | order = ecap_pss(iommu->ecap) + 7 - PAGE_SHIFT; | 42 | /* Start at 2 because it's defined as 2^(1+PSS) */ |
| 43 | if (order < 0) | 43 | iommu->pasid_max = 2 << ecap_pss(iommu->ecap); |
| 44 | order = 0; | 44 | |
| 45 | 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 | pages = alloc_pages(GFP_KERNEL | __GFP_ZERO, order); | 54 | pages = alloc_pages(GFP_KERNEL | __GFP_ZERO, order); |
| 47 | if (!pages) { | 55 | if (!pages) { |
| 48 | pr_warn("IOMMU: %s: Failed to allocate PASID table\n", | 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 | pr_info("%s: Allocated order %d PASID table.\n", iommu->name, order); | 61 | pr_info("%s: Allocated order %d PASID table.\n", iommu->name, order); |
| 54 | 62 | ||
| 55 | if (ecap_dis(iommu->ecap)) { | 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 | pages = alloc_pages(GFP_KERNEL | __GFP_ZERO, order); | 66 | pages = alloc_pages(GFP_KERNEL | __GFP_ZERO, order); |
| 57 | if (pages) | 67 | if (pages) |
| 58 | iommu->pasid_state_table = page_address(pages); | 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 | int intel_svm_free_pasid_tables(struct intel_iommu *iommu) | 79 | int intel_svm_free_pasid_tables(struct intel_iommu *iommu) |
| 70 | { | 80 | { |
| 71 | int order; | 81 | int order = get_order(sizeof(struct pasid_entry) * iommu->pasid_max); |
| 72 | |||
| 73 | order = ecap_pss(iommu->ecap) + 7 - PAGE_SHIFT; | ||
| 74 | if (order < 0) | ||
| 75 | order = 0; | ||
| 76 | 82 | ||
| 77 | if (iommu->pasid_table) { | 83 | if (iommu->pasid_table) { |
| 78 | free_pages((unsigned long)iommu->pasid_table, order); | 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 | svm->iommu = iommu; | 378 | svm->iommu = iommu; |
| 373 | 379 | ||
| 374 | if (pasid_max > 2 << ecap_pss(iommu->ecap)) | 380 | if (pasid_max > iommu->pasid_max) |
| 375 | pasid_max = 2 << ecap_pss(iommu->ecap); | 381 | pasid_max = iommu->pasid_max; |
| 376 | 382 | ||
| 377 | /* Do not use PASID 0 in caching mode (virtualised IOMMU) */ | 383 | /* Do not use PASID 0 in caching mode (virtualised IOMMU) */ |
| 378 | ret = idr_alloc(&iommu->pasid_idr, svm, | 384 | ret = idr_alloc(&iommu->pasid_idr, svm, |
| @@ -429,6 +429,7 @@ struct intel_iommu { · 428 unmodified lines | |||
| 429 | struct page_req_dsc *prq; | 429 | struct page_req_dsc *prq; |
| 430 | unsigned char prq_name[16]; /* Name for PRQ interrupt */ | 430 | unsigned char prq_name[16]; /* Name for PRQ interrupt */ |
| 431 | struct idr pasid_idr; | 431 | struct idr pasid_idr; |
| 432 | u32 pasid_max; | ||
| 432 | #endif | 433 | #endif |
| 433 | struct q_inval *qi; /* Queued invalidation info */ | 434 | struct q_inval *qi; /* Queued invalidation info */ |
| 434 | u32 *iommu_state; /* Store iommu states between suspend and resume.*/ | 435 | u32 *iommu_state; /* Store iommu states between suspend and resume.*/ |