Skip to content

Commit 926b5df

Browse files
author
Marc Zyngier
committed
irqchip/gic-v3: Only provision redistributors that are enabled in ACPI
We currently allocate redistributor region structures for individual redistributors when ACPI doesn't present us with compact MMIO regions covering multiple redistributors. It turns out that we allocate these structures even when the redistributor is flagged as disabled by ACPI. It works fine until someone actually tries to tarse one of these structures, and access the corresponding MMIO region. Instead, track the number of enabled redistributors, and only allocate what is required. This makes sure that there is no invalid data to misuse. Signed-off-by: Marc Zyngier <[email protected]> Reported-by: Heyi Guo <[email protected]> Tested-by: Heyi Guo <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent f4a81f5 commit 926b5df

File tree

1 file changed

+7
-2
lines changed

1 file changed

+7
-2
lines changed

drivers/irqchip/irq-gic-v3.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1839,6 +1839,7 @@ static struct
18391839
struct redist_region *redist_regs;
18401840
u32 nr_redist_regions;
18411841
bool single_redist;
1842+
int enabled_rdists;
18421843
u32 maint_irq;
18431844
int maint_irq_mode;
18441845
phys_addr_t vcpu_base;
@@ -1933,8 +1934,10 @@ static int __init gic_acpi_match_gicc(union acpi_subtable_headers *header,
19331934
* If GICC is enabled and has valid gicr base address, then it means
19341935
* GICR base is presented via GICC
19351936
*/
1936-
if ((gicc->flags & ACPI_MADT_ENABLED) && gicc->gicr_base_address)
1937+
if ((gicc->flags & ACPI_MADT_ENABLED) && gicc->gicr_base_address) {
1938+
acpi_data.enabled_rdists++;
19371939
return 0;
1940+
}
19381941

19391942
/*
19401943
* It's perfectly valid firmware can pass disabled GICC entry, driver
@@ -1964,8 +1967,10 @@ static int __init gic_acpi_count_gicr_regions(void)
19641967

19651968
count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT,
19661969
gic_acpi_match_gicc, 0);
1967-
if (count > 0)
1970+
if (count > 0) {
19681971
acpi_data.single_redist = true;
1972+
count = acpi_data.enabled_rdists;
1973+
}
19691974

19701975
return count;
19711976
}

0 commit comments

Comments
 (0)