提交 0fa83fd0 编写于 作者: X Xiongfeng Wang 提交者: Zheng Zengkai

sdei_watchdog: avoid possible false hardlockup

hulk inclusion
category: feature
bugzilla: 48046
CVE: NA

-------------------------------------------------------------------------

Firmware may not trigger SDEI event as required frequency. SDEI event
may be triggered too soon, which cause false hardlockup in kernel. Check
the time stamp in sdei_watchdog_callbak and skip the hardlockup check if
it is invoked too soon.
Signed-off-by: NXiongfeng Wang <wangxiongfeng2@huawei.com>
Reviewed-by: NHanjun Guo <guohanjun@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
Signed-off-by: NXiongfeng Wang <wangxiongfeng2@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 bdda54cc
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
static int sdei_watchdog_event_num; static int sdei_watchdog_event_num;
static bool disable_sdei_nmi_watchdog; static bool disable_sdei_nmi_watchdog;
static bool sdei_watchdog_registered; static bool sdei_watchdog_registered;
static DEFINE_PER_CPU(ktime_t, last_check_time);
int watchdog_nmi_enable(unsigned int cpu) int watchdog_nmi_enable(unsigned int cpu)
{ {
...@@ -35,6 +36,7 @@ int watchdog_nmi_enable(unsigned int cpu) ...@@ -35,6 +36,7 @@ int watchdog_nmi_enable(unsigned int cpu)
refresh_hld_last_timestamp(); refresh_hld_last_timestamp();
#endif #endif
__this_cpu_write(last_check_time, ktime_get_mono_fast_ns());
sdei_api_set_secure_timer_period(watchdog_thresh); sdei_api_set_secure_timer_period(watchdog_thresh);
ret = sdei_api_event_enable(sdei_watchdog_event_num); ret = sdei_api_event_enable(sdei_watchdog_event_num);
...@@ -63,6 +65,23 @@ void watchdog_nmi_disable(unsigned int cpu) ...@@ -63,6 +65,23 @@ void watchdog_nmi_disable(unsigned int cpu)
static int sdei_watchdog_callback(u32 event, static int sdei_watchdog_callback(u32 event,
struct pt_regs *regs, void *arg) struct pt_regs *regs, void *arg)
{ {
ktime_t delta, now = ktime_get_mono_fast_ns();
delta = now - __this_cpu_read(last_check_time);
__this_cpu_write(last_check_time, now);
/*
* Set delta to 4/5 of the actual watchdog threshold period so the
* hrtimer is guaranteed to fire at least once within the real
* watchdog threshold.
*/
if (delta < watchdog_thresh * (u64)NSEC_PER_SEC * 4 / 5) {
pr_err(FW_BUG "SDEI Watchdog event triggered too soon, "
"time to last check:%lld ns\n", delta);
WARN_ON(1);
return 0;
}
watchdog_hardlockup_check(regs); watchdog_hardlockup_check(regs);
return 0; return 0;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册