Pull iommu fixes from Joerg Roedel: - fix device setup failures in the Intel VT-d driver when the PASID table is shared - fix Intel VT-d device hot-add failure due to wrong device notifier order - remove the old IOMMU mailing list from the MAINTAINERS file now that it has been retired * tag 'iommu-fixes-v5.19-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu: MAINTAINERS: Remove iommu@lists.linux-foundation.org iommu/vt-d: Fix RID2PASID setup/teardown failure iommu/vt-d: Fix PCI bus rescan device hot add
Unified · Split
| @@ -426,7 +426,6 @@ F: drivers/acpi/*thermal* · 425 unmodified lines | |||
| 426 | ACPI VIOT DRIVER | 426 | ACPI VIOT DRIVER |
| 427 | M: Jean-Philippe Brucker <jean-philippe@linaro.org> | 427 | M: Jean-Philippe Brucker <jean-philippe@linaro.org> |
| 428 | L: linux-acpi@vger.kernel.org | 428 | L: linux-acpi@vger.kernel.org |
| 429 | L: iommu@lists.linux-foundation.org | ||
| 430 | L: iommu@lists.linux.dev | 429 | L: iommu@lists.linux.dev |
| 431 | S: Maintained | 430 | S: Maintained |
| 432 | F: drivers/acpi/viot.c | 431 | F: drivers/acpi/viot.c |
| @@ -960,7 +959,6 @@ F: drivers/video/fbdev/geode/ · 527 unmodified lines | |||
| 960 | AMD IOMMU (AMD-VI) | 959 | AMD IOMMU (AMD-VI) |
| 961 | M: Joerg Roedel <joro@8bytes.org> | 960 | M: Joerg Roedel <joro@8bytes.org> |
| 962 | R: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com> | 961 | R: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com> |
| 963 | L: iommu@lists.linux-foundation.org | ||
| 964 | L: iommu@lists.linux.dev | 962 | L: iommu@lists.linux.dev |
| 965 | S: Maintained | 963 | S: Maintained |
| 966 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git | 964 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git |
| @@ -6055,7 +6053,6 @@ DMA MAPPING HELPERS · 5088 unmodified lines | |||
| 6055 | M: Christoph Hellwig <hch@lst.de> | 6053 | M: Christoph Hellwig <hch@lst.de> |
| 6056 | M: Marek Szyprowski <m.szyprowski@samsung.com> | 6054 | M: Marek Szyprowski <m.szyprowski@samsung.com> |
| 6057 | R: Robin Murphy <robin.murphy@arm.com> | 6055 | R: Robin Murphy <robin.murphy@arm.com> |
| 6058 | L: iommu@lists.linux-foundation.org | ||
| 6059 | L: iommu@lists.linux.dev | 6056 | L: iommu@lists.linux.dev |
| 6060 | S: Supported | 6057 | S: Supported |
| 6061 | W: http://git.infradead.org/users/hch/dma-mapping.git | 6058 | W: http://git.infradead.org/users/hch/dma-mapping.git |
| @@ -6068,7 +6065,6 @@ F: kernel/dma/ · 6 unmodified lines | |||
| 6068 | 6065 | ||
| 6069 | DMA MAPPING BENCHMARK | 6066 | DMA MAPPING BENCHMARK |
| 6070 | M: Xiang Chen <chenxiang66@hisilicon.com> | 6067 | M: Xiang Chen <chenxiang66@hisilicon.com> |
| 6071 | L: iommu@lists.linux-foundation.org | ||
| 6072 | L: iommu@lists.linux.dev | 6068 | L: iommu@lists.linux.dev |
| 6073 | F: kernel/dma/map_benchmark.c | 6069 | F: kernel/dma/map_benchmark.c |
| 6074 | F: tools/testing/selftests/dma/ | 6070 | F: tools/testing/selftests/dma/ |
| @@ -7653,7 +7649,6 @@ F: drivers/gpu/drm/exynos/exynos_dp* · 1578 unmodified lines | |||
| 7653 | 7649 | ||
| 7654 | EXYNOS SYSMMU (IOMMU) driver | 7650 | EXYNOS SYSMMU (IOMMU) driver |
| 7655 | M: Marek Szyprowski <m.szyprowski@samsung.com> | 7651 | M: Marek Szyprowski <m.szyprowski@samsung.com> |
| 7656 | L: iommu@lists.linux-foundation.org | ||
| 7657 | L: iommu@lists.linux.dev | 7652 | L: iommu@lists.linux.dev |
| 7658 | S: Maintained | 7653 | S: Maintained |
| 7659 | F: drivers/iommu/exynos-iommu.c | 7654 | F: drivers/iommu/exynos-iommu.c |
| @@ -10078,7 +10073,6 @@ F: drivers/hid/intel-ish-hid/ · 2418 unmodified lines | |||
| 10078 | INTEL IOMMU (VT-d) | 10073 | INTEL IOMMU (VT-d) |
| 10079 | M: David Woodhouse <dwmw2@infradead.org> | 10074 | M: David Woodhouse <dwmw2@infradead.org> |
| 10080 | M: Lu Baolu <baolu.lu@linux.intel.com> | 10075 | M: Lu Baolu <baolu.lu@linux.intel.com> |
| 10081 | L: iommu@lists.linux-foundation.org | ||
| 10082 | L: iommu@lists.linux.dev | 10076 | L: iommu@lists.linux.dev |
| 10083 | S: Supported | 10077 | S: Supported |
| 10084 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git | 10078 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git |
| @@ -10458,7 +10452,6 @@ F: include/linux/iomap.h · 373 unmodified lines | |||
| 10458 | IOMMU DRIVERS | 10452 | IOMMU DRIVERS |
| 10459 | M: Joerg Roedel <joro@8bytes.org> | 10453 | M: Joerg Roedel <joro@8bytes.org> |
| 10460 | M: Will Deacon <will@kernel.org> | 10454 | M: Will Deacon <will@kernel.org> |
| 10461 | L: iommu@lists.linux-foundation.org | ||
| 10462 | L: iommu@lists.linux.dev | 10455 | L: iommu@lists.linux.dev |
| 10463 | S: Maintained | 10456 | S: Maintained |
| 10464 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git | 10457 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git |
| @@ -12618,7 +12611,6 @@ F: drivers/i2c/busses/i2c-mt65xx.c · 2153 unmodified lines | |||
| 12618 | 12611 | ||
| 12619 | MEDIATEK IOMMU DRIVER | 12612 | MEDIATEK IOMMU DRIVER |
| 12620 | M: Yong Wu <yong.wu@mediatek.com> | 12613 | M: Yong Wu <yong.wu@mediatek.com> |
| 12621 | L: iommu@lists.linux-foundation.org | ||
| 12622 | L: iommu@lists.linux.dev | 12614 | L: iommu@lists.linux.dev |
| 12623 | L: linux-mediatek@lists.infradead.org (moderated for non-subscribers) | 12615 | L: linux-mediatek@lists.infradead.org (moderated for non-subscribers) |
| 12624 | S: Supported | 12616 | S: Supported |
| @@ -16670,7 +16662,6 @@ F: drivers/i2c/busses/i2c-qcom-cci.c · 4045 unmodified lines | |||
| 16670 | 16662 | ||
| 16671 | QUALCOMM IOMMU | 16663 | QUALCOMM IOMMU |
| 16672 | M: Rob Clark <robdclark@gmail.com> | 16664 | M: Rob Clark <robdclark@gmail.com> |
| 16673 | L: iommu@lists.linux-foundation.org | ||
| 16674 | L: iommu@lists.linux.dev | 16665 | L: iommu@lists.linux.dev |
| 16675 | L: linux-arm-msm@vger.kernel.org | 16666 | L: linux-arm-msm@vger.kernel.org |
| 16676 | S: Maintained | 16667 | S: Maintained |
| @@ -19299,7 +19290,6 @@ F: arch/x86/boot/video* · 2622 unmodified lines | |||
| 19299 | 19290 | ||
| 19300 | SWIOTLB SUBSYSTEM | 19291 | SWIOTLB SUBSYSTEM |
| 19301 | M: Christoph Hellwig <hch@infradead.org> | 19292 | M: Christoph Hellwig <hch@infradead.org> |
| 19302 | L: iommu@lists.linux-foundation.org | ||
| 19303 | L: iommu@lists.linux.dev | 19293 | L: iommu@lists.linux.dev |
| 19304 | S: Supported | 19294 | S: Supported |
| 19305 | W: http://git.infradead.org/users/hch/dma-mapping.git | 19295 | W: http://git.infradead.org/users/hch/dma-mapping.git |
| @@ -21975,7 +21965,6 @@ XEN SWIOTLB SUBSYSTEM · 2669 unmodified lines | |||
| 21975 | M: Juergen Gross <jgross@suse.com> | 21965 | M: Juergen Gross <jgross@suse.com> |
| 21976 | M: Stefano Stabellini <sstabellini@kernel.org> | 21966 | M: Stefano Stabellini <sstabellini@kernel.org> |
| 21977 | L: xen-devel@lists.xenproject.org (moderated for non-subscribers) | 21967 | L: xen-devel@lists.xenproject.org (moderated for non-subscribers) |
| 21978 | L: iommu@lists.linux-foundation.org | ||
| 21979 | L: iommu@lists.linux.dev | 21968 | L: iommu@lists.linux.dev |
| 21980 | S: Supported | 21969 | S: Supported |
| 21981 | F: arch/x86/xen/*swiotlb* | 21970 | F: arch/x86/xen/*swiotlb* |
| @@ -382,7 +382,7 @@ static int dmar_pci_bus_notifier(struct notifier_block *nb, · 381 unmodified lines | |||
| 382 | 382 | ||
| 383 | static struct notifier_block dmar_pci_bus_nb = { | 383 | static struct notifier_block dmar_pci_bus_nb = { |
| 384 | .notifier_call = dmar_pci_bus_notifier, | 384 | .notifier_call = dmar_pci_bus_notifier, |
| 385 | .priority = INT_MIN, | 385 | .priority = 1, |
| 386 | }; | 386 | }; |
| 387 | 387 | ||
| 388 | static struct dmar_drhd_unit * | 388 | static struct dmar_drhd_unit * |
| @@ -320,30 +320,6 @@ EXPORT_SYMBOL_GPL(intel_iommu_gfx_mapped); · 319 unmodified lines | |||
| 320 | DEFINE_SPINLOCK(device_domain_lock); | 320 | DEFINE_SPINLOCK(device_domain_lock); |
| 321 | static LIST_HEAD(device_domain_list); | 321 | static LIST_HEAD(device_domain_list); |
| 322 | 322 | ||
| 323 | /* | ||
| 324 | * Iterate over elements in device_domain_list and call the specified | ||
| 325 | * callback @fn against each element. | ||
| 326 | */ | ||
| 327 | int for_each_device_domain(int (*fn)(struct device_domain_info *info, | ||
| 328 | void *data), void *data) | ||
| 329 | { | ||
| 330 | int ret = 0; | ||
| 331 | unsigned long flags; | ||
| 332 | struct device_domain_info *info; | ||
| 333 | |||
| 334 | spin_lock_irqsave(&device_domain_lock, flags); | ||
| 335 | list_for_each_entry(info, &device_domain_list, global) { | ||
| 336 | ret = fn(info, data); | ||
| 337 | if (ret) { | ||
| 338 | spin_unlock_irqrestore(&device_domain_lock, flags); | ||
| 339 | return ret; | ||
| 340 | } | ||
| 341 | } | ||
| 342 | spin_unlock_irqrestore(&device_domain_lock, flags); | ||
| 343 | |||
| 344 | return 0; | ||
| 345 | } | ||
| 346 | |||
| 347 | const struct iommu_ops intel_iommu_ops; | 323 | const struct iommu_ops intel_iommu_ops; |
| 348 | 324 | ||
| 349 | static bool translation_pre_enabled(struct intel_iommu *iommu) | 325 | static bool translation_pre_enabled(struct intel_iommu *iommu) |
| @@ -86,54 +86,6 @@ void vcmd_free_pasid(struct intel_iommu *iommu, u32 pasid) · 85 unmodified lines | |||
| 86 | /* | 86 | /* |
| 87 | * Per device pasid table management: | 87 | * Per device pasid table management: |
| 88 | */ | 88 | */ |
| 89 | static inline void | ||
| 90 | device_attach_pasid_table(struct device_domain_info *info, | ||
| 91 | struct pasid_table *pasid_table) | ||
| 92 | { | ||
| 93 | info->pasid_table = pasid_table; | ||
| 94 | list_add(&info->table, &pasid_table->dev); | ||
| 95 | } | ||
| 96 | |||
| 97 | static inline void | ||
| 98 | device_detach_pasid_table(struct device_domain_info *info, | ||
| 99 | struct pasid_table *pasid_table) | ||
| 100 | { | ||
| 101 | info->pasid_table = NULL; | ||
| 102 | list_del(&info->table); | ||
| 103 | } | ||
| 104 | |||
| 105 | struct pasid_table_opaque { | ||
| 106 | struct pasid_table **pasid_table; | ||
| 107 | int segment; | ||
| 108 | int bus; | ||
| 109 | int devfn; | ||
| 110 | }; | ||
| 111 | |||
| 112 | static int search_pasid_table(struct device_domain_info *info, void *opaque) | ||
| 113 | { | ||
| 114 | struct pasid_table_opaque *data = opaque; | ||
| 115 | |||
| 116 | if (info->iommu->segment == data->segment && | ||
| 117 | info->bus == data->bus && | ||
| 118 | info->devfn == data->devfn && | ||
| 119 | info->pasid_table) { | ||
| 120 | *data->pasid_table = info->pasid_table; | ||
| 121 | return 1; | ||
| 122 | } | ||
| 123 | |||
| 124 | return 0; | ||
| 125 | } | ||
| 126 | |||
| 127 | static int get_alias_pasid_table(struct pci_dev *pdev, u16 alias, void *opaque) | ||
| 128 | { | ||
| 129 | struct pasid_table_opaque *data = opaque; | ||
| 130 | |||
| 131 | data->segment = pci_domain_nr(pdev->bus); | ||
| 132 | data->bus = PCI_BUS_NUM(alias); | ||
| 133 | data->devfn = alias & 0xff; | ||
| 134 | |||
| 135 | return for_each_device_domain(&search_pasid_table, data); | ||
| 136 | } | ||
| 137 | 89 | ||
| 138 | /* | 90 | /* |
| 139 | * Allocate a pasid table for @dev. It should be called in a | 91 | * Allocate a pasid table for @dev. It should be called in a |
| @@ -143,28 +95,18 @@ int intel_pasid_alloc_table(struct device *dev) · 3 unmodified lines | |||
| 143 | { | 95 | { |
| 144 | struct device_domain_info *info; | 96 | struct device_domain_info *info; |
| 145 | struct pasid_table *pasid_table; | 97 | struct pasid_table *pasid_table; |
| 146 | struct pasid_table_opaque data; | ||
| 147 | struct page *pages; | 98 | struct page *pages; |
| 148 | u32 max_pasid = 0; | 99 | u32 max_pasid = 0; |
| 149 | int ret, order; | 100 | int order, size; |
| 150 | int size; | ||
| 151 | 101 | ||
| 152 | might_sleep(); | 102 | might_sleep(); |
| 153 | info = dev_iommu_priv_get(dev); | 103 | info = dev_iommu_priv_get(dev); |
| 154 | if (WARN_ON(!info || !dev_is_pci(dev) || info->pasid_table)) | 104 | if (WARN_ON(!info || !dev_is_pci(dev) || info->pasid_table)) |
| 155 | return -EINVAL; | 105 | return -EINVAL; |
| 156 | 106 | ||
| 157 | /* DMA alias device already has a pasid table, use it: */ | ||
| 158 | data.pasid_table = &pasid_table; | ||
| 159 | ret = pci_for_each_dma_alias(to_pci_dev(dev), | ||
| 160 | &get_alias_pasid_table, &data); | ||
| 161 | if (ret) | ||
| 162 | goto attach_out; | ||
| 163 | |||
| 164 | pasid_table = kzalloc(sizeof(*pasid_table), GFP_KERNEL); | 107 | pasid_table = kzalloc(sizeof(*pasid_table), GFP_KERNEL); |
| 165 | if (!pasid_table) | 108 | if (!pasid_table) |
| 166 | return -ENOMEM; | 109 | return -ENOMEM; |
| 167 | INIT_LIST_HEAD(&pasid_table->dev); | ||
| 168 | 110 | ||
| 169 | if (info->pasid_supported) | 111 | if (info->pasid_supported) |
| 170 | max_pasid = min_t(u32, pci_max_pasids(to_pci_dev(dev)), | 112 | max_pasid = min_t(u32, pci_max_pasids(to_pci_dev(dev)), |
| @@ -182,9 +124,7 @@ int intel_pasid_alloc_table(struct device *dev) · 11 unmodified lines | |||
| 182 | pasid_table->table = page_address(pages); | 124 | pasid_table->table = page_address(pages); |
| 183 | pasid_table->order = order; | 125 | pasid_table->order = order; |
| 184 | pasid_table->max_pasid = 1 << (order + PAGE_SHIFT + 3); | 126 | pasid_table->max_pasid = 1 << (order + PAGE_SHIFT + 3); |
| 185 | 127 | info->pasid_table = pasid_table; | |
| 186 | attach_out: | ||
| 187 | device_attach_pasid_table(info, pasid_table); | ||
| 188 | 128 | ||
| 189 | return 0; | 129 | return 0; |
| 190 | } | 130 | } |
| @@ -202,10 +142,7 @@ void intel_pasid_free_table(struct device *dev) · 11 unmodified lines | |||
| 202 | return; | 142 | return; |
| 203 | 143 | ||
| 204 | pasid_table = info->pasid_table; | 144 | pasid_table = info->pasid_table; |
| 205 | device_detach_pasid_table(info, pasid_table); | 145 | info->pasid_table = NULL; |
| 206 | |||
| 207 | if (!list_empty(&pasid_table->dev)) | ||
| 208 | return; | ||
| 209 | 146 | ||
| 210 | /* Free scalable mode PASID directory tables: */ | 147 | /* Free scalable mode PASID directory tables: */ |
| 211 | dir = pasid_table->table; | 148 | dir = pasid_table->table; |
| @@ -74,7 +74,6 @@ struct pasid_table { · 73 unmodified lines | |||
| 74 | void *table; /* pasid table pointer */ | 74 | void *table; /* pasid table pointer */ |
| 75 | int order; /* page order of pasid table */ | 75 | int order; /* page order of pasid table */ |
| 76 | u32 max_pasid; /* max pasid */ | 76 | u32 max_pasid; /* max pasid */ |
| 77 | struct list_head dev; /* device list */ | ||
| 78 | }; | 77 | }; |
| 79 | 78 | ||
| 80 | /* Get PRESENT bit of a PASID directory entry. */ | 79 | /* Get PRESENT bit of a PASID directory entry. */ |
| @@ -612,7 +612,6 @@ struct intel_iommu { · 611 unmodified lines | |||
| 612 | struct device_domain_info { | 612 | struct device_domain_info { |
| 613 | struct list_head link; /* link to domain siblings */ | 613 | struct list_head link; /* link to domain siblings */ |
| 614 | struct list_head global; /* link to global list */ | 614 | struct list_head global; /* link to global list */ |
| 615 | struct list_head table; /* link to pasid table */ | ||
| 616 | u32 segment; /* PCI segment number */ | 615 | u32 segment; /* PCI segment number */ |
| 617 | u8 bus; /* PCI bus number */ | 616 | u8 bus; /* PCI bus number */ |
| 618 | u8 devfn; /* PCI devfn number */ | 617 | u8 devfn; /* PCI devfn number */ |
| @@ -729,8 +728,6 @@ extern int dmar_ir_support(void); · 110 unmodified lines | |||
| 729 | void *alloc_pgtable_page(int node); | 728 | void *alloc_pgtable_page(int node); |
| 730 | void free_pgtable_page(void *vaddr); | 729 | void free_pgtable_page(void *vaddr); |
| 731 | struct intel_iommu *domain_get_iommu(struct dmar_domain *domain); | 730 | struct intel_iommu *domain_get_iommu(struct dmar_domain *domain); |
| 732 | int for_each_device_domain(int (*fn)(struct device_domain_info *info, | ||
| 733 | void *data), void *data); | ||
| 734 | void iommu_flush_write_buffer(struct intel_iommu *iommu); | 731 | void iommu_flush_write_buffer(struct intel_iommu *iommu); |
| 735 | int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct device *dev); | 732 | int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct device *dev); |
| 736 | struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devfn); | 733 | struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devfn); |