report guest crash information in GUEST_PANICKED event

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>
Message-Id: <1487053524-18674-3-git-send-email-den@openvz.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Anton Nefedov 2017-02-14 09:25:23 +03:00 committed by Paolo Bonzini
parent d187e08dc4
commit c86f106b85
10 changed files with 41 additions and 11 deletions

View File

@ -42,7 +42,7 @@ static void handle_event(int event)
} }
if (event & PVPANIC_PANICKED) { if (event & PVPANIC_PANICKED) {
qemu_system_guest_panicked(); qemu_system_guest_panicked(NULL);
return; return;
} }
} }

View File

@ -334,7 +334,8 @@ static void rtas_ibm_os_term(PowerPCCPU *cpu,
{ {
target_ulong ret = 0; 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); rtas_st(rets, 0, ret);
} }

View File

@ -158,6 +158,7 @@ typedef struct CPUClass {
uint8_t *buf, int len, bool is_write); uint8_t *buf, int len, bool is_write);
void (*dump_state)(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, void (*dump_state)(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
int flags); int flags);
GuestPanicInformation* (*get_crash_info)(CPUState *cpu);
void (*dump_statistics)(CPUState *cpu, FILE *f, void (*dump_statistics)(CPUState *cpu, FILE *f,
fprintf_function cpu_fprintf, int flags); fprintf_function cpu_fprintf, int flags);
int64_t (*get_arch_id)(CPUState *cpu); int64_t (*get_arch_id)(CPUState *cpu);
@ -471,6 +472,15 @@ int cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cpu,
int cpu_write_elf32_qemunote(WriteCoreDumpFunction f, CPUState *cpu, int cpu_write_elf32_qemunote(WriteCoreDumpFunction f, CPUState *cpu,
void *opaque); 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: * CPUDumpFlags:
* @CPU_DUMP_CODE: * @CPU_DUMP_CODE:

View File

@ -66,7 +66,7 @@ int qemu_shutdown_requested_get(void);
int qemu_reset_requested_get(void); int qemu_reset_requested_get(void);
void qemu_system_killed(int signal, pid_t pid); void qemu_system_killed(int signal, pid_t pid);
void qemu_system_reset(bool report); 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); size_t qemu_target_page_bits(void);
void qemu_add_exit_notifier(Notifier *notify); void qemu_add_exit_notifier(Notifier *notify);

View File

@ -2002,7 +2002,7 @@ int kvm_cpu_exec(CPUState *cpu)
case KVM_SYSTEM_EVENT_CRASH: case KVM_SYSTEM_EVENT_CRASH:
kvm_cpu_synchronize_state(cpu); kvm_cpu_synchronize_state(cpu);
qemu_mutex_lock_iothread(); qemu_mutex_lock_iothread();
qemu_system_guest_panicked(); qemu_system_guest_panicked(cpu_get_crash_info(cpu));
qemu_mutex_unlock_iothread(); qemu_mutex_unlock_iothread();
ret = 0; ret = 0;
break; break;

View File

@ -488,7 +488,9 @@
# #
# @action: action that has been taken, currently always "pause" # @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: # Example:
# #
@ -497,7 +499,7 @@
# #
## ##
{ 'event': 'GUEST_PANICKED', { 'event': 'GUEST_PANICKED',
'data': { 'action': 'GuestPanicAction' } } 'data': { 'action': 'GuestPanicAction', '*info': 'GuestPanicInformation' } }
## ##
# @QUORUM_FAILURE: # @QUORUM_FAILURE:

View File

@ -218,6 +218,17 @@ static bool cpu_common_exec_interrupt(CPUState *cpu, int int_req)
return false; 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, void cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
int flags) int flags)
{ {

View File

@ -3734,6 +3734,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
cc->do_interrupt = x86_cpu_do_interrupt; cc->do_interrupt = x86_cpu_do_interrupt;
cc->cpu_exec_interrupt = x86_cpu_exec_interrupt; cc->cpu_exec_interrupt = x86_cpu_exec_interrupt;
cc->dump_state = x86_cpu_dump_state; cc->dump_state = x86_cpu_dump_state;
cc->get_crash_info = x86_cpu_get_crash_info;
cc->set_pc = x86_cpu_set_pc; cc->set_pc = x86_cpu_set_pc;
cc->synchronize_from_tb = x86_cpu_synchronize_from_tb; cc->synchronize_from_tb = x86_cpu_synchronize_from_tb;
cc->gdb_read_register = x86_cpu_gdb_read_register; cc->gdb_read_register = x86_cpu_gdb_read_register;

View File

@ -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), str, cs->cpu_index, ldq_phys(cs->as, cpu->env.psa + pswoffset),
ldq_phys(cs->as, cpu->env.psa + pswoffset + 8)); ldq_phys(cs->as, cpu->env.psa + pswoffset + 8));
s390_cpu_halt(cpu); s390_cpu_halt(cpu);
qemu_system_guest_panicked(); qemu_system_guest_panicked(NULL);
} }
static int handle_intercept(S390CPU *cpu) static int handle_intercept(S390CPU *cpu)
@ -1897,7 +1897,7 @@ static int handle_intercept(S390CPU *cpu)
if (is_special_wait_psw(cs)) { if (is_special_wait_psw(cs)) {
qemu_system_shutdown_request(); qemu_system_shutdown_request();
} else { } else {
qemu_system_guest_panicked(); qemu_system_guest_panicked(NULL);
} }
} }
r = EXCP_HALTED; r = EXCP_HALTED;

11
vl.c
View File

@ -1679,18 +1679,23 @@ void qemu_system_reset(bool report)
cpu_synchronize_all_post_reset(); cpu_synchronize_all_post_reset();
} }
void qemu_system_guest_panicked(void) void qemu_system_guest_panicked(GuestPanicInformation *info)
{ {
if (current_cpu) { if (current_cpu) {
current_cpu->crash_occurred = true; 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); vm_stop(RUN_STATE_GUEST_PANICKED);
if (!no_shutdown) { if (!no_shutdown) {
qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_POWEROFF, qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_POWEROFF,
&error_abort); !!info, info, &error_abort);
qemu_system_shutdown_request(); qemu_system_shutdown_request();
} }
if (info) {
qapi_free_GuestPanicInformation(info);
}
} }
void qemu_system_reset_request(void) void qemu_system_reset_request(void)