diff options
Diffstat (limited to 'qemu/hw/watchdog')
-rw-r--r-- | qemu/hw/watchdog/watchdog.c | 17 | ||||
-rw-r--r-- | qemu/hw/watchdog/wdt_diag288.c | 16 | ||||
-rw-r--r-- | qemu/hw/watchdog/wdt_i6300esb.c | 13 | ||||
-rw-r--r-- | qemu/hw/watchdog/wdt_ib700.c | 3 |
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); } |