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

sdei_watchdog: clear EOI of the secure timer before kdump

hulk inclusion
category: feature
bugzilla: 48046
CVE: NA

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

When we panic in hardlockup, the secure timer interrupt remains activate
because firmware clear eoi after dispatch is completed. This will cause
arm_arch_timer interrupt failed to trigger in the second kernel.

This patch add a new SMC helper to clear eoi of a certain interrupt and
clear eoi of the secure timer before booting the second kernel.
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>
上级 14d70ff4
......@@ -10,6 +10,7 @@
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/kexec.h>
#include <linux/nmi.h>
#include <linux/page-flags.h>
#include <linux/smp.h>
......@@ -254,6 +255,15 @@ void machine_crash_shutdown(struct pt_regs *regs)
/* shutdown non-crashing cpus */
crash_smp_send_stop();
/*
* when we panic in hardlockup detected by sdei_watchdog, the secure
* timer interrupt remains activate here because firmware clear eoi
* after dispatch is completed. This will cause arm_arch_timer
* interrupt failed to trigger in the second kernel. So we clear eoi
* of the secure timer before booting the second kernel.
*/
sdei_watchdog_clear_eoi();
/* for crashing cpu */
crash_save_cpu(regs, smp_processor_id());
machine_kexec_mask_interrupts();
......
......@@ -80,6 +80,12 @@ static int __init disable_sdei_nmi_watchdog_setup(char *str)
}
__setup("disable_sdei_nmi_watchdog", disable_sdei_nmi_watchdog_setup);
void sdei_watchdog_clear_eoi(void)
{
if (sdei_watchdog_registered)
sdei_api_clear_eoi(SDEI_NMI_WATCHDOG_HWIRQ);
}
int __init watchdog_nmi_probe(void)
{
int ret;
......
......@@ -197,6 +197,12 @@ int sdei_api_event_interrupt_bind(int hwirq)
return (int)event_number;
}
int sdei_api_clear_eoi(int hwirq)
{
return invoke_sdei_fn(SDEI_1_0_FN_SDEI_CLEAR_EOI, hwirq, 0, 0, 0, 0,
NULL);
}
static int sdei_api_event_get_info(u32 event, u32 info, u64 *result)
{
return invoke_sdei_fn(SDEI_1_0_FN_SDEI_EVENT_GET_INFO, event, info, 0,
......
......@@ -39,6 +39,7 @@ int sdei_event_disable(u32 event_num);
int sdei_api_event_interrupt_bind(int hwirq);
int sdei_api_event_disable(u32 event_num);
int sdei_api_event_enable(u32 event_num);
int sdei_api_clear_eoi(int hwirq);
/* GHES register/unregister helpers */
int sdei_register_ghes(struct ghes *ghes, sdei_event_callback *normal_cb,
......
......@@ -222,4 +222,10 @@ int proc_watchdog_cpumask(struct ctl_table *, int, void *, size_t *, loff_t *);
#include <asm/nmi.h>
#endif
#ifdef CONFIG_SDEI_WATCHDOG
void sdei_watchdog_clear_eoi(void);
#else
static inline void sdei_watchdog_clear_eoi(void) { }
#endif
#endif
......@@ -24,6 +24,7 @@
#define SDEI_1_0_FN_SDEI_INTERRUPT_RELEASE SDEI_1_0_FN(0x0E)
#define SDEI_1_0_FN_SDEI_PRIVATE_RESET SDEI_1_0_FN(0x11)
#define SDEI_1_0_FN_SDEI_SHARED_RESET SDEI_1_0_FN(0x12)
#define SDEI_1_0_FN_SDEI_CLEAR_EOI SDEI_1_0_FN(0x18)
#define SDEI_VERSION_MAJOR_SHIFT 48
#define SDEI_VERSION_MAJOR_MASK 0x7fff
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册