From: Nicholas Piggin <npiggin@gmail.com>
To: qemu-ppc@nongnu.org
Cc: "Aravinda Prasad" <arawinda.p@gmail.com>,
"Alexey Kardashevskiy" <aik@ozlabs.ru>,
qemu-devel@nongnu.org, "Nicholas Piggin" <npiggin@gmail.com>,
"Greg Kurz" <groug@kaod.org>, "Cédric Le Goater" <clg@fr.ibm.com>,
"Ganesh Goudar" <ganeshgr@linux.ibm.com>,
"David Gibson" <david@gibson.dropbear.id.au>
Subject: [PATCH 5/5] target/ppc: Implement simple monitor mce injection
Date: Tue, 17 Mar 2020 15:02:15 +1000 [thread overview]
Message-ID: <20200317050215.159334-6-npiggin@gmail.com> (raw)
In-Reply-To: <20200317050215.159334-1-npiggin@gmail.com>
This enables the mce monitor command for ppc, and adds a spapr
facility to inject machine check exception to a CPU by setting
low level registers.
(qemu) mce 0 0x200000 0x80 0xdeadbeef 1
Disabling lock debugging due to kernel taint
MCE: CPU0: machine check (Severe) Host SLB Multihit [Recovered]
MCE: CPU0: PID: 495 Comm: a NIP: [0000000130ee07c8]
MCE: CPU0: Initiator CPU
MCE: CPU0: Unknown
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
hmp-commands.hx | 20 +++++++++++++++++++-
hw/ppc/spapr.c | 42 ++++++++++++++++++++++++++++++++++++++++++
include/hw/ppc/spapr.h | 3 +++
target/ppc/cpu.h | 3 +++
target/ppc/monitor.c | 26 ++++++++++++++++++++++++++
5 files changed, 93 insertions(+), 1 deletion(-)
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 7f0f3974ad..4a9089b431 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1581,12 +1581,30 @@ ERST
.cmd = hmp_mce,
},
-#endif
SRST
``mce`` *cpu* *bank* *status* *mcgstatus* *addr* *misc*
Inject an MCE on the given CPU (x86 only).
ERST
+#endif
+
+#if defined(TARGET_PPC)
+
+ {
+ .name = "mce",
+ .args_type = "cpu_index:i,srr1_mask:l,dsisr:i,dar:l,recovered:i",
+ .params = "cpu srr1_mask dsisr dar recovered",
+ .help = "inject a MCE on the given CPU",
+ .cmd = hmp_mce,
+ },
+
+SRST
+``mce`` *cpu* *srr1_mask* *dsisr* *dar* *recovered*
+ Inject an MCE on the given CPU (PPC only).
+ERST
+
+#endif
+
{
.name = "getfd",
.args_type = "fdname:s",
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 78e649f47d..d83245c438 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -3454,6 +3454,47 @@ static void spapr_nmi(NMIState *n, int cpu_index, Error **errp)
}
}
+typedef struct MCEInjectionParams {
+ uint64_t srr1_mask;
+ uint32_t dsisr;
+ uint64_t dar;
+ bool recovered;
+} MCEInjectionParams;
+
+static void spapr_do_mce_on_cpu(CPUState *cs, run_on_cpu_data data)
+{
+ MCEInjectionParams *params = data.host_ptr;
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ CPUPPCState *env = &cpu->env;
+ uint64_t srr1_mce_bits = PPC_BITMASK(42,45) | PPC_BIT(36); /* POWER9 bits */
+
+ cpu_synchronize_state(cs);
+
+ env->spr[SPR_SRR0] = env->nip;
+ env->spr[SPR_SRR1] = (env->msr & ~srr1_mce_bits) |
+ (params->srr1_mask & srr1_mce_bits);
+ if (params->dsisr) {
+ env->spr[SPR_DSISR] = params->dsisr;
+ env->spr[SPR_DAR] = params->dar;
+ }
+
+ spapr_mce_req_event(cpu, params->recovered);
+}
+
+static void spapr_cpu_mce_inject(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu,
+ uint64_t srr1_mask, uint32_t dsisr,
+ uint64_t dar, bool recovered)
+{
+ CPUState *cs = CPU(cpu);
+ MCEInjectionParams params = {
+ .srr1_mask = srr1_mask,
+ .dsisr = dsisr,
+ .dar = dar,
+ .recovered = recovered,
+ };
+ run_on_cpu(cs, spapr_do_mce_on_cpu, RUN_ON_CPU_HOST_PTR(¶ms));
+}
+
int spapr_lmb_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr,
void *fdt, int *fdt_start_offset, Error **errp)
{
@@ -4556,6 +4597,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
vhc->encode_hpt_for_kvm_pr = spapr_encode_hpt_for_kvm_pr;
vhc->cpu_exec_enter = spapr_cpu_exec_enter;
vhc->cpu_exec_exit = spapr_cpu_exec_exit;
+ vhc->cpu_mce_inject = spapr_cpu_mce_inject;
xic->ics_get = spapr_ics_get;
xic->ics_resend = spapr_ics_resend;
xic->icp_get = spapr_icp_get;
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 42d64a0368..72f86a2ee8 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -929,4 +929,7 @@ void spapr_check_pagesize(SpaprMachineState *spapr, hwaddr pagesize,
void spapr_set_all_lpcrs(target_ulong value, target_ulong mask);
hwaddr spapr_get_rtas_addr(void);
+
+void spapr_mce_inject(CPUState *cs, uint64_t srr1_mask, uint32_t dsisr,
+ uint64_t dar, bool recovered);
#endif /* HW_SPAPR_H */
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index f8c7d6f19c..ed8d2015bd 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1189,6 +1189,9 @@ struct PPCVirtualHypervisorClass {
#ifndef CONFIG_USER_ONLY
void (*cpu_exec_enter)(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu);
void (*cpu_exec_exit)(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu);
+ void (*cpu_mce_inject)(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu,
+ uint64_t srr1_mask, uint32_t dsisr, uint64_t dar,
+ bool recovered);
#endif
};
diff --git a/target/ppc/monitor.c b/target/ppc/monitor.c
index a5a177d717..ec997ce673 100644
--- a/target/ppc/monitor.c
+++ b/target/ppc/monitor.c
@@ -28,6 +28,7 @@
#include "qemu/ctype.h"
#include "monitor/hmp-target.h"
#include "monitor/hmp.h"
+#include "qapi/qmp/qdict.h"
static target_long monitor_get_ccr(const struct MonitorDef *md, int val)
{
@@ -72,6 +73,31 @@ void hmp_info_tlb(Monitor *mon, const QDict *qdict)
dump_mmu(env1);
}
+void hmp_mce(Monitor *mon, const QDict *qdict)
+{
+ CPUState *cs;
+ int cpu_index = qdict_get_int(qdict, "cpu_index");
+ uint64_t srr1_mask = qdict_get_int(qdict, "srr1_mask");
+ uint32_t dsisr = qdict_get_int(qdict, "dsisr");
+ uint64_t dar = qdict_get_int(qdict, "dar");
+ bool recovered = qdict_get_int(qdict, "recovered");
+
+ cs = qemu_get_cpu(cpu_index);
+
+ if (cs != NULL) {
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+
+ if (cpu->vhyp) {
+ PPCVirtualHypervisorClass *vhc =
+ PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
+ if (vhc->cpu_mce_inject) {
+ vhc->cpu_mce_inject(cpu->vhyp, cpu,
+ srr1_mask, dsisr, dar, recovered);
+ }
+ }
+ }
+}
+
const MonitorDef monitor_defs[] = {
{ "fpscr", offsetof(CPUPPCState, fpscr) },
/* Next instruction pointer */
--
2.23.0
prev parent reply other threads:[~2020-03-17 5:07 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-03-17 5:02 [PATCH 0/5] FWNMI follow up patches Nicholas Piggin
2020-03-17 5:02 ` [PATCH 1/5] ppc/spapr: KVM FWNMI should not be enabled until guest requests it Nicholas Piggin
2020-03-17 11:02 ` Greg Kurz
2020-03-19 2:27 ` Nicholas Piggin
2020-03-17 5:02 ` [PATCH 2/5] ppc/spapr: Improve FWNMI machine check delivery corner case comments Nicholas Piggin
2020-03-17 12:16 ` Greg Kurz
2020-03-17 5:02 ` [PATCH 3/5] ppc/spapr: Add FWNMI machine check delivery warnings Nicholas Piggin
2020-03-17 12:20 ` Greg Kurz
2020-03-19 2:28 ` Nicholas Piggin
2020-03-17 5:02 ` [PATCH 4/5] ppc/spapr: Don't kill the guest if a recovered FWNMI machine check delivery fails Nicholas Piggin
2020-03-17 16:57 ` Greg Kurz
2020-03-19 2:29 ` Nicholas Piggin
2020-03-17 5:02 ` Nicholas Piggin [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200317050215.159334-6-npiggin@gmail.com \
--to=npiggin@gmail.com \
--cc=aik@ozlabs.ru \
--cc=arawinda.p@gmail.com \
--cc=clg@fr.ibm.com \
--cc=david@gibson.dropbear.id.au \
--cc=ganeshgr@linux.ibm.com \
--cc=groug@kaod.org \
--cc=qemu-devel@nongnu.org \
--cc=qemu-ppc@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).