summaryrefslogtreecommitdiff
path: root/target/s390x/cpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/s390x/cpu.c')
-rw-r--r--target/s390x/cpu.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
index a665b9e60e..3e1be56536 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -35,6 +35,8 @@
#include "qemu/error-report.h"
#include "trace.h"
#include "qapi/visitor.h"
+#include "qapi-visit.h"
+#include "sysemu/hw_accel.h"
#include "exec/exec-all.h"
#include "hw/qdev-properties.h"
#ifndef CONFIG_USER_ONLY
@@ -228,6 +230,46 @@ out:
error_propagate(errp, err);
}
+static GuestPanicInformation *s390_cpu_get_crash_info(CPUState *cs)
+{
+ GuestPanicInformation *panic_info;
+ S390CPU *cpu = S390_CPU(cs);
+
+ cpu_synchronize_state(cs);
+ panic_info = g_malloc0(sizeof(GuestPanicInformation));
+
+ panic_info->type = GUEST_PANIC_INFORMATION_TYPE_S390;
+#if !defined(CONFIG_USER_ONLY)
+ panic_info->u.s390.core = cpu->env.core_id;
+#else
+ panic_info->u.s390.core = 0; /* sane default for non system emulation */
+#endif
+ panic_info->u.s390.psw_mask = cpu->env.psw.mask;
+ panic_info->u.s390.psw_addr = cpu->env.psw.addr;
+ panic_info->u.s390.reason = cpu->env.crash_reason;
+
+ return panic_info;
+}
+
+static void s390_cpu_get_crash_info_qom(Object *obj, Visitor *v,
+ const char *name, void *opaque,
+ Error **errp)
+{
+ CPUState *cs = CPU(obj);
+ GuestPanicInformation *panic_info;
+
+ if (!cs->crash_occurred) {
+ error_setg(errp, "No crash occurred");
+ return;
+ }
+
+ panic_info = s390_cpu_get_crash_info(cs);
+
+ visit_type_GuestPanicInformation(v, "crash-information", &panic_info,
+ errp);
+ qapi_free_GuestPanicInformation(panic_info);
+}
+
static void s390_cpu_initfn(Object *obj)
{
CPUState *cs = CPU(obj);
@@ -240,6 +282,8 @@ static void s390_cpu_initfn(Object *obj)
cs->env_ptr = env;
cs->halted = 1;
cs->exception_index = EXCP_HLT;
+ object_property_add(obj, "crash-information", "GuestPanicInformation",
+ s390_cpu_get_crash_info_qom, NULL, NULL, NULL, NULL);
s390_cpu_model_register_props(obj);
#if !defined(CONFIG_USER_ONLY)
qemu_get_timedate(&tm, 0);
@@ -473,6 +517,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
cc->do_interrupt = s390_cpu_do_interrupt;
#endif
cc->dump_state = s390_cpu_dump_state;
+ cc->get_crash_info = s390_cpu_get_crash_info;
cc->set_pc = s390_cpu_set_pc;
cc->gdb_read_register = s390_cpu_gdb_read_register;
cc->gdb_write_register = s390_cpu_gdb_write_register;