Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Yi Liu and committed by
Jason Gunthorpe
03c9b102 8a9e1e77

+52 -39
+41 -29
drivers/iommu/iommufd/device.c
··· 368 368 } 369 369 370 370 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) 372 373 { 373 374 struct iommufd_attach_handle *handle; 374 375 int rc; ··· 387 386 } 388 387 389 388 handle->idev = idev; 389 + WARN_ON(pasid != IOMMU_NO_PASID); 390 390 rc = iommu_attach_group_handle(hwpt->domain, idev->igroup->group, 391 391 &handle->handle); 392 392 if (rc) ··· 404 402 } 405 403 406 404 static struct iommufd_attach_handle * 407 - iommufd_device_get_attach_handle(struct iommufd_device *idev) 405 + iommufd_device_get_attach_handle(struct iommufd_device *idev, ioasid_t pasid) 408 406 { 409 407 struct iommu_attach_handle *handle; 410 408 411 409 lockdep_assert_held(&idev->igroup->lock); 412 410 413 411 handle = 414 - iommu_attach_handle_get(idev->igroup->group, IOMMU_NO_PASID, 0); 412 + iommu_attach_handle_get(idev->igroup->group, pasid, 0); 415 413 if (IS_ERR(handle)) 416 414 return NULL; 417 415 return to_iommufd_handle(handle); 418 416 } 419 417 420 418 static void iommufd_hwpt_detach_device(struct iommufd_hw_pagetable *hwpt, 421 - struct iommufd_device *idev) 419 + struct iommufd_device *idev, 420 + ioasid_t pasid) 422 421 { 423 422 struct iommufd_attach_handle *handle; 424 423 425 - handle = iommufd_device_get_attach_handle(idev); 424 + WARN_ON(pasid != IOMMU_NO_PASID); 425 + 426 + handle = iommufd_device_get_attach_handle(idev, pasid); 426 427 iommu_detach_group_handle(hwpt->domain, idev->igroup->group); 427 428 if (hwpt->fault) { 428 429 iommufd_auto_response_faults(hwpt, handle); ··· 435 430 } 436 431 437 432 static int iommufd_hwpt_replace_device(struct iommufd_device *idev, 433 + ioasid_t pasid, 438 434 struct iommufd_hw_pagetable *hwpt, 439 435 struct iommufd_hw_pagetable *old) 440 436 { 441 - struct iommufd_attach_handle *handle, *old_handle = 442 - iommufd_device_get_attach_handle(idev); 437 + struct iommufd_attach_handle *handle, *old_handle; 443 438 int rc; 439 + 440 + WARN_ON(pasid != IOMMU_NO_PASID); 441 + 442 + old_handle = iommufd_device_get_attach_handle(idev, pasid); 444 443 445 444 handle = kzalloc(sizeof(*handle), GFP_KERNEL); 446 445 if (!handle) ··· 480 471 } 481 472 482 473 int iommufd_hw_pagetable_attach(struct iommufd_hw_pagetable *hwpt, 483 - struct iommufd_device *idev) 474 + struct iommufd_device *idev, ioasid_t pasid) 484 475 { 485 476 struct iommufd_hwpt_paging *hwpt_paging = find_hwpt_paging(hwpt); 486 477 int rc; ··· 506 497 * attachment. 507 498 */ 508 499 if (list_empty(&idev->igroup->device_list)) { 509 - rc = iommufd_hwpt_attach_device(hwpt, idev); 500 + rc = iommufd_hwpt_attach_device(hwpt, idev, pasid); 510 501 if (rc) 511 502 goto err_unresv; 512 503 idev->igroup->hwpt = hwpt; ··· 524 515 } 525 516 526 517 struct iommufd_hw_pagetable * 527 - iommufd_hw_pagetable_detach(struct iommufd_device *idev) 518 + iommufd_hw_pagetable_detach(struct iommufd_device *idev, ioasid_t pasid) 528 519 { 529 520 struct iommufd_hw_pagetable *hwpt = idev->igroup->hwpt; 530 521 struct iommufd_hwpt_paging *hwpt_paging = find_hwpt_paging(hwpt); ··· 532 523 mutex_lock(&idev->igroup->lock); 533 524 list_del(&idev->group_item); 534 525 if (list_empty(&idev->igroup->device_list)) { 535 - iommufd_hwpt_detach_device(hwpt, idev); 526 + iommufd_hwpt_detach_device(hwpt, idev, pasid); 536 527 idev->igroup->hwpt = NULL; 537 528 } 538 529 if (hwpt_paging) ··· 544 535 } 545 536 546 537 static struct iommufd_hw_pagetable * 547 - iommufd_device_do_attach(struct iommufd_device *idev, 538 + iommufd_device_do_attach(struct iommufd_device *idev, ioasid_t pasid, 548 539 struct iommufd_hw_pagetable *hwpt) 549 540 { 550 541 int rc; 551 542 552 - rc = iommufd_hw_pagetable_attach(hwpt, idev); 543 + rc = iommufd_hw_pagetable_attach(hwpt, idev, pasid); 553 544 if (rc) 554 545 return ERR_PTR(rc); 555 546 return NULL; ··· 598 589 } 599 590 600 591 static struct iommufd_hw_pagetable * 601 - iommufd_device_do_replace(struct iommufd_device *idev, 592 + iommufd_device_do_replace(struct iommufd_device *idev, ioasid_t pasid, 602 593 struct iommufd_hw_pagetable *hwpt) 603 594 { 604 595 struct iommufd_hwpt_paging *hwpt_paging = find_hwpt_paging(hwpt); ··· 632 623 goto err_unlock; 633 624 } 634 625 635 - rc = iommufd_hwpt_replace_device(idev, hwpt, old_hwpt); 626 + rc = iommufd_hwpt_replace_device(idev, pasid, hwpt, old_hwpt); 636 627 if (rc) 637 628 goto err_unresv; 638 629 ··· 665 656 } 666 657 667 658 typedef struct iommufd_hw_pagetable *(*attach_fn)( 668 - struct iommufd_device *idev, struct iommufd_hw_pagetable *hwpt); 659 + struct iommufd_device *idev, ioasid_t pasid, 660 + struct iommufd_hw_pagetable *hwpt); 669 661 670 662 /* 671 663 * When automatically managing the domains we search for a compatible domain in ··· 674 664 * Automatic domain selection will never pick a manually created domain. 675 665 */ 676 666 static struct iommufd_hw_pagetable * 677 - iommufd_device_auto_get_domain(struct iommufd_device *idev, 667 + iommufd_device_auto_get_domain(struct iommufd_device *idev, ioasid_t pasid, 678 668 struct iommufd_ioas *ioas, u32 *pt_id, 679 669 attach_fn do_attach) 680 670 { ··· 703 693 hwpt = &hwpt_paging->common; 704 694 if (!iommufd_lock_obj(&hwpt->obj)) 705 695 continue; 706 - destroy_hwpt = (*do_attach)(idev, hwpt); 696 + destroy_hwpt = (*do_attach)(idev, pasid, hwpt); 707 697 if (IS_ERR(destroy_hwpt)) { 708 698 iommufd_put_object(idev->ictx, &hwpt->obj); 709 699 /* ··· 721 711 goto out_unlock; 722 712 } 723 713 724 - hwpt_paging = iommufd_hwpt_paging_alloc(idev->ictx, ioas, idev, 0, 725 - immediate_attach, NULL); 714 + hwpt_paging = iommufd_hwpt_paging_alloc(idev->ictx, ioas, idev, pasid, 715 + 0, immediate_attach, NULL); 726 716 if (IS_ERR(hwpt_paging)) { 727 717 destroy_hwpt = ERR_CAST(hwpt_paging); 728 718 goto out_unlock; ··· 730 720 hwpt = &hwpt_paging->common; 731 721 732 722 if (!immediate_attach) { 733 - destroy_hwpt = (*do_attach)(idev, hwpt); 723 + destroy_hwpt = (*do_attach)(idev, pasid, hwpt); 734 724 if (IS_ERR(destroy_hwpt)) 735 725 goto out_abort; 736 726 } else { ··· 751 741 return destroy_hwpt; 752 742 } 753 743 754 - static int iommufd_device_change_pt(struct iommufd_device *idev, u32 *pt_id, 755 - attach_fn do_attach) 744 + static int iommufd_device_change_pt(struct iommufd_device *idev, 745 + ioasid_t pasid, 746 + u32 *pt_id, attach_fn do_attach) 756 747 { 757 748 struct iommufd_hw_pagetable *destroy_hwpt; 758 749 struct iommufd_object *pt_obj; ··· 768 757 struct iommufd_hw_pagetable *hwpt = 769 758 container_of(pt_obj, struct iommufd_hw_pagetable, obj); 770 759 771 - destroy_hwpt = (*do_attach)(idev, hwpt); 760 + destroy_hwpt = (*do_attach)(idev, pasid, hwpt); 772 761 if (IS_ERR(destroy_hwpt)) 773 762 goto out_put_pt_obj; 774 763 break; ··· 777 766 struct iommufd_ioas *ioas = 778 767 container_of(pt_obj, struct iommufd_ioas, obj); 779 768 780 - destroy_hwpt = iommufd_device_auto_get_domain(idev, ioas, pt_id, 781 - do_attach); 769 + destroy_hwpt = iommufd_device_auto_get_domain(idev, pasid, ioas, 770 + pt_id, do_attach); 782 771 if (IS_ERR(destroy_hwpt)) 783 772 goto out_put_pt_obj; 784 773 break; ··· 815 804 { 816 805 int rc; 817 806 818 - rc = iommufd_device_change_pt(idev, pt_id, &iommufd_device_do_attach); 807 + rc = iommufd_device_change_pt(idev, IOMMU_NO_PASID, pt_id, 808 + &iommufd_device_do_attach); 819 809 if (rc) 820 810 return rc; 821 811 ··· 846 834 */ 847 835 int iommufd_device_replace(struct iommufd_device *idev, u32 *pt_id) 848 836 { 849 - return iommufd_device_change_pt(idev, pt_id, 837 + return iommufd_device_change_pt(idev, IOMMU_NO_PASID, pt_id, 850 838 &iommufd_device_do_replace); 851 839 } 852 840 EXPORT_SYMBOL_NS_GPL(iommufd_device_replace, "IOMMUFD"); ··· 862 850 { 863 851 struct iommufd_hw_pagetable *hwpt; 864 852 865 - hwpt = iommufd_hw_pagetable_detach(idev); 853 + hwpt = iommufd_hw_pagetable_detach(idev, IOMMU_NO_PASID); 866 854 iommufd_hw_pagetable_put(idev->ictx, hwpt); 867 855 refcount_dec(&idev->obj.users); 868 856 }
+7 -6
drivers/iommu/iommufd/hw_pagetable.c
··· 90 90 * @ictx: iommufd context 91 91 * @ioas: IOAS to associate the domain with 92 92 * @idev: Device to get an iommu_domain for 93 + * @pasid: PASID to get an iommu_domain for 93 94 * @flags: Flags from userspace 94 95 * @immediate_attach: True if idev should be attached to the hwpt 95 96 * @user_data: The user provided driver specific data describing the domain to ··· 106 105 */ 107 106 struct iommufd_hwpt_paging * 108 107 iommufd_hwpt_paging_alloc(struct iommufd_ctx *ictx, struct iommufd_ioas *ioas, 109 - struct iommufd_device *idev, u32 flags, 110 - bool immediate_attach, 108 + struct iommufd_device *idev, ioasid_t pasid, 109 + u32 flags, bool immediate_attach, 111 110 const struct iommu_user_data *user_data) 112 111 { 113 112 const u32 valid_flags = IOMMU_HWPT_ALLOC_NEST_PARENT | ··· 190 189 * sequence. Once those drivers are fixed this should be removed. 191 190 */ 192 191 if (immediate_attach) { 193 - rc = iommufd_hw_pagetable_attach(hwpt, idev); 192 + rc = iommufd_hw_pagetable_attach(hwpt, idev, pasid); 194 193 if (rc) 195 194 goto out_abort; 196 195 } ··· 203 202 204 203 out_detach: 205 204 if (immediate_attach) 206 - iommufd_hw_pagetable_detach(idev); 205 + iommufd_hw_pagetable_detach(idev, pasid); 207 206 out_abort: 208 207 iommufd_object_abort_and_destroy(ictx, &hwpt->obj); 209 208 return ERR_PTR(rc); ··· 365 364 ioas = container_of(pt_obj, struct iommufd_ioas, obj); 366 365 mutex_lock(&ioas->mutex); 367 366 hwpt_paging = iommufd_hwpt_paging_alloc( 368 - ucmd->ictx, ioas, idev, cmd->flags, false, 369 - user_data.len ? &user_data : NULL); 367 + ucmd->ictx, ioas, idev, IOMMU_NO_PASID, cmd->flags, 368 + false, user_data.len ? &user_data : NULL); 370 369 if (IS_ERR(hwpt_paging)) { 371 370 rc = PTR_ERR(hwpt_paging); 372 371 goto out_unlock;
+4 -4
drivers/iommu/iommufd/iommufd_private.h
··· 369 369 370 370 struct iommufd_hwpt_paging * 371 371 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, 374 374 const struct iommu_user_data *user_data); 375 375 int iommufd_hw_pagetable_attach(struct iommufd_hw_pagetable *hwpt, 376 - struct iommufd_device *idev); 376 + struct iommufd_device *idev, ioasid_t pasid); 377 377 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); 379 379 void iommufd_hwpt_paging_destroy(struct iommufd_object *obj); 380 380 void iommufd_hwpt_paging_abort(struct iommufd_object *obj); 381 381 void iommufd_hwpt_nested_destroy(struct iommufd_object *obj);