summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Zyngier <maz@kernel.org>2019-12-16 11:24:57 +0000
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-02-24 08:34:52 +0100
commit60f3843b695b9bccaff70a46d5975613d5386c7d (patch)
treed9479ae42ddf135b85f6cf20ed33a235058ef00b
parent138ed22777b48332712220e2ea57ef4dafe1dab6 (diff)
downloadlinux-stable-60f3843b695b9bccaff70a46d5975613d5386c7d.tar.gz
linux-stable-60f3843b695b9bccaff70a46d5975613d5386c7d.tar.bz2
linux-stable-60f3843b695b9bccaff70a46d5975613d5386c7d.zip
irqchip/gic-v3: Only provision redistributors that are enabled in ACPI
[ Upstream commit 926b5dfa6b8dc666ff398044af6906b156e1d949 ] 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 <maz@kernel.org> Reported-by: Heyi Guo <guoheyi@huawei.com> Tested-by: Heyi Guo <guoheyi@huawei.com> Link: https://lore.kernel.org/r/20191216062745.63397-1-guoheyi@huawei.com Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--drivers/irqchip/irq-gic-v3.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index d5912f1ec884..ac888d7a0b00 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -1347,6 +1347,7 @@ static struct
struct redist_region *redist_regs;
u32 nr_redist_regions;
bool single_redist;
+ int enabled_rdists;
u32 maint_irq;
int maint_irq_mode;
phys_addr_t vcpu_base;
@@ -1441,8 +1442,10 @@ static int __init gic_acpi_match_gicc(struct acpi_subtable_header *header,
* If GICC is enabled and has valid gicr base address, then it means
* 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;
+ }
/*
* It's perfectly valid firmware can pass disabled GICC entry, driver
@@ -1472,8 +1475,10 @@ static int __init gic_acpi_count_gicr_regions(void)
count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT,
gic_acpi_match_gicc, 0);
- if (count > 0)
+ if (count > 0) {
acpi_data.single_redist = true;
+ count = acpi_data.enabled_rdists;
+ }
return count;
}