From nobody Wed Oct 22 13:02:49 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 151991193362533.53596800568971; Thu, 1 Mar 2018 05:45:33 -0800 (PST) Received: from localhost ([::1]:56787 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1erOWa-0001FH-LB for importer@patchew.org; Thu, 01 Mar 2018 08:45:32 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58803) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1erNrQ-0004In-2l for qemu-devel@nongnu.org; Thu, 01 Mar 2018 08:03:01 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1erNrJ-0007P7-Bs for qemu-devel@nongnu.org; Thu, 01 Mar 2018 08:03:00 -0500 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:47180 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1erNrJ-0007P0-7Q; Thu, 01 Mar 2018 08:02:53 -0500 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id B41034084FEC; Thu, 1 Mar 2018 13:02:52 +0000 (UTC) Received: from localhost (ovpn-117-50.ams2.redhat.com [10.36.117.50]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 2A58B2026E04; Thu, 1 Mar 2018 13:02:52 +0000 (UTC) From: Cornelia Huck To: peter.maydell@linaro.org Date: Thu, 1 Mar 2018 14:01:49 +0100 Message-Id: <20180301130201.24666-16-cohuck@redhat.com> In-Reply-To: <20180301130201.24666-1-cohuck@redhat.com> References: <20180301130201.24666-1-cohuck@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.4 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.5]); Thu, 01 Mar 2018 13:02:52 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.5]); Thu, 01 Mar 2018 13:02:52 +0000 (UTC) for IP:'10.11.54.4' DOMAIN:'int-mx04.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'cohuck@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [PULL v2 15/27] s390x/cpu: expose the guest crash information X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: thuth@redhat.com, david@redhat.com, Cornelia Huck , qemu-devel@nongnu.org, agraf@suse.de, borntraeger@de.ibm.com, qemu-s390x@nongnu.org, rth@twiddle.net Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Christian Borntraeger This patch is the s390 implementation of guest crash information, similar to commit d187e08dc4 ("i386/cpu: add crash-information QOM property") and the related commits. We will detect several crash reasons, with the "disabled wait" being the most important one, since this is used by all s390 guests as a "panic like" notification. Demonstrate these ways with examples as follows. 1. crash-information QOM property; Run qemu with -qmp unix:qmp-sock,server, then use utility "qmp-shell" to execute "qom-get" command, and might get the result like, (QEMU) (QEMU) qom-get path=3D/machine/unattached/device[0] \ property=3Dcrash-information {"return": {"core": 0, "reason": "disabled-wait", "psw-mask": 56295639587= 2256, \ "type": "s390", "psw-addr": 1102832}} 2. GUEST_PANICKED event reporting; Run qemu with a socket option, and telnet or nc to that, -chardev socket,id=3Dqmp,port=3D4444,host=3Dlocalhost,server \ -mon chardev=3Dqmp,mode=3Dcontrol,pretty=3Don \ Negotiating the mode by { "execute": "qmp_capabilities" }, and the crash information will be reported on a guest crash event like, { "timestamp": { "seconds": 1518004739, "microseconds": 552563 }, "event": "GUEST_PANICKED", "data": { "action": "pause", "info": { "core": 0, "psw-addr": 1102832, "reason": "disabled-wait", "psw-mask": 562956395872256, "type": "s390" } } } 3. log; Run qemu with the parameters: -D -d guest_errors, to specify the logfile and log item. The results might be, Guest crashed on cpu 0: disabled-wait PSW: 0x0002000180000000 0x000000000010d3f0 Co-authored-by: Jing Liu Signed-off-by: Christian Borntraeger Message-Id: <20180209122543.25755-1-borntraeger@de.ibm.com> Reviewed-by: Eric Blake [CH: tweaked qapi comment] Signed-off-by: Cornelia Huck --- qapi/run-state.json | 55 +++++++++++++++++++++++++++++++++++++++++++++++= ++-- target/s390x/cpu.c | 45 +++++++++++++++++++++++++++++++++++++++++ target/s390x/cpu.h | 2 ++ target/s390x/helper.c | 5 ++++- target/s390x/kvm.c | 15 +++++++------- vl.c | 11 +++++++++-- 6 files changed, 120 insertions(+), 13 deletions(-) diff --git a/qapi/run-state.json b/qapi/run-state.json index bca46a8785..92d29fd571 100644 --- a/qapi/run-state.json +++ b/qapi/run-state.json @@ -320,22 +320,29 @@ # # An enumeration of the guest panic information types # +# @hyper-v: hyper-v guest panic information type +# +# @s390: s390 guest panic information type (Since: 2.12) +# # Since: 2.9 ## { 'enum': 'GuestPanicInformationType', - 'data': [ 'hyper-v'] } + 'data': [ 'hyper-v', 's390' ] } =20 ## # @GuestPanicInformation: # # Information about a guest panic # +# @type: Crash type that defines the hypervisor specific information +# # Since: 2.9 ## {'union': 'GuestPanicInformation', 'base': {'type': 'GuestPanicInformationType'}, 'discriminator': 'type', - 'data': { 'hyper-v': 'GuestPanicInformationHyperV' } } + 'data': { 'hyper-v': 'GuestPanicInformationHyperV', + 's390': 'GuestPanicInformationS390' } } =20 ## # @GuestPanicInformationHyperV: @@ -350,3 +357,47 @@ 'arg3': 'uint64', 'arg4': 'uint64', 'arg5': 'uint64' } } + +## +# @S390CrashReason: +# +# Reason why the CPU is in a crashed state. +# +# @unknown: no crash reason was set +# +# @disabled-wait: the CPU has entered a disabled wait state +# +# @extint-loop: clock comparator or cpu timer interrupt with new PSW enabl= ed +# for external interrupts +# +# @pgmint-loop: program interrupt with BAD new PSW +# +# @opint-loop: operation exception interrupt with invalid code at the prog= ram +# interrupt new PSW +# +# Since: 2.12 +## +{ 'enum': 'S390CrashReason', + 'data': [ 'unknown', + 'disabled-wait', + 'extint-loop', + 'pgmint-loop', + 'opint-loop' ] } + +## +# @GuestPanicInformationS390: +# +# S390 specific guest panic information (PSW) +# +# @core: core id of the CPU that crashed +# @psw-mask: control fields of guest PSW +# @psw-addr: guest instruction address +# @reason: guest crash reason +# +# Since: 2.12 +## +{'struct': 'GuestPanicInformationS390', + 'data': { 'core': 'uint32', + 'psw-mask': 'uint64', + 'psw-addr': 'uint64', + 'reason': 'S390CrashReason' } } 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); } =20 +static GuestPanicInformation *s390_cpu_get_crash_info(CPUState *cs) +{ + GuestPanicInformation *panic_info; + S390CPU *cpu =3D S390_CPU(cs); + + cpu_synchronize_state(cs); + panic_info =3D g_malloc0(sizeof(GuestPanicInformation)); + + panic_info->type =3D GUEST_PANIC_INFORMATION_TYPE_S390; +#if !defined(CONFIG_USER_ONLY) + panic_info->u.s390.core =3D cpu->env.core_id; +#else + panic_info->u.s390.core =3D 0; /* sane default for non system emulatio= n */ +#endif + panic_info->u.s390.psw_mask =3D cpu->env.psw.mask; + panic_info->u.s390.psw_addr =3D cpu->env.psw.addr; + panic_info->u.s390.reason =3D 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 =3D CPU(obj); + GuestPanicInformation *panic_info; + + if (!cs->crash_occurred) { + error_setg(errp, "No crash occurred"); + return; + } + + panic_info =3D 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 =3D CPU(obj); @@ -240,6 +282,8 @@ static void s390_cpu_initfn(Object *obj) cs->env_ptr =3D env; cs->halted =3D 1; cs->exception_index =3D EXCP_HLT; + object_property_add(obj, "crash-information", "GuestPanicInformation", + s390_cpu_get_crash_info_qom, NULL, NULL, NULL, NUL= L); 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 =3D s390_cpu_do_interrupt; #endif cc->dump_state =3D s390_cpu_dump_state; + cc->get_crash_info =3D s390_cpu_get_crash_info; cc->set_pc =3D s390_cpu_set_pc; cc->gdb_read_register =3D s390_cpu_gdb_read_register; cc->gdb_write_register =3D s390_cpu_gdb_write_register; diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h index 96df2fe5c9..09ec8a9b76 100644 --- a/target/s390x/cpu.h +++ b/target/s390x/cpu.h @@ -83,6 +83,8 @@ struct CPUS390XState { =20 PSW psw; =20 + S390CrashReason crash_reason; + uint64_t cc_src; uint64_t cc_dst; uint64_t cc_vr; diff --git a/target/s390x/helper.c b/target/s390x/helper.c index 84aaef3a53..615fa24ab9 100644 --- a/target/s390x/helper.c +++ b/target/s390x/helper.c @@ -83,12 +83,15 @@ static inline bool is_special_wait_psw(uint64_t psw_add= r) =20 void s390_handle_wait(S390CPU *cpu) { + CPUState *cs =3D CPU(cpu); + if (s390_cpu_halt(cpu) =3D=3D 0) { #ifndef CONFIG_USER_ONLY if (is_special_wait_psw(cpu->env.psw.addr)) { qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); } else { - qemu_system_guest_panicked(NULL); + cpu->env.crash_reason =3D S390_CRASH_REASON_DISABLED_WAIT; + qemu_system_guest_panicked(cpu_get_crash_info(cs)); } #endif } diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c index e13c8907df..83e4eaf45d 100644 --- a/target/s390x/kvm.c +++ b/target/s390x/kvm.c @@ -1541,15 +1541,14 @@ static int handle_instruction(S390CPU *cpu, struct = kvm_run *run) return r; } =20 -static void unmanageable_intercept(S390CPU *cpu, const char *str, int pswo= ffset) +static void unmanageable_intercept(S390CPU *cpu, S390CrashReason reason, + int pswoffset) { CPUState *cs =3D CPU(cpu); =20 - error_report("Unmanageable %s! CPU%i new PSW: 0x%016lx:%016lx", - str, cs->cpu_index, ldq_phys(cs->as, cpu->env.psa + pswof= fset), - ldq_phys(cs->as, cpu->env.psa + pswoffset + 8)); s390_cpu_halt(cpu); - qemu_system_guest_panicked(NULL); + cpu->env.crash_reason =3D reason; + qemu_system_guest_panicked(cpu_get_crash_info(cs)); } =20 /* try to detect pgm check loops */ @@ -1579,7 +1578,7 @@ static int handle_oper_loop(S390CPU *cpu, struct kvm_= run *run) !(oldpsw.mask & PSW_MASK_PSTATE) && (newpsw.mask & PSW_MASK_ASC) =3D=3D (oldpsw.mask & PSW_MASK_ASC) && (newpsw.mask & PSW_MASK_DAT) =3D=3D (oldpsw.mask & PSW_MASK_DAT)) { - unmanageable_intercept(cpu, "operation exception loop", + unmanageable_intercept(cpu, S390_CRASH_REASON_OPINT_LOOP, offsetof(LowCore, program_new_psw)); return EXCP_HALTED; } @@ -1600,12 +1599,12 @@ static int handle_intercept(S390CPU *cpu) r =3D handle_instruction(cpu, run); break; case ICPT_PROGRAM: - unmanageable_intercept(cpu, "program interrupt", + unmanageable_intercept(cpu, S390_CRASH_REASON_PGMINT_LOOP, offsetof(LowCore, program_new_psw)); r =3D EXCP_HALTED; break; case ICPT_EXT_INT: - unmanageable_intercept(cpu, "external interrupt", + unmanageable_intercept(cpu, S390_CRASH_REASON_EXTINT_LOOP, offsetof(LowCore, external_new_psw)); r =3D EXCP_HALTED; break; diff --git a/vl.c b/vl.c index 9e7235df6d..3018433706 100644 --- a/vl.c +++ b/vl.c @@ -1736,7 +1736,7 @@ void qemu_system_reset(ShutdownCause reason) =20 void qemu_system_guest_panicked(GuestPanicInformation *info) { - qemu_log_mask(LOG_GUEST_ERROR, "Guest crashed\n"); + qemu_log_mask(LOG_GUEST_ERROR, "Guest crashed"); =20 if (current_cpu) { current_cpu->crash_occurred =3D true; @@ -1752,13 +1752,20 @@ void qemu_system_guest_panicked(GuestPanicInformati= on *info) =20 if (info) { if (info->type =3D=3D GUEST_PANIC_INFORMATION_TYPE_HYPER_V) { - qemu_log_mask(LOG_GUEST_ERROR, "HV crash parameters: (%#"PRIx64 + qemu_log_mask(LOG_GUEST_ERROR, "\nHV crash parameters: (%#"PRI= x64 " %#"PRIx64" %#"PRIx64" %#"PRIx64" %#"PRIx64")\n= ", info->u.hyper_v.arg1, info->u.hyper_v.arg2, info->u.hyper_v.arg3, info->u.hyper_v.arg4, info->u.hyper_v.arg5); + } else if (info->type =3D=3D GUEST_PANIC_INFORMATION_TYPE_S390) { + qemu_log_mask(LOG_GUEST_ERROR, " on cpu %d: %s\n" + "PSW: 0x%016" PRIx64 " 0x%016" PRIx64"\n", + info->u.s390.core, + S390CrashReason_str(info->u.s390.reason), + info->u.s390.psw_mask, + info->u.s390.psw_addr); } qapi_free_GuestPanicInformation(info); } --=20 2.13.6