RE: [PATCH] iommufd/device: Enforce reserved IOVA also when attached to hwpt_nested
From: Tian, Kevin
Date: Mon Aug 05 2024 - 03:40:55 EST
> From: Nicolin Chen <nicolinc@xxxxxxxxxx>
> Sent: Friday, August 2, 2024 1:35 PM
>
> static int
> -iommufd_group_do_replace_paging(struct iommufd_group *igroup,
> - struct iommufd_hwpt_paging *hwpt_paging)
> +iommufd_group_do_replace_reserved_iova(struct iommufd_group *igroup,
> + struct iommufd_hw_pagetable *hwpt)
> {
> + struct iommufd_hwpt_paging *hwpt_paging =
> to_hwpt_paging(hwpt);
> struct iommufd_hw_pagetable *old_hwpt = igroup->hwpt;
> struct iommufd_device *cur;
> int rc;
>
> lockdep_assert_held(&igroup->lock);
>
> - if (!hwpt_is_paging(old_hwpt) ||
> - hwpt_paging->ioas != to_hwpt_paging(old_hwpt)->ioas) {
> + if (!hwpt_paging)
> + return 0;
> +
> + if (iommufd_hw_pagetable_compare_ioas(old_hwpt, hwpt)) {
hmm this change is broken. In this helper:
if (!old_hwpt_paging || !new_hwpt_paging)
return false;
return old_hwpt_paging->ioas != new_hwpt_paging->ioas;
Obviously the original code wants to enforce reserved regions if
new_hwpt is paging && old_hwpt is not paging, but this change
skips this scenario.
>
> rc = iommufd_hwpt_replace_device(idev, hwpt, old_hwpt);
> if (rc)
> goto err_unresv;
>
> - if (hwpt_is_paging(old_hwpt) &&
> - (!hwpt_is_paging(hwpt) ||
> - to_hwpt_paging(hwpt)->ioas != to_hwpt_paging(old_hwpt)->ioas))
> - iommufd_group_remove_reserved_iova(igroup,
> - to_hwpt_paging(old_hwpt));
> + if (iommufd_hw_pagetable_compare_ioas(old_hwpt, hwpt))
> + iommufd_group_remove_reserved_iova(igroup, old_hwpt);
this is also broken.
Probably it's clearer to continue open-coding those conditions in
iommufd_group_do_replace_reserved_iova() and
iommufd_group_remove_reserved_iova().