Lines Matching +full:iommu +full:- +full:secure +full:- +full:id

1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright (c) 2021-2022, NVIDIA CORPORATION & AFFILIATES
6 #include <linux/iommu.h>
8 #include "../iommu-priv.h"
25 WARN_ON(igroup->hwpt || !list_empty(&igroup->device_list)); in iommufd_group_release()
27 xa_cmpxchg(&igroup->ictx->groups, iommu_group_id(igroup->group), igroup, in iommufd_group_release()
29 iommu_group_put(igroup->group); in iommufd_group_release()
30 mutex_destroy(&igroup->lock); in iommufd_group_release()
36 kref_put(&group->ref, iommufd_group_release); in iommufd_put_group()
45 * group ID's cannot be re-used until the group is put back which does in iommufd_group_try_get()
48 if (WARN_ON(igroup->group != group)) in iommufd_group_try_get()
50 return kref_get_unless_zero(&igroup->ref); in iommufd_group_try_get()
55 * parallel xarray indexed by iommu_group id to hold this instead of putting it
67 unsigned int id; in iommufd_get_group() local
71 return ERR_PTR(-ENODEV); in iommufd_get_group()
73 id = iommu_group_id(group); in iommufd_get_group()
75 xa_lock(&ictx->groups); in iommufd_get_group()
76 igroup = xa_load(&ictx->groups, id); in iommufd_get_group()
78 xa_unlock(&ictx->groups); in iommufd_get_group()
82 xa_unlock(&ictx->groups); in iommufd_get_group()
87 return ERR_PTR(-ENOMEM); in iommufd_get_group()
90 kref_init(&new_igroup->ref); in iommufd_get_group()
91 mutex_init(&new_igroup->lock); in iommufd_get_group()
92 INIT_LIST_HEAD(&new_igroup->device_list); in iommufd_get_group()
93 new_igroup->sw_msi_start = PHYS_ADDR_MAX; in iommufd_get_group()
95 new_igroup->group = group; in iommufd_get_group()
101 new_igroup->ictx = ictx; in iommufd_get_group()
108 xa_lock(&ictx->groups); in iommufd_get_group()
110 igroup = __xa_cmpxchg(&ictx->groups, id, cur_igroup, new_igroup, in iommufd_get_group()
113 xa_unlock(&ictx->groups); in iommufd_get_group()
120 xa_unlock(&ictx->groups); in iommufd_get_group()
126 xa_unlock(&ictx->groups); in iommufd_get_group()
139 iommu_device_release_dma_owner(idev->dev); in iommufd_device_destroy()
140 iommufd_put_group(idev->igroup); in iommufd_device_destroy()
141 if (!iommufd_selftest_is_mock_dev(idev->dev)) in iommufd_device_destroy()
142 iommufd_ctx_put(idev->ictx); in iommufd_device_destroy()
146 * iommufd_device_bind - Bind a physical device to an iommu fd
149 * @id: Output ID number to return to userspace for this device
162 struct device *dev, u32 *id) in iommufd_device_bind() argument
173 return ERR_PTR(-EINVAL); in iommufd_device_bind()
181 * allowed if the module parameter is set. Secure/Isolated means that a in iommufd_device_bind()
186 !iommu_group_has_isolated_msi(igroup->group)) { in iommufd_device_bind()
188 rc = -EPERM; in iommufd_device_bind()
194 "MSI interrupts are not secure, they cannot be isolated by the platform. " in iommufd_device_bind()
208 idev->ictx = ictx; in iommufd_device_bind()
211 idev->dev = dev; in iommufd_device_bind()
212 idev->enforce_cache_coherency = in iommufd_device_bind()
215 refcount_inc(&idev->obj.users); in iommufd_device_bind()
217 idev->igroup = igroup; in iommufd_device_bind()
225 iommufd_object_finalize(ictx, &idev->obj); in iommufd_device_bind()
226 *id = idev->obj.id; in iommufd_device_bind()
238 * iommufd_ctx_has_group - True if any device within the group is bound
254 xa_lock(&ictx->objects); in iommufd_ctx_has_group()
255 xa_for_each(&ictx->objects, index, obj) { in iommufd_ctx_has_group()
256 if (obj->type == IOMMUFD_OBJ_DEVICE && in iommufd_ctx_has_group()
258 ->igroup->group == group) { in iommufd_ctx_has_group()
259 xa_unlock(&ictx->objects); in iommufd_ctx_has_group()
263 xa_unlock(&ictx->objects); in iommufd_ctx_has_group()
269 * iommufd_device_unbind - Undo iommufd_device_bind()
279 iommufd_object_destroy_user(idev->ictx, &idev->obj); in iommufd_device_unbind()
285 return idev->ictx; in iommufd_device_to_ictx()
291 return idev->obj.id; in iommufd_device_to_id()
298 phys_addr_t sw_msi_start = igroup->sw_msi_start; in iommufd_group_setup_msi()
302 * If the IOMMU driver gives a IOMMU_RESV_SW_MSI then it is asking us to in iommufd_group_setup_msi()
314 if (sw_msi_start != PHYS_ADDR_MAX && !hwpt_paging->msi_cookie) { in iommufd_group_setup_msi()
315 rc = iommu_get_msi_cookie(hwpt_paging->common.domain, in iommufd_group_setup_msi()
322 * it returns -EBUSY on later calls. in iommufd_group_setup_msi()
324 hwpt_paging->msi_cookie = true; in iommufd_group_setup_msi()
334 lockdep_assert_held(&idev->igroup->lock); in iommufd_hwpt_paging_attach()
336 rc = iopt_table_enforce_dev_resv_regions(&hwpt_paging->ioas->iopt, in iommufd_hwpt_paging_attach()
337 idev->dev, in iommufd_hwpt_paging_attach()
338 &idev->igroup->sw_msi_start); in iommufd_hwpt_paging_attach()
342 if (list_empty(&idev->igroup->device_list)) { in iommufd_hwpt_paging_attach()
343 rc = iommufd_group_setup_msi(idev->igroup, hwpt_paging); in iommufd_hwpt_paging_attach()
345 iopt_remove_reserved_iova(&hwpt_paging->ioas->iopt, in iommufd_hwpt_paging_attach()
346 idev->dev); in iommufd_hwpt_paging_attach()
358 mutex_lock(&idev->igroup->lock); in iommufd_hw_pagetable_attach()
360 if (idev->igroup->hwpt != NULL && idev->igroup->hwpt != hwpt) { in iommufd_hw_pagetable_attach()
361 rc = -EINVAL; in iommufd_hw_pagetable_attach()
374 * should attach every device individually to the hwpt as the per-device in iommufd_hw_pagetable_attach()
378 if (list_empty(&idev->igroup->device_list)) { in iommufd_hw_pagetable_attach()
379 rc = iommu_attach_group(hwpt->domain, idev->igroup->group); in iommufd_hw_pagetable_attach()
382 idev->igroup->hwpt = hwpt; in iommufd_hw_pagetable_attach()
384 refcount_inc(&hwpt->obj.users); in iommufd_hw_pagetable_attach()
385 list_add_tail(&idev->group_item, &idev->igroup->device_list); in iommufd_hw_pagetable_attach()
386 mutex_unlock(&idev->igroup->lock); in iommufd_hw_pagetable_attach()
390 iopt_remove_reserved_iova(&to_hwpt_paging(hwpt)->ioas->iopt, in iommufd_hw_pagetable_attach()
391 idev->dev); in iommufd_hw_pagetable_attach()
393 mutex_unlock(&idev->igroup->lock); in iommufd_hw_pagetable_attach()
400 struct iommufd_hw_pagetable *hwpt = idev->igroup->hwpt; in iommufd_hw_pagetable_detach()
402 mutex_lock(&idev->igroup->lock); in iommufd_hw_pagetable_detach()
403 list_del(&idev->group_item); in iommufd_hw_pagetable_detach()
404 if (list_empty(&idev->igroup->device_list)) { in iommufd_hw_pagetable_detach()
405 iommu_detach_group(hwpt->domain, idev->igroup->group); in iommufd_hw_pagetable_detach()
406 idev->igroup->hwpt = NULL; in iommufd_hw_pagetable_detach()
409 iopt_remove_reserved_iova(&to_hwpt_paging(hwpt)->ioas->iopt, in iommufd_hw_pagetable_detach()
410 idev->dev); in iommufd_hw_pagetable_detach()
411 mutex_unlock(&idev->igroup->lock); in iommufd_hw_pagetable_detach()
435 lockdep_assert_held(&igroup->lock); in iommufd_group_remove_reserved_iova()
437 list_for_each_entry(cur, &igroup->device_list, group_item) in iommufd_group_remove_reserved_iova()
438 iopt_remove_reserved_iova(&hwpt_paging->ioas->iopt, cur->dev); in iommufd_group_remove_reserved_iova()
445 struct iommufd_hw_pagetable *old_hwpt = igroup->hwpt; in iommufd_group_do_replace_paging()
449 lockdep_assert_held(&igroup->lock); in iommufd_group_do_replace_paging()
452 hwpt_paging->ioas != to_hwpt_paging(old_hwpt)->ioas) { in iommufd_group_do_replace_paging()
453 list_for_each_entry(cur, &igroup->device_list, group_item) { in iommufd_group_do_replace_paging()
455 &hwpt_paging->ioas->iopt, cur->dev, NULL); in iommufd_group_do_replace_paging()
475 struct iommufd_group *igroup = idev->igroup; in iommufd_device_do_replace()
480 mutex_lock(&idev->igroup->lock); in iommufd_device_do_replace()
482 if (igroup->hwpt == NULL) { in iommufd_device_do_replace()
483 rc = -EINVAL; in iommufd_device_do_replace()
487 if (hwpt == igroup->hwpt) { in iommufd_device_do_replace()
488 mutex_unlock(&idev->igroup->lock); in iommufd_device_do_replace()
492 old_hwpt = igroup->hwpt; in iommufd_device_do_replace()
500 rc = iommu_group_replace_domain(igroup->group, hwpt->domain); in iommufd_device_do_replace()
506 to_hwpt_paging(hwpt)->ioas != to_hwpt_paging(old_hwpt)->ioas)) in iommufd_device_do_replace()
510 igroup->hwpt = hwpt; in iommufd_device_do_replace()
512 num_devices = list_count_nodes(&igroup->device_list); in iommufd_device_do_replace()
517 refcount_add(num_devices, &hwpt->obj.users); in iommufd_device_do_replace()
519 WARN_ON(refcount_sub_and_test(num_devices - 1, in iommufd_device_do_replace()
520 &old_hwpt->obj.users)); in iommufd_device_do_replace()
521 mutex_unlock(&idev->igroup->lock); in iommufd_device_do_replace()
530 mutex_unlock(&idev->igroup->lock); in iommufd_device_do_replace()
564 mutex_lock(&ioas->mutex); in iommufd_device_auto_get_domain()
565 list_for_each_entry(hwpt_paging, &ioas->hwpt_list, hwpt_item) { in iommufd_device_auto_get_domain()
566 if (!hwpt_paging->auto_domain) in iommufd_device_auto_get_domain()
569 hwpt = &hwpt_paging->common; in iommufd_device_auto_get_domain()
570 if (!iommufd_lock_obj(&hwpt->obj)) in iommufd_device_auto_get_domain()
574 iommufd_put_object(idev->ictx, &hwpt->obj); in iommufd_device_auto_get_domain()
576 * -EINVAL means the domain is incompatible with the in iommufd_device_auto_get_domain()
581 if (PTR_ERR(destroy_hwpt) == -EINVAL) in iommufd_device_auto_get_domain()
585 *pt_id = hwpt->obj.id; in iommufd_device_auto_get_domain()
586 iommufd_put_object(idev->ictx, &hwpt->obj); in iommufd_device_auto_get_domain()
590 hwpt_paging = iommufd_hwpt_paging_alloc(idev->ictx, ioas, idev, 0, in iommufd_device_auto_get_domain()
596 hwpt = &hwpt_paging->common; in iommufd_device_auto_get_domain()
606 hwpt_paging->auto_domain = true; in iommufd_device_auto_get_domain()
607 *pt_id = hwpt->obj.id; in iommufd_device_auto_get_domain()
609 iommufd_object_finalize(idev->ictx, &hwpt->obj); in iommufd_device_auto_get_domain()
610 mutex_unlock(&ioas->mutex); in iommufd_device_auto_get_domain()
614 iommufd_object_abort_and_destroy(idev->ictx, &hwpt->obj); in iommufd_device_auto_get_domain()
616 mutex_unlock(&ioas->mutex); in iommufd_device_auto_get_domain()
626 pt_obj = iommufd_get_object(idev->ictx, *pt_id, IOMMUFD_OBJ_ANY); in iommufd_device_change_pt()
630 switch (pt_obj->type) { in iommufd_device_change_pt()
652 destroy_hwpt = ERR_PTR(-EINVAL); in iommufd_device_change_pt()
655 iommufd_put_object(idev->ictx, pt_obj); in iommufd_device_change_pt()
659 iommufd_hw_pagetable_put(idev->ictx, destroy_hwpt); in iommufd_device_change_pt()
663 iommufd_put_object(idev->ictx, pt_obj); in iommufd_device_change_pt()
668 * iommufd_device_attach - Connect a device to an iommu_domain
671 * Output the IOMMUFD_OBJ_HWPT_PAGING ID
688 * Pairs with iommufd_device_detach() - catches caller bugs attempting in iommufd_device_attach()
691 refcount_inc(&idev->obj.users); in iommufd_device_attach()
697 * iommufd_device_replace - Change the device's iommu_domain
700 * Output the IOMMUFD_OBJ_HWPT_PAGING ID
707 * If it fails then no change is made to the attachment. The iommu driver may
719 * iommufd_device_detach - Disconnect a device to an iommu_domain
730 iommufd_hw_pagetable_put(idev->ictx, hwpt); in iommufd_device_detach()
731 refcount_dec(&idev->obj.users); in iommufd_device_detach()
737 * a valid cur_ioas (access->ioas). A caller passing in a valid new_ioas should
743 u32 iopt_access_list_id = access->iopt_access_list_id; in iommufd_access_change_ioas()
744 struct iommufd_ioas *cur_ioas = access->ioas; in iommufd_access_change_ioas()
747 lockdep_assert_held(&access->ioas_lock); in iommufd_access_change_ioas()
750 if (cur_ioas != access->ioas_unpin) in iommufd_access_change_ioas()
751 return -EBUSY; in iommufd_access_change_ioas()
758 * iommufd_access_unpin_pages() can continue using access->ioas_unpin. in iommufd_access_change_ioas()
760 access->ioas = NULL; in iommufd_access_change_ioas()
763 rc = iopt_add_access(&new_ioas->iopt, access); in iommufd_access_change_ioas()
765 access->ioas = cur_ioas; in iommufd_access_change_ioas()
768 refcount_inc(&new_ioas->obj.users); in iommufd_access_change_ioas()
772 if (access->ops->unmap) { in iommufd_access_change_ioas()
773 mutex_unlock(&access->ioas_lock); in iommufd_access_change_ioas()
774 access->ops->unmap(access->data, 0, ULONG_MAX); in iommufd_access_change_ioas()
775 mutex_lock(&access->ioas_lock); in iommufd_access_change_ioas()
777 iopt_remove_access(&cur_ioas->iopt, access, iopt_access_list_id); in iommufd_access_change_ioas()
778 refcount_dec(&cur_ioas->obj.users); in iommufd_access_change_ioas()
781 access->ioas = new_ioas; in iommufd_access_change_ioas()
782 access->ioas_unpin = new_ioas; in iommufd_access_change_ioas()
787 static int iommufd_access_change_ioas_id(struct iommufd_access *access, u32 id) in iommufd_access_change_ioas_id() argument
789 struct iommufd_ioas *ioas = iommufd_get_ioas(access->ictx, id); in iommufd_access_change_ioas_id()
795 iommufd_put_object(access->ictx, &ioas->obj); in iommufd_access_change_ioas_id()
804 mutex_lock(&access->ioas_lock); in iommufd_access_destroy_object()
805 if (access->ioas) in iommufd_access_destroy_object()
807 mutex_unlock(&access->ioas_lock); in iommufd_access_destroy_object()
808 iommufd_ctx_put(access->ictx); in iommufd_access_destroy_object()
812 * iommufd_access_create - Create an iommufd_access
816 * @id: Output ID number to return to userspace for this access
826 const struct iommufd_access_ops *ops, void *data, u32 *id) in iommufd_access_create() argument
838 access->data = data; in iommufd_access_create()
839 access->ops = ops; in iommufd_access_create()
841 if (ops->needs_pin_pages) in iommufd_access_create()
842 access->iova_alignment = PAGE_SIZE; in iommufd_access_create()
844 access->iova_alignment = 1; in iommufd_access_create()
847 refcount_inc(&access->obj.users); in iommufd_access_create()
848 access->ictx = ictx; in iommufd_access_create()
850 iommufd_object_finalize(ictx, &access->obj); in iommufd_access_create()
851 *id = access->obj.id; in iommufd_access_create()
852 mutex_init(&access->ioas_lock); in iommufd_access_create()
858 * iommufd_access_destroy - Destroy an iommufd_access
865 iommufd_object_destroy_user(access->ictx, &access->obj); in iommufd_access_destroy()
871 mutex_lock(&access->ioas_lock); in iommufd_access_detach()
872 if (WARN_ON(!access->ioas)) { in iommufd_access_detach()
873 mutex_unlock(&access->ioas_lock); in iommufd_access_detach()
877 mutex_unlock(&access->ioas_lock); in iommufd_access_detach()
885 mutex_lock(&access->ioas_lock); in iommufd_access_attach()
886 if (WARN_ON(access->ioas)) { in iommufd_access_attach()
887 mutex_unlock(&access->ioas_lock); in iommufd_access_attach()
888 return -EINVAL; in iommufd_access_attach()
892 mutex_unlock(&access->ioas_lock); in iommufd_access_attach()
901 mutex_lock(&access->ioas_lock); in iommufd_access_replace()
902 if (!access->ioas) { in iommufd_access_replace()
903 mutex_unlock(&access->ioas_lock); in iommufd_access_replace()
904 return -ENOENT; in iommufd_access_replace()
907 mutex_unlock(&access->ioas_lock); in iommufd_access_replace()
913 * iommufd_access_notify_unmap - Notify users of an iopt to stop using it
936 xa_lock(&ioas->iopt.access_list); in iommufd_access_notify_unmap()
937 xa_for_each(&ioas->iopt.access_list, index, access) { in iommufd_access_notify_unmap()
938 if (!iommufd_lock_obj(&access->obj)) in iommufd_access_notify_unmap()
940 xa_unlock(&ioas->iopt.access_list); in iommufd_access_notify_unmap()
942 access->ops->unmap(access->data, iova, length); in iommufd_access_notify_unmap()
944 iommufd_put_object(access->ictx, &access->obj); in iommufd_access_notify_unmap()
945 xa_lock(&ioas->iopt.access_list); in iommufd_access_notify_unmap()
947 xa_unlock(&ioas->iopt.access_list); in iommufd_access_notify_unmap()
951 * iommufd_access_unpin_pages() - Undo iommufd_access_pin_pages
968 WARN_ON(check_add_overflow(iova, length - 1, &last_iova))) in iommufd_access_unpin_pages()
971 mutex_lock(&access->ioas_lock); in iommufd_access_unpin_pages()
976 if (WARN_ON(!access->ioas_unpin)) { in iommufd_access_unpin_pages()
977 mutex_unlock(&access->ioas_lock); in iommufd_access_unpin_pages()
980 iopt = &access->ioas_unpin->iopt; in iommufd_access_unpin_pages()
982 down_read(&iopt->iova_rwsem); in iommufd_access_unpin_pages()
990 up_read(&iopt->iova_rwsem); in iommufd_access_unpin_pages()
991 mutex_unlock(&access->ioas_lock); in iommufd_access_unpin_pages()
997 if (iopt_area_start_byte(iter->area, iter->cur_iova) % PAGE_SIZE) in iopt_area_contig_is_aligned()
1001 (iopt_area_start_byte(iter->area, iopt_area_last_iova(iter->area)) % in iopt_area_contig_is_aligned()
1002 PAGE_SIZE) != (PAGE_SIZE - 1)) in iopt_area_contig_is_aligned()
1010 return area->iommu_prot & IOMMU_WRITE; in check_area_prot()
1011 return area->iommu_prot & IOMMU_READ; in check_area_prot()
1015 * iommufd_access_pin_pages() - Return a list of pages under the iova
1045 WARN_ON(access->iova_alignment != PAGE_SIZE || !access->ops->unmap)) in iommufd_access_pin_pages()
1046 return -EINVAL; in iommufd_access_pin_pages()
1049 return -EINVAL; in iommufd_access_pin_pages()
1050 if (check_add_overflow(iova, length - 1, &last_iova)) in iommufd_access_pin_pages()
1051 return -EOVERFLOW; in iommufd_access_pin_pages()
1053 mutex_lock(&access->ioas_lock); in iommufd_access_pin_pages()
1054 if (!access->ioas) { in iommufd_access_pin_pages()
1055 mutex_unlock(&access->ioas_lock); in iommufd_access_pin_pages()
1056 return -ENOENT; in iommufd_access_pin_pages()
1058 iopt = &access->ioas->iopt; in iommufd_access_pin_pages()
1060 down_read(&iopt->iova_rwsem); in iommufd_access_pin_pages()
1067 if (area->prevent_access || in iommufd_access_pin_pages()
1069 rc = -EINVAL; in iommufd_access_pin_pages()
1074 rc = -EPERM; in iommufd_access_pin_pages()
1082 out_pages += last_index - index + 1; in iommufd_access_pin_pages()
1085 rc = -ENOENT; in iommufd_access_pin_pages()
1089 up_read(&iopt->iova_rwsem); in iommufd_access_pin_pages()
1090 mutex_unlock(&access->ioas_lock); in iommufd_access_pin_pages()
1095 last_iova = iter.cur_iova - 1; in iommufd_access_pin_pages()
1104 up_read(&iopt->iova_rwsem); in iommufd_access_pin_pages()
1105 mutex_unlock(&access->ioas_lock); in iommufd_access_pin_pages()
1111 * iommufd_access_rw - Read or write data under the iova
1132 return -EINVAL; in iommufd_access_rw()
1133 if (check_add_overflow(iova, length - 1, &last_iova)) in iommufd_access_rw()
1134 return -EOVERFLOW; in iommufd_access_rw()
1136 mutex_lock(&access->ioas_lock); in iommufd_access_rw()
1137 if (!access->ioas) { in iommufd_access_rw()
1138 mutex_unlock(&access->ioas_lock); in iommufd_access_rw()
1139 return -ENOENT; in iommufd_access_rw()
1141 iopt = &access->ioas->iopt; in iommufd_access_rw()
1143 down_read(&iopt->iova_rwsem); in iommufd_access_rw()
1146 unsigned long bytes = (last - iter.cur_iova) + 1; in iommufd_access_rw()
1148 if (area->prevent_access) { in iommufd_access_rw()
1149 rc = -EINVAL; in iommufd_access_rw()
1154 rc = -EPERM; in iommufd_access_rw()
1159 area->pages, iopt_area_start_byte(area, iter.cur_iova), in iommufd_access_rw()
1166 rc = -ENOENT; in iommufd_access_rw()
1168 up_read(&iopt->iova_rwsem); in iommufd_access_rw()
1169 mutex_unlock(&access->ioas_lock); in iommufd_access_rw()
1176 struct iommu_hw_info *cmd = ucmd->cmd; in iommufd_get_hw_info()
1177 void __user *user_ptr = u64_to_user_ptr(cmd->data_uptr); in iommufd_get_hw_info()
1185 if (cmd->flags || cmd->__reserved) in iommufd_get_hw_info()
1186 return -EOPNOTSUPP; in iommufd_get_hw_info()
1188 idev = iommufd_get_device(ucmd, cmd->dev_id); in iommufd_get_hw_info()
1192 ops = dev_iommu_ops(idev->dev); in iommufd_get_hw_info()
1193 if (ops->hw_info) { in iommufd_get_hw_info()
1194 data = ops->hw_info(idev->dev, &data_len, &cmd->out_data_type); in iommufd_get_hw_info()
1204 if (WARN_ON_ONCE(cmd->out_data_type == in iommufd_get_hw_info()
1206 rc = -ENODEV; in iommufd_get_hw_info()
1210 cmd->out_data_type = IOMMU_HW_INFO_TYPE_NONE; in iommufd_get_hw_info()
1215 copy_len = min(cmd->data_len, data_len); in iommufd_get_hw_info()
1217 rc = -EFAULT; in iommufd_get_hw_info()
1225 if (copy_len < cmd->data_len) { in iommufd_get_hw_info()
1226 if (clear_user(user_ptr + copy_len, cmd->data_len - copy_len)) { in iommufd_get_hw_info()
1227 rc = -EFAULT; in iommufd_get_hw_info()
1236 cmd->data_len = data_len; in iommufd_get_hw_info()
1238 cmd->out_capabilities = 0; in iommufd_get_hw_info()
1239 if (device_iommu_capable(idev->dev, IOMMU_CAP_DIRTY_TRACKING)) in iommufd_get_hw_info()
1240 cmd->out_capabilities |= IOMMU_HW_CAP_DIRTY_TRACKING; in iommufd_get_hw_info()
1246 iommufd_put_object(ucmd->ictx, &idev->obj); in iommufd_get_hw_info()