summaryrefslogtreecommitdiffstats
path: root/qemu/hw/watchdog
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/hw/watchdog')
-rw-r--r--qemu/hw/watchdog/watchdog.c17
-rw-r--r--qemu/hw/watchdog/wdt_diag288.c16
-rw-r--r--qemu/hw/watchdog/wdt_i6300esb.c13
-rw-r--r--qemu/hw/watchdog/wdt_ib700.c3
4 files changed, 27 insertions, 22 deletions
diff --git a/qemu/hw/watchdog/watchdog.c b/qemu/hw/watchdog/watchdog.c
index 8d4b0eeeb..bbf3646ba 100644
--- a/qemu/hw/watchdog/watchdog.c
+++ b/qemu/hw/watchdog/watchdog.c
@@ -19,7 +19,7 @@
* By Richard W.M. Jones (rjones@redhat.com).
*/
-#include "qemu-common.h"
+#include "qemu/osdep.h"
#include "qemu/option.h"
#include "qemu/config-file.h"
#include "qemu/queue.h"
@@ -28,15 +28,7 @@
#include "sysemu/watchdog.h"
#include "qapi-event.h"
#include "hw/nmi.h"
-
-/* Possible values for action parameter. */
-#define WDT_RESET 1 /* Hard reset. */
-#define WDT_SHUTDOWN 2 /* Shutdown. */
-#define WDT_POWEROFF 3 /* Quit. */
-#define WDT_PAUSE 4 /* Pause. */
-#define WDT_DEBUG 5 /* Prints a message and continues running. */
-#define WDT_NONE 6 /* Do nothing. */
-#define WDT_NMI 7 /* Inject nmi into the guest */
+#include "qemu/help_option.h"
static int watchdog_action = WDT_RESET;
static QLIST_HEAD(watchdog_list, WatchdogTimerModel) watchdog_list;
@@ -105,6 +97,11 @@ int select_watchdog_action(const char *p)
return 0;
}
+int get_watchdog_action(void)
+{
+ return watchdog_action;
+}
+
/* This actually performs the "action" once a watchdog has expired,
* ie. reboot, shutdown, exit, etc.
*/
diff --git a/qemu/hw/watchdog/wdt_diag288.c b/qemu/hw/watchdog/wdt_diag288.c
index 2a885a447..f54a35a0e 100644
--- a/qemu/hw/watchdog/wdt_diag288.c
+++ b/qemu/hw/watchdog/wdt_diag288.c
@@ -11,6 +11,7 @@
*
*/
+#include "qemu/osdep.h"
#include "sysemu/watchdog.h"
#include "hw/sysbus.h"
#include "qemu/timer.h"
@@ -50,8 +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");
+ /* 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:
+ break;
+ default:
+ wdt_diag288_reset(dev);
+ }
watchdog_perform_action();
- wdt_diag288_reset(dev);
}
static int wdt_diag288_handle_timer(DIAG288State *diag288,
@@ -67,7 +79,7 @@ static int wdt_diag288_handle_timer(DIAG288State *diag288,
}
timer_mod(diag288->timer,
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
- timeout * get_ticks_per_sec());
+ timeout * NANOSECONDS_PER_SECOND);
break;
case WDT_DIAG288_CANCEL:
if (!diag288->enabled) {
diff --git a/qemu/hw/watchdog/wdt_i6300esb.c b/qemu/hw/watchdog/wdt_i6300esb.c
index cfa2b1be1..a83d95121 100644
--- a/qemu/hw/watchdog/wdt_i6300esb.c
+++ b/qemu/hw/watchdog/wdt_i6300esb.c
@@ -19,7 +19,7 @@
* By Richard W.M. Jones (rjones@redhat.com).
*/
-#include <inttypes.h>
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/timer.h"
@@ -129,14 +129,9 @@ static void i6300esb_restart_timer(I6300State *d, int stage)
else
timeout <<= 5;
- /* Get the timeout in units of ticks_per_sec.
- *
- * ticks_per_sec is typically 10^9 == 0x3B9ACA00 (30 bits), with
- * 20 bits of user supplied preload, and 15 bits of scale, the
- * multiply here can exceed 64-bits, before we divide by 33MHz, so
- * we use a higher-precision intermediate result.
- */
- timeout = muldiv64(get_ticks_per_sec(), timeout, 33000000);
+ /* Get the timeout in nanoseconds. */
+
+ timeout = timeout * 30; /* on a PCI bus, 1 tick is 30 ns*/
i6300esb_debug("stage %d, timeout %" PRIi64 "\n", d->stage, timeout);
diff --git a/qemu/hw/watchdog/wdt_ib700.c b/qemu/hw/watchdog/wdt_ib700.c
index 0917a713d..532afe89e 100644
--- a/qemu/hw/watchdog/wdt_ib700.c
+++ b/qemu/hw/watchdog/wdt_ib700.c
@@ -19,6 +19,7 @@
* By Richard W.M. Jones (rjones@redhat.com).
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/timer.h"
#include "sysemu/watchdog.h"
@@ -63,7 +64,7 @@ static void ib700_write_enable_reg(void *vp, uint32_t addr, uint32_t data)
ib700_debug("addr = %x, data = %x\n", addr, data);
- timeout = (int64_t) time_map[data & 0xF] * get_ticks_per_sec();
+ timeout = (int64_t) time_map[data & 0xF] * NANOSECONDS_PER_SECOND;
timer_mod(s->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + timeout);
}