* [PATCH 0/4] iommu: Fix SVA, iommufd, and iommupt error paths
@ 2026-07-26 7:43 Shuai Xue
2026-07-26 7:43 ` [PATCH 1/4] iommu/sva: Set handle->dev before the SVA handle is visible Shuai Xue
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Shuai Xue @ 2026-07-26 7:43 UTC (permalink / raw)
To: joro, will, robin.murphy, jgg, kevin.tian
Cc: iommu, linux-kernel, oliver.yang, zhuo.song, xueshuai
This series fixes four independent error-path/lifetime issues in the
IOMMU core helpers, iommufd, and generic page table code.
Patch 1 fixes an SVA race where an attach handle becomes visible before
handle->dev is initialized. A racing bind can reuse the handle and later
unbind can dereference a NULL handle->dev.
Patches 2 and 3 fix iommufd reference/lock leaks. Patch 2 avoids taking
an object reference for internal accesses that are skipped by the unmap
notification path. Patch 3 releases the current IOAS rwsem and object
reference if xa_store() fails before the IOAS is inserted into the
unwind list.
Patch 4 fixes the generic page table iova_to_phys() op to return 0 on
range validation failures. Returning a negative errno from a phys_addr_t
function can make callers consume a bogus physical address.
All patches are small fixes with Fixes tags and Cc: stable.
Shuai Xue (4):
iommu/sva: Set handle->dev before the SVA handle is visible
iommufd: Avoid locking internal accesses during unmap
iommufd: Release current IOAS on xa_store() failure
iommupt: Return zero for invalid iova_to_phys() ranges
drivers/iommu/generic_pt/iommu_pt.h | 2 +-
drivers/iommu/iommu-sva.c | 2 +-
drivers/iommu/iommufd/device.c | 4 ++--
drivers/iommu/iommufd/ioas.c | 2 ++
4 files changed, 6 insertions(+), 4 deletions(-)
--
2.39.3
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/4] iommu/sva: Set handle->dev before the SVA handle is visible
2026-07-26 7:43 [PATCH 0/4] iommu: Fix SVA, iommufd, and iommupt error paths Shuai Xue
@ 2026-07-26 7:43 ` Shuai Xue
2026-07-26 7:43 ` [PATCH 2/4] iommufd: Avoid locking internal accesses during unmap Shuai Xue
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Shuai Xue @ 2026-07-26 7:43 UTC (permalink / raw)
To: joro, will, robin.murphy, jgg, kevin.tian
Cc: iommu, linux-kernel, oliver.yang, zhuo.song, xueshuai
iommu_attach_device_pasid() installs the new SVA attach handle in the
group PASID lookup before iommu_sva_bind_device() returns. A concurrent
bind can therefore find and reuse the same handle after iommu_sva_lock is
dropped.
handle->dev was initialized after dropping iommu_sva_lock. This leaves a
window where a racing bind can return a handle whose dev pointer is still
NULL. A subsequent iommu_sva_unbind_device() can then dereference it via
handle->dev->iommu_group.
Initialize handle->dev before releasing iommu_sva_lock so any visible SVA
handle is fully initialized.
Fixes: be51b1d6bbff ("iommu/sva: Refactoring iommu_sva_bind/unbind_device()")
Cc: stable@vger.kernel.org
Assisted-by: Qoder:Qwen-3.8-MAX-Preview
Signed-off-by: Shuai Xue <xueshuai@linux.alibaba.com>
---
drivers/iommu/iommu-sva.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iommu/iommu-sva.c b/drivers/iommu/iommu-sva.c
index bc7c7232a43e..9742cb593577 100644
--- a/drivers/iommu/iommu-sva.c
+++ b/drivers/iommu/iommu-sva.c
@@ -145,8 +145,8 @@ struct iommu_sva *iommu_sva_bind_device(struct device *dev, struct mm_struct *mm
list_add(&domain->next, &iommu_mm->sva_domains);
out:
refcount_set(&handle->users, 1);
- mutex_unlock(&iommu_sva_lock);
handle->dev = dev;
+ mutex_unlock(&iommu_sva_lock);
return handle;
out_free_domain:
--
2.39.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/4] iommufd: Avoid locking internal accesses during unmap
2026-07-26 7:43 [PATCH 0/4] iommu: Fix SVA, iommufd, and iommupt error paths Shuai Xue
2026-07-26 7:43 ` [PATCH 1/4] iommu/sva: Set handle->dev before the SVA handle is visible Shuai Xue
@ 2026-07-26 7:43 ` Shuai Xue
2026-07-26 7:43 ` [PATCH 3/4] iommufd: Release current IOAS on xa_store() failure Shuai Xue
2026-07-26 7:43 ` [PATCH 4/4] iommupt: Return zero for invalid iova_to_phys() ranges Shuai Xue
3 siblings, 0 replies; 5+ messages in thread
From: Shuai Xue @ 2026-07-26 7:43 UTC (permalink / raw)
To: joro, will, robin.murphy, jgg, kevin.tian
Cc: iommu, linux-kernel, oliver.yang, zhuo.song, xueshuai
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: stable@vger.kernel.org
Assisted-by: Qoder:Qwen-3.8-MAX-Preview
Signed-off-by: Shuai Xue <xueshuai@linux.alibaba.com>
---
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
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 3/4] iommufd: Release current IOAS on xa_store() failure
2026-07-26 7:43 [PATCH 0/4] iommu: Fix SVA, iommufd, and iommupt error paths Shuai Xue
2026-07-26 7:43 ` [PATCH 1/4] iommu/sva: Set handle->dev before the SVA handle is visible Shuai Xue
2026-07-26 7:43 ` [PATCH 2/4] iommufd: Avoid locking internal accesses during unmap Shuai Xue
@ 2026-07-26 7:43 ` Shuai Xue
2026-07-26 7:43 ` [PATCH 4/4] iommupt: Return zero for invalid iova_to_phys() ranges Shuai Xue
3 siblings, 0 replies; 5+ messages in thread
From: Shuai Xue @ 2026-07-26 7:43 UTC (permalink / raw)
To: joro, will, robin.murphy, jgg, kevin.tian
Cc: iommu, linux-kernel, oliver.yang, zhuo.song, xueshuai
iommufd_take_all_iova_rwsem() takes an object reference and the
iova_rwsem write lock before storing the IOAS in the temporary ioas_list
xarray.
If xa_store() fails, the current IOAS has not been inserted into
ioas_list yet. iommufd_release_all_iova_rwsem() only unwinds IOAS
objects already present in that xarray, so it cannot release the current
IOAS.
Release the current IOAS rwsem and object reference before unwinding the
previously stored entries.
Fixes: 051ae5aa73d7 ("iommufd: Lock all IOAS objects")
Cc: stable@vger.kernel.org
Assisted-by: Qoder:Qwen-3.8-MAX-Preview
Signed-off-by: Shuai Xue <xueshuai@linux.alibaba.com>
---
drivers/iommu/iommufd/ioas.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/iommu/iommufd/ioas.c b/drivers/iommu/iommufd/ioas.c
index fed06c2b728e..28616465ea6a 100644
--- a/drivers/iommu/iommufd/ioas.c
+++ b/drivers/iommu/iommufd/ioas.c
@@ -427,6 +427,8 @@ static int iommufd_take_all_iova_rwsem(struct iommufd_ctx *ictx,
rc = xa_err(xa_store(ioas_list, index, ioas, GFP_KERNEL));
if (rc) {
+ up_write(&ioas->iopt.iova_rwsem);
+ refcount_dec(&ioas->obj.users);
iommufd_release_all_iova_rwsem(ictx, ioas_list);
return rc;
}
--
2.39.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 4/4] iommupt: Return zero for invalid iova_to_phys() ranges
2026-07-26 7:43 [PATCH 0/4] iommu: Fix SVA, iommufd, and iommupt error paths Shuai Xue
` (2 preceding siblings ...)
2026-07-26 7:43 ` [PATCH 3/4] iommufd: Release current IOAS on xa_store() failure Shuai Xue
@ 2026-07-26 7:43 ` Shuai Xue
3 siblings, 0 replies; 5+ messages in thread
From: Shuai Xue @ 2026-07-26 7:43 UTC (permalink / raw)
To: joro, will, robin.murphy, jgg, kevin.tian
Cc: iommu, linux-kernel, oliver.yang, zhuo.song, xueshuai
DOMAIN_NS(iova_to_phys) returns a phys_addr_t and follows the IOMMU
iova_to_phys() convention of returning 0 when there is no valid
translation.
make_range() returns a negative errno if the input IOVA cannot be
represented by this page table format. Returning that errno directly
casts it to phys_addr_t. Callers treat zero as no translation and use
non-zero values as physical addresses, so this can make them consume a
bogus physical address instead of seeing a failed translation.
Match the page-table walk failure path and return 0 for range validation
failures too.
Fixes: 9d4c274cd7d5 ("iommupt: Add iova_to_phys op")
Cc: stable@vger.kernel.org
Assisted-by: Qoder:Qwen-3.8-MAX-Preview
Signed-off-by: Shuai Xue <xueshuai@linux.alibaba.com>
---
drivers/iommu/generic_pt/iommu_pt.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iommu/generic_pt/iommu_pt.h b/drivers/iommu/generic_pt/iommu_pt.h
index c2752151c80a..07ec2b3ab986 100644
--- a/drivers/iommu/generic_pt/iommu_pt.h
+++ b/drivers/iommu/generic_pt/iommu_pt.h
@@ -224,7 +224,7 @@ phys_addr_t DOMAIN_NS(iova_to_phys)(struct iommu_domain *domain,
ret = make_range(common_from_iommu(iommu_table), &range, iova, 1);
if (ret)
- return ret;
+ return 0;
ret = pt_walk_range(&range, __iova_to_phys, &res);
/* PHYS_ADDR_MAX would be a better error code */
--
2.39.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-07-26 7:43 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-26 7:43 [PATCH 0/4] iommu: Fix SVA, iommufd, and iommupt error paths Shuai Xue
2026-07-26 7:43 ` [PATCH 1/4] iommu/sva: Set handle->dev before the SVA handle is visible Shuai Xue
2026-07-26 7:43 ` [PATCH 2/4] iommufd: Avoid locking internal accesses during unmap Shuai Xue
2026-07-26 7:43 ` [PATCH 3/4] iommufd: Release current IOAS on xa_store() failure Shuai Xue
2026-07-26 7:43 ` [PATCH 4/4] iommupt: Return zero for invalid iova_to_phys() ranges Shuai Xue
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox