Commit 4f18d3fd authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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

Pul iommu fixes from Joerg Roedel:

 - Make iommu_ops->default_domain work without CONFIG_IOMMU_DMA to fix
   initialization of FSL-PAMU devices

 - Fix for Tegra fbdev initialization failure

 - Fix for a VFIO device unbinding failure on PowerPC

* tag 'iommu-fixes-v6.8-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu:
  powerpc: iommu: Bring back table group release_ownership() call
  drm/tegra: Do not assume that a NULL domain means no DMA IOMMU
  iommu: Allow ops->default_domain to work when !CONFIG_IOMMU_DMA
parents 6897cea7 d2d00e15
Loading
Loading
Loading
Loading
+28 −9
Original line number Diff line number Diff line
@@ -1287,20 +1287,20 @@ spapr_tce_platform_iommu_attach_dev(struct iommu_domain *platform_domain,
	struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
	struct iommu_group *grp = iommu_group_get(dev);
	struct iommu_table_group *table_group;
	int ret = -EINVAL;

	/* At first attach the ownership is already set */
	if (!domain)
		return 0;

	if (!grp)
		return -ENODEV;

	table_group = iommu_group_get_iommudata(grp);
	ret = table_group->ops->take_ownership(table_group);
	/*
	 * The domain being set to PLATFORM from earlier
	 * BLOCKED. The table_group ownership has to be released.
	 */
	table_group->ops->release_ownership(table_group);
	iommu_group_put(grp);

	return ret;
	return 0;
}

static const struct iommu_domain_ops spapr_tce_platform_domain_ops = {
@@ -1312,13 +1312,32 @@ static struct iommu_domain spapr_tce_platform_domain = {
	.ops = &spapr_tce_platform_domain_ops,
};

static struct iommu_domain spapr_tce_blocked_domain = {
	.type = IOMMU_DOMAIN_BLOCKED,
static int
spapr_tce_blocked_iommu_attach_dev(struct iommu_domain *platform_domain,
				     struct device *dev)
{
	struct iommu_group *grp = iommu_group_get(dev);
	struct iommu_table_group *table_group;
	int ret = -EINVAL;

	/*
	 * FIXME: SPAPR mixes blocked and platform behaviors, the blocked domain
	 * also sets the dma_api ops
	 */
	.ops = &spapr_tce_platform_domain_ops,
	table_group = iommu_group_get_iommudata(grp);
	ret = table_group->ops->take_ownership(table_group);
	iommu_group_put(grp);

	return ret;
}

static const struct iommu_domain_ops spapr_tce_blocked_domain_ops = {
	.attach_dev = spapr_tce_blocked_iommu_attach_dev,
};

static struct iommu_domain spapr_tce_blocked_domain = {
	.type = IOMMU_DOMAIN_BLOCKED,
	.ops = &spapr_tce_blocked_domain_ops,
};

static bool spapr_tce_iommu_capable(struct device *dev, enum iommu_cap cap)
+2 −1
Original line number Diff line number Diff line
@@ -960,7 +960,8 @@ int host1x_client_iommu_attach(struct host1x_client *client)
	 * not the shared IOMMU domain, don't try to attach it to a different
	 * domain. This allows using the IOMMU-backed DMA API.
	 */
	if (domain && domain != tegra->domain)
	if (domain && domain->type != IOMMU_DOMAIN_IDENTITY &&
	    domain != tegra->domain)
		return 0;

	if (tegra->domain) {
+13 −5
Original line number Diff line number Diff line
@@ -1799,7 +1799,7 @@ iommu_group_alloc_default_domain(struct iommu_group *group, int req_type)
	 * domain. Do not use in new drivers.
	 */
	if (ops->default_domain) {
		if (req_type)
		if (req_type != ops->default_domain->type)
			return ERR_PTR(-EINVAL);
		return ops->default_domain;
	}
@@ -1871,10 +1871,18 @@ static int iommu_get_def_domain_type(struct iommu_group *group,
	const struct iommu_ops *ops = dev_iommu_ops(dev);
	int type;

	if (!ops->def_domain_type)
		return cur_type;

	if (ops->default_domain) {
		/*
		 * Drivers that declare a global static default_domain will
		 * always choose that.
		 */
		type = ops->default_domain->type;
	} else {
		if (ops->def_domain_type)
			type = ops->def_domain_type(dev);
		else
			return cur_type;
	}
	if (!type || cur_type == type)
		return cur_type;
	if (!cur_type)