summaryrefslogtreecommitdiff
path: root/drivers/irqchip/irq-gic-v3.c
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2018-02-25 14:27:04 +0300
committerMarc Zyngier <marc.zyngier@arm.com>2018-03-14 14:11:29 +0300
commitf736d65df0acefcb50f7f7c6ad6070e7b954c79a (patch)
treee82235f2508b40e3c7727ffb6f7834a96cb2b3bc /drivers/irqchip/irq-gic-v3.c
parentd6062a6d62c643a06c393745d032da3e6441d4bd (diff)
downloadlinux-f736d65df0acefcb50f7f7c6ad6070e7b954c79a.tar.xz
irqchip/gic-v3: Allow LPIs to be disabled from the command line
For most GICv3 implementations, enabling LPIs is a one way switch. Once they're on, there is no turning back, which completely kills kexec (pending tables will always be live, and we can't tell the secondary kernel where they are). This is really annoying if you plan to use Linux as a bootloader, as it pretty much guarantees that the secondary kernel won't be able to use MSIs, and may even see some memory corruption. Bad. A workaround for this unfortunate situation is to allow the kernel not to enable LPIs, even if the feature is present in the HW. This would allow Linux-as-a-bootloader to leave LPIs alone, and let the secondary kernel to do whatever it wants with them. Let's introduce a boolean "irqchip.gicv3_nolpi" command line option that serves that purpose. Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Diffstat (limited to 'drivers/irqchip/irq-gic-v3.c')
-rw-r--r--drivers/irqchip/irq-gic-v3.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index 0ea02504115d..3e9eeb6cb294 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -613,9 +613,17 @@ static void gic_cpu_sys_reg_init(void)
pr_crit_once("RSS is required but GICD doesn't support it\n");
}
+static bool gicv3_nolpi;
+
+static int __init gicv3_nolpi_cfg(char *buf)
+{
+ return strtobool(buf, &gicv3_nolpi);
+}
+early_param("irqchip.gicv3_nolpi", gicv3_nolpi_cfg);
+
static int gic_dist_supports_lpis(void)
{
- return !!(readl_relaxed(gic_data.dist_base + GICD_TYPER) & GICD_TYPER_LPIS);
+ return !!(readl_relaxed(gic_data.dist_base + GICD_TYPER) & GICD_TYPER_LPIS) && !gicv3_nolpi;
}
static void gic_cpu_init(void)