Commit 89e50359 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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
parents 4de593fb f0b63680
Loading
Loading
Loading
Loading
+35 −21
Original line number Diff line number Diff line
@@ -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;
}

+3 −3
Original line number Diff line number Diff line
@@ -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,