Skip to content

Commit 64214c2

Browse files
committed
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: Lu Baolu <baolu.lu@linux.intel.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
1 parent 2d76228 commit 64214c2

File tree

6 files changed

+29
-21
lines changed

6 files changed

+29
-21
lines changed

drivers/iommu/intel/iommu.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3340,12 +3340,8 @@ intel_iommu_domain_alloc_user(struct device *dev, u32 flags,
33403340
struct iommu_domain *domain;
33413341
bool first_stage;
33423342

3343-
/* Must be NESTING domain */
3344-
if (parent) {
3345-
if (!nested_supported(iommu) || flags)
3346-
return ERR_PTR(-EOPNOTSUPP);
3347-
return intel_nested_domain_alloc(parent, user_data);
3348-
}
3343+
if (parent)
3344+
return ERR_PTR(-EOPNOTSUPP);
33493345

33503346
if (flags &
33513347
(~(IOMMU_HWPT_ALLOC_NEST_PARENT | IOMMU_HWPT_ALLOC_DIRTY_TRACKING
@@ -4475,6 +4471,7 @@ const struct iommu_ops intel_iommu_ops = {
44754471
.domain_alloc_user = intel_iommu_domain_alloc_user,
44764472
.domain_alloc_sva = intel_svm_domain_alloc,
44774473
.domain_alloc_paging = intel_iommu_domain_alloc_paging,
4474+
.domain_alloc_nested = intel_iommu_domain_alloc_nested,
44784475
.probe_device = intel_iommu_probe_device,
44794476
.release_device = intel_iommu_release_device,
44804477
.get_resv_regions = intel_iommu_get_resv_regions,

drivers/iommu/intel/iommu.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1265,8 +1265,10 @@ int __domain_setup_first_level(struct intel_iommu *iommu,
12651265
int dmar_ir_support(void);
12661266

12671267
void iommu_flush_write_buffer(struct intel_iommu *iommu);
1268-
struct iommu_domain *intel_nested_domain_alloc(struct iommu_domain *parent,
1269-
const struct iommu_user_data *user_data);
1268+
struct iommu_domain *
1269+
intel_iommu_domain_alloc_nested(struct device *dev, struct iommu_domain *parent,
1270+
u32 flags,
1271+
const struct iommu_user_data *user_data);
12701272
struct device *device_rbtree_find(struct intel_iommu *iommu, u16 rid);
12711273

12721274
enum cache_tag_type {

drivers/iommu/intel/nested.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,14 +186,21 @@ static const struct iommu_domain_ops intel_nested_domain_ops = {
186186
.cache_invalidate_user = intel_nested_cache_invalidate_user,
187187
};
188188

189-
struct iommu_domain *intel_nested_domain_alloc(struct iommu_domain *parent,
190-
const struct iommu_user_data *user_data)
189+
struct iommu_domain *
190+
intel_iommu_domain_alloc_nested(struct device *dev, struct iommu_domain *parent,
191+
u32 flags,
192+
const struct iommu_user_data *user_data)
191193
{
194+
struct device_domain_info *info = dev_iommu_priv_get(dev);
192195
struct dmar_domain *s2_domain = to_dmar_domain(parent);
196+
struct intel_iommu *iommu = info->iommu;
193197
struct iommu_hwpt_vtd_s1 vtd;
194198
struct dmar_domain *domain;
195199
int ret;
196200

201+
if (!nested_supported(iommu) || flags)
202+
return ERR_PTR(-EOPNOTSUPP);
203+
197204
/* Must be nested domain */
198205
if (user_data->type != IOMMU_HWPT_DATA_VTD_S1)
199206
return ERR_PTR(-EOPNOTSUPP);

drivers/iommu/iommufd/hw_pagetable.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ iommufd_hwpt_nested_alloc(struct iommufd_ctx *ictx,
227227
int rc;
228228

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

245-
hwpt->domain = ops->domain_alloc_user(idev->dev,
246-
flags & ~IOMMU_HWPT_FAULT_ID_VALID,
247-
parent->common.domain, user_data);
245+
hwpt->domain = ops->domain_alloc_nested(
246+
idev->dev, parent->common.domain,
247+
flags & ~IOMMU_HWPT_FAULT_ID_VALID, user_data);
248248
if (IS_ERR(hwpt->domain)) {
249249
rc = PTR_ERR(hwpt->domain);
250250
hwpt->domain = NULL;

drivers/iommu/iommufd/selftest.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -356,8 +356,8 @@ __mock_domain_alloc_nested(const struct iommu_user_data *user_data)
356356
}
357357

358358
static struct iommu_domain *
359-
mock_domain_alloc_nested(struct iommu_domain *parent, u32 flags,
360-
const struct iommu_user_data *user_data)
359+
mock_domain_alloc_nested(struct device *dev, struct iommu_domain *parent,
360+
u32 flags, const struct iommu_user_data *user_data)
361361
{
362362
struct mock_iommu_domain_nested *mock_nested;
363363
struct mock_iommu_domain *mock_parent;
@@ -391,7 +391,7 @@ mock_domain_alloc_user(struct device *dev, u32 flags,
391391
struct iommu_domain *domain;
392392

393393
if (parent)
394-
return mock_domain_alloc_nested(parent, flags, user_data);
394+
return ERR_PTR(-EOPNOTSUPP);
395395

396396
if (user_data)
397397
return ERR_PTR(-EOPNOTSUPP);
@@ -719,6 +719,7 @@ static const struct iommu_ops mock_ops = {
719719
.hw_info = mock_domain_hw_info,
720720
.domain_alloc_paging = mock_domain_alloc_paging,
721721
.domain_alloc_user = mock_domain_alloc_user,
722+
.domain_alloc_nested = mock_domain_alloc_nested,
722723
.capable = mock_domain_capable,
723724
.device_group = generic_device_group,
724725
.probe_device = mock_probe_device,

include/linux/iommu.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -559,15 +559,13 @@ iommu_copy_struct_from_full_user_array(void *kdst, size_t kdst_entry_size,
559559
* the caller iommu_domain_alloc() returns.
560560
* @domain_alloc_user: Allocate an iommu domain corresponding to the input
561561
* parameters as defined in include/uapi/linux/iommufd.h.
562-
* Upon success, if the @user_data is valid and the @parent
563-
* points to a kernel-managed domain, the new domain must be
564-
* IOMMU_DOMAIN_NESTED type; otherwise, the @parent must be
565-
* NULL while the @user_data can be optionally provided, the
562+
* The @user_data can be optionally provided, the
566563
* new domain must support __IOMMU_DOMAIN_PAGING.
567564
* Upon failure, ERR_PTR must be returned.
568565
* @domain_alloc_paging: Allocate an iommu_domain that can be used for
569566
* UNMANAGED, DMA, and DMA_FQ domain types.
570567
* @domain_alloc_sva: Allocate an iommu_domain for Shared Virtual Addressing.
568+
* @domain_alloc_nested: Allocate an iommu_domain for nested translation.
571569
* @probe_device: Add device to iommu driver handling
572570
* @release_device: Remove device from iommu driver handling
573571
* @probe_finalize: Do final setup work after the device is added to an IOMMU
@@ -622,6 +620,9 @@ struct iommu_ops {
622620
struct iommu_domain *(*domain_alloc_paging)(struct device *dev);
623621
struct iommu_domain *(*domain_alloc_sva)(struct device *dev,
624622
struct mm_struct *mm);
623+
struct iommu_domain *(*domain_alloc_nested)(
624+
struct device *dev, struct iommu_domain *parent, u32 flags,
625+
const struct iommu_user_data *user_data);
625626

626627
struct iommu_device *(*probe_device)(struct device *dev);
627628
void (*release_device)(struct device *dev);

0 commit comments

Comments
 (0)