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. --- 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) -- 2.48.1