[v3,2/3] report guest crash information in GUEST_PANICKED event
diff mbox

Message ID 1486969742-16539-3-git-send-email-den@openvz.org
State New
Headers show

Commit Message

Denis V. Lunev Feb. 13, 2017, 7:09 a.m. UTC
From: Anton Nefedov <anton.nefedov@virtuozzo.com>

it's not very convenient to use the crash-information property interface,
so provide a CPU class callback to get the guest crash information, and pass
that information in the event

Signed-off-by: Anton Nefedov <anton.nefedov@virtuozzo.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
---
 hw/misc/pvpanic.c       |  2 +-
 hw/ppc/spapr_rtas.c     |  3 ++-
 include/qom/cpu.h       | 10 ++++++++++
 include/sysemu/sysemu.h |  2 +-
 kvm-all.c               |  2 +-
 qapi/event.json         |  6 ++++--
 qom/cpu.c               | 11 +++++++++++
 target/i386/cpu.c       |  1 +
 target/s390x/kvm.c      |  4 ++--
 vl.c                    | 14 +++++++++++---
 10 files changed, 44 insertions(+), 11 deletions(-)

Comments

Paolo Bonzini Feb. 13, 2017, 12:08 p.m. UTC | #1
On 13/02/2017 08:09, Denis V. Lunev wrote:
> From: Anton Nefedov <anton.nefedov@virtuozzo.com>
> 
> it's not very convenient to use the crash-information property interface,
> so provide a CPU class callback to get the guest crash information, and pass
> that information in the event
> 
> Signed-off-by: Anton Nefedov <anton.nefedov@virtuozzo.com>
> Signed-off-by: Denis V. Lunev <den@openvz.org>
> ---
>  hw/misc/pvpanic.c       |  2 +-
>  hw/ppc/spapr_rtas.c     |  3 ++-
>  include/qom/cpu.h       | 10 ++++++++++
>  include/sysemu/sysemu.h |  2 +-
>  kvm-all.c               |  2 +-
>  qapi/event.json         |  6 ++++--
>  qom/cpu.c               | 11 +++++++++++
>  target/i386/cpu.c       |  1 +
>  target/s390x/kvm.c      |  4 ++--
>  vl.c                    | 14 +++++++++++---
>  10 files changed, 44 insertions(+), 11 deletions(-)
> 
> diff --git a/hw/misc/pvpanic.c b/hw/misc/pvpanic.c
> index 0ac1e6a..57da7f2 100644
> --- a/hw/misc/pvpanic.c
> +++ b/hw/misc/pvpanic.c
> @@ -42,7 +42,7 @@ static void handle_event(int event)
>      }
>  
>      if (event & PVPANIC_PANICKED) {
> -        qemu_system_guest_panicked();
> +        qemu_system_guest_panicked(NULL);
>          return;
>      }
>  }
> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
> index bb19944..619f32c 100644
> --- a/hw/ppc/spapr_rtas.c
> +++ b/hw/ppc/spapr_rtas.c
> @@ -334,7 +334,8 @@ static void rtas_ibm_os_term(PowerPCCPU *cpu,
>  {
>      target_ulong ret = 0;
>  
> -    qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_PAUSE, &error_abort);
> +    qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_PAUSE, false, NULL,
> +                                   &error_abort);
>  
>      rtas_st(rets, 0, ret);
>  }
> diff --git a/include/qom/cpu.h b/include/qom/cpu.h
> index ca4d0fb..f95a6c3 100644
> --- a/include/qom/cpu.h
> +++ b/include/qom/cpu.h
> @@ -156,6 +156,7 @@ typedef struct CPUClass {
>                             uint8_t *buf, int len, bool is_write);
>      void (*dump_state)(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
>                         int flags);
> +    GuestPanicInformation* (*get_crash_info)(CPUState *cpu);
>      void (*dump_statistics)(CPUState *cpu, FILE *f,
>                              fprintf_function cpu_fprintf, int flags);
>      int64_t (*get_arch_id)(CPUState *cpu);
> @@ -469,6 +470,15 @@ int cpu_write_elf32_qemunote(WriteCoreDumpFunction f, CPUState *cpu,
>                               void *opaque);
>  
>  /**
> + * cpu_get_crash_info:
> + * @cpu: The CPU to get crash information for
> + *
> + * Gets the previously saved crash information.
> + * Caller is responsible for freeing the data.
> + */
> +GuestPanicInformation *cpu_get_crash_info(CPUState *cpu);
> +
> +/**
>   * CPUDumpFlags:
>   * @CPU_DUMP_CODE:
>   * @CPU_DUMP_FPU: dump FPU register state, not just integer
> diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
> index 4d50694..2c39bed 100644
> --- a/include/sysemu/sysemu.h
> +++ b/include/sysemu/sysemu.h
> @@ -64,7 +64,7 @@ int qemu_shutdown_requested_get(void);
>  int qemu_reset_requested_get(void);
>  void qemu_system_killed(int signal, pid_t pid);
>  void qemu_system_reset(bool report);
> -void qemu_system_guest_panicked(void);
> +void qemu_system_guest_panicked(GuestPanicInformation *info);
>  size_t qemu_target_page_bits(void);
>  
>  void qemu_add_exit_notifier(Notifier *notify);
> diff --git a/kvm-all.c b/kvm-all.c
> index abfe92d..8fe69bb 100644
> --- a/kvm-all.c
> +++ b/kvm-all.c
> @@ -2002,7 +2002,7 @@ int kvm_cpu_exec(CPUState *cpu)
>              case KVM_SYSTEM_EVENT_CRASH:
>                  kvm_arch_save_crash_info(cpu);
>                  qemu_mutex_lock_iothread();
> -                qemu_system_guest_panicked();
> +                qemu_system_guest_panicked(cpu_get_crash_info(cpu));
>                  qemu_mutex_unlock_iothread();
>                  ret = 0;
>                  break;
> diff --git a/qapi/event.json b/qapi/event.json
> index 7bf539b..970ff02 100644
> --- a/qapi/event.json
> +++ b/qapi/event.json
> @@ -488,7 +488,9 @@
>  #
>  # @action: action that has been taken, currently always "pause"
>  #
> -# Since: 1.5
> +# @info: optional information about a panic
> +#
> +# Since: 1.5 (@info since 2.9)
>  #
>  # Example:
>  #
> @@ -497,7 +499,7 @@
>  #
>  ##
>  { 'event': 'GUEST_PANICKED',
> -  'data': { 'action': 'GuestPanicAction' } }
> +  'data': { 'action': 'GuestPanicAction', '*info': 'GuestPanicInformation' } }
>  
>  ##
>  # @QUORUM_FAILURE:
> diff --git a/qom/cpu.c b/qom/cpu.c
> index d57faf3..5158f31 100644
> --- a/qom/cpu.c
> +++ b/qom/cpu.c
> @@ -218,6 +218,17 @@ static bool cpu_common_exec_interrupt(CPUState *cpu, int int_req)
>      return false;
>  }
>  
> +GuestPanicInformation *cpu_get_crash_info(CPUState *cpu)
> +{
> +    CPUClass *cc = CPU_GET_CLASS(cpu);
> +    GuestPanicInformation *res = NULL;
> +
> +    if (cc->get_crash_info) {
> +        res = cc->get_crash_info(cpu);
> +    }
> +    return res;
> +}
> +
>  void cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
>                      int flags)
>  {
> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> index 275e236..8bed688 100644
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c
> @@ -3738,6 +3738,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
>      cc->do_interrupt = x86_cpu_do_interrupt;
>      cc->cpu_exec_interrupt = x86_cpu_exec_interrupt;
>      cc->dump_state = x86_cpu_dump_state;
> +    cc->get_crash_info = x86_cpu_get_crash_info;
>      cc->set_pc = x86_cpu_set_pc;
>      cc->synchronize_from_tb = x86_cpu_synchronize_from_tb;
>      cc->gdb_read_register = x86_cpu_gdb_read_register;
> diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
> index 6ed3876..2536780 100644
> --- a/target/s390x/kvm.c
> +++ b/target/s390x/kvm.c
> @@ -1864,7 +1864,7 @@ static void unmanageable_intercept(S390CPU *cpu, const char *str, int pswoffset)
>                   str, cs->cpu_index, ldq_phys(cs->as, cpu->env.psa + pswoffset),
>                   ldq_phys(cs->as, cpu->env.psa + pswoffset + 8));
>      s390_cpu_halt(cpu);
> -    qemu_system_guest_panicked();
> +    qemu_system_guest_panicked(NULL);
>  }
>  
>  static int handle_intercept(S390CPU *cpu)
> @@ -1897,7 +1897,7 @@ static int handle_intercept(S390CPU *cpu)
>                  if (is_special_wait_psw(cs)) {
>                      qemu_system_shutdown_request();
>                  } else {
> -                    qemu_system_guest_panicked();
> +                    qemu_system_guest_panicked(NULL);
>                  }
>              }
>              r = EXCP_HALTED;
> diff --git a/vl.c b/vl.c
> index b4eaf03..d5a183f 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -1707,18 +1707,26 @@ void qemu_system_reset(bool report)
>      cpu_synchronize_all_post_reset();
>  }
>  
> -void qemu_system_guest_panicked(void)
> +void qemu_system_guest_panicked(GuestPanicInformation *info)
>  {
>      if (current_cpu) {
>          current_cpu->crash_occurred = true;
>      }
> -    qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_PAUSE, &error_abort);
> +    qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_PAUSE,
> +                                   !!info, info, &error_abort);
>      vm_stop(RUN_STATE_GUEST_PANICKED);
>      if (!no_shutdown) {
>          qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_POWEROFF,
> -                                       &error_abort);
> +                                       !!info, info, &error_abort);
>          qemu_system_shutdown_request();
>      }
> +
> +    if (info) {
> +        if (info->type == GUEST_PANIC_INFORMATION_KIND_HYPER_V) {
> +            g_free(info->u.hyper_v.data);
> +        }
> +        g_free(info);

if (info) {
    qapi_free_GuestPanicInformation(info);
}

Paolo

> +    }
>  }
>  
>  void qemu_system_reset_request(void)
>

Patch
diff mbox

diff --git a/hw/misc/pvpanic.c b/hw/misc/pvpanic.c
index 0ac1e6a..57da7f2 100644
--- a/hw/misc/pvpanic.c
+++ b/hw/misc/pvpanic.c
@@ -42,7 +42,7 @@  static void handle_event(int event)
     }
 
     if (event & PVPANIC_PANICKED) {
-        qemu_system_guest_panicked();
+        qemu_system_guest_panicked(NULL);
         return;
     }
 }
diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index bb19944..619f32c 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -334,7 +334,8 @@  static void rtas_ibm_os_term(PowerPCCPU *cpu,
 {
     target_ulong ret = 0;
 
-    qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_PAUSE, &error_abort);
+    qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_PAUSE, false, NULL,
+                                   &error_abort);
 
     rtas_st(rets, 0, ret);
 }
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index ca4d0fb..f95a6c3 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -156,6 +156,7 @@  typedef struct CPUClass {
                            uint8_t *buf, int len, bool is_write);
     void (*dump_state)(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
                        int flags);
+    GuestPanicInformation* (*get_crash_info)(CPUState *cpu);
     void (*dump_statistics)(CPUState *cpu, FILE *f,
                             fprintf_function cpu_fprintf, int flags);
     int64_t (*get_arch_id)(CPUState *cpu);
@@ -469,6 +470,15 @@  int cpu_write_elf32_qemunote(WriteCoreDumpFunction f, CPUState *cpu,
                              void *opaque);
 
 /**
+ * cpu_get_crash_info:
+ * @cpu: The CPU to get crash information for
+ *
+ * Gets the previously saved crash information.
+ * Caller is responsible for freeing the data.
+ */
+GuestPanicInformation *cpu_get_crash_info(CPUState *cpu);
+
+/**
  * CPUDumpFlags:
  * @CPU_DUMP_CODE:
  * @CPU_DUMP_FPU: dump FPU register state, not just integer
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 4d50694..2c39bed 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -64,7 +64,7 @@  int qemu_shutdown_requested_get(void);
 int qemu_reset_requested_get(void);
 void qemu_system_killed(int signal, pid_t pid);
 void qemu_system_reset(bool report);
-void qemu_system_guest_panicked(void);
+void qemu_system_guest_panicked(GuestPanicInformation *info);
 size_t qemu_target_page_bits(void);
 
 void qemu_add_exit_notifier(Notifier *notify);
diff --git a/kvm-all.c b/kvm-all.c
index abfe92d..8fe69bb 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -2002,7 +2002,7 @@  int kvm_cpu_exec(CPUState *cpu)
             case KVM_SYSTEM_EVENT_CRASH:
                 kvm_arch_save_crash_info(cpu);
                 qemu_mutex_lock_iothread();
-                qemu_system_guest_panicked();
+                qemu_system_guest_panicked(cpu_get_crash_info(cpu));
                 qemu_mutex_unlock_iothread();
                 ret = 0;
                 break;
diff --git a/qapi/event.json b/qapi/event.json
index 7bf539b..970ff02 100644
--- a/qapi/event.json
+++ b/qapi/event.json
@@ -488,7 +488,9 @@ 
 #
 # @action: action that has been taken, currently always "pause"
 #
-# Since: 1.5
+# @info: optional information about a panic
+#
+# Since: 1.5 (@info since 2.9)
 #
 # Example:
 #
@@ -497,7 +499,7 @@ 
 #
 ##
 { 'event': 'GUEST_PANICKED',
-  'data': { 'action': 'GuestPanicAction' } }
+  'data': { 'action': 'GuestPanicAction', '*info': 'GuestPanicInformation' } }
 
 ##
 # @QUORUM_FAILURE:
diff --git a/qom/cpu.c b/qom/cpu.c
index d57faf3..5158f31 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -218,6 +218,17 @@  static bool cpu_common_exec_interrupt(CPUState *cpu, int int_req)
     return false;
 }
 
+GuestPanicInformation *cpu_get_crash_info(CPUState *cpu)
+{
+    CPUClass *cc = CPU_GET_CLASS(cpu);
+    GuestPanicInformation *res = NULL;
+
+    if (cc->get_crash_info) {
+        res = cc->get_crash_info(cpu);
+    }
+    return res;
+}
+
 void cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
                     int flags)
 {
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 275e236..8bed688 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -3738,6 +3738,7 @@  static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
     cc->do_interrupt = x86_cpu_do_interrupt;
     cc->cpu_exec_interrupt = x86_cpu_exec_interrupt;
     cc->dump_state = x86_cpu_dump_state;
+    cc->get_crash_info = x86_cpu_get_crash_info;
     cc->set_pc = x86_cpu_set_pc;
     cc->synchronize_from_tb = x86_cpu_synchronize_from_tb;
     cc->gdb_read_register = x86_cpu_gdb_read_register;
diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
index 6ed3876..2536780 100644
--- a/target/s390x/kvm.c
+++ b/target/s390x/kvm.c
@@ -1864,7 +1864,7 @@  static void unmanageable_intercept(S390CPU *cpu, const char *str, int pswoffset)
                  str, cs->cpu_index, ldq_phys(cs->as, cpu->env.psa + pswoffset),
                  ldq_phys(cs->as, cpu->env.psa + pswoffset + 8));
     s390_cpu_halt(cpu);
-    qemu_system_guest_panicked();
+    qemu_system_guest_panicked(NULL);
 }
 
 static int handle_intercept(S390CPU *cpu)
@@ -1897,7 +1897,7 @@  static int handle_intercept(S390CPU *cpu)
                 if (is_special_wait_psw(cs)) {
                     qemu_system_shutdown_request();
                 } else {
-                    qemu_system_guest_panicked();
+                    qemu_system_guest_panicked(NULL);
                 }
             }
             r = EXCP_HALTED;
diff --git a/vl.c b/vl.c
index b4eaf03..d5a183f 100644
--- a/vl.c
+++ b/vl.c
@@ -1707,18 +1707,26 @@  void qemu_system_reset(bool report)
     cpu_synchronize_all_post_reset();
 }
 
-void qemu_system_guest_panicked(void)
+void qemu_system_guest_panicked(GuestPanicInformation *info)
 {
     if (current_cpu) {
         current_cpu->crash_occurred = true;
     }
-    qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_PAUSE, &error_abort);
+    qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_PAUSE,
+                                   !!info, info, &error_abort);
     vm_stop(RUN_STATE_GUEST_PANICKED);
     if (!no_shutdown) {
         qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_POWEROFF,
-                                       &error_abort);
+                                       !!info, info, &error_abort);
         qemu_system_shutdown_request();
     }
+
+    if (info) {
+        if (info->type == GUEST_PANIC_INFORMATION_KIND_HYPER_V) {
+            g_free(info->u.hyper_v.data);
+        }
+        g_free(info);
+    }
 }
 
 void qemu_system_reset_request(void)