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

Re: [PATCH v7 04/12] xen/arm: gic-v3: add ITS suspend/resume support


  • To: Oleksandr Tyshchenko <olekstysh@xxxxxxxxx>
  • From: Mykola Kvach <xakep.amatop@xxxxxxxxx>
  • Date: Tue, 3 Feb 2026 13:00:09 +0200
  • Arc-authentication-results: i=1; mx.google.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=jIxlsfW7bCP8xx7xyp7U8w8Ij3LEG65Yj25nxXi5zCI=; fh=1+BAPob5BoQkkpmA3P9c5RHtJP6+f4C/krYhKM3WBxQ=; b=eHIgMa8H58NLOTaJzrvHyk75fkT1B8zpyDroWsB75pBK8XzMBbqKX4lnCzb1IxbOnE OYqKc4ieoinYrSfRYUiGYw7q03QgxC39VfR33uCxdCg0fQksvXPOetqdE4wGOEFp16Ee H1QH1mIc83JuBzgSXlbymfLCKOIkSrP31q7J7CTitC1RL5quU045Q5sUNOpVnPmkKdhy pOmGLt1we6uc1y4NyqOci+n0rBZXbxOlmg4nkRLwBLlKVcdWUjunJ3o8x6Y/uDtu/o7a m6h3nMvIpY+aClOFo4gcKy2h4s4qAZkFOE/TZPz8xsmWusbXASeX9mW65flqY+CE66Ll tb6g==; darn=lists.xenproject.org
  • Arc-seal: i=1; a=rsa-sha256; t=1770116421; cv=none; d=google.com; s=arc-20240605; b=N61g7jZNWntS2zCLbWpqb6MskKCBb9KpaCweI/qWNIH8IE312vHWunQtQt5+LWTRyA eXFYiOVi5ahaVJsqwU+5W382hwS6vac7zZd76qXul1CnEmN325V1MdsxF0nqdavkTkSC Qt7dGswP/hZXWRLa2UHEy5xRcqrfpaPSaYTC5HirlxUXHQLYAXqyMSR3Oe7gFCK+nlZJ ReTgL2yTMdrf2NBCKu8zqYn3d6lPpxWP55qh8VBgicx1Z+VE26Dq7oAOBI5QriRE3WTP 7jTqlBbC0kk1DVwTz9+OYMNEOIN3IpBqPJCjmhEdKTZjgA9BmhFOiXlbZmeKz+LlaaJM lhrw==
  • Cc: 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>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Anthony PERARD <anthony.perard@xxxxxxxxxx>, Jan Beulich <jbeulich@xxxxxxxx>, Roger Pau Monné <roger.pau@xxxxxxxxxx>
  • Delivery-date: Tue, 03 Feb 2026 11:00:32 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

Hi Oleksandr,

Thanks for the review.

On Sat, Jan 31, 2026 at 7:00 PM Oleksandr Tyshchenko
<olekstysh@xxxxxxxxx> wrote:
>
>
>
> On 11.12.25 20:43, Mykola Kvach wrote:
>
> Hello Mykola
>
> > From: Mykola Kvach <mykola_kvach@xxxxxxxx>
> >
> > Handle system suspend/resume for GICv3 with an ITS present so LPIs keep
> > working after firmware powers the GIC down. Snapshot the CPU interface,
> > distributor and last-CPU redistributor state, disable the ITS to cache its
> > CTLR/CBASER/BASER registers, then restore everything and re-arm the
> > collection on resume.
> >
> > Add list_for_each_entry_continue_reverse() in list.h for the ITS suspend
> > error path that needs to roll back partially saved state.
> >
> > Based on Linux commit: dba0bc7b76dc ("irqchip/gic-v3-its: Add ability to 
> > save/restore ITS state")
> > Signed-off-by: Mykola Kvach <mykola_kvach@xxxxxxxx>
> > ---
> >   xen/arch/arm/gic-v3-its.c             | 91 +++++++++++++++++++++++++++
> >   xen/arch/arm/gic-v3.c                 | 15 ++++-
> >   xen/arch/arm/include/asm/gic_v3_its.h | 23 +++++++
> >   xen/include/xen/list.h                | 14 +++++
> >   4 files changed, 140 insertions(+), 3 deletions(-)
> >
> > diff --git a/xen/arch/arm/gic-v3-its.c b/xen/arch/arm/gic-v3-its.c
> > index 34833166ad..08a3d8d1ef 100644
> > --- a/xen/arch/arm/gic-v3-its.c
> > +++ b/xen/arch/arm/gic-v3-its.c
> > @@ -1209,6 +1209,97 @@ int gicv3_its_init(void)
> >       return 0;
> >   }
> >
> > +#ifdef CONFIG_SYSTEM_SUSPEND
> > +int gicv3_its_suspend(void)
> > +{
> > +    struct host_its *its;
> > +    int ret;
> > +
> > +    list_for_each_entry(its, &host_its_list, entry)
> > +    {
> > +        unsigned int i;
> > +        void __iomem *base = its->its_base;
> > +
> > +        its->suspend_ctx.ctlr = readl_relaxed(base + GITS_CTLR);
> > +        ret = gicv3_disable_its(its);
> > +        if ( ret )
> > +        {
> > +            writel_relaxed(its->suspend_ctx.ctlr, base + GITS_CTLR);
> > +            goto err;
> > +        }
> > +
> > +        its->suspend_ctx.cbaser = readq_relaxed(base + GITS_CBASER);
> > +
> > +        for (i = 0; i < GITS_BASER_NR_REGS; i++) {
> > +            uint64_t baser = readq_relaxed(base + GITS_BASER0 + i * 8);
> > +
> > +            if ( !(baser & GITS_VALID_BIT) )
> > +                continue;
> > +
> > +            its->suspend_ctx.baser[i] = baser;
> > +        }
> > +    }
> > +
> > +    return 0;
> > +
> > + err:
> > +    list_for_each_entry_continue_reverse(its, &host_its_list, entry)
> > +        writel_relaxed(its->suspend_ctx.ctlr, its->its_base + GITS_CTLR);
> > +
> > +    return ret;
> > +}
> > +
> > +void gicv3_its_resume(void)
> > +{
> > +    struct host_its *its;
> > +    int ret;
> > +
> > +    list_for_each_entry(its, &host_its_list, entry)
> > +    {
> > +        void __iomem *base;
> > +        unsigned int i;
> > +
> > +        base = its->its_base;
> > +
> > +        /*
> > +         * Make sure that the ITS is disabled. If it fails to quiesce,
> > +         * don't restore it since writing to CBASER or BASER<n>
> > +         * registers is undefined according to the GIC v3 ITS
> > +         * Specification.
> > +         *
> > +         * Firmware resuming with the ITS enabled is terminally broken.
> > +         */
> > +        WARN_ON(readl_relaxed(base + GITS_CTLR) & GITS_CTLR_ENABLE);
> > +        ret = gicv3_disable_its(its);
> > +        if ( ret )
> > +            continue;
>
> If ITS fails to disable (quiesce), the code skips restoration and ITS
> remains in an unconfigured state. However, immediately after the loop ...
>
>
> > +
> > +        writeq_relaxed(its->suspend_ctx.cbaser, base + GITS_CBASER);
> > +
> > +        /*
> > +         * Writing CBASER resets CREADR to 0, so make CWRITER and
> > +         * cmd_write line up with it.
>
> NIT: The variable "cmd_write" does not exist in the Xen driver. As I
> understand, this comment was ported from the Linux kernel driver as is,
> which maintains a software shadow copy of the write pointer named
> "cmd_write".

Good catch, thanks.
You’re right - cmd_write doesn’t exist in the Xen driver; this comment
was ported from Linux. I’ll drop the cmd_write mention and keep the
comment focused on aligning CWRITER with the reset CREADR.

>
>
> > +         */
> > +        writeq_relaxed(0, base + GITS_CWRITER);
> > +
> > +        /* Restore GITS_BASER from the value cache. */
> > +        for (i = 0; i < GITS_BASER_NR_REGS; i++) {
> > +            uint64_t baser = its->suspend_ctx.baser[i];
> > +
> > +            if ( !(baser & GITS_VALID_BIT) )
> > +                continue;
> > +
> > +            writeq_relaxed(baser, base + GITS_BASER0 + i * 8);
> > +        }
> > +        writel_relaxed(its->suspend_ctx.ctlr, base + GITS_CTLR);
> > +    }
> > +
> > +    ret = gicv3_its_setup_collection(smp_processor_id());
>
>   ... this function iterates over all host ITS instances (including the
> one we skipped) and attempts to send MAPC commands. I am afraid, that
> attempting to write to the command queue of an uninitialized/unrestored
> ITS might have bad consequences.

Good catch, thanks.
Since gicv3_its_setup_collection() iterates over all host ITS instances,
it may send MAPC commands through an ITS that we intentionally skipped or
failed to restore. That’s unsafe. I’ll fix this by invoking collection
setup only for ITS instances successfully restored in this loop.

Best regards,
Mykola



>
> > +    if ( ret )
> > +        panic("GICv3: ITS: resume setup collection failed: %d\n", ret);
> > +}
> > +
> > +#endif /* CONFIG_SYSTEM_SUSPEND */
> >
>
> [snip]
>



 


Rackspace

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