From 12f5096ab6649d64817559c7c0bc2eeeeaaebce1 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Fri, 27 Jul 2018 16:23:18 +0100 Subject: [PATCH] irqchip/gic-v3-its: Allow use of LPI tables in reserved memory commit 5e2c9f9a627772672accd80fa15359c0de6aa894 upstream If the LPI tables have been reserved with the EFI reservation mechanism, we assume that these tables are safe to use even when we find the redistributors to have LPIs enabled at boot time, meaning that kexec can now work with GICv3. You're welcome. Tested-by: Jeremy Linton Tested-by: Bhupesh Sharma Tested-by: Lei Zhang Signed-off-by: Marc Zyngier Signed-off-by: Zou Cao Reviewed-by: Baoyou Xie --- drivers/irqchip/irq-gic-v3-its.c | 43 ++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index c257a92f0028..e16f57028d65 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -1651,6 +1652,33 @@ static void its_free_prop_table(struct page *prop_page) get_order(LPI_PROPBASE_SZ)); } +static bool gic_check_reserved_range(phys_addr_t addr, unsigned long size) +{ + phys_addr_t start, end, addr_end; + u64 i; + + /* + * We don't bother checking for a kdump kernel as by + * construction, the LPI tables are out of this kernel's + * memory map. + */ + if (is_kdump_kernel()) + return true; + + addr_end = addr + size - 1; + + for_each_reserved_mem_region(i, &start, &end) { + if (addr >= start && addr_end <= end) + return true; + } + + /* Not found, not a good sign... */ + pr_warn("GICv3: Expected reserved range [%pa:%pa], not found\n", + &addr, &addr_end); + add_taint(TAINT_CRAP, LOCKDEP_STILL_OK); + return false; +} + static int gic_reserve_range(phys_addr_t addr, unsigned long size) { if (efi_enabled(EFI_CONFIG_TABLES)) @@ -2004,15 +2032,19 @@ static void its_free_pending_table(struct page *pt) } /* - * Booting with kdump and LPIs enabled is generally fine. + * Booting with kdump and LPIs enabled is generally fine. Any other + * case is wrong in the absence of firmware/EFI support. */ static bool enabled_lpis_allowed(void) { - /* Allow a kdump kernel */ - if (is_kdump_kernel()) - return true; + phys_addr_t addr; + u64 val; - return false; + /* Check whether the property table is in a reserved region */ + val = gicr_read_propbaser(gic_data_rdist_rd_base() + GICR_PROPBASER); + addr = val & GENMASK_ULL(51, 12); + + return gic_check_reserved_range(addr, LPI_PROPBASE_SZ); } static u64 its_clear_vpend_valid(void __iomem *vlpi_base) @@ -2103,6 +2135,7 @@ static void its_cpu_init_lpis(void) paddr = gicr_read_pendbaser(rbase + GICR_PENDBASER); paddr &= GENMASK_ULL(51, 16); + WARN_ON(!gic_check_reserved_range(paddr, LPI_PENDBASE_SZ)); its_free_pending_table(gic_data_rdist()->pend_page); gic_data_rdist()->pend_page = NULL; -- GitLab