[PATCH 2/4] iommufd: Avoid locking internal accesses during unmap

Shuai Xue <[email protected]> Sun, 26 Jul 2026 15:43:30 +0800
Newsgroups dev.linux.lists.iommu,org.kernel.vger.linux-kernel
Message-ID <e1141361f8850ada55ba4435c5a36b1ccc4eb1a4.1785050951.git.xueshuai@linux.alibaba.com>
iommufd_access_notify_unmap() skips internal accesses because they do
not have an external unmap callback to invoke.

However, the current test calls iommufd_lock_obj() before checking
whether the access is internal. If iommufd_lock_obj() succeeds, the loop
then sees the internal access and continues, bypassing the matching
iommufd_put_object() used by the normal unmap path. This leaks the
object reference taken by iommufd_lock_obj().

Check for internal accesses first so skipped entries are never locked.

Fixes: 27b77ea5feaa ("iommufd/access: Bypass access->ops->unmap for internal use")
Cc: [email protected]
Assisted-by: Qoder:Qwen-3.8-MAX-Preview
Signed-off-by: Shuai Xue <[email protected]>
---
 drivers/iommu/iommufd/device.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/iommufd/device.c b/drivers/iommu/iommufd/device.c
index 170a7005f0bc..e4537db724d5 100644
--- a/drivers/iommu/iommufd/device.c
+++ b/drivers/iommu/iommufd/device.c
@@ -1307,8 +1307,8 @@ void iommufd_access_notify_unmap(struct io_pagetable *iopt, unsigned long iova,
 
 	xa_lock(&ioas->iopt.access_list);
 	xa_for_each(&ioas->iopt.access_list, index, access) {
-		if (!iommufd_lock_obj(&access->obj) ||
-		    iommufd_access_is_internal(access))
+		if (iommufd_access_is_internal(access) ||
+		    !iommufd_lock_obj(&access->obj))
 			continue;
 		xa_unlock(&ioas->iopt.access_list);
 
-- 
2.39.3