From: Sascha Bischoff <Sascha.Bischoff@arm.com>
To: "linux-arm-kernel@lists.infradead.org"
<linux-arm-kernel@lists.infradead.org>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Cc: nd <nd@arm.com>, Lorenzo Pieralisi <lpieralisi@kernel.org>,
Marc Zyngier <maz@kernel.org>, Thomas Gleixner <tglx@kernel.org>
Subject: [PATCH v2 2/3] irqchip/gic-v5: Support range allocation for LPIs
Date: Wed, 6 May 2026 09:37:23 +0000 [thread overview]
Message-ID: <20260506093634.382062-3-sascha.bischoff@arm.com> (raw)
In-Reply-To: <20260506093634.382062-1-sascha.bischoff@arm.com>
The GICv5 LPI domain now owns LPI allocation and teardown internally,
but its irq_domain callbacks still reject requests where nr_irqs is
greater than one. This forces child domains to allocate and free LPIs
one at a time even when the interrupt core requests a contiguous
range.
Handle multi-interrupt allocation and teardown in the LPI domain by
iterating over the requested range and unwinding any partially
allocated state on failure.
Allocate the parent LPIs for the IPI domain with a single range
request as well. The previous per-IPI parent allocation loop returned
immediately on failure and leaked any parent IRQs allocated by earlier
iterations.
Fixes: 0f0101325876 ("irqchip/gic-v5: Add GICv5 LPI/IPI support")
Signed-off-by: Sascha Bischoff <sascha.bischoff@arm.com>
Reviewed-by: Marc Zyngier <maz@kernel.org>
Reviewed-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
---
drivers/irqchip/irq-gic-v5.c | 77 ++++++++++++++++++++----------------
1 file changed, 42 insertions(+), 35 deletions(-)
diff --git a/drivers/irqchip/irq-gic-v5.c b/drivers/irqchip/irq-gic-v5.c
index 15a2a04398d25..c1af07083ceff 100644
--- a/drivers/irqchip/irq-gic-v5.c
+++ b/drivers/irqchip/irq-gic-v5.c
@@ -801,15 +801,14 @@ static void gicv5_irq_lpi_domain_free(struct irq_domain *domain, unsigned int vi
{
struct irq_data *d;
- if (WARN_ON_ONCE(nr_irqs != 1))
- return;
-
- d = irq_domain_get_irq_data(domain, virq);
+ for (unsigned int i = 0; i < nr_irqs; i++, virq++) {
+ d = irq_domain_get_irq_data(domain, virq);
- release_lpi(d->hwirq);
+ release_lpi(d->hwirq);
- irq_set_handler(virq, NULL);
- irq_domain_reset_irq_data(d);
+ irq_set_handler(virq, NULL);
+ irq_domain_reset_irq_data(d);
+ }
}
static int gicv5_irq_lpi_domain_alloc(struct irq_domain *domain, unsigned int virq,
@@ -817,32 +816,39 @@ static int gicv5_irq_lpi_domain_alloc(struct irq_domain *domain, unsigned int vi
{
irq_hw_number_t hwirq;
struct irq_data *irqd;
+ unsigned int i;
int ret;
- if (WARN_ON_ONCE(nr_irqs != 1))
- return -EINVAL;
-
- ret = alloc_lpi();
- if (ret < 0)
- return ret;
- hwirq = ret;
+ for (i = 0; i < nr_irqs; i++) {
+ ret = alloc_lpi();
+ if (ret < 0)
+ goto out_free_lpis;
+ hwirq = ret;
+
+ ret = gicv5_irs_iste_alloc(hwirq);
+ if (ret < 0) {
+ /* Undo partial state first, then clean up the rest */
+ release_lpi(hwirq);
+ goto out_free_lpis;
+ }
- irqd = irq_domain_get_irq_data(domain, virq);
+ irqd = irq_domain_get_irq_data(domain, virq + i);
- irq_domain_set_info(domain, virq, hwirq, &gicv5_lpi_irq_chip, NULL,
- handle_fasteoi_irq, NULL, NULL);
- irqd_set_single_target(irqd);
+ irq_domain_set_info(domain, virq + i, hwirq, &gicv5_lpi_irq_chip,
+ NULL, handle_fasteoi_irq, NULL, NULL);
+ irqd_set_single_target(irqd);
- ret = gicv5_irs_iste_alloc(hwirq);
- if (ret < 0) {
- release_lpi(hwirq);
- return ret;
+ gicv5_hwirq_init(hwirq, GICV5_IRQ_PRI_MI, GICV5_HWIRQ_TYPE_LPI);
+ gicv5_lpi_config_reset(irqd);
}
- gicv5_hwirq_init(hwirq, GICV5_IRQ_PRI_MI, GICV5_HWIRQ_TYPE_LPI);
- gicv5_lpi_config_reset(irqd);
-
return 0;
+
+out_free_lpis:
+ if (i)
+ gicv5_irq_lpi_domain_free(domain, virq, i);
+
+ return ret;
}
static const struct irq_domain_ops gicv5_irq_lpi_domain_ops = {
@@ -868,21 +874,21 @@ static int gicv5_irq_ipi_domain_alloc(struct irq_domain *domain, unsigned int vi
unsigned int nr_irqs, void *arg)
{
struct irq_data *irqd;
- int ret, i;
+ int ret;
- for (i = 0; i < nr_irqs; i++) {
- ret = irq_domain_alloc_irqs_parent(domain, virq + i, 1, NULL);
- if (ret)
- return ret;
+ ret = irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, arg);
+ if (ret)
+ return ret;
- irqd = irq_domain_get_irq_data(domain, virq + i);
+ for (unsigned int i = 0; i < nr_irqs; i++, virq++) {
+ irqd = irq_domain_get_irq_data(domain, virq);
- irq_domain_set_hwirq_and_chip(domain, virq + i, i,
- &gicv5_ipi_irq_chip, NULL);
+ irq_domain_set_hwirq_and_chip(domain, virq, i,
+ &gicv5_ipi_irq_chip, NULL);
irqd_set_single_target(irqd);
- irq_set_handler(virq + i, handle_percpu_irq);
+ irq_set_handler(virq, handle_percpu_irq);
}
return 0;
@@ -902,8 +908,9 @@ static void gicv5_irq_ipi_domain_free(struct irq_domain *domain, unsigned int vi
irq_set_handler(virq + i, NULL);
irq_domain_reset_irq_data(d);
- irq_domain_free_irqs_parent(domain, virq + i, 1);
}
+
+ irq_domain_free_irqs_parent(domain, virq, nr_irqs);
}
static const struct irq_domain_ops gicv5_irq_ipi_domain_ops = {
--
2.34.1
next prev parent reply other threads:[~2026-05-06 9:38 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-06 9:36 [PATCH v2 0/3] irqchip/gic-v5: Tidy up LPI allocation Sascha Bischoff
2026-05-06 9:37 ` [PATCH v2 1/3] irqchip/gic-v5: Move LPI allocation into the LPI domain Sascha Bischoff
2026-05-06 9:37 ` Sascha Bischoff [this message]
2026-05-06 9:37 ` [PATCH v2 3/3] irqchip/gic-v5: Allocate ITS parent LPIs as a range Sascha Bischoff
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260506093634.382062-3-sascha.bischoff@arm.com \
--to=sascha.bischoff@arm.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lpieralisi@kernel.org \
--cc=maz@kernel.org \
--cc=nd@arm.com \
--cc=tglx@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox