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

[PATCH v3 2/4] xen/arm: validate IRQs before descriptor lookup


  • To: xen-devel@xxxxxxxxxxxxxxxxxxxx
  • From: Mykola Kvach <mykola_kvach@xxxxxxxx>
  • Date: Tue, 18 Aug 2026 14:33:00 +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=F3h0aDabB4S3N+q+n0dwzdXfsKs/jsW96yHUTuqm6Mk=; b=e7SxnYfW/bsU5HvTqX98o8MeNhq7dMwAitR48kpZ2s9cuJHaSqsZgC1XpRC3qvttU1IE+H7KuSe9Nl1o+AK0NSIfnb5BvZxBR2ZYDRsbwbJij8Dz1tn5DT+ngpDT5n8ps3mbHOgAB8Ydvypm4A1Z2VYviaKWgbIicC9DzHkr4VdZnkocivPEriQEidEXRboCRj6FGyUSGY3YuhSajUSU4G+428wXRD3gRISDBNQO73TMVtcEhsGAi6FxASngd/ATVI+20xoEXL5AqHimxscJsacEKKCAYa4LEJRjdHbJRJvG2qsjH99dh6Gvf+V4E7g+C6f5v6TdhdS8bcaiGo8Ejw==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=PmuUxKl4mAHx2fh1kbIG7whTmNtoBJgzrNLFSRevSfu6mA3s2GhXHkB6xH4axyquLq06R69hzyV8cdQas+HKFoOFzL++Hnb0wskQnwL9oJ5kD2rJ8yCLdCTsXZckFpH1Cx1sgBimYqeNmcNR5AGnV54N+opXRKTyyJKUXMhpvojiLGKNxf4sSVnFlgnTDuI8CmMCiPn/f0M3AVDK4gui2t5X7S/WHqAfd7DS6er3ybZZ8eAVnEP8hCUZXKxU43s0mcuIRNo5JJx6it/BImVmPoGFiXjvpgPgJepwopCvpV0P+t50fJaBXPHd4/4Rf/a1WWpT0acmRTSB8X+/mbyL+g==
  • 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: 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, 18 Aug 2026 11:33:22 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

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.

Assert the regular descriptor bound in __irq_to_desc() so direct callers
cannot silently index the sparse gap in debug builds.

Fixes: 98f7060b9ed5 ("xen/arm/irq: add handling for IRQs in the eSPI range")
Signed-off-by: Mykola Kvach <mykola_kvach@xxxxxxxx>
---
Changes in v3:
- Add the requested bound assertion and retain the SPI-only comment.

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 | 26 ++++++++++++++++++++++----
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/xen/arch/arm/irq.c b/xen/arch/arm/irq.c
index 73e58a5108..bf14180f97 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));
+}
+
 static unsigned int local_irqs_type[NR_LOCAL_IRQS];
 static DEFINE_SPINLOCK(local_irqs_type_lock);
 
@@ -76,7 +82,6 @@ static int __init init_espi_data(void)
     return 0;
 }
 #else
-
 static int __init init_espi_data(void)
 {
     return 0;
@@ -95,6 +100,8 @@ struct irq_desc *__irq_to_desc(unsigned int irq)
         return espi_to_desc(irq);
 #endif
 
+    ASSERT(irq < NR_IRQS);
+
     return &irq_desc[irq-NR_LOCAL_IRQS];
 }
 
@@ -416,6 +423,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 +657,21 @@ 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 */
-    if ( spi < NR_LOCAL_IRQS )
+    /*
+     * This function should not be used for other than SPIs.
+     *
+     * The implemented GIC line counts are not available when early
+     * callers configure IRQ types. Check descriptor storage here; setup_irq()
+     * validates the implemented line before the interrupt is used.
+     */
+    if ( spi < NR_LOCAL_IRQS || !irq_has_desc(spi) )
         return -EINVAL;
 
+    desc = irq_to_desc(spi);
+
     spin_lock_irqsave(&desc->lock, flags);
 
     if ( !irq_validate_new_type(desc->arch.type, type) )
-- 
2.43.0




 


Rackspace

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