Skip to content

Commit 03c9b10

Browse files
yiliu1765jgunthorpe
authored andcommitted
iommufd: Pass @Pasid through the device attach/replace path
Most of the core logic before conducting the actual device attach/ replace operation can be shared with pasid attach/replace. So pass @Pasid through the device attach/replace helpers to prepare adding pasid attach/replace. So far the @Pasid should only be IOMMU_NO_PASID. No functional change. Link: https://patch.msgid.link/r/20250321171940.7213-4-yi.l.liu@intel.com Signed-off-by: Kevin Tian <kevin.tian@intel.com> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com> Reviewed-by: Nicolin Chen <nicolinc@nvidia.com> Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com> Signed-off-by: Yi Liu <yi.l.liu@intel.com> Tested-by: Nicolin Chen <nicolinc@nvidia.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
1 parent 8a9e1e7 commit 03c9b10

3 files changed

Lines changed: 52 additions & 39 deletions

File tree

drivers/iommu/iommufd/device.c

Lines changed: 41 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,8 @@ static bool iommufd_device_is_attached(struct iommufd_device *idev)
368368
}
369369

370370
static int iommufd_hwpt_attach_device(struct iommufd_hw_pagetable *hwpt,
371-
struct iommufd_device *idev)
371+
struct iommufd_device *idev,
372+
ioasid_t pasid)
372373
{
373374
struct iommufd_attach_handle *handle;
374375
int rc;
@@ -386,6 +387,7 @@ static int iommufd_hwpt_attach_device(struct iommufd_hw_pagetable *hwpt,
386387
}
387388

388389
handle->idev = idev;
390+
WARN_ON(pasid != IOMMU_NO_PASID);
389391
rc = iommu_attach_group_handle(hwpt->domain, idev->igroup->group,
390392
&handle->handle);
391393
if (rc)
@@ -402,25 +404,28 @@ static int iommufd_hwpt_attach_device(struct iommufd_hw_pagetable *hwpt,
402404
}
403405

404406
static struct iommufd_attach_handle *
405-
iommufd_device_get_attach_handle(struct iommufd_device *idev)
407+
iommufd_device_get_attach_handle(struct iommufd_device *idev, ioasid_t pasid)
406408
{
407409
struct iommu_attach_handle *handle;
408410

409411
lockdep_assert_held(&idev->igroup->lock);
410412

411413
handle =
412-
iommu_attach_handle_get(idev->igroup->group, IOMMU_NO_PASID, 0);
414+
iommu_attach_handle_get(idev->igroup->group, pasid, 0);
413415
if (IS_ERR(handle))
414416
return NULL;
415417
return to_iommufd_handle(handle);
416418
}
417419

418420
static void iommufd_hwpt_detach_device(struct iommufd_hw_pagetable *hwpt,
419-
struct iommufd_device *idev)
421+
struct iommufd_device *idev,
422+
ioasid_t pasid)
420423
{
421424
struct iommufd_attach_handle *handle;
422425

423-
handle = iommufd_device_get_attach_handle(idev);
426+
WARN_ON(pasid != IOMMU_NO_PASID);
427+
428+
handle = iommufd_device_get_attach_handle(idev, pasid);
424429
iommu_detach_group_handle(hwpt->domain, idev->igroup->group);
425430
if (hwpt->fault) {
426431
iommufd_auto_response_faults(hwpt, handle);
@@ -430,13 +435,17 @@ static void iommufd_hwpt_detach_device(struct iommufd_hw_pagetable *hwpt,
430435
}
431436

432437
static int iommufd_hwpt_replace_device(struct iommufd_device *idev,
438+
ioasid_t pasid,
433439
struct iommufd_hw_pagetable *hwpt,
434440
struct iommufd_hw_pagetable *old)
435441
{
436-
struct iommufd_attach_handle *handle, *old_handle =
437-
iommufd_device_get_attach_handle(idev);
442+
struct iommufd_attach_handle *handle, *old_handle;
438443
int rc;
439444

445+
WARN_ON(pasid != IOMMU_NO_PASID);
446+
447+
old_handle = iommufd_device_get_attach_handle(idev, pasid);
448+
440449
handle = kzalloc(sizeof(*handle), GFP_KERNEL);
441450
if (!handle)
442451
return -ENOMEM;
@@ -471,7 +480,7 @@ static int iommufd_hwpt_replace_device(struct iommufd_device *idev,
471480
}
472481

473482
int iommufd_hw_pagetable_attach(struct iommufd_hw_pagetable *hwpt,
474-
struct iommufd_device *idev)
483+
struct iommufd_device *idev, ioasid_t pasid)
475484
{
476485
struct iommufd_hwpt_paging *hwpt_paging = find_hwpt_paging(hwpt);
477486
int rc;
@@ -497,7 +506,7 @@ int iommufd_hw_pagetable_attach(struct iommufd_hw_pagetable *hwpt,
497506
* attachment.
498507
*/
499508
if (list_empty(&idev->igroup->device_list)) {
500-
rc = iommufd_hwpt_attach_device(hwpt, idev);
509+
rc = iommufd_hwpt_attach_device(hwpt, idev, pasid);
501510
if (rc)
502511
goto err_unresv;
503512
idev->igroup->hwpt = hwpt;
@@ -515,15 +524,15 @@ int iommufd_hw_pagetable_attach(struct iommufd_hw_pagetable *hwpt,
515524
}
516525

517526
struct iommufd_hw_pagetable *
518-
iommufd_hw_pagetable_detach(struct iommufd_device *idev)
527+
iommufd_hw_pagetable_detach(struct iommufd_device *idev, ioasid_t pasid)
519528
{
520529
struct iommufd_hw_pagetable *hwpt = idev->igroup->hwpt;
521530
struct iommufd_hwpt_paging *hwpt_paging = find_hwpt_paging(hwpt);
522531

523532
mutex_lock(&idev->igroup->lock);
524533
list_del(&idev->group_item);
525534
if (list_empty(&idev->igroup->device_list)) {
526-
iommufd_hwpt_detach_device(hwpt, idev);
535+
iommufd_hwpt_detach_device(hwpt, idev, pasid);
527536
idev->igroup->hwpt = NULL;
528537
}
529538
if (hwpt_paging)
@@ -535,12 +544,12 @@ iommufd_hw_pagetable_detach(struct iommufd_device *idev)
535544
}
536545

537546
static struct iommufd_hw_pagetable *
538-
iommufd_device_do_attach(struct iommufd_device *idev,
547+
iommufd_device_do_attach(struct iommufd_device *idev, ioasid_t pasid,
539548
struct iommufd_hw_pagetable *hwpt)
540549
{
541550
int rc;
542551

543-
rc = iommufd_hw_pagetable_attach(hwpt, idev);
552+
rc = iommufd_hw_pagetable_attach(hwpt, idev, pasid);
544553
if (rc)
545554
return ERR_PTR(rc);
546555
return NULL;
@@ -589,7 +598,7 @@ iommufd_group_do_replace_reserved_iova(struct iommufd_group *igroup,
589598
}
590599

591600
static struct iommufd_hw_pagetable *
592-
iommufd_device_do_replace(struct iommufd_device *idev,
601+
iommufd_device_do_replace(struct iommufd_device *idev, ioasid_t pasid,
593602
struct iommufd_hw_pagetable *hwpt)
594603
{
595604
struct iommufd_hwpt_paging *hwpt_paging = find_hwpt_paging(hwpt);
@@ -623,7 +632,7 @@ iommufd_device_do_replace(struct iommufd_device *idev,
623632
goto err_unlock;
624633
}
625634

626-
rc = iommufd_hwpt_replace_device(idev, hwpt, old_hwpt);
635+
rc = iommufd_hwpt_replace_device(idev, pasid, hwpt, old_hwpt);
627636
if (rc)
628637
goto err_unresv;
629638

@@ -656,15 +665,16 @@ iommufd_device_do_replace(struct iommufd_device *idev,
656665
}
657666

658667
typedef struct iommufd_hw_pagetable *(*attach_fn)(
659-
struct iommufd_device *idev, struct iommufd_hw_pagetable *hwpt);
668+
struct iommufd_device *idev, ioasid_t pasid,
669+
struct iommufd_hw_pagetable *hwpt);
660670

661671
/*
662672
* When automatically managing the domains we search for a compatible domain in
663673
* the iopt and if one is found use it, otherwise create a new domain.
664674
* Automatic domain selection will never pick a manually created domain.
665675
*/
666676
static struct iommufd_hw_pagetable *
667-
iommufd_device_auto_get_domain(struct iommufd_device *idev,
677+
iommufd_device_auto_get_domain(struct iommufd_device *idev, ioasid_t pasid,
668678
struct iommufd_ioas *ioas, u32 *pt_id,
669679
attach_fn do_attach)
670680
{
@@ -693,7 +703,7 @@ iommufd_device_auto_get_domain(struct iommufd_device *idev,
693703
hwpt = &hwpt_paging->common;
694704
if (!iommufd_lock_obj(&hwpt->obj))
695705
continue;
696-
destroy_hwpt = (*do_attach)(idev, hwpt);
706+
destroy_hwpt = (*do_attach)(idev, pasid, hwpt);
697707
if (IS_ERR(destroy_hwpt)) {
698708
iommufd_put_object(idev->ictx, &hwpt->obj);
699709
/*
@@ -711,16 +721,16 @@ iommufd_device_auto_get_domain(struct iommufd_device *idev,
711721
goto out_unlock;
712722
}
713723

714-
hwpt_paging = iommufd_hwpt_paging_alloc(idev->ictx, ioas, idev, 0,
715-
immediate_attach, NULL);
724+
hwpt_paging = iommufd_hwpt_paging_alloc(idev->ictx, ioas, idev, pasid,
725+
0, immediate_attach, NULL);
716726
if (IS_ERR(hwpt_paging)) {
717727
destroy_hwpt = ERR_CAST(hwpt_paging);
718728
goto out_unlock;
719729
}
720730
hwpt = &hwpt_paging->common;
721731

722732
if (!immediate_attach) {
723-
destroy_hwpt = (*do_attach)(idev, hwpt);
733+
destroy_hwpt = (*do_attach)(idev, pasid, hwpt);
724734
if (IS_ERR(destroy_hwpt))
725735
goto out_abort;
726736
} else {
@@ -741,8 +751,9 @@ iommufd_device_auto_get_domain(struct iommufd_device *idev,
741751
return destroy_hwpt;
742752
}
743753

744-
static int iommufd_device_change_pt(struct iommufd_device *idev, u32 *pt_id,
745-
attach_fn do_attach)
754+
static int iommufd_device_change_pt(struct iommufd_device *idev,
755+
ioasid_t pasid,
756+
u32 *pt_id, attach_fn do_attach)
746757
{
747758
struct iommufd_hw_pagetable *destroy_hwpt;
748759
struct iommufd_object *pt_obj;
@@ -757,7 +768,7 @@ static int iommufd_device_change_pt(struct iommufd_device *idev, u32 *pt_id,
757768
struct iommufd_hw_pagetable *hwpt =
758769
container_of(pt_obj, struct iommufd_hw_pagetable, obj);
759770

760-
destroy_hwpt = (*do_attach)(idev, hwpt);
771+
destroy_hwpt = (*do_attach)(idev, pasid, hwpt);
761772
if (IS_ERR(destroy_hwpt))
762773
goto out_put_pt_obj;
763774
break;
@@ -766,8 +777,8 @@ static int iommufd_device_change_pt(struct iommufd_device *idev, u32 *pt_id,
766777
struct iommufd_ioas *ioas =
767778
container_of(pt_obj, struct iommufd_ioas, obj);
768779

769-
destroy_hwpt = iommufd_device_auto_get_domain(idev, ioas, pt_id,
770-
do_attach);
780+
destroy_hwpt = iommufd_device_auto_get_domain(idev, pasid, ioas,
781+
pt_id, do_attach);
771782
if (IS_ERR(destroy_hwpt))
772783
goto out_put_pt_obj;
773784
break;
@@ -804,7 +815,8 @@ int iommufd_device_attach(struct iommufd_device *idev, u32 *pt_id)
804815
{
805816
int rc;
806817

807-
rc = iommufd_device_change_pt(idev, pt_id, &iommufd_device_do_attach);
818+
rc = iommufd_device_change_pt(idev, IOMMU_NO_PASID, pt_id,
819+
&iommufd_device_do_attach);
808820
if (rc)
809821
return rc;
810822

@@ -834,7 +846,7 @@ EXPORT_SYMBOL_NS_GPL(iommufd_device_attach, "IOMMUFD");
834846
*/
835847
int iommufd_device_replace(struct iommufd_device *idev, u32 *pt_id)
836848
{
837-
return iommufd_device_change_pt(idev, pt_id,
849+
return iommufd_device_change_pt(idev, IOMMU_NO_PASID, pt_id,
838850
&iommufd_device_do_replace);
839851
}
840852
EXPORT_SYMBOL_NS_GPL(iommufd_device_replace, "IOMMUFD");
@@ -850,7 +862,7 @@ void iommufd_device_detach(struct iommufd_device *idev)
850862
{
851863
struct iommufd_hw_pagetable *hwpt;
852864

853-
hwpt = iommufd_hw_pagetable_detach(idev);
865+
hwpt = iommufd_hw_pagetable_detach(idev, IOMMU_NO_PASID);
854866
iommufd_hw_pagetable_put(idev->ictx, hwpt);
855867
refcount_dec(&idev->obj.users);
856868
}

drivers/iommu/iommufd/hw_pagetable.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ iommufd_hwpt_paging_enforce_cc(struct iommufd_hwpt_paging *hwpt_paging)
9090
* @ictx: iommufd context
9191
* @ioas: IOAS to associate the domain with
9292
* @idev: Device to get an iommu_domain for
93+
* @pasid: PASID to get an iommu_domain for
9394
* @flags: Flags from userspace
9495
* @immediate_attach: True if idev should be attached to the hwpt
9596
* @user_data: The user provided driver specific data describing the domain to
@@ -105,8 +106,8 @@ iommufd_hwpt_paging_enforce_cc(struct iommufd_hwpt_paging *hwpt_paging)
105106
*/
106107
struct iommufd_hwpt_paging *
107108
iommufd_hwpt_paging_alloc(struct iommufd_ctx *ictx, struct iommufd_ioas *ioas,
108-
struct iommufd_device *idev, u32 flags,
109-
bool immediate_attach,
109+
struct iommufd_device *idev, ioasid_t pasid,
110+
u32 flags, bool immediate_attach,
110111
const struct iommu_user_data *user_data)
111112
{
112113
const u32 valid_flags = IOMMU_HWPT_ALLOC_NEST_PARENT |
@@ -189,7 +190,7 @@ iommufd_hwpt_paging_alloc(struct iommufd_ctx *ictx, struct iommufd_ioas *ioas,
189190
* sequence. Once those drivers are fixed this should be removed.
190191
*/
191192
if (immediate_attach) {
192-
rc = iommufd_hw_pagetable_attach(hwpt, idev);
193+
rc = iommufd_hw_pagetable_attach(hwpt, idev, pasid);
193194
if (rc)
194195
goto out_abort;
195196
}
@@ -202,7 +203,7 @@ iommufd_hwpt_paging_alloc(struct iommufd_ctx *ictx, struct iommufd_ioas *ioas,
202203

203204
out_detach:
204205
if (immediate_attach)
205-
iommufd_hw_pagetable_detach(idev);
206+
iommufd_hw_pagetable_detach(idev, pasid);
206207
out_abort:
207208
iommufd_object_abort_and_destroy(ictx, &hwpt->obj);
208209
return ERR_PTR(rc);
@@ -364,8 +365,8 @@ int iommufd_hwpt_alloc(struct iommufd_ucmd *ucmd)
364365
ioas = container_of(pt_obj, struct iommufd_ioas, obj);
365366
mutex_lock(&ioas->mutex);
366367
hwpt_paging = iommufd_hwpt_paging_alloc(
367-
ucmd->ictx, ioas, idev, cmd->flags, false,
368-
user_data.len ? &user_data : NULL);
368+
ucmd->ictx, ioas, idev, IOMMU_NO_PASID, cmd->flags,
369+
false, user_data.len ? &user_data : NULL);
369370
if (IS_ERR(hwpt_paging)) {
370371
rc = PTR_ERR(hwpt_paging);
371372
goto out_unlock;

drivers/iommu/iommufd/iommufd_private.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -369,13 +369,13 @@ int iommufd_hwpt_get_dirty_bitmap(struct iommufd_ucmd *ucmd);
369369

370370
struct iommufd_hwpt_paging *
371371
iommufd_hwpt_paging_alloc(struct iommufd_ctx *ictx, struct iommufd_ioas *ioas,
372-
struct iommufd_device *idev, u32 flags,
373-
bool immediate_attach,
372+
struct iommufd_device *idev, ioasid_t pasid,
373+
u32 flags, bool immediate_attach,
374374
const struct iommu_user_data *user_data);
375375
int iommufd_hw_pagetable_attach(struct iommufd_hw_pagetable *hwpt,
376-
struct iommufd_device *idev);
376+
struct iommufd_device *idev, ioasid_t pasid);
377377
struct iommufd_hw_pagetable *
378-
iommufd_hw_pagetable_detach(struct iommufd_device *idev);
378+
iommufd_hw_pagetable_detach(struct iommufd_device *idev, ioasid_t pasid);
379379
void iommufd_hwpt_paging_destroy(struct iommufd_object *obj);
380380
void iommufd_hwpt_paging_abort(struct iommufd_object *obj);
381381
void iommufd_hwpt_nested_destroy(struct iommufd_object *obj);

0 commit comments

Comments
 (0)