Re: [PATCH v3 12/18] iommu/vt-d: Handle reattach of the restored domain
From: Baolu Lu
Date: Sun Jul 12 2026 - 06:27:44 EST
On 6/23/2026 8:26 AM, Samiullah Khawaja wrote:
On Mon, Jun 22, 2026 at 01:44:06PM +0800, Baolu Lu wrote:
On 6/15/26 07:37, Samiullah Khawaja wrote:
Reattach the restored domain to the preserved device using restored
domain ID. While reattaching do not setup the context and PASID entries
as those are preserved during liveupdate.
Signed-off-by: Samiullah Khawaja<skhawaja@xxxxxxxxxx>
---
drivers/iommu/intel/iommu.c | 46 ++++++++++---
drivers/iommu/intel/iommu.h | 17 +++++
drivers/iommu/intel/liveupdate.c | 111 +++++++++++++++++++++++++++++++
3 files changed, 163 insertions(+), 11 deletions(-)
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index cd40e274482b..91b67ccba011 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -1311,10 +1311,16 @@ static int dmar_domain_attach_device(struct dmar_domain *domain,
{
struct device_domain_info *info = dev_iommu_priv_get(dev);
struct intel_iommu *iommu = info->iommu;
+ struct iommu_device_ser *device_ser;
unsigned long flags;
int ret;
- ret = domain_attach_iommu(domain, iommu);
+ device_ser = dev_iommu_restored_state(dev);
+ if (!device_ser)
+ ret = domain_attach_iommu(domain, iommu);
+ else
+ ret = intel_iommu_domain_reattach_iommu(domain,
+ iommu, device_ser);
if (ret)
return ret;
@@ -1327,16 +1333,20 @@ static int dmar_domain_attach_device(struct dmar_domain *domain,
if (dev_is_real_dma_subdevice(dev))
return 0;
- if (!sm_supported(iommu))
- ret = domain_context_mapping(domain, dev);
- else if (intel_domain_is_fs_paging(domain))
- ret = domain_setup_first_level(iommu, domain, dev,
- IOMMU_NO_PASID, NULL);
- else if (intel_domain_is_ss_paging(domain))
- ret = domain_setup_second_level(iommu, domain, dev,
- IOMMU_NO_PASID, NULL);
- else if (WARN_ON(true))
- ret = -EINVAL;
+ if (!device_ser) {
+ if (!sm_supported(iommu))
+ ret = domain_context_mapping(domain, dev);
+ else if (intel_domain_is_fs_paging(domain))
+ ret = domain_setup_first_level(iommu, domain, dev,
+ IOMMU_NO_PASID, NULL);
+ else if (intel_domain_is_ss_paging(domain))
+ ret = domain_setup_second_level(iommu, domain, dev,
+ IOMMU_NO_PASID, NULL);
+ else if (WARN_ON(true))
+ ret = -EINVAL;
+ } else if (!sm_supported(iommu)) {
+ iommu_enable_pci_ats(info);
+ }
Instead of merging domain restoration into the attach_dev path, how
about adding a new callback to restore a preserved domain for a device?
Even with a new callback, the driver still just fetches the restored
state and takes a different path. I am guessing we can just do the
following inside the driver to keep it clean:
static int intel_iommu_attach_device(struct iommu_domain *domain,
struct device *dev,
struct iommu_domain *old)
{
struct iommu_device_ser *device_ser = dev_iommu_restored_state(dev);
if (device_ser)
return _intel_iommu_restore_dev(domain, dev, device_ser);
return _intel_iommu_attach_device(domain, dev, old);
}
This keeps the separation you want without touching the generic ops.
WDYT?
With the new callback, this check is just moved into the core inside
__iommu_attach_device(). I am concerned that later down the road when we
add PASID support, we will add restore_dev_pasid().
Okay, that also works for me.
Thanks,
baolu