From nobody Fri Oct 31 03:46:10 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1754945351; cv=none; d=zohomail.com; s=zohoarc; b=eAw62I7cGrBSJRWQLxTXMLEBJT1Wp/6TET4YpXdZ//BvUfvy5B/mXNc7oL83Ip1IU03ggMBhZ1W5++gvlH1VNiCjUzm9S3TiT4Be1g8QXCRpKU0BVRYo1e0w2mIQaeQWMh8t5MZ63gwKH89JxRa7+Jr1FopCTZ7jrG2uyTbcQic= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1754945351; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=Jf3vC/bMLxsK+qQIEq63MqPOkecni+X3pTICciqQJuw=; b=Knenk4bsXJUYtMIudQiMXDz1fJyD1ZvblbjFPaxpkCBkxPsTxZNeV0vke78vX47AL84Kqx6yzYopui75RTyYNyxBu8nqtUMOeBL8WaCfhFT/qL2ac4i+vVkCGYPLceLNsEOuMCLZLu3/GPUhV5D43qsSd2OdlaY34cMbgQZmBV4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1754945351115399.76058786236854; Mon, 11 Aug 2025 13:49:11 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1077945.1438966 (Exim 4.92) (envelope-from ) id 1ulZRu-00065X-Be; Mon, 11 Aug 2025 20:48:54 +0000 Received: by outflank-mailman (output) from mailman id 1077945.1438966; Mon, 11 Aug 2025 20:48:54 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1ulZRu-00065P-8R; Mon, 11 Aug 2025 20:48:54 +0000 Received: by outflank-mailman (input) for mailman id 1077945; Mon, 11 Aug 2025 20:48:53 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1ulZRt-00063z-8g for xen-devel@lists.xenproject.org; Mon, 11 Aug 2025 20:48:53 +0000 Received: from mail-ej1-x629.google.com (mail-ej1-x629.google.com [2a00:1450:4864:20::629]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 95fa957c-76f4-11f0-b898-0df219b8e170; Mon, 11 Aug 2025 22:48:51 +0200 (CEST) Received: by mail-ej1-x629.google.com with SMTP id a640c23a62f3a-af66f444488so681718366b.0 for ; Mon, 11 Aug 2025 13:48:51 -0700 (PDT) Received: from yp-VivoBook-ASUSLaptop-M1503QA-M1503QA.Dlink ([77.52.179.38]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-af91a0a3bd2sm2065710466b.54.2025.08.11.13.48.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 11 Aug 2025 13:48:49 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 95fa957c-76f4-11f0-b898-0df219b8e170 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1754945330; x=1755550130; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Jf3vC/bMLxsK+qQIEq63MqPOkecni+X3pTICciqQJuw=; b=OlN1c0VwLF7hxXz4fD6XS4+JI+erNwONBy1g1LW22l7j4/87QIS+XlCDbjla1rVvKh Y7iqkxgXrTkvwKNGjFeVOTjmtyBPn56+d18/yYYEDA/7R/r2LE6J+LsiYpNvOt27t1A1 +0mjuVYO22aOju+KscwFgAzcYmSnc99EljxyOuK7xSCq5mHyiVQg0bKFTBMbX9pkM1QU ULzQrWqqQsDpO3fg+VhSm6TRL19lCX7ECDTMZ8TuTinzjX6DSM6zpzXtHhVDuqznvIUf o0DurDNnCtkRdC+2vcpl1kx23EVeXqef5kyQQBYnq2hTkVrwWSpWtrVO32wY9PK5V1ie J3tw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1754945330; x=1755550130; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Jf3vC/bMLxsK+qQIEq63MqPOkecni+X3pTICciqQJuw=; b=kDn+byP24nuv5IQHaGffR+TWubMbuudds9ZhM+p5nSCLHxMuZYssUp2W5yBKiyFWLv FcX2dD9ady9TRq4a3zpZeu/d/D0gH94SLoCXaa+VxGXEjXTnaZWYMJhv3XR0i9Ft1lqJ LJstCaamroOgwOC4jODlWdXbkHvNvP4hmeosNrKA+w9rdmtEXU2Qwz2cDPD7Tv56o2Gc 9Hqm3jJZQmkpKowzVvfnzzOXT9wxpf97zRTpoBzCBFy3+iS1sQF9nR8gs5h9KegnC5Gb WRF5ypK788C2ph9nmkFwZX5OIaXITjfOxhMjrpLubBVuLWrw1ul3GEcl+dOzAZn1p2oO 0J6Q== X-Gm-Message-State: AOJu0YxhQpNPk6pFEca3yFRtC+SLR0THyHIPFybdl23iTyLRLcWWrW0K LguHCJ5uFkFVm2+QBjKyFYC62xQu547+S4xpfPqhKFYOvy5n/IxyW9L36ikkHQ== X-Gm-Gg: ASbGncsUOZdk5s++PDxftvmCbgRgGov9T2w3IFZPYuDoFS3l1FlJnh8nsJ8d+W+JsvK kIRgdRJmj+2UQ5IKcNaJF3BRt3H43wa4StTU5bWPmNHtbhEy9zDWyXqqhW8TFHiFSGOIWFEFKcm SF93j15TCfHpC0dlPEumN0ADy0GKcS5QrgEVT0rKlj/3wt2A15/Qovv8+UXp8mNoQT3xB53YIVJ M8PcO4qeyq/Ky4y3YA9pJk1kMnXn04HwN2YKPZy5M+i59fFNp5/OAc5zi5CavPWtp+azW1sjBs6 nvRBzt94ZQOJInV0DEf3q2vTIs9RBZMZYJtCTyRLwyvoES8uPOBCrvRg94sctcn8UqsJR5YEkB8 35qMfSbGvWCF5U/qMK5flN8OijCBKx6pFY6getDKJRDhxqqTfVY0aXSF91NrCz7Vr1aBsgyJY+v xm0g== X-Google-Smtp-Source: AGHT+IFBO8GBEBI4lp8QB14504qUcSt99Pg0isBR7NzLTnjZPSQSGyh0nQRdh+b79bbwVdR8Na+iXw== X-Received: by 2002:a17:906:fb05:b0:af9:e505:f620 with SMTP id a640c23a62f3a-af9e505fb9bmr705198266b.57.1754945330021; Mon, 11 Aug 2025 13:48:50 -0700 (PDT) From: Mykola Kvach To: xen-devel@lists.xenproject.org Cc: Mirela Simonovic , Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk , Saeed Nowshadi , Mykyta Poturai , Mykola Kvach Subject: [PATCH v5 02/12] xen/arm: gic-v2: Implement GIC suspend/resume functions Date: Mon, 11 Aug 2025 23:47:58 +0300 Message-ID: X-Mailer: git-send-email 2.48.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1754945352921116600 Content-Type: text/plain; charset="utf-8" From: Mirela Simonovic System suspend may lead to a state where GIC would be powered down. Therefore, Xen should save/restore the context of GIC on suspend/resume. Note that the context consists of states of registers which are controlled by the hypervisor. Other GIC registers which are accessible by guests are saved/restored on context switch. Tested on Xilinx Ultrascale+ MPSoC with (and without) powering down the GIC. Signed-off-by: Mirela Simonovic Signed-off-by: Saeed Nowshadi Signed-off-by: Mykyta Poturai Signed-off-by: Mykola Kvach --- Changes in v4: - Add error logging for allocation failures Changes in v3: - Drop asserts and return error codes instead. - Wrap code with CONFIG_SYSTEM_SUSPEND. Changes in v2: - Minor fixes after review. --- xen/arch/arm/gic-v2.c | 154 +++++++++++++++++++++++++++++++++ xen/arch/arm/gic.c | 29 +++++++ xen/arch/arm/include/asm/gic.h | 12 +++ 3 files changed, 195 insertions(+) diff --git a/xen/arch/arm/gic-v2.c b/xen/arch/arm/gic-v2.c index b23e72a3d0..dce8f5e924 100644 --- a/xen/arch/arm/gic-v2.c +++ b/xen/arch/arm/gic-v2.c @@ -1098,6 +1098,151 @@ static int gicv2_iomem_deny_access(struct domain *d) return iomem_deny_access(d, mfn, mfn + nr); } =20 +#ifdef CONFIG_SYSTEM_SUSPEND + +/* GICv2 registers to be saved/restored on system suspend/resume */ +struct gicv2_context { + /* GICC context */ + uint32_t gicc_ctlr; + uint32_t gicc_pmr; + uint32_t gicc_bpr; + /* GICD context */ + uint32_t gicd_ctlr; + uint32_t *gicd_isenabler; + uint32_t *gicd_isactiver; + uint32_t *gicd_ipriorityr; + uint32_t *gicd_itargetsr; + uint32_t *gicd_icfgr; +}; + +static struct gicv2_context gicv2_context; + +static int gicv2_suspend(void) +{ + unsigned int i; + + if ( !gicv2_context.gicd_isenabler ) + { + dprintk(XENLOG_WARNING, "%s:%d: GICv2 suspend context not allocate= d!\n", + __func__, __LINE__); + return -ENOMEM; + } + + /* Save GICC configuration */ + gicv2_context.gicc_ctlr =3D readl_gicc(GICC_CTLR); + gicv2_context.gicc_pmr =3D readl_gicc(GICC_PMR); + gicv2_context.gicc_bpr =3D readl_gicc(GICC_BPR); + + /* Save GICD configuration */ + gicv2_context.gicd_ctlr =3D readl_gicd(GICD_CTLR); + + for ( i =3D 0; i < DIV_ROUND_UP(gicv2_info.nr_lines, 32); i++ ) + gicv2_context.gicd_isenabler[i] =3D readl_gicd(GICD_ISENABLER + i = * 4); + + for ( i =3D 0; i < DIV_ROUND_UP(gicv2_info.nr_lines, 32); i++ ) + gicv2_context.gicd_isactiver[i] =3D readl_gicd(GICD_ISACTIVER + i = * 4); + + for ( i =3D 0; i < DIV_ROUND_UP(gicv2_info.nr_lines, 4); i++ ) + gicv2_context.gicd_ipriorityr[i] =3D readl_gicd(GICD_IPRIORITYR + = i * 4); + + for ( i =3D 0; i < DIV_ROUND_UP(gicv2_info.nr_lines, 4); i++ ) + gicv2_context.gicd_itargetsr[i] =3D readl_gicd(GICD_ITARGETSR + i = * 4); + + for ( i =3D 0; i < DIV_ROUND_UP(gicv2_info.nr_lines, 16); i++ ) + gicv2_context.gicd_icfgr[i] =3D readl_gicd(GICD_ICFGR + i * 4); + + return 0; +} + +static void gicv2_resume(void) +{ + unsigned int i; + + if ( !gicv2_context.gicd_isenabler ) + { + dprintk(XENLOG_WARNING, "%s:%d: GICv2 suspend context not allocate= d!\n", + __func__, __LINE__); + return; + } + + gicv2_cpu_disable(); + /* Disable distributor */ + writel_gicd(0, GICD_CTLR); + + /* Restore GICD configuration */ + for ( i =3D 0; i < DIV_ROUND_UP(gicv2_info.nr_lines, 32); i++ ) { + writel_gicd(0xffffffff, GICD_ICENABLER + i * 4); + writel_gicd(gicv2_context.gicd_isenabler[i], GICD_ISENABLER + i * = 4); + } + + for ( i =3D 0; i < DIV_ROUND_UP(gicv2_info.nr_lines, 32); i++ ) { + writel_gicd(0xffffffff, GICD_ICACTIVER + i * 4); + writel_gicd(gicv2_context.gicd_isactiver[i], GICD_ISACTIVER + i * = 4); + } + + for ( i =3D 0; i < DIV_ROUND_UP(gicv2_info.nr_lines, 4); i++ ) + writel_gicd(gicv2_context.gicd_ipriorityr[i], GICD_IPRIORITYR + i = * 4); + + for ( i =3D 0; i < DIV_ROUND_UP(gicv2_info.nr_lines, 4); i++ ) + writel_gicd(gicv2_context.gicd_itargetsr[i], GICD_ITARGETSR + i * = 4); + + for ( i =3D 0; i < DIV_ROUND_UP(gicv2_info.nr_lines, 16); i++ ) + writel_gicd(gicv2_context.gicd_icfgr[i], GICD_ICFGR + i * 4); + + /* Make sure all registers are restored and enable distributor */ + writel_gicd(gicv2_context.gicd_ctlr | GICD_CTL_ENABLE, GICD_CTLR); + + /* Restore GIC CPU interface configuration */ + writel_gicc(gicv2_context.gicc_pmr, GICC_PMR); + writel_gicc(gicv2_context.gicc_bpr, GICC_BPR); + + /* Enable GIC CPU interface */ + writel_gicc(gicv2_context.gicc_ctlr | GICC_CTL_ENABLE | GICC_CTL_EOI, + GICC_CTLR); +} + +static void gicv2_alloc_context(struct gicv2_context *gc) +{ + uint32_t n =3D gicv2_info.nr_lines; + + gc->gicd_isenabler =3D xzalloc_array(uint32_t, DIV_ROUND_UP(n, 32)); + if ( !gc->gicd_isenabler ) + goto err_free; + + gc->gicd_isactiver =3D xzalloc_array(uint32_t, DIV_ROUND_UP(n, 32)); + if ( !gc->gicd_isactiver ) + goto err_free; + + gc->gicd_itargetsr =3D xzalloc_array(uint32_t, DIV_ROUND_UP(n, 4)); + if ( !gc->gicd_itargetsr ) + goto err_free; + + gc->gicd_ipriorityr =3D xzalloc_array(uint32_t, DIV_ROUND_UP(n, 4)); + if ( !gc->gicd_ipriorityr ) + goto err_free; + + gc->gicd_icfgr =3D xzalloc_array(uint32_t, DIV_ROUND_UP(n, 16)); + if ( !gc->gicd_icfgr ) + goto err_free; + + return; + + err_free: + dprintk(XENLOG_ERR, + "%s:%d: failed to allocate memory for GICv2 suspend context\n", + __func__, __LINE__); + + xfree(gc->gicd_icfgr); + xfree(gc->gicd_ipriorityr); + xfree(gc->gicd_itargetsr); + xfree(gc->gicd_isactiver); + xfree(gc->gicd_isenabler); + + memset(gc, 0, sizeof(*gc)); +} + +#endif /* CONFIG_SYSTEM_SUSPEND */ + #ifdef CONFIG_ACPI static unsigned long gicv2_get_hwdom_extra_madt_size(const struct domain *= d) { @@ -1302,6 +1447,11 @@ static int __init gicv2_init(void) =20 spin_unlock(&gicv2.lock); =20 +#ifdef CONFIG_SYSTEM_SUSPEND + /* Allocate memory to be used for saving GIC context during the suspen= d */ + gicv2_alloc_context(&gicv2_context); +#endif /* CONFIG_SYSTEM_SUSPEND */ + return 0; } =20 @@ -1345,6 +1495,10 @@ static const struct gic_hw_operations gicv2_ops =3D { .map_hwdom_extra_mappings =3D gicv2_map_hwdom_extra_mappings, .iomem_deny_access =3D gicv2_iomem_deny_access, .do_LPI =3D gicv2_do_LPI, +#ifdef CONFIG_SYSTEM_SUSPEND + .suspend =3D gicv2_suspend, + .resume =3D gicv2_resume, +#endif /* CONFIG_SYSTEM_SUSPEND */ }; =20 /* Set up the GIC */ diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c index e80fe0ca24..a018bd7715 100644 --- a/xen/arch/arm/gic.c +++ b/xen/arch/arm/gic.c @@ -425,6 +425,35 @@ int gic_iomem_deny_access(struct domain *d) return gic_hw_ops->iomem_deny_access(d); } =20 +#ifdef CONFIG_SYSTEM_SUSPEND + +int gic_suspend(void) +{ + /* Must be called by boot CPU#0 with interrupts disabled */ + ASSERT(!local_irq_is_enabled()); + ASSERT(!smp_processor_id()); + + if ( !gic_hw_ops->suspend || !gic_hw_ops->resume ) + return -ENOSYS; + + return gic_hw_ops->suspend(); +} + +void gic_resume(void) +{ + /* + * Must be called by boot CPU#0 with interrupts disabled after gic_sus= pend + * has returned successfully. + */ + ASSERT(!local_irq_is_enabled()); + ASSERT(!smp_processor_id()); + ASSERT(gic_hw_ops->resume); + + gic_hw_ops->resume(); +} + +#endif /* CONFIG_SYSTEM_SUSPEND */ + static int cpu_gic_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) diff --git a/xen/arch/arm/include/asm/gic.h b/xen/arch/arm/include/asm/gic.h index 541f0eeb80..a706303008 100644 --- a/xen/arch/arm/include/asm/gic.h +++ b/xen/arch/arm/include/asm/gic.h @@ -280,6 +280,12 @@ extern int gicv_setup(struct domain *d); extern void gic_save_state(struct vcpu *v); extern void gic_restore_state(struct vcpu *v); =20 +#ifdef CONFIG_SYSTEM_SUSPEND +/* Suspend/resume */ +extern int gic_suspend(void); +extern void gic_resume(void); +#endif /* CONFIG_SYSTEM_SUSPEND */ + /* SGI (AKA IPIs) */ enum gic_sgi { GIC_SGI_EVENT_CHECK, @@ -395,6 +401,12 @@ struct gic_hw_operations { int (*iomem_deny_access)(struct domain *d); /* Handle LPIs, which require special handling */ void (*do_LPI)(unsigned int lpi); +#ifdef CONFIG_SYSTEM_SUSPEND + /* Save GIC configuration due to the system suspend */ + int (*suspend)(void); + /* Restore GIC configuration due to the system resume */ + void (*resume)(void); +#endif /* CONFIG_SYSTEM_SUSPEND */ }; =20 extern const struct gic_hw_operations *gic_hw_ops; --=20 2.48.1