@@ -368,7 +368,8 @@ static bool iommufd_device_is_attached(struct iommufd_device *idev)
368368}
369369
370370static 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
404406static 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
418420static 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
432437static 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
473482int 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
517526struct 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
537546static 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
591600static 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
658667typedef 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 */
666676static 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 */
835847int 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}
840852EXPORT_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}
0 commit comments