Commit 926b5dfa authored by Marc Zyngier's avatar Marc Zyngier

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: default avatarMarc Zyngier <maz@kernel.org>
Reported-by: default avatarHeyi Guo <guoheyi@huawei.com>
Tested-by: default avatarHeyi Guo <guoheyi@huawei.com>
Link: https://lore.kernel.org/r/20191216062745.63397-1-guoheyi@huawei.com
parent f4a81f5a
...@@ -1839,6 +1839,7 @@ static struct ...@@ -1839,6 +1839,7 @@ static struct
struct redist_region *redist_regs; struct redist_region *redist_regs;
u32 nr_redist_regions; u32 nr_redist_regions;
bool single_redist; bool single_redist;
int enabled_rdists;
u32 maint_irq; u32 maint_irq;
int maint_irq_mode; int maint_irq_mode;
phys_addr_t vcpu_base; phys_addr_t vcpu_base;
...@@ -1933,8 +1934,10 @@ static int __init gic_acpi_match_gicc(union acpi_subtable_headers *header, ...@@ -1933,8 +1934,10 @@ static int __init gic_acpi_match_gicc(union acpi_subtable_headers *header,
* If GICC is enabled and has valid gicr base address, then it means * If GICC is enabled and has valid gicr base address, then it means
* GICR base is presented via GICC * GICR base is presented via GICC
*/ */
if ((gicc->flags & ACPI_MADT_ENABLED) && gicc->gicr_base_address) if ((gicc->flags & ACPI_MADT_ENABLED) && gicc->gicr_base_address) {
acpi_data.enabled_rdists++;
return 0; return 0;
}
/* /*
* It's perfectly valid firmware can pass disabled GICC entry, driver * It's perfectly valid firmware can pass disabled GICC entry, driver
...@@ -1964,8 +1967,10 @@ static int __init gic_acpi_count_gicr_regions(void) ...@@ -1964,8 +1967,10 @@ static int __init gic_acpi_count_gicr_regions(void)
count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT, count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT,
gic_acpi_match_gicc, 0); gic_acpi_match_gicc, 0);
if (count > 0) if (count > 0) {
acpi_data.single_redist = true; acpi_data.single_redist = true;
count = acpi_data.enabled_rdists;
}
return count; return count;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment