summary refs log tree commit diff stats
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/watchdog/wdt_diag288.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/hw/watchdog/wdt_diag288.c b/hw/watchdog/wdt_diag288.c
index 5eb5b94e43..1c3658e4a8 100644
--- a/hw/watchdog/wdt_diag288.c
+++ b/hw/watchdog/wdt_diag288.c
@@ -51,15 +51,19 @@ static void diag288_reset(void *opaque)
 static void diag288_timer_expired(void *dev)
 {
     qemu_log_mask(CPU_LOG_RESET, "Watchdog timer expired.\n");
-    watchdog_perform_action();
-    /* Reset the watchdog only if the guest was notified about expiry. */
+    /* Reset the watchdog only if the guest gets notified about
+     * expiry. watchdog_perform_action() may temporarily relinquish
+     * the BQL; reset before triggering the action to avoid races with
+     * diag288 instructions. */
     switch (get_watchdog_action()) {
     case WDT_DEBUG:
     case WDT_NONE:
     case WDT_PAUSE:
-         return;
+        break;
+    default:
+        wdt_diag288_reset(dev);
     }
-    wdt_diag288_reset(dev);
+    watchdog_perform_action();
 }
 
 static int wdt_diag288_handle_timer(DIAG288State *diag288,