Discussion:
[Qemu-devel] [PATCH] hw/acpi/tco.c: fix tco timer stop
Michael Tokarev
2017-02-15 10:34:34 UTC
Permalink
TCO timer does not actually stop
---
hw/acpi/tco.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/hw/acpi/tco.c b/hw/acpi/tco.c
index 8ce7daf..b4adac8 100644
--- a/hw/acpi/tco.c
+++ b/hw/acpi/tco.c
@@ -49,6 +49,7 @@ static inline void tco_timer_reload(TCOIORegs *tr)
static inline void tco_timer_stop(TCOIORegs *tr)
{
tr->expire_time = -1;
+ timer_del(tr->tco_timer);
}
static void tco_timer_expired(void *opaque)
I'm not sure this is really trivial change.
Can you elaborate a bit please?

And please Cc qemu-devel@ too (doing this now).

Thanks,

/mjt
Igor Pavlikevich
2017-02-15 15:45:26 UTC
Permalink
Post by Michael Tokarev
TCO timer does not actually stop
---
hw/acpi/tco.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/hw/acpi/tco.c b/hw/acpi/tco.c
index 8ce7daf..b4adac8 100644
--- a/hw/acpi/tco.c
+++ b/hw/acpi/tco.c
@@ -49,6 +49,7 @@ static inline void tco_timer_reload(TCOIORegs *tr)
static inline void tco_timer_stop(TCOIORegs *tr)
{
tr->expire_time = -1;
+ timer_del(tr->tco_timer);
}
static void tco_timer_expired(void *opaque)
I'm not sure this is really trivial change.
Can you elaborate a bit please?
When linux guest goes to first reboot, it calls
watchdog_open()->watchdog_start()->iTCO_wdt_start() and write 0 to
TCO1_CNT.
After that can_start_tco_timer() returns true, starts timer in
tco_timer_reload() and guest kernel starts flooding
[ 590.392055] Uhhuh. NMI received for unknown reason 30 on CPU 0.
[ 590.392055] Do you have a strange power saving mode enabled?
[ 590.392055] Dazed and confused, but trying to continue
[ 620.392035] Uhhuh. NMI received for unknown reason 20 on CPU 0.
[ 620.392035] Do you have a strange power saving mode enabled?
[ 620.392035] Dazed and confused, but trying to continue

Timer keeps reloading after ich9_generate_nmi() so there is only one
way to stop reloading by clearing ICH9_CC_GCS_NO_REBOOT and reset
guest via watchdog_perform_action(), becasue tco_timer_stop() does
not actually modify tr->tco_timer.

Tested on Debian wheezy/jessie guests with default kernels and qemu
2.5+ q35 machine.
Post by Michael Tokarev
Thanks,
/mjt
Loading...