diff --git a/hw/watchdog/wdt_diag288.c b/hw/watchdog/wdt_diag288.c index 5eb5b94e4302dd6a343abee0533b087e5e18969f..1c3658e4a82afaa176464c44243ce7efdf8189ad 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,