Re: [PATCH v2 10/16] iommu: Restore and reattach preserved domains to devices

From: Samiullah Khawaja

Date: Fri May 29 2026 - 13:04:03 EST


On Fri, May 29, 2026 at 04:43:42PM +0000, Ankit Soni wrote:
On Mon, Apr 27, 2026 at 05:56:27PM +0000, Samiullah Khawaja wrote:
Restore the preserved domains by restoring the page tables using restore
IOMMU domain op. Reattach the preserved domain to the device during
default domain setup. While attaching, reuse the domain ID that was used
in the previous kernel. The context entry setup is not needed as that is
preserved during liveupdate.

Signed-off-by: Samiullah Khawaja <skhawaja@xxxxxxxxxx>
---
drivers/iommu/intel/iommu.c | 49 ++++++++++++++------
drivers/iommu/intel/iommu.h | 3 +-
drivers/iommu/intel/nested.c | 2 +-
drivers/iommu/iommu.c | 61 ++++++++++++++++++++++++-
drivers/iommu/liveupdate.c | 78 ++++++++++++++++++++++++++++++++
include/linux/iommu-liveupdate.h | 50 ++++++++++++++++++++
6 files changed, 224 insertions(+), 19 deletions(-)

diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 4118a0861f38..b90757164cd8 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -1031,7 +1031,8 @@ static bool first_level_by_default(struct intel_iommu *iommu)
return true;
}

-int domain_attach_iommu(struct dmar_domain *domain, struct intel_iommu *iommu)
+int domain_attach_iommu(struct dmar_domain *domain, struct intel_iommu *iommu,
+ int restore_did)
{
struct iommu_domain_info *info, *curr;
int num, ret = -ENOSPC;
@@ -1051,8 +1052,11 @@ int domain_attach_iommu(struct dmar_domain *domain, struct intel_iommu *iommu)
return 0;
}

- num = ida_alloc_range(&iommu->domain_ida, IDA_START_DID,
- cap_ndoms(iommu->cap) - 1, GFP_KERNEL);
+ if (restore_did >= IDA_START_DID)
+ num = restore_did;
+ else
+ num = ida_alloc_range(&iommu->domain_ida, IDA_START_DID,
+ cap_ndoms(iommu->cap) - 1, GFP_KERNEL);
if (num < 0) {
pr_err("%s: No free domain ids\n", iommu->name);
goto err_unlock;
@@ -1320,10 +1324,14 @@ 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 device_ser *device_ser = NULL;

Typo here? iommu_device_ser.
compiles because dev_iommu_restored_state() returns void * and the
variable is only null-checked, never dereferenced.

Agreed. Will update this.

Ankit

unsigned long flags;
int ret;

- ret = domain_attach_iommu(domain, iommu);
+ device_ser = dev_iommu_restored_state(dev);
+
+ ret = domain_attach_iommu(domain, iommu,
+ dev_iommu_restore_did(dev, &domain->domain));
if (ret)
return ret;


[snip]
static inline struct iommu_hw_ser *iommu_get_preserved_data(u64 token, enum iommu_type_ser type)
{
return NULL;
--
2.54.0.545.g6539524ca2-goog


Thanks,
Sami