On 02.09.25 01:10, Mykola Kvach wrote:

Hello Mykola

From: Oleksandr Tyshchenko <oleksandr_tyshche...@epam.com>

This is done using generic iommu_suspend/resume functions that cause
IOMMU driver specific suspend/resume handlers to be called for enabled
IOMMU (if one has suspend/resume driver handlers implemented).

Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshche...@epam.com>
Signed-off-by: Mykola Kvach <mykola_kv...@epam.com>
---
Changes in V6:
- Drop iommu_enabled check from host system suspend.

I do not have any comments for the updated version, thanks.


---
  xen/arch/arm/suspend.c                | 11 +++++++++++
  xen/drivers/passthrough/arm/smmu-v3.c | 10 ++++++++++
  xen/drivers/passthrough/arm/smmu.c    | 10 ++++++++++
  3 files changed, 31 insertions(+)

diff --git a/xen/arch/arm/suspend.c b/xen/arch/arm/suspend.c
index 35b20581f1..f3a3b831c5 100644
--- a/xen/arch/arm/suspend.c
+++ b/xen/arch/arm/suspend.c
@@ -5,6 +5,7 @@
#include <xen/console.h>
  #include <xen/cpu.h>
+#include <xen/iommu.h>
  #include <xen/llc-coloring.h>
  #include <xen/sched.h>
  #include <xen/tasklet.h>
@@ -62,6 +63,13 @@ static void cf_check system_suspend(void *data)
time_suspend(); + status = iommu_suspend();
+    if ( status )
+    {
+        system_state = SYS_STATE_resume;
+        goto resume_time;
+    }
+
      console_start_sync();
      status = console_suspend();
      if ( status )
@@ -118,6 +126,9 @@ static void cf_check system_suspend(void *data)
      console_resume();
      console_end_sync();
+ iommu_resume();
+
+ resume_time:
      time_resume();
resume_nonboot_cpus:
diff --git a/xen/drivers/passthrough/arm/smmu-v3.c 
b/xen/drivers/passthrough/arm/smmu-v3.c
index 81071f4018..f887faf7dc 100644
--- a/xen/drivers/passthrough/arm/smmu-v3.c
+++ b/xen/drivers/passthrough/arm/smmu-v3.c
@@ -2854,6 +2854,13 @@ static void arm_smmu_iommu_xen_domain_teardown(struct 
domain *d)
        xfree(xen_domain);
  }
+#ifdef CONFIG_SYSTEM_SUSPEND
+static int arm_smmu_suspend(void)
+{
+       return -ENOSYS;
+}
+#endif
+
  static const struct iommu_ops arm_smmu_iommu_ops = {
        .page_sizes             = PAGE_SIZE_4K,
        .init                   = arm_smmu_iommu_xen_domain_init,
@@ -2866,6 +2873,9 @@ static const struct iommu_ops arm_smmu_iommu_ops = {
        .unmap_page             = arm_iommu_unmap_page,
        .dt_xlate               = arm_smmu_dt_xlate,
        .add_device             = arm_smmu_add_device,
+#ifdef CONFIG_SYSTEM_SUSPEND
+       .suspend                = arm_smmu_suspend,
+#endif
  };
static __init int arm_smmu_dt_init(struct dt_device_node *dev,
diff --git a/xen/drivers/passthrough/arm/smmu.c 
b/xen/drivers/passthrough/arm/smmu.c
index 22d306d0cb..45f29ef8ec 100644
--- a/xen/drivers/passthrough/arm/smmu.c
+++ b/xen/drivers/passthrough/arm/smmu.c
@@ -2947,6 +2947,13 @@ static void arm_smmu_iommu_domain_teardown(struct domain 
*d)
        xfree(xen_domain);
  }
+#ifdef CONFIG_SYSTEM_SUSPEND
+static int arm_smmu_suspend(void)
+{
+       return -ENOSYS;
+}
+#endif
+
  static const struct iommu_ops arm_smmu_iommu_ops = {
      .page_sizes = PAGE_SIZE_4K,
      .init = arm_smmu_iommu_domain_init,
@@ -2960,6 +2967,9 @@ static const struct iommu_ops arm_smmu_iommu_ops = {
      .map_page = arm_iommu_map_page,
      .unmap_page = arm_iommu_unmap_page,
      .dt_xlate = arm_smmu_dt_xlate_generic,
+#ifdef CONFIG_SYSTEM_SUSPEND
+    .suspend = arm_smmu_suspend,
+#endif
  };
static struct arm_smmu_device *find_smmu(const struct device *dev)


Reply via email to