From 5bffbe2174676c4c18b60874a30ee9e5fe273f97 Mon Sep 17 00:00:00 2001 From: Wei Li Date: Wed, 20 Mar 2019 22:29:51 +0800 Subject: [PATCH] arm64: Add support for hard lockup by using pmu counter hulk inclusion category: feature bugzilla: 12805 CVE: NA ------------------------------------------------- This patch is based on "arm64: perf: add nmi support for pmu" patch series. This feature is alternative to the SDEI NMI watchdog. As we can not get the cpu frequency, kernel cmdline parameter hardlockup_cpu_freq=xxx (in KHZ) need to be passed by user currently. If it is not be passed, the perf NMI watchdog will be disabled defaultly. Signed-off-by: Wei Li Signed-off-by: Yang Yingliang --- arch/arm64/Kconfig | 2 ++ arch/arm64/kernel/smp.c | 16 ++++++++++++++++ kernel/watchdog_hld.c | 2 ++ lib/Kconfig.debug | 2 +- 4 files changed, 21 insertions(+), 1 deletion(-) diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 9f8b65407eee..126b814170cb 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -138,6 +138,7 @@ config ARM64 select HAVE_NMI select HAVE_PATA_PLATFORM select HAVE_PERF_EVENTS + select HAVE_HARDLOCKUP_DETECTOR_PERF if PERF_EVENTS && HAVE_PERF_EVENTS_NMI select HAVE_PERF_REGS select HAVE_PERF_USER_STACK_DUMP select HAVE_REGS_AND_STACK_ACCESS_API @@ -1201,6 +1202,7 @@ config ARM64_MODULE_PLTS config ARM64_PSEUDO_NMI bool "Support for NMI-like interrupts" select CONFIG_ARM_GIC_V3 + select HAVE_PERF_EVENTS_NMI help Adds support for mimicking Non-Maskable Interrupts through the use of GIC interrupt priority. This support requires version 3 or later of diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index 9a4b67e88bd7..1e77a26d13eb 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -1107,3 +1107,19 @@ void arch_trigger_cpumask_backtrace(const cpumask_t *mask, bool exclude_self) { nmi_trigger_cpumask_backtrace(mask, exclude_self, raise_nmi); } + +#ifdef CONFIG_HARDLOCKUP_DETECTOR_PERF +u64 hardlockup_cpu_freq; + +static int __init hardlockup_cpu_freq_setup(char *str) +{ + hardlockup_cpu_freq = simple_strtoull(str, NULL, 0); + return 1; +} +__setup("hardlockup_cpu_freq=", hardlockup_cpu_freq_setup); + +u64 hw_nmi_get_sample_period(int watchdog_thresh) +{ + return hardlockup_cpu_freq * 1000 * watchdog_thresh; +} +#endif diff --git a/kernel/watchdog_hld.c b/kernel/watchdog_hld.c index 6eafba4223dd..aaa08dad884f 100644 --- a/kernel/watchdog_hld.c +++ b/kernel/watchdog_hld.c @@ -186,6 +186,8 @@ static int hardlockup_detector_event_create(void) wd_attr = &wd_hw_attr; wd_attr->sample_period = hw_nmi_get_sample_period(watchdog_thresh); + if (!wd_attr->sample_period) + return -EINVAL; /* Try to register using hardware perf events */ evt = perf_event_create_kernel_counter(wd_attr, cpu, NULL, diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 8194d5d4bc53..7b1133dab07a 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -837,7 +837,7 @@ config HARDLOCKUP_DETECTOR_PERF config SDEI_WATCHDOG bool "SDEI NMI Watchdog support" - depends on ARM_SDE_INTERFACE + depends on ARM_SDE_INTERFACE && !HAVE_HARDLOCKUP_DETECTOR_PERF select HAVE_HARDLOCKUP_DETECTOR_ARCH select HARDLOCKUP_CHECK_TIMESTAMP -- GitLab