xen/arm/irq: add handling for IRQs in the eSPI range

Currently, Xen does not support eSPI interrupts, leading
to a data abort when such interrupts are defined in the DTS.

This patch introduces a separate array to initialize up to
1024 interrupt descriptors in the eSPI range and adds the
necessary defines and helper function. These changes lay the
groundwork for future implementation of full eSPI interrupt
support. As this GICv3.1 feature is not required by all vendors,
all changes are guarded by ifdefs, depending on the corresponding
Kconfig option.

Signed-off-by: Leonid Komarianskyi <leonid_komarianskyi@epam.com>
Reviewed-by: Volodymyr Babchuk <volodymyr_babchuk@epam.com>
Reviewed-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
Acked-by: Stefano Stabellini <sstabellini@kernel.org>
This commit is contained in:
Leonid Komarianskyi authored and Stefano Stabellini committed 2025-09-09 16:31:53 -07:00
1 parent 2b8b93fa96
commit 98f7060b9e
3 files changed
+89 -2

No files matched your search

+8
View File
@@ -134,6 +134,14 @@ config GICV3
Driver for the ARM Generic Interrupt Controller v3.
If unsure, use the default setting.
config GICV3_ESPI
bool "Extended SPI range support"
depends on GICV3 && !NEW_VGIC
help
Allow Xen and domains to use interrupt numbers from the extended SPI
range, from 4096 to 5119. This feature is introduced in GICv3.1
architecture.
config HAS_ITS
bool "GICv3 ITS MSI controller support (UNSUPPORTED)" if UNSUPPORTED
depends on GICV3 && !NEW_VGIC && !ARM_32
+37
View File
@@ -32,6 +32,10 @@ struct arch_irq_desc {
#define SPI_MAX_INTID 1019
#define LPI_OFFSET 8192
#define ESPI_BASE_INTID 4096
#define ESPI_MAX_INTID 5119
#define NR_ESPI_IRQS 1024
/* LPIs are always numbered starting at 8192, so 0 is a good invalid case. */
#define INVALID_LPI 0
@@ -39,7 +43,12 @@ struct arch_irq_desc {
#define INVALID_IRQ 1023
extern const unsigned int nr_irqs;
#ifdef CONFIG_GICV3_ESPI
/* This will cover the eSPI range, to allow assignment of eSPIs to domains. */
#define nr_static_irqs (ESPI_MAX_INTID + 1)
#else
#define nr_static_irqs NR_IRQS
#endif
struct irq_desc;
struct irqaction;
@@ -55,6 +64,34 @@ static inline bool is_lpi(unsigned int irq)
return irq >= LPI_OFFSET;
}
static inline bool is_espi(unsigned int irq)
{
#ifdef CONFIG_GICV3_ESPI
return irq >= ESPI_BASE_INTID && irq <= ESPI_MAX_INTID;
#else
/*
* The function should not be called for eSPIs when CONFIG_GICV3_ESPI is
* disabled. Returning false allows the compiler to optimize the code
* when the config is disabled, while the assert ensures that out-of-range
* array resources are not accessed.
*/
ASSERT(!(irq >= ESPI_BASE_INTID && irq <= ESPI_MAX_INTID));
return false;
#endif
}
static inline unsigned int espi_intid_to_idx(unsigned int intid)
{
ASSERT(is_espi(intid));
return intid - ESPI_BASE_INTID;
}
static inline unsigned int espi_idx_to_intid(unsigned int idx)
{
ASSERT(idx <= NR_ESPI_IRQS);
return idx + ESPI_BASE_INTID;
}
#define domain_pirq_to_irq(d, pirq) (pirq)
bool is_assignable_irq(unsigned int irq);
+44 -2
View File
@@ -19,7 +19,9 @@
#include <asm/gic.h>
#include <asm/vgic.h>
const unsigned int nr_irqs = NR_IRQS;
const unsigned int nr_irqs = IS_ENABLED(CONFIG_GICV3_ESPI) ?
(ESPI_MAX_INTID + 1) :
NR_IRQS;
static unsigned int local_irqs_type[NR_LOCAL_IRQS];
static DEFINE_SPINLOCK(local_irqs_type_lock);
@@ -46,6 +48,41 @@ void irq_end_none(struct irq_desc *irq)
}
static irq_desc_t irq_desc[NR_IRQS - NR_LOCAL_IRQS];
#ifdef CONFIG_GICV3_ESPI
/* TODO: Consider allocating an array dynamically */
static irq_desc_t espi_desc[NR_ESPI_IRQS];
static struct irq_desc *espi_to_desc(unsigned int irq)
{
return &espi_desc[espi_intid_to_idx(irq)];
}
static int __init init_espi_data(void)
{
unsigned int irq;
for ( irq = ESPI_BASE_INTID; irq <= ESPI_MAX_INTID; irq++ )
{
struct irq_desc *desc = irq_to_desc(irq);
int rc = init_one_irq_desc(desc);
if ( rc )
return rc;
desc->irq = irq;
desc->action = NULL;
}
return 0;
}
#else
static int __init init_espi_data(void)
{
return 0;
}
#endif
static DEFINE_PER_CPU(irq_desc_t[NR_LOCAL_IRQS], local_irq_desc);
struct irq_desc *__irq_to_desc(unsigned int irq)
@@ -53,6 +90,11 @@ 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];
}
@@ -79,7 +121,7 @@ static int __init init_irq_data(void)
desc->action = NULL;
}
return 0;
return init_espi_data();
}
static int init_local_irq_data(unsigned int cpu)
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.