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

Re: [PATCH v2 1/3] xen/arm: validate IRQs before descriptor lookup


  • To: "Orzel, Michal" <michal.orzel@xxxxxxx>
  • From: Mykola Kvach <mykola_kvach@xxxxxxxx>
  • Date: Tue, 18 Aug 2026 12:46:57 +0300
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=epam.com; dmarc=pass action=none header.from=epam.com; dkim=pass header.d=epam.com; arc=none
  • 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=kz1gqIWWsKdIgKvBwJLn8N3sahAW1xLtDaWTiYno8Kg=; b=NicTafW3zGpktRtU18o4Uekz8n8eM9h2uBdz/cC0Q9YtFI8e4Kd5T43+iwm2vM3IhF1sc9SCfroV3r9lGOBlkD8NSecma1wroxfU8aR92uUT916DkCGZYg+mQ8c8PnlOy7+Sx13bgpzbk9oUQewf8eWyrobN3+Mqq+ggdGLYP3Zzx0dNJUaa+WwMqwxISLsxP8FLnag8dTjV/mIrklYa9fO+3aVC40kD9GBVVJmKNRQT5KbfVzTds4otOiLp70IIr0n1DBZU/WMM4h9AbiorlMfUL03TY7lVgq9F7sHlneer/bSz1cS+VokPP/HfgFh1SbUDyj+7DKaSBqQ8iEAKMw==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=b2LTZ+NYxCiyyUTQB6dBzArHlizulz2kB4GG3NvE4GqWHbkFre4YM6QHyZ0ukLLX7AyWH+tabNXGBy1CdPXWGWxL6XEdD7cLpSw0zeHr181K7s6m3si8Uj8KaxQqLL7fuDuIcun0FRnY4LUSrzRn84cgaYC/inGMq0KNgV7NorpHKl8vTypxS3p5gfqIRI69SdReOVwX0SBlFiC3+6PVweCSDL2obExP8UlmM3IWhMCpY3V9dl+IHzxI1gkVzYDW/vfayzB+5e0Ik1jXWpiFVmS2lARrq5eUigdCjSSlP9pcogFFGHniRmJ6E5aUnpb2EnQ0MtVE3GBxpwam3MtGlA==
  • Authentication-results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=epam.com header.i="@epam.com" header.h="From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck"
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=epam.com;
  • Cc: xen-devel@xxxxxxxxxxxxxxxxxxxx, Stefano Stabellini <sstabellini@xxxxxxxxxx>, Julien Grall <julien@xxxxxxx>, Bertrand Marquis <bertrand.marquis@xxxxxxx>, Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>
  • Delivery-date: Tue, 18 Aug 2026 09:47:11 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Mail-followup-to: "Orzel, Michal" <michal.orzel@xxxxxxx>, xen-devel@xxxxxxxxxxxxxxxxxxxx, Stefano Stabellini <sstabellini@xxxxxxxxxx>, Julien Grall <julien@xxxxxxx>, Bertrand Marquis <bertrand.marquis@xxxxxxx>, Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>

Hi Michal,

Thank you for the review.

On Tue, Aug 11, 2026 at 10:51:47AM +0200, Orzel, Michal wrote:
> 
> 
> On 10-Aug-26 20:38, Mykola Kvach wrote:
> > GICv3 eSPI support makes nr_irqs span the architectural INTID namespace
> > through ESPI_MAX_INTID, but descriptor storage is sparse. local_irq_desc[]
> > and irq_desc[] cover INTIDs below NR_IRQS, while espi_desc[] covers eSPIs.
> > INTIDs 1024 through 4095 have no backing descriptors.
> > 
> > Validation based only on nr_irqs accepts an INTID in this gap.
> > __irq_to_desc() then indexes beyond irq_desc[], and callers may lock or
> > update unrelated Xen memory.
> > 
> > Reject INTIDs that the GIC reports as unimplemented in setup_irq() before
> > looking up a descriptor. irq_set_spi_type() can run before the implemented
> > GIC line counts are available, so validate descriptor-backed ranges there
> > before looking up a descriptor.
> > 
> > Call is_espi() unconditionally in __irq_to_desc() and provide an
> > espi_to_desc() stub when eSPI support is disabled. This preserves the
> > is_espi() debug check for eSPI-range INTIDs when support is disabled.
> > 
> > Fixes: 98f7060b9ed5 ("xen/arm/irq: add handling for IRQs in the eSPI range")
> > Signed-off-by: Mykola Kvach <mykola_kvach@xxxxxxxx>
> > ---
> > Changes in v2:
> > - Validate descriptor-backed ranges in irq_set_spi_type().
> > - Validate implemented GIC lines in setup_irq().
> > - Preserve is_espi() validation with CONFIG_GICV3_ESPI disabled.
> > ---
> >  xen/arch/arm/irq.c | 29 ++++++++++++++++++++++++-----
> >  1 file changed, 24 insertions(+), 5 deletions(-)
> > 
> > diff --git a/xen/arch/arm/irq.c b/xen/arch/arm/irq.c
> > index 73e58a5108..0f5d3496bf 100644
> > --- a/xen/arch/arm/irq.c
> > +++ b/xen/arch/arm/irq.c
> > @@ -23,6 +23,12 @@ const unsigned int nr_irqs = 
> > IS_ENABLED(CONFIG_GICV3_ESPI) ?
> >                                          (ESPI_MAX_INTID + 1) :
> >                                          NR_IRQS;
> >  
> > +static bool irq_has_desc(unsigned int irq)
> > +{
> > +    return irq < NR_IRQS ||
> > +           (IS_ENABLED(CONFIG_GICV3_ESPI) && is_espi(irq));
> This IS_ENABLED reads redundant because is_espi() contains #ifdef
> CONFIG_GICV3_ESPI inside. AFAICT you added it here to prevent the !ESPI build
> from reaching ASSERT inside is_espi() when the irq is in ESPI range. I don't
> like the ASSERT inside is_espi(). I think it does not make much sense in a
> helper that should really just tell us whether the IRQ is in ESPI range or 
> not.
> It should be up to the caller to decide what to do based on whether ESPI is
> compiled in or not. I think this cleanup would be best to be done first. If 
> you
> don't want to do that, at least document this in the commit msg because others
> may be tempted to drop this IS_ENABLED.

Ack. I’ll add a preparatory cleanup patch making is_espi() a pure
range predicate and keep the configuration handling at the call sites.

> 
> > +}
> > +
> >  static unsigned int local_irqs_type[NR_LOCAL_IRQS];
> >  static DEFINE_SPINLOCK(local_irqs_type_lock);
> >  
> > @@ -77,6 +83,12 @@ static int __init init_espi_data(void)
> >  }
> >  #else
> >  
> > +static struct irq_desc *espi_to_desc(unsigned int irq)
> > +{
> > +    ASSERT_UNREACHABLE();
> > +    return NULL;
> > +}
> > +
> >  static int __init init_espi_data(void)
> >  {
> >      return 0;
> > @@ -90,10 +102,8 @@ struct irq_desc *__irq_to_desc(unsigned int irq)
> >      if ( irq < NR_LOCAL_IRQS )
> >          return &this_cpu(local_irq_desc)[irq];
> >  
> > -#ifdef CONFIG_GICV3_ESPI
> >      if ( is_espi(irq) )
> >          return espi_to_desc(irq);
> > -#endif
> >  
> >      return &irq_desc[irq-NR_LOCAL_IRQS];
> Nothing here covers 1024..4095. I think we should add at least:
> ASSERT(irq < NR_IRQS) like we discussed some time ago.

Ack, I’ll restore the assertion before indexing irq_desc[].

> 
> >  }
> > @@ -416,6 +426,9 @@ int setup_irq(unsigned int irq, unsigned int irqflags, 
> > struct irqaction *new)
> >      struct irq_desc *desc;
> >      bool disabled;
> >  
> > +    if ( !gic_is_valid_line(irq) )
> > +        return -EINVAL;
> > +
> >      desc = irq_to_desc(irq);
> >  
> >      spin_lock_irqsave(&desc->lock, flags);
> > @@ -647,13 +660,19 @@ static bool irq_validate_new_type(unsigned int curr, 
> > unsigned int new)
> >  int irq_set_spi_type(unsigned int spi, unsigned int type)
> >  {
> >      unsigned long flags;
> > -    struct irq_desc *desc = irq_to_desc(spi);
> > +    struct irq_desc *desc;
> >      int ret = -EBUSY;
> >  
> > -    /* This function should not be used for other than SPIs */
> This is an important line that you should keep.

Ack.

Best regards,
Mykola



 


Rackspace

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