[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v8 02/13] xen/arm: gic-v2: Implement GIC suspend/resume functions


  • To: Mykola Kvach <xakep.amatop@xxxxxxxxx>
  • From: Luca Fancellu <Luca.Fancellu@xxxxxxx>
  • Date: Tue, 21 Apr 2026 13:24:51 +0000
  • Accept-language: en-GB, en-US
  • Arc-authentication-results: i=2; mx.microsoft.com 1; spf=pass (sender ip is 4.158.2.129) smtp.rcpttodomain=gmail.com smtp.mailfrom=arm.com; dmarc=pass (p=none sp=none pct=100) action=none header.from=arm.com; dkim=pass (signature was verified) header.d=arm.com; arc=pass (0 oda=1 ltdi=1 spf=[1,1,smtp.mailfrom=arm.com] dkim=[1,1,header.d=arm.com] dmarc=[1,1,header.from=arm.com])
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=arm.com; dmarc=pass action=none header.from=arm.com; dkim=pass header.d=arm.com; arc=none
  • Arc-message-signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=CpGVs+CZAb05IuNP22MMkQS8t0793vH3LX8eKdVjC9g=; b=s0sIBJBH8esbafd+IbijHmMcPxdY8ZVbOm48O8Lk6f5lCcOAY8c3GpkVKD5TDY6Y+Kll8LhQM0qIqKr5th/ipLf0g0VIg66hTGCDcv3rxJZumwRX8PiN6q/OtkA21qyoJEJ2X6sSLgTUpoAcXE9R/HCx3xpfbT0y0kfCpSrDN30c6fwdVzNSiKm5CuWvCUNwhJ3EHP7MyOnHEXeBkLfflTiIyY0aWYvBqCB9tAwF/6x2k7LQ95ccgtGVJHt9U8wWY+O6KzOK5vSrRszkUmVynF2XBl6SFE7vnlMwROvLWXEh9LRyuE4LGzgB2xxz+3aFDMtTYQk38sKVj2hvRLaB2A==
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=CpGVs+CZAb05IuNP22MMkQS8t0793vH3LX8eKdVjC9g=; b=XKwz5rvHXuhvji5WRIZNo/1OW6R37+oc7zoiaO696WOvho3gTNMYdUDbJUiDwJVoY+DCEMCmO6zpn7i5b8tzy8BYYNNfs9lXRyF80jXAbmZC7excswRVRdivb1gXrUTPAwLAY8IDf0BeXXVSEhqWpUIMtHlcq1P4DPEv6iGpVODZgMFWnvVuTj+hO93sHrjXfs2zHW/SLZ7XGT4E0QTSdI4AZZhnSS4TWGquTlP/fRtVPUqzs8nobGU0aIZV539RYoSuClCUAMi9CD5W8L6ykz5Eo5FHxM0eBR/s03NvKuL3rIHmt7VMN6Kb+74TGjZYCu958xjcu8GebVghW2lQqA==
  • Arc-seal: i=2; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=pass; b=f+y16iM0ACWtrCyXZzPCMKEyCRil39/bSx/xZ9mpsLLqtnewfTggq2YIfIbaxzAnOVMTiTvOPzUyIPNe81X5rGfn01LneNKiJtxbJQC8z66gtU8A0e2OaxSdATjQxmPk2a5RiwO6np3MRHrTG169DNEe9HGIQZalG/ZnMLe9ZDdaRt43SM/FYm7rJ9WK/xlCj6XDtGYUzjK2k+E+Rjb9Ldp53CY8nxuolXA0YsWr7OzUuxJamrK+ZjqTEVsYZxRWp/QBUaMPOOs+NdT1zewPt5Pbi7clWlVXpGQfiYyJY+ym7Yt7F12p4lx+XI9OZPg7KLnh+WG6ToSDjEvNcNKbzA==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=T0iwkWHIY6U9i2r8j118hbKqPzY5S+GifMcR8TgiGv/VpnhkeWDCG3a/POxbxuGl2wJFhi0WSkGlYnkODlcuYizPHfbYCT9cYapCBuaN0EiVmxpBTAodN3e7Sl0PKE2V5EqhMiTta5A0wU/v6m759QmFgjlP0OaiyY6rYoqn3iKI5sTjkFG+IZVDFphGkxE3/P2fBkAB88dDOEprEMOSm91Jk0DRWEGY0JXCol6tBQWRmezQeh41UxLHZ9mB2X30ahUaJK1X5ZodmmyRtOTOeG5wcHc1Mvl1UblgKV23E/HdI3A++/tjsYnVM+FSg0PY/COlzt01VjkjL8QGtDa85Q==
  • Authentication-results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=arm.com header.i="@arm.com" header.h="From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck"; dkim=pass header.s=selector1 header.d=arm.com header.i="@arm.com" header.h="From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck"
  • Authentication-results-original: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com;
  • Cc: "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>, Mykola Kvach <mykola_kvach@xxxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, Julien Grall <julien@xxxxxxx>, Bertrand Marquis <Bertrand.Marquis@xxxxxxx>, Michal Orzel <michal.orzel@xxxxxxx>, Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>
  • Delivery-date: Tue, 21 Apr 2026 13:26:10 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Nodisclaimer: true
  • Thread-index: AQHc0ZI74iA20ItBV0OKtUp08vt6Qg==
  • Thread-topic: [PATCH v8 02/13] xen/arm: gic-v2: Implement GIC suspend/resume functions

Hi Mykola,

> 
> diff --git a/xen/arch/arm/gic-v2.c b/xen/arch/arm/gic-v2.c
> index b23e72a3d0..dbff470962 100644
> --- a/xen/arch/arm/gic-v2.c
> +++ b/xen/arch/arm/gic-v2.c
> @@ -1098,6 +1098,129 @@ static int gicv2_iomem_deny_access(struct domain *d)
>     return iomem_deny_access(d, mfn, mfn + nr);
> }
> 
> +#ifdef CONFIG_SYSTEM_SUSPEND
> +
> +/* This struct represents block of 32 IRQs */
> +struct irq_block {
> +    uint32_t icfgr[2]; /* 2 registers of 16 IRQs each */
> +    uint32_t ipriorityr[8];
> +    uint32_t isenabler;
> +    uint32_t isactiver;
> +    uint32_t itargetsr[8];
> +};
> +
> +/* GICv2 registers to be saved/restored on system suspend/resume */
> +struct gicv2_context {
> +    /* GICC context */
> +    struct cpu_ctx {
> +        uint32_t ctlr;
> +        uint32_t pmr;
> +        uint32_t bpr;
> +    } cpu;
> +
> +    /* GICD context */
> +    struct dist_ctx {
> +        uint32_t ctlr;
> +        /* Includes banked SGI/PPI state for the boot CPU. */
> +        struct irq_block *irqs;
> +    } dist;
> +};
> +
> +static struct gicv2_context gic_ctx;
> +
> +static int gicv2_suspend(void)
> +{
> +    unsigned int i, blocks = DIV_ROUND_UP(gicv2_info.nr_lines, 32);
> +
> +    /* Save GICC_CTLR configuration. */
> +    gic_ctx.cpu.ctlr = readl_gicc(GICC_CTLR);
> +
> +    /* Quiesce the GIC CPU interface before suspend. */
> +    gicv2_cpu_disable();
> +
> +    /* Save GICD configuration */
> +    gic_ctx.dist.ctlr = readl_gicd(GICD_CTLR);
> +    writel_gicd(0, GICD_CTLR);
> +
> +    gic_ctx.cpu.pmr = readl_gicc(GICC_PMR);
> +    gic_ctx.cpu.bpr = readl_gicc(GICC_BPR);
> +
> +    for ( i = 0; i < blocks; i++ )
> +    {
> +        struct irq_block *irqs = gic_ctx.dist.irqs + i;
> +        size_t j, off = i * sizeof(irqs->isenabler);
> +
> +        irqs->isenabler = readl_gicd(GICD_ISENABLER + off);
> +        irqs->isactiver = readl_gicd(GICD_ISACTIVER + off);
> +
> +        off = i * sizeof(irqs->ipriorityr);
> +        for ( j = 0; j < ARRAY_SIZE(irqs->ipriorityr); j++ )
> +        {
> +            irqs->ipriorityr[j] = readl_gicd(GICD_IPRIORITYR + off + j * 4);
> +            irqs->itargetsr[j] = readl_gicd(GICD_ITARGETSR + off + j * 4);

regarding GICD_ITARGETSR ...

> +        }
> +
> +        off = i * sizeof(irqs->icfgr);
> +        for ( j = 0; j < ARRAY_SIZE(irqs->icfgr); j++ )
> +            irqs->icfgr[j] = readl_gicd(GICD_ICFGR + off + j * 4);
> +    }
> +
> +    return 0;
> +}
> +
> +static void gicv2_resume(void)
> +{
> +    unsigned int i, blocks = DIV_ROUND_UP(gicv2_info.nr_lines, 32);
> +
> +    gicv2_cpu_disable();
> +    /* Disable distributor */
> +    writel_gicd(0, GICD_CTLR);
> +
> +    for ( i = 0; i < blocks; i++ )
> +    {
> +        struct irq_block *irqs = gic_ctx.dist.irqs + i;
> +        size_t j, off = i * sizeof(irqs->isenabler);
> +
> +        writel_gicd(GENMASK(31, 0), GICD_ICENABLER + off);
> +        writel_gicd(irqs->isenabler, GICD_ISENABLER + off);
> +
> +        writel_gicd(GENMASK(31, 0), GICD_ICACTIVER + off);
> +        writel_gicd(irqs->isactiver, GICD_ISACTIVER + off);
> +
> +        off = i * sizeof(irqs->ipriorityr);
> +        for ( j = 0; j < ARRAY_SIZE(irqs->ipriorityr); j++ )
> +        {
> +            writel_gicd(irqs->ipriorityr[j], GICD_IPRIORITYR + off + j * 4);
> +            writel_gicd(irqs->itargetsr[j], GICD_ITARGETSR + off + j * 4);

… please let me know if I read correctly this loop, but here GICD_ITARGETSR0 … 7
are restored when i=0, but the specificaitons says that this block is read only 
on
multiprocessor, so we should skip the restore part.
Also saving it could be skipped because each field returns a value that 
corresponds
only to the processor reading the register.

4.3.12 User constraints [1]

> +        }
> +
> +        off = i * sizeof(irqs->icfgr);
> +        for ( j = 0; j < ARRAY_SIZE(irqs->icfgr); j++ )
> +            writel_gicd(irqs->icfgr[j], GICD_ICFGR + off + j * 4);
> +    }
> +
> +    /* Make sure all registers are restored and enable distributor */
> +    writel_gicd(gic_ctx.dist.ctlr, GICD_CTLR);
> +
> +    /* Restore GIC CPU interface configuration */
> +    writel_gicc(gic_ctx.cpu.pmr, GICC_PMR);
> +    writel_gicc(gic_ctx.cpu.bpr, GICC_BPR);
> +
> +    /* Enable GIC CPU interface */
> +    writel_gicc(gic_ctx.cpu.ctlr, GICC_CTLR);
> +}
> +

I also see that we don’t save pending SGIs state (by 
GICD_CPENDSGIRn/GICD_SPENDSGIRn) or Active Priorities registers
state (GICC_APRn/GICC_NSAPRn [latter if security extension are there]) as 
written in [1] “4.5 Preserving and restoring GIC state”,
was it intentional?

[1] https://developer.arm.com/documentation/ihi0048/bb/?lang=en

Cheers,
Luca



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.