[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v6 04/12] xen/arm/irq: add handling for IRQs in the eSPI range
Hi Volodymyr, Thank you for your close review and for your time while reviewing so many versions. On 03.09.25 23:56, Volodymyr Babchuk wrote: > Hi Leonid, > > Leonid Komarianskyi <Leonid_Komarianskyi@xxxxxxxx> writes: > >> 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@xxxxxxxx> >> >> --- >> Changes in V6: >> - added an assert in is_espi() when CONFIG_GICV3_ESPI=n to ensure that >> out-of-range array resources are not accessed, e.g., in __irq_to_desc() >> - removed unnecessary parentheses in is_espi() >> - converted helper macro to inline functions and added sanity checks >> with ASSERTs to them >> - defined espi_to_desc for non-eSPI builds as a prototype >> - updates the comments >> - used the IS_ENABLED(CONFIG_GICV3_ESPI) macro to initialize nr_irqs >> >> Changes in V5: >> - no functional changes introduced by this version compared with V4, only >> minor fixes and removal of ifdefs for macroses >> - added TODO comment, suggested by Oleksandr Tyshchenko >> - changed int to unsigned int for irqs >> - removed ifdefs for eSPI-specific defines and macros to reduce the >> number of ifdefs and code duplication in further changes >> - removed reviewed-by as moving defines from ifdefs requires additional >> confirmation from reviewers >> >> Changes in V4: >> - removed redundant line with 'default n' in Kconfig, as it is disabled >> by default, without explicit specification >> - added reviewed-by from Volodymyr Babchuk >> >> Changes in V3: >> - introduced a new define NR_ESPI_IRQS to avoid confusion, like in the >> case of using NR_IRQS for espi_desc array >> - implemented helper functions espi_to_desc and init_espi_data to make >> it possible to add stubs with the same name, and as a result, reduce >> the number of #ifdefs >> - disable CONFIG_GICV3_ESPI default value to n >> >> Changes in V2: >> - use (ESPI_MAX_INTID + 1) instead of (ESPI_BASE_INTID + NR_IRQS) >> - remove unnecessary comment for nr_irqs initialization >> --- >> xen/arch/arm/Kconfig | 8 +++++ >> xen/arch/arm/include/asm/irq.h | 37 ++++++++++++++++++++++++ >> xen/arch/arm/irq.c | 53 ++++++++++++++++++++++++++++++++-- >> 3 files changed, 96 insertions(+), 2 deletions(-) >> >> diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig >> index 17df147b25..43b05533b1 100644 >> --- a/xen/arch/arm/Kconfig >> +++ b/xen/arch/arm/Kconfig >> @@ -135,6 +135,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 >> diff --git a/xen/arch/arm/include/asm/irq.h b/xen/arch/arm/include/asm/irq.h >> index 5bc6475eb4..f4d0997651 100644 >> --- a/xen/arch/arm/include/asm/irq.h >> +++ b/xen/arch/arm/include/asm/irq.h >> @@ -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 asignmant 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 unsigned int espi_intid_to_idx(unsigned int intid) >> +{ >> + ASSERT(intid >= ESPI_BASE_INTID && intid <= ESPI_MAX_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; >> +} >> + >> +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, e.g., in __irq_to_desc(). >> + */ >> + ASSERT(irq >= ESPI_BASE_INTID); > > This really puzzles me. Should it be other way around? I.e. > > ASSERT(irq < ESPI_BASE_INTID) ? Or even ASSERT(irq <= 1022) ? > > Actually, I tried to your series. XEN does not boots at all when > CONFIG_GICV3_ESPI=n. Looks like it panics even before it can bring up > the console, as I don't see any prints in QEMU. Non-debug build boots > fine, thought, but this is expected, as ASSERTs are disabled. > > Yes, it's my bad, I really apologize for that. It is a critical issue. It should definitely be at least irq < ESPI_BASE_INTID... >> + return false; >> +#endif >> +} >> + >> #define domain_pirq_to_irq(d, pirq) (pirq) >> >> bool is_assignable_irq(unsigned int irq); >> diff --git a/xen/arch/arm/irq.c b/xen/arch/arm/irq.c >> index b8eccfc924..c934d39bf6 100644 >> --- a/xen/arch/arm/irq.c >> +++ b/xen/arch/arm/irq.c >> @@ -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,50 @@ 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 */ > > I'd considered using radix tree, honestly... But this is just topic for > discussion, no action should be taken here. > >> +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 >> +/* >> + * Defined as a prototype as it should not be called if CONFIG_GICV3_ESPI=n. >> + * Without CONFIG_GICV3_ESPI, the additional 1024 IRQ descriptors will not >> + * be defined, and thus, they cannot be used. Unless INTIDs from the eSPI >> + * range are mistakenly defined in Xen DTS when the appropriate config is >> + * disabled, this function will not be reached because is_espi will return >> + * false for non-eSPI INTIDs. >> + */ >> +struct irq_desc *espi_to_desc(unsigned int irq); >> + >> +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 +99,9 @@ struct irq_desc *__irq_to_desc(unsigned int irq) >> if ( irq < NR_LOCAL_IRQS ) >> return &this_cpu(local_irq_desc)[irq]; >> >> + if ( is_espi(irq) ) >> + return espi_to_desc(irq); >> + >> return &irq_desc[irq-NR_LOCAL_IRQS]; >> } >> >> @@ -79,7 +128,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) > Best regards, Leonid
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |