Re: [PATCH v5 3/4] shutdown: Add source information to SHUTDOWN and RESET

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Apr 27, 2017 at 09:13:16PM -0500, Eric Blake wrote:
> Libvirt would like to be able to distinguish between a SHUTDOWN
> event triggered solely by guest request and one triggered by a
> SIGTERM or other action on the host.  While qemu_kill_report() is
> already able to tell whether a shutdown was triggered by a host
> signal (but NOT by a host UI event, such as clicking the X on
> the window), that information was then lost after being printed
> to stderr.  The previous patch prepped things to use an enum
> internally; now it's time to wire it up through all callers, and
> to extend the SHUTDOWN and RESET events to report the details.
> 
> Enhance the shutdown request path to take a parameter of which
> way it is being triggered, and update ALL callers.  It would have
> been less churn to keep the common case with no arguments as
> meaning guest-triggered, and only modified the host-triggered
> code paths, via a wrapper function, but then we'd still have to
> audit that I didn't miss any host-triggered spots; changing the
> signature forces us to double-check that I correctly categorized
> all callers.
> 
> Since command line options can change whether a guest reset request
> causes an actual reset vs. a shutdown, it's easy to also add the
> information to the RESET event, even though libvirt has not yet
> expressed a need to know that.
> 
> For the moment, we keep the enum ShutdownCause for internal use
> only, and merely expose a single boolean of 'guest':true|false
> to the QMP client; this is because we don't yet have evidence that
> the further distinctions will be useful, or whether the addition
> of new enum members would cause problems to clients coded to an
> older version of the enum.
> 
> Update expected iotest outputs to match the new data.
> 
> Here is output from 'virsh qemu-monitor-event --loop' with the
> patch installed:
> 
> event SHUTDOWN at 1492639680.731251 for domain fedora_13: {"guest":true}
> event STOP at 1492639680.732116 for domain fedora_13: <null>
> event SHUTDOWN at 1492639680.732830 for domain fedora_13: {"guest":false}
> 
> Note that libvirt runs qemu with -no-quit: the first SHUTDOWN event
> was triggered by an action I took directly in the guest (shutdown -h),
> at which point qemu stops the vcpus and waits for libvirt to do any
> final cleanups; the second SHUTDOWN event is the result of libvirt
> sending SIGTERM now that it has completed cleanup.
> 
> The replay driver needs a followup patch if we want to be able to
> faithfully replay the difference between a host- and guest-initiated
> shutdown (for now, the replayed event is always attributed to host).
> 
> See also https://bugzilla.redhat.com/1384007
> 
> Signed-off-by: Eric Blake <eblake@xxxxxxxxxx>

ppc parts

Acked-by: David Gibson <david@xxxxxxxxxxxxxxxxxxxxx>

> 
> ---
> v5: drop accidental addition of unrelated files
> v4: s/ShutdownType/ShutdownCause/, no thanks to mingw header pollution
> v3: retitle again, fix qemu-iotests, use enum rather than raw bool
> in all callers
> v2: retitle (was "event: Add signal information to SHUTDOWN"),
> completely rework to post bool based on whether it is guest-initiated
> v1: initial submission, exposing just Unix signals from host
> ---
>  qapi/event.json             | 17 +++++++++++++----
>  include/sysemu/sysemu.h     |  4 ++--
>  vl.c                        | 22 +++++++++++-----------
>  hw/acpi/core.c              |  4 ++--
>  hw/arm/highbank.c           |  4 ++--
>  hw/arm/integratorcp.c       |  2 +-
>  hw/arm/musicpal.c           |  2 +-
>  hw/arm/omap1.c              | 10 ++++++----
>  hw/arm/omap2.c              |  2 +-
>  hw/arm/spitz.c              |  2 +-
>  hw/arm/stellaris.c          |  2 +-
>  hw/arm/tosa.c               |  2 +-
>  hw/i386/pc.c                |  2 +-
>  hw/i386/xen/xen-hvm.c       |  2 +-
>  hw/input/pckbd.c            |  4 ++--
>  hw/ipmi/ipmi.c              |  4 ++--
>  hw/isa/lpc_ich9.c           |  2 +-
>  hw/mips/boston.c            |  2 +-
>  hw/mips/mips_malta.c        |  2 +-
>  hw/mips/mips_r4k.c          |  4 ++--
>  hw/misc/arm_sysctl.c        |  8 ++++----
>  hw/misc/cbus.c              |  2 +-
>  hw/misc/macio/cuda.c        |  4 ++--
>  hw/misc/slavio_misc.c       |  4 ++--
>  hw/misc/zynq_slcr.c         |  2 +-
>  hw/pci-host/apb.c           |  4 ++--
>  hw/pci-host/bonito.c        |  2 +-
>  hw/pci-host/piix.c          |  2 +-
>  hw/ppc/e500.c               |  2 +-
>  hw/ppc/mpc8544_guts.c       |  2 +-
>  hw/ppc/ppc.c                |  2 +-
>  hw/ppc/ppc405_uc.c          |  2 +-
>  hw/ppc/spapr_hcall.c        |  2 +-
>  hw/ppc/spapr_rtas.c         |  4 ++--
>  hw/s390x/ipl.c              |  2 +-
>  hw/sh4/r2d.c                |  2 +-
>  hw/timer/etraxfs_timer.c    |  2 +-
>  hw/timer/m48t59.c           |  4 ++--
>  hw/timer/milkymist-sysctl.c |  4 ++--
>  hw/timer/pxa2xx_timer.c     |  2 +-
>  hw/watchdog/watchdog.c      |  2 +-
>  hw/xenpv/xen_domainbuild.c  |  2 +-
>  hw/xtensa/xtfpga.c          |  2 +-
>  kvm-all.c                   |  6 +++---
>  os-win32.c                  |  2 +-
>  qmp.c                       |  4 ++--
>  replay/replay.c             |  5 ++++-
>  target/alpha/sys_helper.c   |  4 ++--
>  target/arm/psci.c           |  4 ++--
>  target/i386/excp_helper.c   |  2 +-
>  target/i386/hax-all.c       |  6 +++---
>  target/i386/helper.c        |  2 +-
>  target/i386/kvm.c           |  2 +-
>  target/s390x/helper.c       |  2 +-
>  target/s390x/kvm.c          |  4 ++--
>  target/s390x/misc_helper.c  |  4 ++--
>  target/sparc/int32_helper.c |  2 +-
>  ui/sdl.c                    |  2 +-
>  ui/sdl2.c                   |  4 ++--
>  tests/qemu-iotests/071.out  |  4 ++--
>  tests/qemu-iotests/081.out  |  2 +-
>  tests/qemu-iotests/087.out  | 12 ++++++------
>  tests/qemu-iotests/094.out  |  2 +-
>  tests/qemu-iotests/117.out  |  2 +-
>  tests/qemu-iotests/119.out  |  2 +-
>  tests/qemu-iotests/120.out  |  2 +-
>  tests/qemu-iotests/140.out  |  2 +-
>  tests/qemu-iotests/143.out  |  2 +-
>  tests/qemu-iotests/156.out  |  2 +-
>  trace-events                |  2 +-
>  ui/cocoa.m                  |  2 +-
>  71 files changed, 132 insertions(+), 118 deletions(-)
> 
> diff --git a/qapi/event.json b/qapi/event.json
> index e80f3f4..6d22b02 100644
> --- a/qapi/event.json
> +++ b/qapi/event.json
> @@ -10,6 +10,10 @@
>  # Emitted when the virtual machine has shut down, indicating that qemu is
>  # about to exit.
>  #
> +# @guest: If true, the shutdown was triggered by a guest request (such as
> +# a guest-initiated ACPI shutdown request or other hardware-specific action)
> +# rather than a host request (such as sending qemu a SIGINT). (since 2.10)
> +#
>  # Note: If the command-line option "-no-shutdown" has been specified, qemu will
>  # not exit, and a STOP event will eventually follow the SHUTDOWN event
>  #
> @@ -17,11 +21,11 @@
>  #
>  # Example:
>  #
> -# <- { "event": "SHUTDOWN",
> +# <- { "event": "SHUTDOWN", "data": { "guest": true },
>  #      "timestamp": { "seconds": 1267040730, "microseconds": 682951 } }
>  #
>  ##
> -{ 'event': 'SHUTDOWN' }
> +{ 'event': 'SHUTDOWN', 'data': { 'guest': 'bool' } }
> 
>  ##
>  # @POWERDOWN:
> @@ -44,15 +48,20 @@
>  #
>  # Emitted when the virtual machine is reset
>  #
> +# @guest: If true, the reset was triggered by a guest request (such as
> +# a guest-initiated ACPI reboot request or other hardware-specific action)
> +# rather than a host request (such as the QMP command system_reset).
> +# (since 2.10)
> +#
>  # Since: 0.12.0
>  #
>  # Example:
>  #
> -# <- { "event": "RESET",
> +# <- { "event": "RESET", "data": { "guest": false },
>  #      "timestamp": { "seconds": 1267041653, "microseconds": 9518 } }
>  #
>  ##
> -{ 'event': 'RESET' }
> +{ 'event': 'RESET', 'data': { 'guest': 'bool' } }
> 
>  ##
>  # @STOP:
> diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
> index 00a907f..ffbf9ac 100644
> --- a/include/sysemu/sysemu.h
> +++ b/include/sysemu/sysemu.h
> @@ -49,13 +49,13 @@ typedef enum WakeupReason {
>      QEMU_WAKEUP_REASON_OTHER,
>  } WakeupReason;
> 
> -void qemu_system_reset_request(void);
> +void qemu_system_reset_request(ShutdownCause reason);
>  void qemu_system_suspend_request(void);
>  void qemu_register_suspend_notifier(Notifier *notifier);
>  void qemu_system_wakeup_request(WakeupReason reason);
>  void qemu_system_wakeup_enable(WakeupReason reason, bool enabled);
>  void qemu_register_wakeup_notifier(Notifier *notifier);
> -void qemu_system_shutdown_request(void);
> +void qemu_system_shutdown_request(ShutdownCause reason);
>  void qemu_system_powerdown_request(void);
>  void qemu_register_powerdown_notifier(Notifier *notifier);
>  void qemu_system_debug_request(void);
> diff --git a/vl.c b/vl.c
> index 2b95b7f..0a933ba 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -1688,7 +1688,7 @@ static int qemu_debug_requested(void)
> 
>  /*
>   * Reset the VM. If @report is VMRESET_REPORT, issue an event, using
> - * the @reason interpreted as ShutdownType for details.  Otherwise,
> + * the @reason interpreted as ShutdownCause for details.  Otherwise,
>   * @report is VMRESET_SILENT and @reason is ignored.
>   */
>  void qemu_system_reset(bool report, int reason)
> @@ -1706,7 +1706,8 @@ void qemu_system_reset(bool report, int reason)
>      }
>      if (report) {
>          assert(reason >= 0);
> -        qapi_event_send_reset(&error_abort);
> +        qapi_event_send_reset(reason >= SHUTDOWN_CAUSE_GUEST_SHUTDOWN,
> +                              &error_abort);
>      }
>      cpu_synchronize_all_post_reset();
>  }
> @@ -1724,7 +1725,7 @@ void qemu_system_guest_panicked(GuestPanicInformation *info)
>      if (!no_shutdown) {
>          qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_POWEROFF,
>                                         !!info, info, &error_abort);
> -        qemu_system_shutdown_request();
> +        qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_PANIC);
>      }
> 
>      if (info) {
> @@ -1741,11 +1742,10 @@ void qemu_system_guest_panicked(GuestPanicInformation *info)
>      }
>  }
> 
> -void qemu_system_reset_request(void)
> +void qemu_system_reset_request(ShutdownCause reason)
>  {
>      if (no_reboot) {
> -        /* FIXME - add a parameter to allow callers to specify reason */
> -        shutdown_requested = SHUTDOWN_CAUSE_GUEST_RESET;
> +        shutdown_requested = reason;
>      } else {
>          reset_requested = SHUTDOWN_CAUSE_GUEST_RESET;
>      }
> @@ -1818,12 +1818,11 @@ void qemu_system_killed(int signal, pid_t pid)
>      qemu_notify_event();
>  }
> 
> -void qemu_system_shutdown_request(void)
> +void qemu_system_shutdown_request(ShutdownCause reason)
>  {
> -    trace_qemu_system_shutdown_request();
> +    trace_qemu_system_shutdown_request(reason);
>      replay_shutdown_request();
> -    /* FIXME - add a parameter to allow callers to specify reason */
> -    shutdown_requested = SHUTDOWN_CAUSE_GUEST_SHUTDOWN;
> +    shutdown_requested = reason;
>      qemu_notify_event();
>  }
> 
> @@ -1865,7 +1864,8 @@ static bool main_loop_should_exit(void)
>      request = qemu_shutdown_requested();
>      if (request >= 0) {
>          qemu_kill_report();
> -        qapi_event_send_shutdown(&error_abort);
> +        qapi_event_send_shutdown(request >= SHUTDOWN_CAUSE_GUEST_SHUTDOWN,
> +                                 &error_abort);
>          if (no_shutdown) {
>              vm_stop(RUN_STATE_SHUTDOWN);
>          } else {
> diff --git a/hw/acpi/core.c b/hw/acpi/core.c
> index e890a5d..95fcac9 100644
> --- a/hw/acpi/core.c
> +++ b/hw/acpi/core.c
> @@ -561,7 +561,7 @@ static void acpi_pm1_cnt_write(ACPIREGS *ar, uint16_t val)
>          uint16_t sus_typ = (val >> 10) & 7;
>          switch(sus_typ) {
>          case 0: /* soft power off */
> -            qemu_system_shutdown_request();
> +            qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
>              break;
>          case 1:
>              qemu_system_suspend_request();
> @@ -569,7 +569,7 @@ static void acpi_pm1_cnt_write(ACPIREGS *ar, uint16_t val)
>          default:
>              if (sus_typ == ar->pm1.cnt.s4_val) { /* S4 request */
>                  qapi_event_send_suspend_disk(&error_abort);
> -                qemu_system_shutdown_request();
> +                qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
>              }
>              break;
>          }
> diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
> index 0a4508c..d209b97 100644
> --- a/hw/arm/highbank.c
> +++ b/hw/arm/highbank.c
> @@ -108,9 +108,9 @@ static void hb_regs_write(void *opaque, hwaddr offset,
> 
>      if (offset == 0xf00) {
>          if (value == 1 || value == 2) {
> -            qemu_system_reset_request();
> +            qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>          } else if (value == 3) {
> -            qemu_system_shutdown_request();
> +            qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
>          }
>      }
> 
> diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
> index 5610ffc..ca3eca1 100644
> --- a/hw/arm/integratorcp.c
> +++ b/hw/arm/integratorcp.c
> @@ -158,7 +158,7 @@ static void integratorcm_do_remap(IntegratorCMState *s)
>  static void integratorcm_set_ctrl(IntegratorCMState *s, uint32_t value)
>  {
>      if (value & 8) {
> -        qemu_system_reset_request();
> +        qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>      }
>      if ((s->cm_ctrl ^ value) & 1) {
>          /* (value & 1) != 0 means the green "MISC LED" is lit.
> diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
> index cbbca4e..9c710f7 100644
> --- a/hw/arm/musicpal.c
> +++ b/hw/arm/musicpal.c
> @@ -898,7 +898,7 @@ static void mv88w8618_pit_write(void *opaque, hwaddr offset,
> 
>      case MP_BOARD_RESET:
>          if (value == MP_BOARD_RESET_MAGIC) {
> -            qemu_system_reset_request();
> +            qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>          }
>          break;
>      }
> diff --git a/hw/arm/omap1.c b/hw/arm/omap1.c
> index b3cf0ec..54582bd 100644
> --- a/hw/arm/omap1.c
> +++ b/hw/arm/omap1.c
> @@ -355,7 +355,7 @@ static void omap_wd_timer_write(void *opaque, hwaddr addr,
>                  /* XXX: on T|E hardware somehow this has no effect,
>                   * on Zire 71 it works as specified.  */
>                  s->reset = 1;
> -                qemu_system_reset_request();
> +                qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>              }
>          }
>          s->last_wr = value & 0xff;
> @@ -1545,8 +1545,10 @@ static inline void omap_clkm_idlect1_update(struct omap_mpu_state_s *s,
>      if (value & (1 << 11)) {                            /* SETARM_IDLE */
>          cpu_interrupt(CPU(s->cpu), CPU_INTERRUPT_HALT);
>      }
> -    if (!(value & (1 << 10)))				/* WKUP_MODE */
> -        qemu_system_shutdown_request();	/* XXX: disable wakeup from IRQ */
> +    if (!(value & (1 << 10))) {                         /* WKUP_MODE */
> +        /* XXX: disable wakeup from IRQ */
> +        qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
> +    }
> 
>  #define SET_CANIDLE(clock, bit)				\
>      if (diff & (1 << bit)) {				\
> @@ -1693,7 +1695,7 @@ static void omap_clkm_write(void *opaque, hwaddr addr,
>          diff = s->clkm.arm_rstct1 ^ value;
>          s->clkm.arm_rstct1 = value & 0x0007;
>          if (value & 9) {
> -            qemu_system_reset_request();
> +            qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>              s->clkm.cold_start = 0xa;
>          }
>          if (diff & ~value & 4) {				/* DSP_RST */
> diff --git a/hw/arm/omap2.c b/hw/arm/omap2.c
> index cf1b4ba..8afb854 100644
> --- a/hw/arm/omap2.c
> +++ b/hw/arm/omap2.c
> @@ -1610,7 +1610,7 @@ static void omap_prcm_write(void *opaque, hwaddr addr,
>      case 0x450:	/* RM_RSTCTRL_WKUP */
>          /* TODO: reset */
>          if (value & 2)
> -            qemu_system_reset_request();
> +            qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>          break;
>      case 0x454:	/* RM_RSTTIME_WKUP */
>          s->rsttime_wkup = value & 0x1fff;
> diff --git a/hw/arm/spitz.c b/hw/arm/spitz.c
> index fe2d5a7..7e9f579 100644
> --- a/hw/arm/spitz.c
> +++ b/hw/arm/spitz.c
> @@ -848,7 +848,7 @@ static void spitz_lcd_hsync_handler(void *opaque, int line, int level)
>  static void spitz_reset(void *opaque, int line, int level)
>  {
>      if (level) {
> -        qemu_system_reset_request();
> +        qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>      }
>  }
> 
> diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
> index ea7a809..cf6e7be 100644
> --- a/hw/arm/stellaris.c
> +++ b/hw/arm/stellaris.c
> @@ -1197,7 +1197,7 @@ static
>  void do_sys_reset(void *opaque, int n, int level)
>  {
>      if (level) {
> -        qemu_system_reset_request();
> +        qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>      }
>  }
> 
> diff --git a/hw/arm/tosa.c b/hw/arm/tosa.c
> index 9f58a23..2421b81 100644
> --- a/hw/arm/tosa.c
> +++ b/hw/arm/tosa.c
> @@ -90,7 +90,7 @@ static void tosa_out_switch(void *opaque, int line, int level)
>  static void tosa_reset(void *opaque, int line, int level)
>  {
>      if (level) {
> -        qemu_system_reset_request();
> +        qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>      }
>  }
> 
> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> index f3b372a..427f123 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -519,7 +519,7 @@ static void port92_write(void *opaque, hwaddr addr, uint64_t val,
>      s->outport = val;
>      qemu_set_irq(s->a20_out, (val >> 1) & 1);
>      if ((val & 1) && !(oldval & 1)) {
> -        qemu_system_reset_request();
> +        qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>      }
>  }
> 
> diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c
> index 3a6484c..70a1c1e 100644
> --- a/hw/i386/xen/xen-hvm.c
> +++ b/hw/i386/xen/xen-hvm.c
> @@ -1398,7 +1398,7 @@ void xen_shutdown_fatal_error(const char *fmt, ...)
>      va_end(ap);
>      fprintf(stderr, "Will destroy the domain.\n");
>      /* destroy the domain */
> -    qemu_system_shutdown_request();
> +    qemu_system_shutdown_request(SHUTDOWN_CAUSE_HOST_ERROR);
>  }
> 
>  void xen_hvm_modified_memory(ram_addr_t start, ram_addr_t length)
> diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c
> index d414288..c479f82 100644
> --- a/hw/input/pckbd.c
> +++ b/hw/input/pckbd.c
> @@ -226,7 +226,7 @@ static void outport_write(KBDState *s, uint32_t val)
>      s->outport = val;
>      qemu_set_irq(s->a20_out, (val >> 1) & 1);
>      if (!(val & 1)) {
> -        qemu_system_reset_request();
> +        qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>      }
>  }
> 
> @@ -301,7 +301,7 @@ static void kbd_write_command(void *opaque, hwaddr addr,
>          s->outport &= ~KBD_OUT_A20;
>          break;
>      case KBD_CCMD_RESET:
> -        qemu_system_reset_request();
> +        qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>          break;
>      case KBD_CCMD_NO_OP:
>          /* ignore that */
> diff --git a/hw/ipmi/ipmi.c b/hw/ipmi/ipmi.c
> index 5cf1caa..afafe14 100644
> --- a/hw/ipmi/ipmi.c
> +++ b/hw/ipmi/ipmi.c
> @@ -44,14 +44,14 @@ static int ipmi_do_hw_op(IPMIInterface *s, enum ipmi_op op, int checkonly)
>          if (checkonly) {
>              return 0;
>          }
> -        qemu_system_reset_request();
> +        qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>          return 0;
> 
>      case IPMI_POWEROFF_CHASSIS:
>          if (checkonly) {
>              return 0;
>          }
> -        qemu_system_shutdown_request();
> +        qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
>          return 0;
> 
>      case IPMI_SEND_NMI:
> diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
> index a0866c3..2b09354 100644
> --- a/hw/isa/lpc_ich9.c
> +++ b/hw/isa/lpc_ich9.c
> @@ -606,7 +606,7 @@ static void ich9_rst_cnt_write(void *opaque, hwaddr addr, uint64_t val,
>      ICH9LPCState *lpc = opaque;
> 
>      if (val & 4) {
> -        qemu_system_reset_request();
> +        qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>          return;
>      }
>      lpc->rst_cnt = val & 0xA; /* keep FULL_RST (bit 3) and SYS_RST (bit 1) */
> diff --git a/hw/mips/boston.c b/hw/mips/boston.c
> index 83f7b82..53d1e0c 100644
> --- a/hw/mips/boston.c
> +++ b/hw/mips/boston.c
> @@ -232,7 +232,7 @@ static void boston_platreg_write(void *opaque, hwaddr addr,
>          break;
>      case PLAT_SOFTRST_CTL:
>          if (val & PLAT_SOFTRST_CTL_SYSRESET) {
> -            qemu_system_reset_request();
> +            qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>          }
>          break;
>      default:
> diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
> index 5dd177e..7814c39 100644
> --- a/hw/mips/mips_malta.c
> +++ b/hw/mips/mips_malta.c
> @@ -470,7 +470,7 @@ static void malta_fpga_write(void *opaque, hwaddr addr,
>      /* SOFTRES Register */
>      case 0x00500:
>          if (val == 0x42)
> -            qemu_system_reset_request ();
> +            qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>          break;
> 
>      /* BRKRES Register */
> diff --git a/hw/mips/mips_r4k.c b/hw/mips/mips_r4k.c
> index 748586e..f4de9fc 100644
> --- a/hw/mips/mips_r4k.c
> +++ b/hw/mips/mips_r4k.c
> @@ -53,9 +53,9 @@ static void mips_qemu_write (void *opaque, hwaddr addr,
>                               uint64_t val, unsigned size)
>  {
>      if ((addr & 0xffff) == 0 && val == 42)
> -        qemu_system_reset_request ();
> +        qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>      else if ((addr & 0xffff) == 4 && val == 42)
> -        qemu_system_shutdown_request ();
> +        qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
>  }
> 
>  static uint64_t mips_qemu_read (void *opaque, hwaddr addr,
> diff --git a/hw/misc/arm_sysctl.c b/hw/misc/arm_sysctl.c
> index 8524008..b20b44e 100644
> --- a/hw/misc/arm_sysctl.c
> +++ b/hw/misc/arm_sysctl.c
> @@ -351,13 +351,13 @@ static bool vexpress_cfgctrl_write(arm_sysctl_state *s, unsigned int dcc,
>          break;
>      case SYS_CFG_SHUTDOWN:
>          if (site == SYS_CFG_SITE_MB && device == 0) {
> -            qemu_system_shutdown_request();
> +            qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
>              return true;
>          }
>          break;
>      case SYS_CFG_REBOOT:
>          if (site == SYS_CFG_SITE_MB && device == 0) {
> -            qemu_system_reset_request();
> +            qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>              return true;
>          }
>          break;
> @@ -429,7 +429,7 @@ static void arm_sysctl_write(void *opaque, hwaddr offset,
>              if (s->lockval == LOCK_VALUE) {
>                  s->resetlevel = val;
>                  if (val & 0x100) {
> -                    qemu_system_reset_request();
> +                    qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>                  }
>              }
>              break;
> @@ -438,7 +438,7 @@ static void arm_sysctl_write(void *opaque, hwaddr offset,
>              if (s->lockval == LOCK_VALUE) {
>                  s->resetlevel = val;
>                  if (val & 0x04) {
> -                    qemu_system_reset_request();
> +                    qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>                  }
>              }
>              break;
> diff --git a/hw/misc/cbus.c b/hw/misc/cbus.c
> index 0c207e3..677274c 100644
> --- a/hw/misc/cbus.c
> +++ b/hw/misc/cbus.c
> @@ -356,7 +356,7 @@ static inline void retu_write(CBusRetu *s, int reg, uint16_t val)
> 
>      case RETU_REG_WATCHDOG:
>          if (val == 0 && (s->cc[0] & 2))
> -            qemu_system_shutdown_request();
> +            qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
>          break;
> 
>      case RETU_REG_TXCR:
> diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
> index 05c02fb..008d8bd 100644
> --- a/hw/misc/macio/cuda.c
> +++ b/hw/misc/macio/cuda.c
> @@ -612,7 +612,7 @@ static bool cuda_cmd_powerdown(CUDAState *s,
>          return false;
>      }
> 
> -    qemu_system_shutdown_request();
> +    qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
>      return true;
>  }
> 
> @@ -624,7 +624,7 @@ static bool cuda_cmd_reset_system(CUDAState *s,
>          return false;
>      }
> 
> -    qemu_system_reset_request();
> +    qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>      return true;
>  }
> 
> diff --git a/hw/misc/slavio_misc.c b/hw/misc/slavio_misc.c
> index edd5de0..18ff677 100644
> --- a/hw/misc/slavio_misc.c
> +++ b/hw/misc/slavio_misc.c
> @@ -258,7 +258,7 @@ static void slavio_aux2_mem_writeb(void *opaque, hwaddr addr,
>          val &= AUX2_PWROFF;
>      s->aux2 = val;
>      if (val & AUX2_PWROFF)
> -        qemu_system_shutdown_request();
> +        qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
>      slavio_misc_update_irq(s);
>  }
> 
> @@ -338,7 +338,7 @@ static void slavio_sysctrl_mem_writel(void *opaque, hwaddr addr,
>      case 0:
>          if (val & SYS_RESET) {
>              s->sysctrl = SYS_RESETSTAT;
> -            qemu_system_reset_request();
> +            qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>          }
>          break;
>      default:
> diff --git a/hw/misc/zynq_slcr.c b/hw/misc/zynq_slcr.c
> index 7891219..44304d4 100644
> --- a/hw/misc/zynq_slcr.c
> +++ b/hw/misc/zynq_slcr.c
> @@ -405,7 +405,7 @@ static void zynq_slcr_write(void *opaque, hwaddr offset,
>      switch (offset) {
>      case PSS_RST_CTRL:
>          if (val & R_PSS_RST_CTRL_SOFT_RST) {
> -            qemu_system_reset_request();
> +            qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>          }
>          break;
>      }
> diff --git a/hw/pci-host/apb.c b/hw/pci-host/apb.c
> index 653e711..83fc6a9 100644
> --- a/hw/pci-host/apb.c
> +++ b/hw/pci-host/apb.c
> @@ -482,9 +482,9 @@ static void apb_config_writel (void *opaque, hwaddr addr,
>              s->reset_control |= val & RESET_WMASK;
>              if (val & SOFT_POR) {
>                  s->nr_resets = 0;
> -                qemu_system_reset_request();
> +                qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>              } else if (val & SOFT_XIR) {
> -                qemu_system_reset_request();
> +                qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>              }
>          }
>          break;
> diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c
> index 1999ece..b1d41d0 100644
> --- a/hw/pci-host/bonito.c
> +++ b/hw/pci-host/bonito.c
> @@ -269,7 +269,7 @@ static void bonito_writel(void *opaque, hwaddr addr,
>          }
>          s->regs[saddr] = val;
>          if (reset) {
> -            qemu_system_reset_request();
> +            qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>          }
>          break;
>      case BONITO_INTENSET:
> diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
> index f9218aa..c1d6a85 100644
> --- a/hw/pci-host/piix.c
> +++ b/hw/pci-host/piix.c
> @@ -638,7 +638,7 @@ static void rcr_write(void *opaque, hwaddr addr, uint64_t val, unsigned len)
>      PIIX3State *d = opaque;
> 
>      if (val & 4) {
> -        qemu_system_reset_request();
> +        qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>          return;
>      }
>      d->rcr = val & 2; /* keep System Reset type only */
> diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
> index f7df238..62f1857 100644
> --- a/hw/ppc/e500.c
> +++ b/hw/ppc/e500.c
> @@ -774,7 +774,7 @@ static qemu_irq *ppce500_init_mpic(MachineState *machine, PPCE500Params *params,
>  static void ppce500_power_off(void *opaque, int line, int on)
>  {
>      if (on) {
> -        qemu_system_shutdown_request();
> +        qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
>      }
>  }
> 
> diff --git a/hw/ppc/mpc8544_guts.c b/hw/ppc/mpc8544_guts.c
> index ba69178..ce1254b 100644
> --- a/hw/ppc/mpc8544_guts.c
> +++ b/hw/ppc/mpc8544_guts.c
> @@ -98,7 +98,7 @@ static void mpc8544_guts_write(void *opaque, hwaddr addr,
>      switch (addr) {
>      case MPC8544_GUTS_ADDR_RSTCR:
>          if (value & MPC8544_GUTS_RSTCR_RESET) {
> -            qemu_system_reset_request();
> +            qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>          }
>          break;
>      default:
> diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
> index 5f93083..224184d 100644
> --- a/hw/ppc/ppc.c
> +++ b/hw/ppc/ppc.c
> @@ -412,7 +412,7 @@ static void ppce500_set_irq(void *opaque, int pin, int level)
>              if (level) {
>                  LOG_IRQ("%s: reset the PowerPC system\n",
>                              __func__);
> -                qemu_system_reset_request();
> +                qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>              }
>              break;
>          case PPCE500_INPUT_RESET_CORE:
> diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
> index d5df94a..fc32e96 100644
> --- a/hw/ppc/ppc405_uc.c
> +++ b/hw/ppc/ppc405_uc.c
> @@ -1807,7 +1807,7 @@ void ppc40x_chip_reset(PowerPCCPU *cpu)
>  void ppc40x_system_reset(PowerPCCPU *cpu)
>  {
>      printf("Reset PowerPC system\n");
> -    qemu_system_reset_request();
> +    qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>  }
> 
>  void store_40x_dbcr0 (CPUPPCState *env, uint32_t val)
> diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
> index 9f18f75..2735fe9 100644
> --- a/hw/ppc/spapr_hcall.c
> +++ b/hw/ppc/spapr_hcall.c
> @@ -1166,7 +1166,7 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
>      spapr_ovec_cleanup(ov5_updates);
> 
>      if (spapr->cas_reboot) {
> -        qemu_system_reset_request();
> +        qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>      } else {
>          /* If ppc_spapr_reset() did not set up a HPT but one is necessary
>           * (because the guest isn't going to use radix) then set it up here. */
> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
> index 619f32c..128d993 100644
> --- a/hw/ppc/spapr_rtas.c
> +++ b/hw/ppc/spapr_rtas.c
> @@ -110,7 +110,7 @@ static void rtas_power_off(PowerPCCPU *cpu, sPAPRMachineState *spapr,
>          rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
>          return;
>      }
> -    qemu_system_shutdown_request();
> +    qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
>      cpu_stop_current();
>      rtas_st(rets, 0, RTAS_OUT_SUCCESS);
>  }
> @@ -124,7 +124,7 @@ static void rtas_system_reboot(PowerPCCPU *cpu, sPAPRMachineState *spapr,
>          rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
>          return;
>      }
> -    qemu_system_reset_request();
> +    qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>      rtas_st(rets, 0, RTAS_OUT_SUCCESS);
>  }
> 
> diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
> index 7978c7d..e5ab0ad 100644
> --- a/hw/s390x/ipl.c
> +++ b/hw/s390x/ipl.c
> @@ -363,7 +363,7 @@ void s390_reipl_request(void)
>      S390IPLState *ipl = get_ipl_device();
> 
>      ipl->reipl_requested = true;
> -    qemu_system_reset_request();
> +    qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>  }
> 
>  void s390_ipl_prepare_cpu(S390CPU *cpu)
> diff --git a/hw/sh4/r2d.c b/hw/sh4/r2d.c
> index 8f520ce..e6fc74e 100644
> --- a/hw/sh4/r2d.c
> +++ b/hw/sh4/r2d.c
> @@ -164,7 +164,7 @@ r2d_fpga_write(void *opaque, hwaddr addr, uint64_t value, unsigned int size)
>  	break;
>      case PA_POWOFF:
>          if (value & 1) {
> -            qemu_system_shutdown_request();
> +            qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
>          }
>          break;
>      case PA_VERREG:
> diff --git a/hw/timer/etraxfs_timer.c b/hw/timer/etraxfs_timer.c
> index 8e18236..d13bc30 100644
> --- a/hw/timer/etraxfs_timer.c
> +++ b/hw/timer/etraxfs_timer.c
> @@ -207,7 +207,7 @@ static void watchdog_hit(void *opaque)
>          qemu_irq_raise(t->nmi);
>      }
>      else
> -        qemu_system_reset_request();
> +        qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
> 
>      t->wd_hits++;
>  }
> diff --git a/hw/timer/m48t59.c b/hw/timer/m48t59.c
> index 474981a..4a064fb 100644
> --- a/hw/timer/m48t59.c
> +++ b/hw/timer/m48t59.c
> @@ -1,7 +1,7 @@
>  /*
>   * QEMU M48T59 and M48T08 NVRAM emulation for PPC PREP and Sparc platforms
>   *
> - * Copyright (c) 2003-2005, 2007 Jocelyn Mayer
> + * Copyright (c) 2003-2005, 2007, 2017 Jocelyn Mayer
>   * Copyright (c) 2013 Hervé Poussineau
>   *
>   * Permission is hereby granted, free of charge, to any person obtaining a copy
> @@ -159,7 +159,7 @@ static void watchdog_cb (void *opaque)
>  	NVRAM->buffer[0x1FF7] = 0x00;
>  	NVRAM->buffer[0x1FFC] &= ~0x40;
>          /* May it be a hw CPU Reset instead ? */
> -        qemu_system_reset_request();
> +        qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>      } else {
>  	qemu_set_irq(NVRAM->IRQ, 1);
>  	qemu_set_irq(NVRAM->IRQ, 0);
> diff --git a/hw/timer/milkymist-sysctl.c b/hw/timer/milkymist-sysctl.c
> index 4488590..93bc6e17 100644
> --- a/hw/timer/milkymist-sysctl.c
> +++ b/hw/timer/milkymist-sysctl.c
> @@ -90,7 +90,7 @@ static void sysctl_icap_write(MilkymistSysctlState *s, uint32_t value)
>      trace_milkymist_sysctl_icap_write(value);
>      switch (value & 0xffff) {
>      case 0x000e:
> -        qemu_system_shutdown_request();
> +        qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
>          break;
>      }
>  }
> @@ -195,7 +195,7 @@ static void sysctl_write(void *opaque, hwaddr addr, uint64_t value,
>          s->regs[addr] = 1;
>          break;
>      case R_SYSTEM_ID:
> -        qemu_system_reset_request();
> +        qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>          break;
> 
>      case R_GPIO_IN:
> diff --git a/hw/timer/pxa2xx_timer.c b/hw/timer/pxa2xx_timer.c
> index 59002b4..68ba5a7 100644
> --- a/hw/timer/pxa2xx_timer.c
> +++ b/hw/timer/pxa2xx_timer.c
> @@ -401,7 +401,7 @@ static void pxa2xx_timer_tick(void *opaque)
>      if (t->num == 3)
>          if (i->reset3 & 1) {
>              i->reset3 = 0;
> -            qemu_system_reset_request();
> +            qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>          }
>  }
> 
> diff --git a/hw/watchdog/watchdog.c b/hw/watchdog/watchdog.c
> index 2aeaf1f..0c5c9cd 100644
> --- a/hw/watchdog/watchdog.c
> +++ b/hw/watchdog/watchdog.c
> @@ -110,7 +110,7 @@ void watchdog_perform_action(void)
>      switch (watchdog_action) {
>      case WDT_RESET:             /* same as 'system_reset' in monitor */
>          qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_RESET, &error_abort);
> -        qemu_system_reset_request();
> +        qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>          break;
> 
>      case WDT_SHUTDOWN:          /* same as 'system_powerdown' in monitor */
> diff --git a/hw/xenpv/xen_domainbuild.c b/hw/xenpv/xen_domainbuild.c
> index 457a897..c89ced2 100644
> --- a/hw/xenpv/xen_domainbuild.c
> +++ b/hw/xenpv/xen_domainbuild.c
> @@ -148,7 +148,7 @@ static void xen_domain_poll(void *opaque)
>      return;
> 
>  quit:
> -    qemu_system_shutdown_request();
> +    qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
>  }
> 
>  static int xen_domain_watcher(void)
> diff --git a/hw/xtensa/xtfpga.c b/hw/xtensa/xtfpga.c
> index 11176e2..4636f8e 100644
> --- a/hw/xtensa/xtfpga.c
> +++ b/hw/xtensa/xtfpga.c
> @@ -100,7 +100,7 @@ static void lx60_fpga_write(void *opaque, hwaddr addr,
> 
>      case 0x10: /*board reset*/
>          if (val == 0xdead) {
> -            qemu_system_reset_request();
> +            qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>          }
>          break;
>      }
> diff --git a/kvm-all.c b/kvm-all.c
> index 90b8573..7df27c8 100644
> --- a/kvm-all.c
> +++ b/kvm-all.c
> @@ -2052,7 +2052,7 @@ int kvm_cpu_exec(CPUState *cpu)
>              break;
>          case KVM_EXIT_SHUTDOWN:
>              DPRINTF("shutdown\n");
> -            qemu_system_reset_request();
> +            qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>              ret = EXCP_INTERRUPT;
>              break;
>          case KVM_EXIT_UNKNOWN:
> @@ -2066,11 +2066,11 @@ int kvm_cpu_exec(CPUState *cpu)
>          case KVM_EXIT_SYSTEM_EVENT:
>              switch (run->system_event.type) {
>              case KVM_SYSTEM_EVENT_SHUTDOWN:
> -                qemu_system_shutdown_request();
> +                qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
>                  ret = EXCP_INTERRUPT;
>                  break;
>              case KVM_SYSTEM_EVENT_RESET:
> -                qemu_system_reset_request();
> +                qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>                  ret = EXCP_INTERRUPT;
>                  break;
>              case KVM_SYSTEM_EVENT_CRASH:
> diff --git a/os-win32.c b/os-win32.c
> index ae98574..586a7c7 100644
> --- a/os-win32.c
> +++ b/os-win32.c
> @@ -52,7 +52,7 @@ int setenv(const char *name, const char *value, int overwrite)
> 
>  static BOOL WINAPI qemu_ctrl_handler(DWORD type)
>  {
> -    qemu_system_shutdown_request();
> +    qemu_system_shutdown_request(SHUTDOWN_CAUSE_HOST_SIGNAL);
>      /* Windows 7 kills application when the function returns.
>         Sleep here to give QEMU a try for closing.
>         Sleep period is 10000ms because Windows kills the program
> diff --git a/qmp.c b/qmp.c
> index ab74cd7..95949d0 100644
> --- a/qmp.c
> +++ b/qmp.c
> @@ -84,7 +84,7 @@ UuidInfo *qmp_query_uuid(Error **errp)
>  void qmp_quit(Error **errp)
>  {
>      no_shutdown = 0;
> -    qemu_system_shutdown_request();
> +    qemu_system_shutdown_request(SHUTDOWN_CAUSE_HOST_QMP);
>  }
> 
>  void qmp_stop(Error **errp)
> @@ -105,7 +105,7 @@ void qmp_stop(Error **errp)
> 
>  void qmp_system_reset(Error **errp)
>  {
> -    qemu_system_reset_request();
> +    qemu_system_reset_request(SHUTDOWN_CAUSE_HOST_QMP);
>  }
> 
>  void qmp_system_powerdown(Error **erp)
> diff --git a/replay/replay.c b/replay/replay.c
> index f810628..55e82d9 100644
> --- a/replay/replay.c
> +++ b/replay/replay.c
> @@ -51,7 +51,10 @@ bool replay_next_event_is(int event)
>          switch (replay_state.data_kind) {
>          case EVENT_SHUTDOWN:
>              replay_finish_event();
> -            qemu_system_shutdown_request();
> +            /* TODO: track source of shutdown request, to replay a
> +             * guest-initiated request rather than always claiming to
> +             * be from the host? */
> +            qemu_system_shutdown_request(SHUTDOWN_CAUSE_HOST_REPLAY);
>              break;
>          default:
>              /* clock, time_t, checkpoint and other events */
> diff --git a/target/alpha/sys_helper.c b/target/alpha/sys_helper.c
> index 652195d..ac22323 100644
> --- a/target/alpha/sys_helper.c
> +++ b/target/alpha/sys_helper.c
> @@ -60,9 +60,9 @@ void helper_tb_flush(CPUAlphaState *env)
>  void helper_halt(uint64_t restart)
>  {
>      if (restart) {
> -        qemu_system_reset_request();
> +        qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>      } else {
> -        qemu_system_shutdown_request();
> +        qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
>      }
>  }
> 
> diff --git a/target/arm/psci.c b/target/arm/psci.c
> index ade9fe2..fc34b26 100644
> --- a/target/arm/psci.c
> +++ b/target/arm/psci.c
> @@ -137,7 +137,7 @@ void arm_handle_psci_call(ARMCPU *cpu)
>          }
>          break;
>      case QEMU_PSCI_0_2_FN_SYSTEM_RESET:
> -        qemu_system_reset_request();
> +        qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>          /* QEMU reset and shutdown are async requests, but PSCI
>           * mandates that we never return from the reset/shutdown
>           * call, so power the CPU off now so it doesn't execute
> @@ -145,7 +145,7 @@ void arm_handle_psci_call(ARMCPU *cpu)
>           */
>          goto cpu_off;
>      case QEMU_PSCI_0_2_FN_SYSTEM_OFF:
> -        qemu_system_shutdown_request();
> +        qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
>          goto cpu_off;
>      case QEMU_PSCI_0_1_FN_CPU_ON:
>      case QEMU_PSCI_0_2_FN_CPU_ON:
> diff --git a/target/i386/excp_helper.c b/target/i386/excp_helper.c
> index ee596c6..b769772 100644
> --- a/target/i386/excp_helper.c
> +++ b/target/i386/excp_helper.c
> @@ -59,7 +59,7 @@ static int check_exception(CPUX86State *env, int intno, int *error_code,
> 
>          qemu_log_mask(CPU_LOG_RESET, "Triple fault\n");
> 
> -        qemu_system_reset_request();
> +        qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>          return EXCP_HLT;
>      }
>  #endif
> diff --git a/target/i386/hax-all.c b/target/i386/hax-all.c
> index ef13015..7346931 100644
> --- a/target/i386/hax-all.c
> +++ b/target/i386/hax-all.c
> @@ -540,14 +540,14 @@ static int hax_vcpu_hax_exec(CPUArchState *env)
>          /* Guest state changed, currently only for shutdown */
>          case HAX_EXIT_STATECHANGE:
>              fprintf(stdout, "VCPU shutdown request\n");
> -            qemu_system_shutdown_request();
> +            qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
>              hax_vcpu_sync_state(env, 0);
>              ret = 1;
>              break;
>          case HAX_EXIT_UNKNOWN_VMEXIT:
>              fprintf(stderr, "Unknown VMX exit %x from guest\n",
>                      ht->_exit_reason);
> -            qemu_system_reset_request();
> +            qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>              hax_vcpu_sync_state(env, 0);
>              cpu_dump_state(cpu, stderr, fprintf, 0);
>              ret = -1;
> @@ -578,7 +578,7 @@ static int hax_vcpu_hax_exec(CPUArchState *env)
>              break;
>          default:
>              fprintf(stderr, "Unknown exit %x from HAX\n", ht->_exit_status);
> -            qemu_system_reset_request();
> +            qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>              hax_vcpu_sync_state(env, 0);
>              cpu_dump_state(cpu, stderr, fprintf, 0);
>              ret = 1;
> diff --git a/target/i386/helper.c b/target/i386/helper.c
> index f11cac6..ee7eff2 100644
> --- a/target/i386/helper.c
> +++ b/target/i386/helper.c
> @@ -1212,7 +1212,7 @@ static void do_inject_x86_mce(CPUState *cs, run_on_cpu_data data)
>                             " triple fault\n",
>                             cs->cpu_index);
>              qemu_log_mask(CPU_LOG_RESET, "Triple fault\n");
> -            qemu_system_reset_request();
> +            qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>              return;
>          }
>          if (banks[1] & MCI_STATUS_VAL) {
> diff --git a/target/i386/kvm.c b/target/i386/kvm.c
> index 55865db..cfd7695 100644
> --- a/target/i386/kvm.c
> +++ b/target/i386/kvm.c
> @@ -2930,7 +2930,7 @@ int kvm_arch_process_async_events(CPUState *cs)
> 
>          if (env->exception_injected == EXCP08_DBLE) {
>              /* this means triple fault */
> -            qemu_system_reset_request();
> +            qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>              cs->exit_request = 1;
>              return 0;
>          }
> diff --git a/target/s390x/helper.c b/target/s390x/helper.c
> index 68bd2f9..d2bb9aa 100644
> --- a/target/s390x/helper.c
> +++ b/target/s390x/helper.c
> @@ -266,7 +266,7 @@ void load_psw(CPUS390XState *env, uint64_t mask, uint64_t addr)
>          S390CPU *cpu = s390_env_get_cpu(env);
>          if (s390_cpu_halt(cpu) == 0) {
>  #ifndef CONFIG_USER_ONLY
> -            qemu_system_shutdown_request();
> +            qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
>  #endif
>          }
>      }
> diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
> index 1a249d8..284f5ef 100644
> --- a/target/s390x/kvm.c
> +++ b/target/s390x/kvm.c
> @@ -1929,7 +1929,7 @@ static int handle_intercept(S390CPU *cpu)
>              cpu_synchronize_state(cs);
>              if (s390_cpu_halt(cpu) == 0) {
>                  if (is_special_wait_psw(cs)) {
> -                    qemu_system_shutdown_request();
> +                    qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
>                  } else {
>                      qemu_system_guest_panicked(NULL);
>                  }
> @@ -1938,7 +1938,7 @@ static int handle_intercept(S390CPU *cpu)
>              break;
>          case ICPT_CPU_STOP:
>              if (s390_cpu_set_state(CPU_STATE_STOPPED, cpu) == 0) {
> -                qemu_system_shutdown_request();
> +                qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
>              }
>              if (cpu->env.sigp_order == SIGP_STOP_STORE_STATUS) {
>                  kvm_s390_store_status(cpu, KVM_S390_STORE_STATUS_DEF_ADDR,
> diff --git a/target/s390x/misc_helper.c b/target/s390x/misc_helper.c
> index eca8244..768043e 100644
> --- a/target/s390x/misc_helper.c
> +++ b/target/s390x/misc_helper.c
> @@ -533,11 +533,11 @@ uint32_t HELPER(sigp)(CPUS390XState *env, uint64_t order_code, uint32_t r1,
>          break;
>  #if !defined(CONFIG_USER_ONLY)
>      case SIGP_RESTART:
> -        qemu_system_reset_request();
> +        qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>          cpu_loop_exit(CPU(s390_env_get_cpu(env)));
>          break;
>      case SIGP_STOP:
> -        qemu_system_shutdown_request();
> +        qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
>          cpu_loop_exit(CPU(s390_env_get_cpu(env)));
>          break;
>  #endif
> diff --git a/target/sparc/int32_helper.c b/target/sparc/int32_helper.c
> index 09afe13..eec9a4d 100644
> --- a/target/sparc/int32_helper.c
> +++ b/target/sparc/int32_helper.c
> @@ -109,7 +109,7 @@ void sparc_cpu_do_interrupt(CPUState *cs)
>      if (env->psret == 0) {
>          if (cs->exception_index == 0x80 &&
>              env->def->features & CPU_FEATURE_TA0_SHUTDOWN) {
> -            qemu_system_shutdown_request();
> +            qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
>          } else {
>              cpu_abort(cs, "Trap 0x%02x while interrupts disabled, Error state",
>                        cs->exception_index);
> diff --git a/ui/sdl.c b/ui/sdl.c
> index 37c21a0..bd51ffd 100644
> --- a/ui/sdl.c
> +++ b/ui/sdl.c
> @@ -837,7 +837,7 @@ static void sdl_refresh(DisplayChangeListener *dcl)
>          case SDL_QUIT:
>              if (!no_quit) {
>                  no_shutdown = 0;
> -                qemu_system_shutdown_request();
> +                qemu_system_shutdown_request(SHUTDOWN_CAUSE_HOST_UI);
>              }
>              break;
>          case SDL_MOUSEMOTION:
> diff --git a/ui/sdl2.c b/ui/sdl2.c
> index faf9bdf..e092636 100644
> --- a/ui/sdl2.c
> +++ b/ui/sdl2.c
> @@ -568,7 +568,7 @@ static void handle_windowevent(SDL_Event *ev)
>      case SDL_WINDOWEVENT_CLOSE:
>          if (!no_quit) {
>              no_shutdown = 0;
> -            qemu_system_shutdown_request();
> +            qemu_system_shutdown_request(SHUTDOWN_CAUSE_HOST_UI);
>          }
>          break;
>      case SDL_WINDOWEVENT_SHOWN:
> @@ -611,7 +611,7 @@ void sdl2_poll_events(struct sdl2_console *scon)
>          case SDL_QUIT:
>              if (!no_quit) {
>                  no_shutdown = 0;
> -                qemu_system_shutdown_request();
> +                qemu_system_shutdown_request(SHUTDOWN_CAUSE_HOST_UI);
>              }
>              break;
>          case SDL_MOUSEMOTION:
> diff --git a/tests/qemu-iotests/071.out b/tests/qemu-iotests/071.out
> index dd879f1..1d5e28d 100644
> --- a/tests/qemu-iotests/071.out
> +++ b/tests/qemu-iotests/071.out
> @@ -46,7 +46,7 @@ QMP_VERSION
>  read failed: Input/output error
>  {"return": ""}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN"}
> +{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
> 
> 
>  === Testing blkverify on existing block device ===
> @@ -85,7 +85,7 @@ wrote 512/512 bytes at offset 0
>  read failed: Input/output error
>  {"return": ""}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN"}
> +{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
>  QEMU_PROG: Failed to flush the L2 table cache: Input/output error
>  QEMU_PROG: Failed to flush the refcount block cache: Input/output error
> 
> diff --git a/tests/qemu-iotests/081.out b/tests/qemu-iotests/081.out
> index 97df69d..2533c31 100644
> --- a/tests/qemu-iotests/081.out
> +++ b/tests/qemu-iotests/081.out
> @@ -36,7 +36,7 @@ read 10485760/10485760 bytes at offset 0
>  10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
>  {"return": ""}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN"}
> +{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
> 
> 
>  == using quorum rewrite corrupted mode ==
> diff --git a/tests/qemu-iotests/087.out b/tests/qemu-iotests/087.out
> index dc6baf9..59c5208 100644
> --- a/tests/qemu-iotests/087.out
> +++ b/tests/qemu-iotests/087.out
> @@ -8,7 +8,7 @@ QMP_VERSION
>  {"return": {}}
>  {"error": {"class": "GenericError", "desc": "'node-name' must be specified for the root node"}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN"}
> +{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
> 
> 
>  === Duplicate ID ===
> @@ -19,7 +19,7 @@ QMP_VERSION
>  {"error": {"class": "GenericError", "desc": "node-name=disk is conflicting with a device id"}}
>  {"error": {"class": "GenericError", "desc": "Duplicate node name"}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN"}
> +{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
> 
> 
>  === aio=native without O_DIRECT ===
> @@ -29,7 +29,7 @@ QMP_VERSION
>  {"return": {}}
>  {"error": {"class": "GenericError", "desc": "aio=native was specified, but it requires cache.direct=on, which was not specified."}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN"}
> +{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
> 
> 
>  === Encrypted image ===
> @@ -40,14 +40,14 @@ QMP_VERSION
>  {"return": {}}
>  {"error": {"class": "GenericError", "desc": "Use of AES-CBC encrypted IMGFMT images is no longer supported in system emulators"}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN"}
> +{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
> 
>  Testing:
>  QMP_VERSION
>  {"return": {}}
>  {"error": {"class": "GenericError", "desc": "Use of AES-CBC encrypted IMGFMT images is no longer supported in system emulators"}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN"}
> +{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
> 
> 
>  === Missing driver ===
> @@ -58,6 +58,6 @@ QMP_VERSION
>  {"return": {}}
>  {"error": {"class": "GenericError", "desc": "Parameter 'driver' is missing"}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN"}
> +{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
> 
>  *** done
> diff --git a/tests/qemu-iotests/094.out b/tests/qemu-iotests/094.out
> index b66dc07..f52baff 100644
> --- a/tests/qemu-iotests/094.out
> +++ b/tests/qemu-iotests/094.out
> @@ -7,5 +7,5 @@ Formatting 'TEST_DIR/source.IMGFMT', fmt=IMGFMT size=67108864
>  {"return": {}}
>  {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN"}
> +{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
>  *** done
> diff --git a/tests/qemu-iotests/117.out b/tests/qemu-iotests/117.out
> index f52dc1a..851e214 100644
> --- a/tests/qemu-iotests/117.out
> +++ b/tests/qemu-iotests/117.out
> @@ -7,7 +7,7 @@ wrote 65536/65536 bytes at offset 0
>  64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
>  {"return": ""}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN"}
> +{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
>  No errors were found on the image.
>  read 65536/65536 bytes at offset 0
>  64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
> diff --git a/tests/qemu-iotests/119.out b/tests/qemu-iotests/119.out
> index 58e7114..a8743b8 100644
> --- a/tests/qemu-iotests/119.out
> +++ b/tests/qemu-iotests/119.out
> @@ -6,6 +6,6 @@ read 65536/65536 bytes at offset 0
>  64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
>  {"return": ""}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN"}
> +{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
> 
>  *** done
> diff --git a/tests/qemu-iotests/120.out b/tests/qemu-iotests/120.out
> index 9131b1b..1af1aeb 100644
> --- a/tests/qemu-iotests/120.out
> +++ b/tests/qemu-iotests/120.out
> @@ -6,7 +6,7 @@ wrote 65536/65536 bytes at offset 0
>  64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
>  {"return": ""}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN"}
> +{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
>  read 65536/65536 bytes at offset 0
>  64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
>  read 65536/65536 bytes at offset 0
> diff --git a/tests/qemu-iotests/140.out b/tests/qemu-iotests/140.out
> index 6c04456..0689b2b 100644
> --- a/tests/qemu-iotests/140.out
> +++ b/tests/qemu-iotests/140.out
> @@ -10,5 +10,5 @@ read 65536/65536 bytes at offset 0
>  {"return": {}}
>  can't open device nbd+unix:///drv?socket=TEST_DIR/nbd: No export with name 'drv' available
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN"}
> +{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
>  *** done
> diff --git a/tests/qemu-iotests/143.out b/tests/qemu-iotests/143.out
> index d24ad20..0978b89 100644
> --- a/tests/qemu-iotests/143.out
> +++ b/tests/qemu-iotests/143.out
> @@ -3,5 +3,5 @@ QA output created by 143
>  {"return": {}}
>  can't open device nbd+unix:///no_such_export?socket=TEST_DIR/nbd: No export with name 'no_such_export' available
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN"}
> +{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
>  *** done
> diff --git a/tests/qemu-iotests/156.out b/tests/qemu-iotests/156.out
> index 3af82ae..f96a564 100644
> --- a/tests/qemu-iotests/156.out
> +++ b/tests/qemu-iotests/156.out
> @@ -34,7 +34,7 @@ read 65536/65536 bytes at offset 196608
>  {"return": ""}
> 
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN"}
> +{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
> 
>  read 65536/65536 bytes at offset 0
>  64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
> diff --git a/trace-events b/trace-events
> index e582d63..433865f 100644
> --- a/trace-events
> +++ b/trace-events
> @@ -38,7 +38,7 @@ vm_state_notify(int running, int reason) "running %d reason %d"
>  load_file(const char *name, const char *path) "name %s location %s"
>  runstate_set(int new_state) "new state %d"
>  system_wakeup_request(int reason) "reason=%d"
> -qemu_system_shutdown_request(void) ""
> +qemu_system_shutdown_request(int reason) "reason=%d"
>  qemu_system_powerdown_request(void) ""
> 
>  # spice-qemu-char.c
> diff --git a/ui/cocoa.m b/ui/cocoa.m
> index 207555e..f89f686 100644
> --- a/ui/cocoa.m
> +++ b/ui/cocoa.m
> @@ -934,7 +934,7 @@ QemuCocoaView *cocoaView;
>  {
>      COCOA_DEBUG("QemuCocoaAppController: applicationWillTerminate\n");
> 
> -    qemu_system_shutdown_request();
> +    qemu_system_shutdown_request(SHUTDOWN_CAUSE_HOST_UI);
>      exit(0);
>  }
> 

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

Attachment: signature.asc
Description: PGP signature


[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux