Commit 64214c2b authored by Jason Gunthorpe's avatar Jason Gunthorpe
Browse files

iommu: Add ops->domain_alloc_nested()

It turns out all the drivers that are using this immediately call into
another function, so just make that function directly into the op. This
makes paging=NULL for domain_alloc_user and we can remove the argument in
the next patch.

The function mirrors the similar op in the viommu that allocates a nested
domain on top of the viommu's nesting parent. This version supports cases
where a viommu is not being used.

Link: https://patch.msgid.link/r/1-v1-c252ebdeb57b+329-iommu_paging_flags_jgg@nvidia.com


Reviewed-by: default avatarLu Baolu <baolu.lu@linux.intel.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
parent 2d762281
Loading
Loading
Loading
Loading
+3 −6
Original line number Diff line number Diff line
@@ -3340,12 +3340,8 @@ intel_iommu_domain_alloc_user(struct device *dev, u32 flags,
	struct iommu_domain *domain;
	bool first_stage;

	/* Must be NESTING domain */
	if (parent) {
		if (!nested_supported(iommu) || flags)
	if (parent)
		return ERR_PTR(-EOPNOTSUPP);
		return intel_nested_domain_alloc(parent, user_data);
	}

	if (flags &
	    (~(IOMMU_HWPT_ALLOC_NEST_PARENT | IOMMU_HWPT_ALLOC_DIRTY_TRACKING
@@ -4475,6 +4471,7 @@ const struct iommu_ops intel_iommu_ops = {
	.domain_alloc_user	= intel_iommu_domain_alloc_user,
	.domain_alloc_sva	= intel_svm_domain_alloc,
	.domain_alloc_paging	= intel_iommu_domain_alloc_paging,
	.domain_alloc_nested	= intel_iommu_domain_alloc_nested,
	.probe_device		= intel_iommu_probe_device,
	.release_device		= intel_iommu_release_device,
	.get_resv_regions	= intel_iommu_get_resv_regions,
+4 −2
Original line number Diff line number Diff line
@@ -1265,7 +1265,9 @@ int __domain_setup_first_level(struct intel_iommu *iommu,
int dmar_ir_support(void);

void iommu_flush_write_buffer(struct intel_iommu *iommu);
struct iommu_domain *intel_nested_domain_alloc(struct iommu_domain *parent,
struct iommu_domain *
intel_iommu_domain_alloc_nested(struct device *dev, struct iommu_domain *parent,
				u32 flags,
				const struct iommu_user_data *user_data);
struct device *device_rbtree_find(struct intel_iommu *iommu, u16 rid);

+9 −2
Original line number Diff line number Diff line
@@ -186,14 +186,21 @@ static const struct iommu_domain_ops intel_nested_domain_ops = {
	.cache_invalidate_user	= intel_nested_cache_invalidate_user,
};

struct iommu_domain *intel_nested_domain_alloc(struct iommu_domain *parent,
struct iommu_domain *
intel_iommu_domain_alloc_nested(struct device *dev, struct iommu_domain *parent,
				u32 flags,
				const struct iommu_user_data *user_data)
{
	struct device_domain_info *info = dev_iommu_priv_get(dev);
	struct dmar_domain *s2_domain = to_dmar_domain(parent);
	struct intel_iommu *iommu = info->iommu;
	struct iommu_hwpt_vtd_s1 vtd;
	struct dmar_domain *domain;
	int ret;

	if (!nested_supported(iommu) || flags)
		return ERR_PTR(-EOPNOTSUPP);

	/* Must be nested domain */
	if (user_data->type != IOMMU_HWPT_DATA_VTD_S1)
		return ERR_PTR(-EOPNOTSUPP);
+4 −4
Original line number Diff line number Diff line
@@ -227,7 +227,7 @@ iommufd_hwpt_nested_alloc(struct iommufd_ctx *ictx,
	int rc;

	if ((flags & ~IOMMU_HWPT_FAULT_ID_VALID) ||
	    !user_data->len || !ops->domain_alloc_user)
	    !user_data->len || !ops->domain_alloc_nested)
		return ERR_PTR(-EOPNOTSUPP);
	if (parent->auto_domain || !parent->nest_parent ||
	    parent->common.domain->owner != ops)
@@ -242,9 +242,9 @@ iommufd_hwpt_nested_alloc(struct iommufd_ctx *ictx,
	refcount_inc(&parent->common.obj.users);
	hwpt_nested->parent = parent;

	hwpt->domain = ops->domain_alloc_user(idev->dev,
					      flags & ~IOMMU_HWPT_FAULT_ID_VALID,
					      parent->common.domain, user_data);
	hwpt->domain = ops->domain_alloc_nested(
		idev->dev, parent->common.domain,
		flags & ~IOMMU_HWPT_FAULT_ID_VALID, user_data);
	if (IS_ERR(hwpt->domain)) {
		rc = PTR_ERR(hwpt->domain);
		hwpt->domain = NULL;
+4 −3
Original line number Diff line number Diff line
@@ -356,8 +356,8 @@ __mock_domain_alloc_nested(const struct iommu_user_data *user_data)
}

static struct iommu_domain *
mock_domain_alloc_nested(struct iommu_domain *parent, u32 flags,
			 const struct iommu_user_data *user_data)
mock_domain_alloc_nested(struct device *dev, struct iommu_domain *parent,
			 u32 flags, const struct iommu_user_data *user_data)
{
	struct mock_iommu_domain_nested *mock_nested;
	struct mock_iommu_domain *mock_parent;
@@ -391,7 +391,7 @@ mock_domain_alloc_user(struct device *dev, u32 flags,
	struct iommu_domain *domain;

	if (parent)
		return mock_domain_alloc_nested(parent, flags, user_data);
		return ERR_PTR(-EOPNOTSUPP);

	if (user_data)
		return ERR_PTR(-EOPNOTSUPP);
@@ -719,6 +719,7 @@ static const struct iommu_ops mock_ops = {
	.hw_info = mock_domain_hw_info,
	.domain_alloc_paging = mock_domain_alloc_paging,
	.domain_alloc_user = mock_domain_alloc_user,
	.domain_alloc_nested = mock_domain_alloc_nested,
	.capable = mock_domain_capable,
	.device_group = generic_device_group,
	.probe_device = mock_probe_device,
Loading