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

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


  • To: Mykola Kvach <xakep.amatop@xxxxxxxxx>
  • From: Luca Fancellu <Luca.Fancellu@xxxxxxx>
  • Date: Wed, 13 May 2026 14:08:37 +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=ZL4+9RzTBp0OdibY7cDOYg9n7P0dqjXUmHHEHExTaC4=; b=WTFxJhu1ObFEFYii43vzitJt3wPvjnGV6RHHd5lqv2GDHSLds8epO1Z1WzrCl44ZqV2VwpWLIlYKv+fO+KLJZ+6ZhLVv+dmsjXTzNg/qaFNdCNL2X11QCOHftgytitup07ptSZ38oaYzk8I9ImIY802DqA1LDT6Ho8qBbzLcL6LT1hMKabs6OoeCyZxMYP5lfScAXasXd0NOmtR8RaIhnme2cXroD1RK668W3rfeGugj2AuNtFOrb6yzj5zwPl9GBvwQpOEgTW0ZNx4c8CdymjTpLF4OIfkW7cpG81ES5ws+EvDVQ85rn0KEO5cZo1N35WM9sn4PGmfIrqRHi5tVQA==
  • 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=ZL4+9RzTBp0OdibY7cDOYg9n7P0dqjXUmHHEHExTaC4=; b=bpop2uDrmmW0xFIcXxuqP78rrwOjsBinFeoQLx/DlaoZV52W0G4zI8YT36IPONPYG8ok+rcfg/IrmrkwlLZM3yADPA7ilinSX0jP0/kIdhzo8R25lq9uqDFUpypJsUSx0Sohud1Yp38LCE9DCEpY3sADFFU3H+yahg0zuxXTBvPhoX43vBXZYek7leflibcL0So5ybIHZlY4xCkDY1Tbdrc6Bi/uQkqd90B3VDlu8Sjh7GNLCcjidSKQJRSgYsvCiA4AF46Aym2F+RfAfiKHfGGOvJeVzNWe6ZnVzhp5dTNStAjYFx1SZmvWchfH9EToQxSf0QaO6fRMUxv3zKhBIg==
  • Arc-seal: i=2; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=pass; b=wKkPM54Ywb64mCG8VXRZomIGCWZUy9vgN5Rh+5Np+jx2QuWG3MCauTRqXity80fP2l7nIs3T5KHR0prdzelQW+QSy2KliLXoCCxjgIqk7SHeNY+Sc77jYtaz1Pv0YiLWjwID3n3C1n1zjXJDnrF/j1z3bccPLooDm4dwuQggOXcanSrO7ICk9ryOW6+PjTMVwUGpZ7+6fuwF0YptLiBuzcHEP60pf1Yqopv17LxRdbpY9K3uNJQnhXtaJrNun73Za9zTG1EUr6B/GKgJPiyX/KuvXZ6+PS7nMv/94ORdpqE4njWrFpJ+48ez5xrmY5Xd9+qCQnTQMAtV0MRctljkoQ==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=vLMu3WoSwNNhsYhWK5jgeF+E9TzOWgsXeZudK5Q4332VIEAAllpq5NbyaDTP64PxlpzxNShbnptbuohx/PezKUaYRDESWQYImpIeRmwtI7p45HRggaANFmUm6ptFnMvwTSyA3cnJdEuodsO2B6NWSPv8cdsICuZjau7L15O4/zVA5j9pB8+yBxH1AwjCA5vyOaA70RJmZTKUceUm9X1JMmQ8zsCQx2THnRp2+nsWeLUd2I4tqI12/bsBvDPIhpMw4+vFEWLBO1ZGdpqWeKU+alwFMqbOO+dBSXfJR2/6RdfnQmeaKsis5xPSS3Gu8MIWCbqKMuE34ErlicpkoX5Onw==
  • 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: Wed, 13 May 2026 14:09:50 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Nodisclaimer: true
  • Thread-index: AQHc4jIxK7EE6l+HQkWYC60FHhQX47YL/3OA
  • Thread-topic: [PATCH v9 02/13] xen/arm: gic-v2: Implement GIC suspend/resume functions

Hi Mykola,

> +
> +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);

apologies for spotting these only now, in case gicv2_info.nr_lines is 1020,
here and below for GICD_ITARGETSR we are going to save also IDs 1020-1023
which are reserved.

Could we assume irqs->ipriorityr and irqs->itargetsr have the same size and 
implement
some cap logic which might cap the last loop (eventually):

    for ( i = 0; i < blocks; i++ )
    {
        struct irq_block *irqs = gic_ctx.dist.irqs + i;
        size_t j, off = i * sizeof(irqs->isenabler);
        size_t nr_regs = ARRAY_SIZE(irqs->ipriorityr);

        if ( i == blocks - 1 )
            nr_regs = DIV_ROUND_UP(gicv2_info.nr_lines - i * 32, 4);

        […]

        off = i * sizeof(irqs->ipriorityr);
        for ( j = 0; j < nr_regs; j++ )
            writel_gicd(irqs->ipriorityr[j], GICD_IPRIORITYR + off + j * 4);

        /*
         * GICD_ITARGETSR0..7 cover SGIs/PPIs and hold no state to save:
         * they are read-only on multiprocessor implementations and RAZ/WI
         * on uniprocessor implementations.
         */
        if ( i )
        {
            off = i * sizeof(irqs->itargetsr);
            for ( j = 0; j < nr_regs; j++ )
                writel_gicd(irqs->itargetsr[j], GICD_ITARGETSR + off + j * 4);
        }

        […]
    }

> +
> +        /*
> +         * GICD_ITARGETSR0..7 cover SGIs/PPIs and hold no state to save:
> +         * they are read-only on multiprocessor implementations and RAZ/WI
> +         * on uniprocessor implementations.
> +         */
> +        if ( i )
> +        {
> +            off = i * sizeof(irqs->itargetsr);
> +            for ( j = 0; j < ARRAY_SIZE(irqs->itargetsr); j++ )
> +                writel_gicd(irqs->itargetsr[j], GICD_ITARGETSR + off + j * 
> 4);
> +        }
> +
> +        off = i * sizeof(irqs->icfgr);
> +        for ( j = 0; j < ARRAY_SIZE(irqs->icfgr); j++ )
> +            writel_gicd(irqs->icfgr[j], GICD_ICFGR + off + j * 4);

in the GICv2 specs the usage constraints
of GICD_ICFGR says: “Before changing the value of a programmable Int_config 
field,
software must disable the corresponding interrupt, otherwise GIC behavior is
UNPREDICTABLE"

ARM IHI 0048B.b, 4.3.13.

I think we should move this restore just after GICD_ICENABLER write, before 
writing
GICD_ISENABLER.

And also the section says that the GICD_ICFGR0 is read-only.

Let me know your thoughts on that.

> +    }
> +
> +    /* 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);
> +}
> +
> +static void __init gicv2_alloc_context(void)
> +{
> +    uint32_t blocks = DIV_ROUND_UP(gicv2_info.nr_lines, 32);
> +
> +    gic_ctx.dist.irqs = xzalloc_array(struct irq_block, blocks);
> +    if ( !gic_ctx.dist.irqs )
> +        panic("Failed to allocate memory for GICv2 suspend context\n");
> +}
> +
> +#endif /* CONFIG_SYSTEM_SUSPEND */
> +
> #ifdef CONFIG_ACPI
> static unsigned long gicv2_get_hwdom_extra_madt_size(const struct domain *d)
> {
> @@ -1312,6 +1484,11 @@ static int __init gicv2_init(void)
> 
>     spin_unlock(&gicv2.lock);
> 
> +#ifdef CONFIG_SYSTEM_SUSPEND
> +    /* Allocate memory to be used for saving GIC context during the suspend 
> */
> +    gicv2_alloc_context();
> +#endif /* CONFIG_SYSTEM_SUSPEND */
> +
>     return 0;
> }
> 
> @@ -1355,6 +1532,10 @@ static const struct gic_hw_operations gicv2_ops = {
>     .map_hwdom_extra_mappings = gicv2_map_hwdom_extra_mappings,
>     .iomem_deny_access   = gicv2_iomem_deny_access,
>     .do_LPI              = gicv2_do_LPI,
> +#ifdef CONFIG_SYSTEM_SUSPEND
> +    .suspend             = gicv2_suspend,
> +    .resume              = gicv2_resume,
> +#endif /* CONFIG_SYSTEM_SUSPEND */
> };
> 

I don’t have any other findings for this patch.

Cheers,
Luca




 


Rackspace

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