diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2021-10-01 10:14:29 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2021-10-01 10:14:29 -0700 |
commit | 89e503592385fbed872c7ea1fb89931ece3409a5 (patch) | |
tree | 20d3e521e54641eca16934b10d6e3b26ee561ee6 | |
parent | 4de593fb965fc2bd11a0b767e0c65ff43540a6e4 (diff) | |
parent | f0b636804c7c4c564efbca5981e3c56b5c6fe0c5 (diff) | |
download | linux-89e503592385fbed872c7ea1fb89931ece3409a5.tar.bz2 |
Merge tag 'iommu-fixes-v5.15-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu
Pull iommu fixes from Joerg Roedel:
- Two fixes for the new Apple DART driver to fix a kernel panic and a
stale data usage issue
- Intel VT-d fix for how PCI device ids are printed
* tag 'iommu-fixes-v5.15-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu:
iommu/dart: Clear sid2group entry when a group is freed
iommu/vt-d: Drop "0x" prefix from PCI bus & device addresses
iommu/dart: Remove iommu_flush_ops
-rw-r--r-- | drivers/iommu/apple-dart.c | 56 | ||||
-rw-r--r-- | drivers/iommu/intel/dmar.c | 6 |
2 files changed, 38 insertions, 24 deletions
diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c index 559db9259e65..fdfa39ec2a4d 100644 --- a/drivers/iommu/apple-dart.c +++ b/drivers/iommu/apple-dart.c @@ -183,7 +183,6 @@ struct apple_dart_master_cfg { static struct platform_driver apple_dart_driver; static const struct iommu_ops apple_dart_iommu_ops; -static const struct iommu_flush_ops apple_dart_tlb_ops; static struct apple_dart_domain *to_dart_domain(struct iommu_domain *dom) { @@ -338,22 +337,6 @@ static void apple_dart_iotlb_sync_map(struct iommu_domain *domain, apple_dart_domain_flush_tlb(to_dart_domain(domain)); } -static void apple_dart_tlb_flush_all(void *cookie) -{ - apple_dart_domain_flush_tlb(cookie); -} - -static void apple_dart_tlb_flush_walk(unsigned long iova, size_t size, - size_t granule, void *cookie) -{ - apple_dart_domain_flush_tlb(cookie); -} - -static const struct iommu_flush_ops apple_dart_tlb_ops = { - .tlb_flush_all = apple_dart_tlb_flush_all, - .tlb_flush_walk = apple_dart_tlb_flush_walk, -}; - static phys_addr_t apple_dart_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova) { @@ -435,7 +418,6 @@ static int apple_dart_finalize_domain(struct iommu_domain *domain, .ias = 32, .oas = 36, .coherent_walk = 1, - .tlb = &apple_dart_tlb_ops, .iommu_dev = dart->dev, }; @@ -661,16 +643,34 @@ static int apple_dart_of_xlate(struct device *dev, struct of_phandle_args *args) return -EINVAL; } +static DEFINE_MUTEX(apple_dart_groups_lock); + +static void apple_dart_release_group(void *iommu_data) +{ + int i, sid; + struct apple_dart_stream_map *stream_map; + struct apple_dart_master_cfg *group_master_cfg = iommu_data; + + mutex_lock(&apple_dart_groups_lock); + + for_each_stream_map(i, group_master_cfg, stream_map) + for_each_set_bit(sid, &stream_map->sidmap, DART_MAX_STREAMS) + stream_map->dart->sid2group[sid] = NULL; + + kfree(iommu_data); + mutex_unlock(&apple_dart_groups_lock); +} + static struct iommu_group *apple_dart_device_group(struct device *dev) { - static DEFINE_MUTEX(lock); int i, sid; struct apple_dart_master_cfg *cfg = dev_iommu_priv_get(dev); struct apple_dart_stream_map *stream_map; + struct apple_dart_master_cfg *group_master_cfg; struct iommu_group *group = NULL; struct iommu_group *res = ERR_PTR(-EINVAL); - mutex_lock(&lock); + mutex_lock(&apple_dart_groups_lock); for_each_stream_map(i, cfg, stream_map) { for_each_set_bit(sid, &stream_map->sidmap, DART_MAX_STREAMS) { @@ -698,6 +698,20 @@ static struct iommu_group *apple_dart_device_group(struct device *dev) #endif group = generic_device_group(dev); + res = ERR_PTR(-ENOMEM); + if (!group) + goto out; + + group_master_cfg = kzalloc(sizeof(*group_master_cfg), GFP_KERNEL); + if (!group_master_cfg) { + iommu_group_put(group); + goto out; + } + + memcpy(group_master_cfg, cfg, sizeof(*group_master_cfg)); + iommu_group_set_iommudata(group, group_master_cfg, + apple_dart_release_group); + for_each_stream_map(i, cfg, stream_map) for_each_set_bit(sid, &stream_map->sidmap, DART_MAX_STREAMS) stream_map->dart->sid2group[sid] = group; @@ -705,7 +719,7 @@ static struct iommu_group *apple_dart_device_group(struct device *dev) res = group; out: - mutex_unlock(&lock); + mutex_unlock(&apple_dart_groups_lock); return res; } diff --git a/drivers/iommu/intel/dmar.c b/drivers/iommu/intel/dmar.c index 0ec5514c9980..b7708b93f3fa 100644 --- a/drivers/iommu/intel/dmar.c +++ b/drivers/iommu/intel/dmar.c @@ -1942,18 +1942,18 @@ static int dmar_fault_do_one(struct intel_iommu *iommu, int type, reason = dmar_get_fault_reason(fault_reason, &fault_type); if (fault_type == INTR_REMAP) - pr_err("[INTR-REMAP] Request device [0x%02x:0x%02x.%d] fault index 0x%llx [fault reason 0x%02x] %s\n", + pr_err("[INTR-REMAP] Request device [%02x:%02x.%d] fault index 0x%llx [fault reason 0x%02x] %s\n", source_id >> 8, PCI_SLOT(source_id & 0xFF), PCI_FUNC(source_id & 0xFF), addr >> 48, fault_reason, reason); else if (pasid == INVALID_IOASID) - pr_err("[%s NO_PASID] Request device [0x%02x:0x%02x.%d] fault addr 0x%llx [fault reason 0x%02x] %s\n", + pr_err("[%s NO_PASID] Request device [%02x:%02x.%d] fault addr 0x%llx [fault reason 0x%02x] %s\n", type ? "DMA Read" : "DMA Write", source_id >> 8, PCI_SLOT(source_id & 0xFF), PCI_FUNC(source_id & 0xFF), addr, fault_reason, reason); else - pr_err("[%s PASID 0x%x] Request device [0x%02x:0x%02x.%d] fault addr 0x%llx [fault reason 0x%02x] %s\n", + pr_err("[%s PASID 0x%x] Request device [%02x:%02x.%d] fault addr 0x%llx [fault reason 0x%02x] %s\n", type ? "DMA Read" : "DMA Write", pasid, source_id >> 8, PCI_SLOT(source_id & 0xFF), PCI_FUNC(source_id & 0xFF), addr, |