[PATCH] x86/hpet: Read HPET directly if panic in progress

From: Tony W Wang-oc
Date: Tue May 28 2024 - 02:55:08 EST


When the clocksource of the system is HPET,a CPU executing read_hpet
might be interrupted by exceptions to executing the panic,this may
lead to read_hpet dead loops:

CPU x CPU x
---- ----
read_hpet()
arch_spin_trylock(&hpet.lock)
[CPU x got the hpet.lock] #MCE happened
do_machine_check()
mce_panic()
panic()
kmsg_dump()
pstore_dump()
pstore_record_init()
ktime_get_real_fast_ns()
read_hpet()
[dead loops]

To avoid this dead loops, read HPET directly if panic in progress.

Signed-off-by: Tony W Wang-oc <TonyWWang-oc@xxxxxxxxxxx>
---
arch/x86/kernel/hpet.c | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index c96ae8fee95e..ecadd0698d6a 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -804,6 +804,12 @@ static u64 read_hpet(struct clocksource *cs)
if (in_nmi())
return (u64)hpet_readl(HPET_COUNTER);

+ /*
+ * Read HPET directly if panic in progress.
+ */
+ if (unlikely(atomic_read(&panic_cpu) != PANIC_CPU_INVALID))
+ return (u64)hpet_readl(HPET_COUNTER);
+
/*
* Read the current state of the lock and HPET value atomically.
*/
--
2.25.1