aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Thompson <daniel.thompson@linaro.org>2015-11-20 19:51:13 +0000
committerDaniel Thompson <daniel.thompson@linaro.org>2016-03-15 14:22:11 +0000
commit563ff0286948e66af5c2eae069ec49527a371b41 (patch)
tree97b76cd3e121d6e977f76adad099efa3eba9e424
parent67db8f587efaa1e93e2ff7105bbd66c1410b4641 (diff)
downloadlinux-563ff0286948e66af5c2eae069ec49527a371b41.tar.gz
arm64: Add runtime NMI disable mode
For benchmarking... Signed-off-by: Daniel Thompson <daniel.thompson@linaro.org>
-rw-r--r--arch/arm64/kernel/smp.c6
-rw-r--r--drivers/irqchip/irq-gic-v3.c19
2 files changed, 22 insertions, 3 deletions
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index e376c4c8582f..0c4637b30c04 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -334,6 +334,9 @@ void __init smp_cpus_done(unsigned int max_cpus)
apply_alternatives_all();
}
+early_param_on_off("nmi", "nonmi", enable_nmi,
+ CONFIG_USE_ICC_SYSREGS_FOR_IRQFLAGS);
+
void __init smp_prepare_boot_cpu(void)
{
cpuinfo_store_boot_cpu();
@@ -344,7 +347,8 @@ void __init smp_prepare_boot_cpu(void)
* alternatives that cannot wait until interrupt handling
* and/or scheduling is enabled.
*/
- apply_alternatives_early();
+ if (enable_nmi)
+ apply_alternatives_early();
/*
* Conditionally switch to GIC PMR for interrupt masking (this
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index 8d3d53f25768..7e9dc1c39f1f 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -377,7 +377,10 @@ static bool gic_handle_nmi(struct pt_regs *regs)
u64 irqnr;
struct pt_regs *old_regs;
- asm volatile("mrs_s %0, " __stringify(ICC_IAR1_EL1) : "=r"(irqnr));
+ asm volatile(ALTERNATIVE(
+ "mov %0, #1023",
+ "mrs_s %0, " __stringify(ICC_IAR1_EL1),
+ ARM64_HAS_SYSREG_GIC_CPUIF) : "=r"(irqnr));
/*
* If no IRQ is acknowledged at this point then we have entered the
@@ -385,7 +388,10 @@ static bool gic_handle_nmi(struct pt_regs *regs)
* If so then unmask the I-bit and return to normal handling.
*/
if (irqnr == ICC_IAR1_EL1_SPURIOUS) {
- asm volatile("msr daifclr, #2" : : : "memory");
+ asm volatile(ALTERNATIVE(
+ "nop",
+ "msr daifclr, #2",
+ ARM64_HAS_SYSREG_GIC_CPUIF) : : : "memory");
return false;
}
@@ -555,6 +561,15 @@ static void gic_cpu_sys_reg_init(void)
#ifndef CONFIG_USE_ICC_SYSREGS_FOR_IRQFLAGS
/* Set priority mask register */
gic_write_pmr(DEFAULT_PMR_VALUE);
+#else
+{
+ unsigned long pmr = DEFAULT_PMR_VALUE;
+
+ asm volatile(ALTERNATIVE(
+ "msr_s " __stringify(ICC_PMR_EL1) ", %0",
+ "nop",
+ ARM64_HAS_SYSREG_GIC_CPUIF) : : "r" (pmr));
+}
#endif
/*