lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251202230303.1017519-2-skhawaja@google.com>
Date: Tue,  2 Dec 2025 23:02:31 +0000
From: Samiullah Khawaja <skhawaja@...gle.com>
To: David Woodhouse <dwmw2@...radead.org>, Lu Baolu <baolu.lu@...ux.intel.com>, 
	Joerg Roedel <joro@...tes.org>, Will Deacon <will@...nel.org>, 
	Pasha Tatashin <pasha.tatashin@...een.com>, Jason Gunthorpe <jgg@...pe.ca>, iommu@...ts.linux.dev
Cc: YiFei Zhu <zhuyifei@...gle.com>, Robin Murphy <robin.murphy@....com>, 
	Pratyush Yadav <pratyush@...nel.org>, Samiullah Khawaja <skhawaja@...gle.com>, 
	Kevin Tian <kevin.tian@...el.com>, Alex Williamson <alex@...zbot.org>, linux-kernel@...r.kernel.org, 
	Saeed Mahameed <saeedm@...dia.com>, Adithya Jayachandran <ajayachandra@...dia.com>, 
	Parav Pandit <parav@...dia.com>, Leon Romanovsky <leonro@...dia.com>, William Tu <witu@...dia.com>, 
	Vipin Sharma <vipinsh@...gle.com>, dmatlack@...gle.com, Chris Li <chrisl@...nel.org>, 
	praan@...gle.com
Subject: [RFC PATCH v2 01/32] iommufd: Allow HWPTs to have a NULL IOAS

From: YiFei Zhu <zhuyifei@...gle.com>

Normally HWPTs are created with a parent IOAS to allow the mappings
to be modified. For liveupdate we want an immutable HWPT upon restore,
so no IOAS is needed. This patch prepares iommufd so it would not
crash on a NULL hwpt_paging->ioas.

Signed-off-by: YiFei Zhu <zhuyifei@...gle.com>
---
 drivers/iommu/iommufd/device.c       | 11 ++++++++---
 drivers/iommu/iommufd/hw_pagetable.c | 15 +++++++++++++--
 2 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/drivers/iommu/iommufd/device.c b/drivers/iommu/iommufd/device.c
index 4c842368289f..ba4d9c3cfa8b 100644
--- a/drivers/iommu/iommufd/device.c
+++ b/drivers/iommu/iommufd/device.c
@@ -418,6 +418,7 @@ iommufd_device_attach_reserved_iova(struct iommufd_device *idev,
 
 	lockdep_assert_held(&igroup->lock);
 
+	/* unreachable if !hwpt_paging->ioas */
 	rc = iopt_table_enforce_dev_resv_regions(&hwpt_paging->ioas->iopt,
 						 idev->dev,
 						 &igroup->sw_msi_start);
@@ -603,7 +604,7 @@ int iommufd_hw_pagetable_attach(struct iommufd_hw_pagetable *hwpt,
 				struct iommufd_device *idev, ioasid_t pasid)
 {
 	struct iommufd_hwpt_paging *hwpt_paging = find_hwpt_paging(hwpt);
-	bool attach_resv = hwpt_paging && pasid == IOMMU_NO_PASID;
+	bool attach_resv = hwpt_paging && pasid == IOMMU_NO_PASID && hwpt_paging->ioas;
 	struct iommufd_group *igroup = idev->igroup;
 	struct iommufd_hw_pagetable *old_hwpt;
 	struct iommufd_attach *attach;
@@ -707,7 +708,7 @@ iommufd_hw_pagetable_detach(struct iommufd_device *idev, ioasid_t pasid)
 		xa_erase(&igroup->pasid_attach, pasid);
 		kfree(attach);
 	}
-	if (hwpt_paging && pasid == IOMMU_NO_PASID)
+	if (hwpt_paging && pasid == IOMMU_NO_PASID && hwpt_paging->ioas)
 		iopt_remove_reserved_iova(&hwpt_paging->ioas->iopt, idev->dev);
 	mutex_unlock(&igroup->lock);
 
@@ -739,6 +740,9 @@ iommufd_group_remove_reserved_iova(struct iommufd_group *igroup,
 
 	lockdep_assert_held(&igroup->lock);
 
+	if (!hwpt_paging->ioas)
+		return;
+
 	attach = xa_load(&igroup->pasid_attach, IOMMU_NO_PASID);
 	xa_for_each(&attach->device_array, index, cur)
 		iopt_remove_reserved_iova(&hwpt_paging->ioas->iopt, cur->dev);
@@ -756,6 +760,7 @@ iommufd_group_do_replace_reserved_iova(struct iommufd_group *igroup,
 
 	lockdep_assert_held(&igroup->lock);
 
+	/* unreachable if !hwpt_paging->ioas */
 	attach = xa_load(&igroup->pasid_attach, IOMMU_NO_PASID);
 	old_hwpt_paging = find_hwpt_paging(attach->hwpt);
 	if (!old_hwpt_paging || hwpt_paging->ioas != old_hwpt_paging->ioas) {
@@ -782,7 +787,7 @@ iommufd_device_do_replace(struct iommufd_device *idev, ioasid_t pasid,
 			  struct iommufd_hw_pagetable *hwpt)
 {
 	struct iommufd_hwpt_paging *hwpt_paging = find_hwpt_paging(hwpt);
-	bool attach_resv = hwpt_paging && pasid == IOMMU_NO_PASID;
+	bool attach_resv = hwpt_paging && pasid == IOMMU_NO_PASID && hwpt_paging->ioas;
 	struct iommufd_hwpt_paging *old_hwpt_paging;
 	struct iommufd_group *igroup = idev->igroup;
 	struct iommufd_hw_pagetable *old_hwpt;
diff --git a/drivers/iommu/iommufd/hw_pagetable.c b/drivers/iommu/iommufd/hw_pagetable.c
index fe789c2dc0c9..78d2130e0061 100644
--- a/drivers/iommu/iommufd/hw_pagetable.c
+++ b/drivers/iommu/iommufd/hw_pagetable.c
@@ -23,6 +23,7 @@ void iommufd_hwpt_paging_destroy(struct iommufd_object *obj)
 		container_of(obj, struct iommufd_hwpt_paging, common.obj);
 
 	if (!list_empty(&hwpt_paging->hwpt_item)) {
+		/* unreachable if !hwpt_paging->ioas */
 		mutex_lock(&hwpt_paging->ioas->mutex);
 		list_del(&hwpt_paging->hwpt_item);
 		mutex_unlock(&hwpt_paging->ioas->mutex);
@@ -32,7 +33,9 @@ void iommufd_hwpt_paging_destroy(struct iommufd_object *obj)
 	}
 
 	__iommufd_hwpt_destroy(&hwpt_paging->common);
-	refcount_dec(&hwpt_paging->ioas->obj.users);
+
+	if (hwpt_paging->ioas)
+		refcount_dec(&hwpt_paging->ioas->obj.users);
 }
 
 void iommufd_hwpt_paging_abort(struct iommufd_object *obj)
@@ -41,9 +44,11 @@ void iommufd_hwpt_paging_abort(struct iommufd_object *obj)
 		container_of(obj, struct iommufd_hwpt_paging, common.obj);
 
 	/* The ioas->mutex must be held until finalize is called. */
-	lockdep_assert_held(&hwpt_paging->ioas->mutex);
+	if (hwpt_paging->ioas)
+		lockdep_assert_held(&hwpt_paging->ioas->mutex);
 
 	if (!list_empty(&hwpt_paging->hwpt_item)) {
+		/* unreachable if !hwpt_paging->ioas */
 		list_del_init(&hwpt_paging->hwpt_item);
 		iopt_table_remove_domain(&hwpt_paging->ioas->iopt,
 					 hwpt_paging->common.domain);
@@ -457,6 +462,9 @@ int iommufd_hwpt_set_dirty_tracking(struct iommufd_ucmd *ucmd)
 		return PTR_ERR(hwpt_paging);
 
 	ioas = hwpt_paging->ioas;
+	if (!ioas)
+		return -EINVAL;
+
 	enable = cmd->flags & IOMMU_HWPT_DIRTY_TRACKING_ENABLE;
 
 	rc = iopt_set_dirty_tracking(&ioas->iopt, hwpt_paging->common.domain,
@@ -482,6 +490,9 @@ int iommufd_hwpt_get_dirty_bitmap(struct iommufd_ucmd *ucmd)
 		return PTR_ERR(hwpt_paging);
 
 	ioas = hwpt_paging->ioas;
+	if (!ioas)
+		return -EINVAL;
+
 	rc = iopt_read_and_clear_dirty_data(
 		&ioas->iopt, hwpt_paging->common.domain, cmd->flags, cmd);
 
-- 
2.52.0.158.g65b55ccf14-goog


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ