From a94fed6c9ffb02a303eb00d9d7953101ea8ee0b1 Mon Sep 17 00:00:00 2001 From: Xiongfeng Wang Date: Fri, 15 Feb 2019 15:53:35 +0800 Subject: [PATCH] sdei_watchdog: refresh 'last_timestamp' when enabling nmi_watchdog euler inclusion category: feature Bugzilla: 5515 CVE: N/A ---------------------------------------- The trigger period of secure time is set by firmware. We need to check the time_stamp every time the secure time fires to make sure the hardlockup detection is not executed too soon. We need to refresh 'last_timestamp' to the current time when we enable the nmi_watchdog. Otherwise, false hardlockup may be detected when the secure timer fires the first time. Signed-off-by: Xiongfeng Wang Reviewed-by: Hanjun Guo Signed-off-by: Yang Yingliang --- arch/arm64/kernel/watchdog_sdei.c | 2 ++ include/linux/nmi.h | 1 + kernel/watchdog_hld.c | 9 +++++++++ 3 files changed, 12 insertions(+) diff --git a/arch/arm64/kernel/watchdog_sdei.c b/arch/arm64/kernel/watchdog_sdei.c index 874d51363f6c..4fd1419729c2 100644 --- a/arch/arm64/kernel/watchdog_sdei.c +++ b/arch/arm64/kernel/watchdog_sdei.c @@ -26,6 +26,8 @@ int watchdog_nmi_enable(unsigned int cpu) { int ret; + refresh_hld_last_timestamp(); + ret = sdei_api_event_enable(sdei_watchdog_event_num); if (ret) { pr_err("Enable NMI Watchdog failed on cpu%d\n", diff --git a/include/linux/nmi.h b/include/linux/nmi.h index 9ce94235a05f..f65cfbb5d46c 100644 --- a/include/linux/nmi.h +++ b/include/linux/nmi.h @@ -204,6 +204,7 @@ u64 hw_nmi_get_sample_period(int watchdog_thresh); #if defined(CONFIG_HARDLOCKUP_CHECK_TIMESTAMP) && \ defined(CONFIG_HARDLOCKUP_DETECTOR) void watchdog_update_hrtimer_threshold(u64 period); +void refresh_hld_last_timestamp(void); #else static inline void watchdog_update_hrtimer_threshold(u64 period) { } #endif diff --git a/kernel/watchdog_hld.c b/kernel/watchdog_hld.c index 0f105c06d831..6eafba4223dd 100644 --- a/kernel/watchdog_hld.c +++ b/kernel/watchdog_hld.c @@ -87,6 +87,15 @@ static bool watchdog_check_timestamp(void) __this_cpu_write(last_timestamp, now); return true; } + +void refresh_hld_last_timestamp(void) +{ + ktime_t now; + + now = ktime_get_mono_fast_ns(); + __this_cpu_write(last_timestamp, now); + +} #else static inline bool watchdog_check_timestamp(void) { -- GitLab