[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251202230303.1017519-31-skhawaja@google.com>
Date: Tue, 2 Dec 2025 23:03:00 +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: Samiullah Khawaja <skhawaja@...gle.com>, Robin Murphy <robin.murphy@....com>,
Pratyush Yadav <pratyush@...nel.org>, 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, YiFei Zhu <zhuyifei@...gle.com>,
Chris Li <chrisl@...nel.org>, praan@...gle.com
Subject: [RFC PATCH v2 30/32] iommu: Transfer device ownership after liveupdate
Get the token of the preserved device and use that to reclaim the
ownership of the preserved device.
Signed-off-by: Samiullah Khawaja <skhawaja@...gle.com>
---
drivers/iommu/iommu.c | 23 ++++++++++++++---------
drivers/iommu/iommufd/device.c | 6 ++++--
drivers/vfio/iommufd.c | 7 ++++++-
drivers/vfio/pci/vfio_pci_liveupdate.c | 1 +
include/linux/iommu.h | 2 +-
include/linux/iommufd.h | 3 ++-
include/linux/vfio.h | 4 ++++
7 files changed, 32 insertions(+), 14 deletions(-)
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 07453611cf8e..ad47597baa04 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -3297,20 +3297,24 @@ static int __iommu_group_alloc_blocking_domain(struct iommu_group *group)
return 0;
}
-static int __iommu_take_dma_ownership(struct iommu_group *group, void *owner)
+static int __iommu_take_dma_ownership(struct iommu_group *group, void *owner, bool transfer)
{
int ret;
- if ((group->domain && group->domain != group->default_domain) ||
- !xa_empty(&group->pasid_array))
+ if (!transfer &&
+ ((group->domain && group->domain != group->default_domain) ||
+ !xa_empty(&group->pasid_array)))
return -EBUSY;
ret = __iommu_group_alloc_blocking_domain(group);
if (ret)
return ret;
- ret = __iommu_group_set_domain(group, group->blocking_domain);
- if (ret)
- return ret;
+
+ if (!transfer) {
+ ret = __iommu_group_set_domain(group, group->blocking_domain);
+ if (ret)
+ return ret;
+ }
group->owner = owner;
group->owner_cnt++;
@@ -3339,7 +3343,7 @@ int iommu_group_claim_dma_owner(struct iommu_group *group, void *owner)
goto unlock_out;
}
- ret = __iommu_take_dma_ownership(group, owner);
+ ret = __iommu_take_dma_ownership(group, owner, false);
unlock_out:
mutex_unlock(&group->mutex);
@@ -3351,12 +3355,13 @@ EXPORT_SYMBOL_GPL(iommu_group_claim_dma_owner);
* iommu_device_claim_dma_owner() - Set DMA ownership of a device
* @dev: The device.
* @owner: Caller specified pointer. Used for exclusive ownership.
+ * @transfer: Transfer ownership even if domain attached.
*
* Claim the DMA ownership of a device. Multiple devices in the same group may
* concurrently claim ownership if they present the same owner value. Returns 0
* on success and error code on failure
*/
-int iommu_device_claim_dma_owner(struct device *dev, void *owner)
+int iommu_device_claim_dma_owner(struct device *dev, void *owner, bool transfer)
{
/* Caller must be a probed driver on dev */
struct iommu_group *group = dev->iommu_group;
@@ -3378,7 +3383,7 @@ int iommu_device_claim_dma_owner(struct device *dev, void *owner)
goto unlock_out;
}
- ret = __iommu_take_dma_ownership(group, owner);
+ ret = __iommu_take_dma_ownership(group, owner, transfer);
unlock_out:
mutex_unlock(&group->mutex);
return ret;
diff --git a/drivers/iommu/iommufd/device.c b/drivers/iommu/iommufd/device.c
index 2c81bfa7dedd..c7b48de53f66 100644
--- a/drivers/iommu/iommufd/device.c
+++ b/drivers/iommu/iommufd/device.c
@@ -205,6 +205,7 @@ void iommufd_device_destroy(struct iommufd_object *obj)
* @ictx: iommufd file descriptor
* @dev: Pointer to a physical device struct
* @id: Output ID number to return to userspace for this device
+ * @restore_token: Preserved state token if restoring.
*
* A successful bind establishes an ownership over the device and returns
* struct iommufd_device pointer, otherwise returns error pointer.
@@ -217,7 +218,8 @@ void iommufd_device_destroy(struct iommufd_object *obj)
* The caller must undo this with iommufd_device_unbind()
*/
struct iommufd_device *iommufd_device_bind(struct iommufd_ctx *ictx,
- struct device *dev, u32 *id)
+ struct device *dev, u32 *id,
+ u32 restore_token)
{
struct iommufd_device *idev;
struct iommufd_group *igroup;
@@ -254,7 +256,7 @@ struct iommufd_device *iommufd_device_bind(struct iommufd_ctx *ictx,
"Use the \"allow_unsafe_interrupts\" module parameter to override\n");
}
- rc = iommu_device_claim_dma_owner(dev, ictx);
+ rc = iommu_device_claim_dma_owner(dev, ictx, restore_token);
if (rc)
goto out_group_put;
diff --git a/drivers/vfio/iommufd.c b/drivers/vfio/iommufd.c
index a38d262c6028..57f0f395408d 100644
--- a/drivers/vfio/iommufd.c
+++ b/drivers/vfio/iommufd.c
@@ -118,8 +118,13 @@ int vfio_iommufd_physical_bind(struct vfio_device *vdev,
struct iommufd_ctx *ictx, u32 *out_device_id)
{
struct iommufd_device *idev;
+ u32 restore_token = 0;
- idev = iommufd_device_bind(ictx, vdev->dev, out_device_id);
+#ifdef CONFIG_LIVEUPDATE
+ restore_token = vdev->preserved_iommufd_token;
+#endif
+
+ idev = iommufd_device_bind(ictx, vdev->dev, out_device_id, restore_token);
if (IS_ERR(idev))
return PTR_ERR(idev);
vdev->iommufd_device = idev;
diff --git a/drivers/vfio/pci/vfio_pci_liveupdate.c b/drivers/vfio/pci/vfio_pci_liveupdate.c
index b721080599d5..208a0b60c10e 100644
--- a/drivers/vfio/pci/vfio_pci_liveupdate.c
+++ b/drivers/vfio/pci/vfio_pci_liveupdate.c
@@ -205,6 +205,7 @@ static int vfio_pci_liveupdate_retrieve(struct liveupdate_file_op_args *args)
vdev = container_of(device, struct vfio_pci_core_device, vdev);
vdev->liveupdate_state = ser;
+ device->preserved_iommufd_token = ser->iommufd_ser.token;
args->file = file;
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 45da5b88f35d..111a892fba1b 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -1211,7 +1211,7 @@ int iommu_group_claim_dma_owner(struct iommu_group *group, void *owner);
void iommu_group_release_dma_owner(struct iommu_group *group);
bool iommu_group_dma_owner_claimed(struct iommu_group *group);
-int iommu_device_claim_dma_owner(struct device *dev, void *owner);
+int iommu_device_claim_dma_owner(struct device *dev, void *owner, bool transfer);
void iommu_device_release_dma_owner(struct device *dev);
int iommu_attach_device_pasid(struct iommu_domain *domain,
diff --git a/include/linux/iommufd.h b/include/linux/iommufd.h
index ba433fb1a481..59d31c76f50d 100644
--- a/include/linux/iommufd.h
+++ b/include/linux/iommufd.h
@@ -60,7 +60,8 @@ struct iommufd_object {
};
struct iommufd_device *iommufd_device_bind(struct iommufd_ctx *ictx,
- struct device *dev, u32 *id);
+ struct device *dev, u32 *id,
+ u32 restore_token);
void iommufd_device_unbind(struct iommufd_device *idev);
int iommufd_device_attach(struct iommufd_device *idev, ioasid_t pasid,
diff --git a/include/linux/vfio.h b/include/linux/vfio.h
index 0e9df71e17ab..eacdc025e26a 100644
--- a/include/linux/vfio.h
+++ b/include/linux/vfio.h
@@ -80,6 +80,10 @@ struct vfio_device {
*/
struct dentry *debug_root;
#endif
+
+#ifdef CONFIG_LIVEUPDATE
+ u32 preserved_iommufd_token;
+#endif
};
struct vfio_device_file {
--
2.52.0.158.g65b55ccf14-goog
Powered by blists - more mailing lists