[tip: irq/drivers] irqchip/gic: Simplify Maintenance Interrupt ACPI parsing
From: tip-bot2 for Marc Zyngier
Date: Fri Sep 04 2026 - 10:14:18 EST
The following commit has been merged into the irq/drivers branch of tip:
Commit-ID: b36bfa477b77901a247e7a192e7404b39e9f522d
Gitweb: https://git.kernel.org/tip/b36bfa477b77901a247e7a192e7404b39e9f522d
Author: Marc Zyngier <maz@xxxxxxxxxx>
AuthorDate: Sat, 25 Jul 2026 16:59:41 +01:00
Committer: Thomas Gleixner <tglx@xxxxxxxxxx>
CommitterDate: Fri, 04 Sep 2026 15:34:33 +02:00
irqchip/gic: Simplify Maintenance Interrupt ACPI parsing
The ACPI spec describes the vgic Maintenance Interrupt with attributes
indicating whether the signalling is Level or Edge. While this
superficially looks like a sensible thing to do, it doesn't actually
make much sense.
By construction, this interrupt is Level, and cannot be anything
else, as the hypervisor actively needs to interact with the vgic
for the level to drop. This indicates a state, and not an event.
Get rid of this nonsense, always register the corresponding GSI as
Level, and let the user know that they run on quality FW should
the interrupt be advertised as Edge.
Signed-off-by: Marc Zyngier <maz@xxxxxxxxxx>
Signed-off-by: Thomas Gleixner <tglx@xxxxxxxxxx>
Reviewed-by: Zenghui Yu <yuzenghui@xxxxxxxxxx>
Reviewed-by: Radu Rendec <radu@xxxxxxxxxx>
Link: https://patch.msgid.link/20260725155941.114322-1-maz@xxxxxxxxxx
---
drivers/irqchip/irq-gic-v3.c | 10 +++-------
drivers/irqchip/irq-gic.c | 8 ++++----
2 files changed, 7 insertions(+), 11 deletions(-)
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index 6e1fa5b..b0fca8f 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -2276,7 +2276,6 @@ static struct
bool single_redist;
int enabled_rdists;
u32 maint_irq;
- int maint_irq_mode;
phys_addr_t vcpu_base;
} acpi_data __initdata;
@@ -2454,21 +2453,19 @@ static int __init gic_acpi_parse_virt_madt_gicc(union acpi_subtable_headers *hea
{
struct acpi_madt_generic_interrupt *gicc =
(struct acpi_madt_generic_interrupt *)header;
- int maint_irq_mode;
static int first_madt = true;
if (!(gicc->flags &
(ACPI_MADT_ENABLED | ACPI_MADT_GICC_ONLINE_CAPABLE)))
return 0;
- maint_irq_mode = (gicc->flags & ACPI_MADT_VGIC_IRQ_MODE) ?
- ACPI_EDGE_SENSITIVE : ACPI_LEVEL_SENSITIVE;
+ if (gicc->flags & ACPI_MADT_VGIC_IRQ_MODE)
+ pr_warn_once(FW_BUG "MI wrongly advertised as Edge-triggered\n");
if (first_madt) {
first_madt = false;
acpi_data.maint_irq = gicc->vgic_interrupt;
- acpi_data.maint_irq_mode = maint_irq_mode;
acpi_data.vcpu_base = gicc->gicv_base_address;
return 0;
@@ -2478,7 +2475,6 @@ static int __init gic_acpi_parse_virt_madt_gicc(union acpi_subtable_headers *hea
* The maintenance interrupt and GICV should be the same for every CPU
*/
if ((acpi_data.maint_irq != gicc->vgic_interrupt) ||
- (acpi_data.maint_irq_mode != maint_irq_mode) ||
(acpi_data.vcpu_base != gicc->gicv_base_address))
return -EINVAL;
@@ -2511,7 +2507,7 @@ static void __init gic_acpi_setup_kvm_info(void)
gic_v3_kvm_info.type = GIC_V3;
irq = acpi_register_gsi(NULL, acpi_data.maint_irq,
- acpi_data.maint_irq_mode,
+ ACPI_LEVEL_SENSITIVE,
ACPI_ACTIVE_HIGH);
if (irq <= 0)
return;
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index f6bc29f..b2926a3 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -1527,7 +1527,6 @@ static struct
{
phys_addr_t cpu_phys_base;
u32 maint_irq;
- int maint_irq_mode;
phys_addr_t vctrl_base;
phys_addr_t vcpu_base;
} acpi_data __initdata;
@@ -1553,10 +1552,11 @@ gic_acpi_parse_madt_cpu(union acpi_subtable_headers *header,
if (cpu_base_assigned && gic_cpu_base != acpi_data.cpu_phys_base)
return -EINVAL;
+ if (processor->flags & ACPI_MADT_VGIC_IRQ_MODE)
+ pr_warn_once(FW_BUG "MI wrongly advertised as Edge-triggered\n");
+
acpi_data.cpu_phys_base = gic_cpu_base;
acpi_data.maint_irq = processor->vgic_interrupt;
- acpi_data.maint_irq_mode = (processor->flags & ACPI_MADT_VGIC_IRQ_MODE) ?
- ACPI_EDGE_SENSITIVE : ACPI_LEVEL_SENSITIVE;
acpi_data.vctrl_base = processor->gich_base_address;
acpi_data.vcpu_base = processor->gicv_base_address;
@@ -1616,7 +1616,7 @@ static void __init gic_acpi_setup_kvm_info(void)
vcpu_res->end = vcpu_res->start + ACPI_GICV2_VCPU_MEM_SIZE - 1;
irq = acpi_register_gsi(NULL, acpi_data.maint_irq,
- acpi_data.maint_irq_mode,
+ ACPI_LEVEL_SENSITIVE,
ACPI_ACTIVE_HIGH);
if (irq <= 0)
return;