Commit c37d2bc9 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'iommu-fixes-v6.17-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/iommu/linux

Pull iommu fixes from Joerg Roedel:

 - AMD-Vi: Fix potential stack buffer overflow via command line

 - NVidia-Tegra: Fix endianess sparse warning

 - ARM-SMMU: Fix ATS-masters reference count issue

 - Virtio-IOMMU: Fix race condition on instance lookup

 - RISC-V IOMMU: Fix potential NULL-ptr dereference in
   riscv_iommu_iova_to_phys()

* tag 'iommu-fixes-v6.17-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/iommu/linux:
  iommu/riscv: prevent NULL deref in iova_to_phys
  iommu/virtio: Make instance lookup robust
  iommu/arm-smmu-v3: Fix smmu_domain->nr_ats_masters decrement
  iommu/tegra241-cmdqv: Fix missing cpu_to_le64 at lvcmdq_err_map
  iommu/amd: Avoid stack buffer overflow from kernel cmdline
parents f28ad47b 99d4d1a0
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -3638,7 +3638,7 @@ static int __init parse_ivrs_acpihid(char *str)
{
	u32 seg = 0, bus, dev, fn;
	char *hid, *uid, *p, *addr;
	char acpiid[ACPIID_LEN] = {0};
	char acpiid[ACPIID_LEN + 1] = { }; /* size with NULL terminator */
	int i;

	addr = strchr(str, '@');
@@ -3664,7 +3664,7 @@ static int __init parse_ivrs_acpihid(char *str)
	/* We have the '@', make it the terminator to get just the acpiid */
	*addr++ = 0;

	if (strlen(str) > ACPIID_LEN + 1)
	if (strlen(str) > ACPIID_LEN)
		goto not_found;

	if (sscanf(str, "=%s", acpiid) != 1)
+1 −1
Original line number Diff line number Diff line
@@ -2997,9 +2997,9 @@ void arm_smmu_attach_commit(struct arm_smmu_attach_state *state)
		/* ATS is being switched off, invalidate the entire ATC */
		arm_smmu_atc_inv_master(master, IOMMU_NO_PASID);
	}
	master->ats_enabled = state->ats_enabled;

	arm_smmu_remove_master_domain(master, state->old_domain, state->ssid);
	master->ats_enabled = state->ats_enabled;
}

static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
+5 −3
Original line number Diff line number Diff line
@@ -301,9 +301,11 @@ static void tegra241_vintf_user_handle_error(struct tegra241_vintf *vintf)
	struct iommu_vevent_tegra241_cmdqv vevent_data;
	int i;

	for (i = 0; i < LVCMDQ_ERR_MAP_NUM_64; i++)
		vevent_data.lvcmdq_err_map[i] =
			readq_relaxed(REG_VINTF(vintf, LVCMDQ_ERR_MAP_64(i)));
	for (i = 0; i < LVCMDQ_ERR_MAP_NUM_64; i++) {
		u64 err = readq_relaxed(REG_VINTF(vintf, LVCMDQ_ERR_MAP_64(i)));

		vevent_data.lvcmdq_err_map[i] = cpu_to_le64(err);
	}

	iommufd_viommu_report_event(viommu, IOMMU_VEVENTQ_TYPE_TEGRA241_CMDQV,
				    &vevent_data, sizeof(vevent_data));
+1 −1
Original line number Diff line number Diff line
@@ -1283,7 +1283,7 @@ static phys_addr_t riscv_iommu_iova_to_phys(struct iommu_domain *iommu_domain,
	unsigned long *ptr;

	ptr = riscv_iommu_pte_fetch(domain, iova, &pte_size);
	if (_io_pte_none(*ptr) || !_io_pte_present(*ptr))
	if (!ptr)
		return 0;

	return pfn_to_phys(__page_val_to_pfn(*ptr)) | (iova & (pte_size - 1));
+9 −6
Original line number Diff line number Diff line
@@ -998,8 +998,7 @@ static void viommu_get_resv_regions(struct device *dev, struct list_head *head)
	iommu_dma_get_resv_regions(dev, head);
}

static const struct iommu_ops viommu_ops;
static struct virtio_driver virtio_iommu_drv;
static const struct bus_type *virtio_bus_type;

static int viommu_match_node(struct device *dev, const void *data)
{
@@ -1008,8 +1007,9 @@ static int viommu_match_node(struct device *dev, const void *data)

static struct viommu_dev *viommu_get_by_fwnode(struct fwnode_handle *fwnode)
{
	struct device *dev = driver_find_device(&virtio_iommu_drv.driver, NULL,
						fwnode, viommu_match_node);
	struct device *dev = bus_find_device(virtio_bus_type, NULL, fwnode,
					     viommu_match_node);

	put_device(dev);

	return dev ? dev_to_virtio(dev)->priv : NULL;
@@ -1160,6 +1160,9 @@ static int viommu_probe(struct virtio_device *vdev)
	if (!viommu)
		return -ENOMEM;

	/* Borrow this for easy lookups later */
	virtio_bus_type = dev->bus;

	spin_lock_init(&viommu->request_lock);
	ida_init(&viommu->domain_ids);
	viommu->dev = dev;
@@ -1229,10 +1232,10 @@ static int viommu_probe(struct virtio_device *vdev)
	if (ret)
		goto err_free_vqs;

	iommu_device_register(&viommu->iommu, &viommu_ops, parent_dev);

	vdev->priv = viommu;

	iommu_device_register(&viommu->iommu, &viommu_ops, parent_dev);

	dev_info(dev, "input address: %u bits\n",
		 order_base_2(viommu->geometry.aperture_end));
	dev_info(dev, "page mask: %#llx\n", viommu->pgsize_bitmap);