From nobody Fri Oct 31 03:46:07 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=1754945350; cv=none; d=zohomail.com; s=zohoarc; b=KGk00UzjXukRkTgd3xop+Fs0ML/KQJwykqo8N65PX9eIZ3XHu3Zwaix7Th3pVM9ZEFoSaCk51bRXfdykZkLHtD128tLfrSq8PugB2mFjXOAi6N/4NW/iVahkSvngeVQJpMmiXbRLfjOBA+wysg4mxLjEkii0qsgbAEUx4znXMYo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1754945350; 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=D2plmqjz1DgU+9gEpcztVWyZmRTrqXcD635KTVAFbqc=; b=hJpqjsb33StwHjBdR1aMYah+pJLwseQNQmPoec7vH7FRTe+U2u1j0sKLOsHSWg8jmrvCMfdyVj6y+f07Cg7yP6grGESu5fub0nWvczv2Hx/1s9jwwIbYGWfP5ewQ8HaBu5Pc4717WTexEE00sdtIuqQEvRHE1JGbCXf37jphcbs= 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 1754945350391160.9340224312108; Mon, 11 Aug 2025 13:49:10 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1077946.1438976 (Exim 4.92) (envelope-from ) id 1ulZRv-0006K9-IA; Mon, 11 Aug 2025 20:48:55 +0000 Received: by outflank-mailman (output) from mailman id 1077946.1438976; Mon, 11 Aug 2025 20:48:55 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1ulZRv-0006K0-F1; Mon, 11 Aug 2025 20:48:55 +0000 Received: by outflank-mailman (input) for mailman id 1077946; Mon, 11 Aug 2025 20:48:54 +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 1ulZRu-00063z-Mh for xen-devel@lists.xenproject.org; Mon, 11 Aug 2025 20:48:54 +0000 Received: from mail-ej1-x636.google.com (mail-ej1-x636.google.com [2a00:1450:4864:20::636]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 9725a984-76f4-11f0-b898-0df219b8e170; Mon, 11 Aug 2025 22:48:53 +0200 (CEST) Received: by mail-ej1-x636.google.com with SMTP id a640c23a62f3a-af9611d8ff7so848816366b.1 for ; Mon, 11 Aug 2025 13:48:53 -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.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 11 Aug 2025 13:48:50 -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: 9725a984-76f4-11f0-b898-0df219b8e170 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1754945332; x=1755550132; 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=D2plmqjz1DgU+9gEpcztVWyZmRTrqXcD635KTVAFbqc=; b=b4e03BYvNz0GSvEHkNtxhAhwhKHTgZNlnGygFoDqwrNdcRUME8jyDl5OXg+W108l5Z S21DgqtZC/6iZQbQ3Fzph3N4c3kSNkSVF8/WQANxGxfHl11SXs4isiHLDNTvJReBKKN0 VCXWOfo0alXm1yeU/tiIiIRUweSg7p7ubEGC2mETDemZKh6q0cXWbj+I9tTlBgWXT1Dx VgL9X31AHHFn+9P8Iqv55h225yZ4omvcWZRkDHXZlMavSfbdbskX+P8+1ARumwquyOQx tBrWtgnu90N4OP5Oxa6zP3PTutMzIqDoGkLoCj+ewuNZszcEEQDRJoS/JcwPYsq7/4EJ IDhw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1754945332; x=1755550132; 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=D2plmqjz1DgU+9gEpcztVWyZmRTrqXcD635KTVAFbqc=; b=Cqc/y2Cq6qs+9FE37W6xkyTC0PCaEZtnLHRu9yhZowvfpz/VhBihTQeuROS+2dQd4T FwakowQ+nbcZldVPcaXeDr79xyTTe+z3Vjis+ZMn+D+LuUayUszhUOe6/sRvv2Fciq0y /sYk/Ctpb6ptb5yx4Hc2h4l3JhzKFWnqGZ2rEyVzXR1xMSoq0ghe9BwPIsPgWaYyIKxr 3wMeByS1Plzd23FqPNJiFszKIBk9EOSb/n8IQExuUV9aZzfdjFAT6yBntmXn4zh4Ff9T CL7hFsKLiq7Wz5drt4KulD1ewuxc+/AUQs0p2d2/itaR78RMuaebpi6cRwpZnsCvVnec /8Dw== X-Gm-Message-State: AOJu0YwMZsaYet7gS1rlqP3/NnFJGM5RUxabWL8D7hOcQHbF7BwMV7Jo g1jJ1KgoEZ8YPM8P8DjBOuTqhVE9H81vZMDPSlmjJ58IUwUM6SwRu4Lb0ddf7A== X-Gm-Gg: ASbGncuUtIVWyfDaO0/cmgfjgUtj81J9GN9nd1cpoSSa6d3WeR7JDxKDUWNRvPKB5Ir mce9uMRcuO4Izqac7EOsEvH7zihJ4PNNUHH3p8D1HC2N5y9Y0lfRv3eoXw9Y0DrkwZdt/kCgYao 1QK3Aq0TqeVpg4tAb7cC/YY2oA+8ZwLJ3MoPXrMf/b1ziMoBZVvUiycyYFrESDzLKAqG1N0k3Sc Ma+TdAPoaEy3RCpl2C29NL07u2FD107ls4vI/MOc45ysTg6cIkZt7/+Pz7E1xrIsqUrvhqaP1cD H+SneS3fAxV07KB4EypGsxIaXQHX0Ylftu3XMESnClqdcK4frg0+1kQztiu2lPFwjGz7o/Nc8ho yiW+7kEDqxJiG2AhZ/S2fvFqLWnf2RjRc61yuFHUB0Fe1j6+bZHgZ1bZzFW7ZZqODw+4= X-Google-Smtp-Source: AGHT+IEfEKJYD9M3gJWf+20en40xDaPHCADL22orakBaGISswdWEmQXSl3jT0ikHDz+HYSPYdX9Vgg== X-Received: by 2002:a17:906:6b93:b0:acb:37ae:619c with SMTP id a640c23a62f3a-afa1d6d2c48mr79546266b.15.1754945331921; Mon, 11 Aug 2025 13:48:51 -0700 (PDT) From: Mykola Kvach To: xen-devel@lists.xenproject.org Cc: Mykola Kvach , Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk Subject: [PATCH v5 03/12] xen/arm: gic-v3: Implement GICv3 suspend/resume functions Date: Mon, 11 Aug 2025 23:47:59 +0300 Message-ID: <451b8a0527a6193b6687e1c85bd254b4dfda142d.1754943874.git.mykola_kvach@epam.com> 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: 1754945352837116600 Content-Type: text/plain; charset="utf-8" From: Mykola Kvach 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. Signed-off-by: Mykola Kvach --- xen/arch/arm/gic-v3.c | 233 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 233 insertions(+) diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c index cd3e1acf79..a9b65ff5d4 100644 --- a/xen/arch/arm/gic-v3.c +++ b/xen/arch/arm/gic-v3.c @@ -1776,6 +1776,231 @@ static bool gic_dist_supports_lpis(void) return (readl_relaxed(GICD + GICD_TYPER) & GICD_TYPE_LPIS); } =20 +#ifdef CONFIG_SYSTEM_SUSPEND + +/* GICv3 registers to be saved/restored on system suspend/resume */ +struct gicv3_ctx { + struct dist_ctx { + uint32_t ctlr; + /* + * This struct represent block of 32 IRQs + * TODO: store extended SPI configuration (GICv3.1+) + */ + struct irq_regs { + uint32_t icfgr[2]; + uint32_t ipriorityr[8]; + uint64_t irouter[32]; + uint32_t isactiver; + uint32_t isenabler; + } *irqs; + } dist; + + /* have only one rdist structure for last running CPU during suspend */ + struct redist_ctx { + uint32_t ctlr; + /* TODO: handle case when we have more than 16 PPIs (GICv3.1+) */ + uint32_t icfgr[2]; + uint32_t igroupr; + uint32_t ipriorityr[8]; + uint32_t isactiver; + uint32_t isenabler; + } rdist; + + struct cpu_ctx { + uint32_t ctlr; + uint32_t pmr; + uint32_t bpr; + uint32_t sre_el2; + uint32_t grpen; + } cpu; +}; + +static struct gicv3_ctx gicv3_ctx; + +static void __init gicv3_alloc_context(void) +{ + uint32_t blocks =3D DIV_ROUND_UP(gicv3_info.nr_lines, 32); + + if ( gicv3_its_host_has_its() ) + return; + + /* according to spec it is possible don't have SPIs */ + if ( blocks =3D=3D 1 ) + return; + + gicv3_ctx.dist.irqs =3D xzalloc_array(typeof(*gicv3_ctx.dist.irqs), bl= ocks - 1); + if ( !gicv3_ctx.dist.irqs ) + dprintk(XENLOG_ERR, + "%s:%d: failed to allocate memory for GICv3 suspend contex= t\n", + __func__, __LINE__); +} + +static void gicv3_disable_redist(void) +{ + void __iomem* waker =3D GICD_RDIST_BASE + GICR_WAKER; + + writel_relaxed(readl_relaxed(waker) | GICR_WAKER_ProcessorSleep, waker= ); + while ( (readl_relaxed(waker) & GICR_WAKER_ChildrenAsleep) =3D=3D 0 ); +} + +static int gicv3_suspend(void) +{ + unsigned int i; + void __iomem *base; + typeof(gicv3_ctx.rdist)* rdist =3D &gicv3_ctx.rdist; + + /* TODO: implement support for ITS */ + if ( gicv3_its_host_has_its() ) + return -EOPNOTSUPP; + + if ( !gicv3_ctx.dist.irqs && gicv3_info.nr_lines > NR_GIC_LOCAL_IRQS ) + { + dprintk(XENLOG_WARNING, + "%s:%d: GICv3 suspend context is not allocated!\n", + __func__, __LINE__); + return -ENOMEM; + } + + gicv3_save_state(current); + + /* Save GICC configuration */ + gicv3_ctx.cpu.ctlr =3D READ_SYSREG(ICC_CTLR_EL1); + gicv3_ctx.cpu.pmr =3D READ_SYSREG(ICC_PMR_EL1); + gicv3_ctx.cpu.bpr =3D READ_SYSREG(ICC_BPR1_EL1); + gicv3_ctx.cpu.sre_el2 =3D READ_SYSREG(ICC_SRE_EL2); + gicv3_ctx.cpu.grpen =3D READ_SYSREG(ICC_IGRPEN1_EL1); + + gicv3_disable_interface(); + gicv3_disable_redist(); + + /* Save GICR configuration */ + gicv3_redist_wait_for_rwp(); + + base =3D GICD_RDIST_SGI_BASE; + + rdist->ctlr =3D readl_relaxed(base + GICR_CTLR); + + /* Set priority on PPI and SGI interrupts */ + for (i =3D 0; i < NR_GIC_LOCAL_IRQS / 4; i +=3D 4) + rdist->ipriorityr[i] =3D readl_relaxed(base + GICR_IPRIORITYR0 + 4= * i); + + rdist->isactiver =3D readl_relaxed(base + GICR_ISACTIVER0); + rdist->isenabler =3D readl_relaxed(base + GICR_ISENABLER0); + rdist->igroupr =3D readl_relaxed(base + GICR_IGROUPR0); + rdist->icfgr[0] =3D readl_relaxed(base + GICR_ICFGR0); + rdist->icfgr[1] =3D readl_relaxed(base + GICR_ICFGR1); + + /* Save GICD configuration */ + gicv3_dist_wait_for_rwp(); + gicv3_ctx.dist.ctlr =3D readl_relaxed(GICD + GICD_CTLR); + + for ( i =3D 1; i < DIV_ROUND_UP(gicv3_info.nr_lines, 32); i++ ) + { + typeof(gicv3_ctx.dist.irqs) irqs =3D gicv3_ctx.dist.irqs + i - 1; + unsigned int irq; + + base =3D GICD + GICD_ICFGR + 8 * i; + irqs->icfgr[0] =3D readl_relaxed(base); + irqs->icfgr[1] =3D readl_relaxed(base + 4); + + base =3D GICD + GICD_IPRIORITYR + 32 * i; + for ( irq =3D 0; irq < 8; irq++ ) + irqs->ipriorityr[irq] =3D readl_relaxed(base + 4 * irq); + + base =3D GICD + GICD_IROUTER + 32 * i; + for ( irq =3D 0; irq < 32; irq++ ) + irqs->irouter[irq] =3D readq_relaxed_non_atomic(base + 8 * irq= ); + + irqs->isactiver =3D readl_relaxed(GICD + GICD_ISACTIVER + 4 * i); + irqs->isenabler =3D readl_relaxed(GICD + GICD_ISENABLER + 4 * i); + } + + return 0; +} + +static void gicv3_resume(void) +{ + unsigned int i; + void __iomem *base; + typeof(gicv3_ctx.rdist)* rdist =3D &gicv3_ctx.rdist; + + if ( !gicv3_ctx.dist.irqs && gicv3_info.nr_lines > NR_GIC_LOCAL_IRQS ) + { + dprintk(XENLOG_WARNING, "%s:%d: GICv3 suspend context not allocate= d!\n", + __func__, __LINE__); + return; + } + + writel_relaxed(0, GICD + GICD_CTLR); + + for ( i =3D NR_GIC_LOCAL_IRQS; i < gicv3_info.nr_lines; i +=3D 32 ) + writel_relaxed(GENMASK(31, 0), GICD + GICD_IGROUPR + (i / 32) * 4); + + for ( i =3D 1; i < DIV_ROUND_UP(gicv3_info.nr_lines, 32); i++ ) + { + typeof(gicv3_ctx.dist.irqs) irqs =3D gicv3_ctx.dist.irqs + i - 1; + unsigned int irq; + + base =3D GICD + GICD_ICFGR + 8 * i; + writel_relaxed(irqs->icfgr[0], base); + writel_relaxed(irqs->icfgr[1], base + 4); + + base =3D GICD + GICD_IPRIORITYR + 32 * i; + for ( irq =3D 0; irq < 8; irq++ ) + writel_relaxed(irqs->ipriorityr[irq], base + 4 * irq ); + + base =3D GICD + GICD_IROUTER + 32 * i; + for ( irq =3D 0; irq < 32; irq++ ) + writeq_relaxed_non_atomic(irqs->irouter[irq], base + 8 * irq); + + writel_relaxed(irqs->isenabler, GICD + GICD_ISENABLER + i * 4); + writel_relaxed(irqs->isactiver, GICD + GICD_ISACTIVER + i * 4); + } + + writel_relaxed(gicv3_ctx.dist.ctlr, GICD + GICD_CTLR); + gicv3_dist_wait_for_rwp(); + + /* Restore GICR (Redistributor) configuration */ + gicv3_enable_redist(); + + base =3D GICD_RDIST_SGI_BASE; + + writel_relaxed(0xffffffff, base + GICR_ICENABLER0); + gicv3_redist_wait_for_rwp(); + + for (i =3D 0; i < NR_GIC_LOCAL_IRQS / 4; i +=3D 4) + writel_relaxed(rdist->ipriorityr[i], base + GICR_IPRIORITYR0 + i *= 4); + + writel_relaxed(rdist->isactiver, base + GICR_ISACTIVER0); + + writel_relaxed(rdist->igroupr, base + GICR_IGROUPR0); + writel_relaxed(rdist->icfgr[0], base + GICR_ICFGR0); + writel_relaxed(rdist->icfgr[1], base + GICR_ICFGR1); + + gicv3_redist_wait_for_rwp(); + + writel_relaxed(rdist->isenabler, base + GICR_ISENABLER0); + writel_relaxed(rdist->ctlr, GICD_RDIST_BASE + GICR_CTLR); + + gicv3_redist_wait_for_rwp(); + + WRITE_SYSREG(gicv3_ctx.cpu.sre_el2, ICC_SRE_EL2); + isb(); + + /* Restore CPU interface (System registers) */ + WRITE_SYSREG(gicv3_ctx.cpu.pmr, ICC_PMR_EL1); + WRITE_SYSREG(gicv3_ctx.cpu.bpr, ICC_BPR1_EL1); + WRITE_SYSREG(gicv3_ctx.cpu.ctlr, ICC_CTLR_EL1); + WRITE_SYSREG(gicv3_ctx.cpu.grpen, ICC_IGRPEN1_EL1); + isb(); + + gicv3_hyp_init(); + + gicv3_restore_state(current); +} + +#endif /* CONFIG_SYSTEM_SUSPEND */ + /* Set up the GIC */ static int __init gicv3_init(void) { @@ -1850,6 +2075,10 @@ static int __init gicv3_init(void) =20 gicv3_hyp_init(); =20 +#ifdef CONFIG_SYSTEM_SUSPEND + gicv3_alloc_context(); +#endif + out: spin_unlock(&gicv3.lock); =20 @@ -1889,6 +2118,10 @@ static const struct gic_hw_operations gicv3_ops =3D { #endif .iomem_deny_access =3D gicv3_iomem_deny_access, .do_LPI =3D gicv3_do_LPI, +#ifdef CONFIG_SYSTEM_SUSPEND + .suspend =3D gicv3_suspend, + .resume =3D gicv3_resume, +#endif }; =20 static int __init gicv3_dt_preinit(struct dt_device_node *node, const void= *data) --=20 2.48.1