]> Git Repo - J-linux.git/commitdiff
iommu: Add ops->domain_alloc_nested()
authorJason Gunthorpe <[email protected]>
Thu, 14 Nov 2024 19:55:30 +0000 (15:55 -0400)
committerJason Gunthorpe <[email protected]>
Fri, 22 Nov 2024 18:43:45 +0000 (14:43 -0400)
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/[email protected]
Reviewed-by: Lu Baolu <[email protected]>
Signed-off-by: Jason Gunthorpe <[email protected]>
drivers/iommu/intel/iommu.c
drivers/iommu/intel/iommu.h
drivers/iommu/intel/nested.c
drivers/iommu/iommufd/hw_pagetable.c
drivers/iommu/iommufd/selftest.c
include/linux/iommu.h

index 527f6f89d8a1f56d48d98e2c3b2a8a3ebedffaa4..6f11a075114f7a72a351b6a1ff462ad46429c504 100644 (file)
@@ -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)
-                       return ERR_PTR(-EOPNOTSUPP);
-               return intel_nested_domain_alloc(parent, user_data);
-       }
+       if (parent)
+               return ERR_PTR(-EOPNOTSUPP);
 
        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,
index 2cca094c259dc1fc8839da85d24dbca1dda1a2a0..6ea7bbe26b19d545f70c23dd58c55c7ecbd6d172 100644 (file)
@@ -1265,8 +1265,10 @@ 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,
-                                              const struct iommu_user_data *user_data);
+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);
 
 enum cache_tag_type {
index 42c4533a6ea21d1ec960d8dba968b26f13dda6e2..aba92c00b427407979b489478bc1e86a5975c229 100644 (file)
@@ -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,
-                                              const struct iommu_user_data *user_data)
+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);
index 9236e8ca9aa8641aff3807f8998c0aeabb6afc2c..ec3c64a8c79633952f601aa9e6bd08926a982d30 100644 (file)
@@ -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;
index 2f9de177dffc79d841fa489014628e6572087693..c58083c3660aee47a92705aad70fa8e1ff0d1888 100644 (file)
@@ -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,
index d6aaaec3caf46291dca7e013d0e76b8df65c0ea8..0472cc1245192dbfec55c1ec9f69eb88fb51e5d0 100644 (file)
@@ -559,15 +559,13 @@ iommu_copy_struct_from_full_user_array(void *kdst, size_t kdst_entry_size,
  *                the caller iommu_domain_alloc() returns.
  * @domain_alloc_user: Allocate an iommu domain corresponding to the input
  *                     parameters as defined in include/uapi/linux/iommufd.h.
- *                     Upon success, if the @user_data is valid and the @parent
- *                     points to a kernel-managed domain, the new domain must be
- *                     IOMMU_DOMAIN_NESTED type; otherwise, the @parent must be
- *                     NULL while the @user_data can be optionally provided, the
+ *                     The @user_data can be optionally provided, the
  *                     new domain must support __IOMMU_DOMAIN_PAGING.
  *                     Upon failure, ERR_PTR must be returned.
  * @domain_alloc_paging: Allocate an iommu_domain that can be used for
  *                       UNMANAGED, DMA, and DMA_FQ domain types.
  * @domain_alloc_sva: Allocate an iommu_domain for Shared Virtual Addressing.
+ * @domain_alloc_nested: Allocate an iommu_domain for nested translation.
  * @probe_device: Add device to iommu driver handling
  * @release_device: Remove device from iommu driver handling
  * @probe_finalize: Do final setup work after the device is added to an IOMMU
@@ -622,6 +620,9 @@ struct iommu_ops {
        struct iommu_domain *(*domain_alloc_paging)(struct device *dev);
        struct iommu_domain *(*domain_alloc_sva)(struct device *dev,
                                                 struct mm_struct *mm);
+       struct iommu_domain *(*domain_alloc_nested)(
+               struct device *dev, struct iommu_domain *parent, u32 flags,
+               const struct iommu_user_data *user_data);
 
        struct iommu_device *(*probe_device)(struct device *dev);
        void (*release_device)(struct device *dev);
This page took 0.077739 seconds and 4 git commands to generate.