diff --git a/arch/arm64/kernel/watchdog_sdei.c b/arch/arm64/kernel/watchdog_sdei.c index 99ab9bdfdee6e891afdbb0f560beb72ff3154f01..c342f86560d530790cbb92848c3d03de8da8ed89 100644 --- a/arch/arm64/kernel/watchdog_sdei.c +++ b/arch/arm64/kernel/watchdog_sdei.c @@ -30,7 +30,11 @@ int watchdog_nmi_enable(unsigned int cpu) if (!sdei_watchdog_registered) return -EINVAL; +#ifdef CONFIG_HARDLOCKUP_CHECK_TIMESTAMP refresh_hld_last_timestamp(); +#endif + + sdei_api_set_secure_timer_period(watchdog_thresh); ret = sdei_api_event_enable(sdei_watchdog_event_num); if (ret) { @@ -104,6 +108,17 @@ int __init watchdog_nmi_probe(void) return sdei_watchdog_event_num; } + /* + * After we introduced 'sdei_api_set_secure_timer_period', we disselect + * 'CONFIG_HARDLOCKUP_CHECK_TIMESTAMP'. So we need to make sure that + * firmware can set the period of the secure timer and the timer + * interrupt doesn't trigger too soon. + */ + if (sdei_api_set_secure_timer_period(watchdog_thresh)) { + pr_err("Firmware doesn't support setting the secure timer period, please update your BIOS !\n"); + return -EINVAL; + } + on_each_cpu(sdei_nmi_watchdog_bind, NULL, true); ret = sdei_event_register(sdei_watchdog_event_num, diff --git a/drivers/firmware/arm_sdei.c b/drivers/firmware/arm_sdei.c index 9231acf5d2e3ae13f4a03c2e89da613719b46528..ac21e8d77ecdf0bc7a6cfd2dbcef41eb07d925f8 100644 --- a/drivers/firmware/arm_sdei.c +++ b/drivers/firmware/arm_sdei.c @@ -206,6 +206,12 @@ int sdei_api_clear_eoi(int hwirq) NULL); } +int sdei_api_set_secure_timer_period(int sec) +{ + return invoke_sdei_fn(SDEI_1_0_FN_SET_SECURE_TIMER_PERIOD, sec, 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, diff --git a/include/linux/arm_sdei.h b/include/linux/arm_sdei.h index 990f4234b244c6ddefb08a6ed953c7c331e9e9d7..55d7d42ddad127ad1d9627bbb96e65675bad456b 100644 --- a/include/linux/arm_sdei.h +++ b/include/linux/arm_sdei.h @@ -42,6 +42,7 @@ 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); +int sdei_api_set_secure_timer_period(int sec); #ifdef CONFIG_ARM_SDE_INTERFACE /* For use by arch code when CPU hotplug notifiers are not appropriate. */ diff --git a/include/uapi/linux/arm_sdei.h b/include/uapi/linux/arm_sdei.h index 1187b1b49c87db86884d9ac50abebced596109b9..a5375679dd503dbef5acc176442ecd073773aef3 100644 --- a/include/uapi/linux/arm_sdei.h +++ b/include/uapi/linux/arm_sdei.h @@ -25,6 +25,7 @@ #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_1_0_FN_SET_SECURE_TIMER_PERIOD SDEI_1_0_FN(0x19) #define SDEI_VERSION_MAJOR_SHIFT 48 #define SDEI_VERSION_MAJOR_MASK 0x7fff diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 486ba8fa74bf84dea28c6814d3e02cc712a9a017..5f8d154a2cf9d977de090342423149612eac53ec 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -845,7 +845,6 @@ config SDEI_WATCHDOG bool "SDEI NMI Watchdog support" depends on ARM_SDE_INTERFACE select HAVE_HARDLOCKUP_DETECTOR_ARCH - select HARDLOCKUP_CHECK_TIMESTAMP config PMU_WATCHDOG bool "PMU NMI Watchdog support"