* [PATCH 0/4] ppc: add machine check injection HMP command
@ 2024-01-18 14:34 Nicholas Piggin
2024-01-18 14:34 ` [PATCH 1/4] nmi: add MCE class for implementing machine check injection commands Nicholas Piggin
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Nicholas Piggin @ 2024-01-18 14:34 UTC (permalink / raw)
To: qemu-ppc
Cc: Nicholas Piggin, Cédric Le Goater, Frédéric Barrat,
Daniel Henrique Barboza, David Gibson, Harsh Prateek Bora,
qemu-devel
I'd like to resurrect this and get it merged, because it's quite
useful for testing (has caught several Linux bugs in the past).
IIRC the main concern David had last time it came up was that it
should have QMP commands too. Which is valid. But I ended up
deciding it wouldn't be nice to expose this low level interface too
much, it would be better to use maybe a higher level error injection
interface that would be emulated in more detail (e.g., not just a
MCE, but would set relevant FIR registers and go through error
handling logic).
Since x86 has a low level 'mce' hmp command without qmp equivalent,
and since better error injection might take some time, I'd like to
just hold nose and take this for now.
Thanks,
Nick
Nicholas Piggin (4):
nmi: add MCE class for implementing machine check injection commands
ppc/spapr: Implement mce injection
target/ppc: Add machine check interrupt injection helper
ppc/pnv: Implement mce injection
include/hw/nmi.h | 20 ++++++++++++
include/hw/ppc/spapr.h | 3 ++
include/monitor/hmp-target.h | 1 -
include/monitor/hmp.h | 1 +
target/ppc/cpu.h | 1 +
hw/core/nmi.c | 61 ++++++++++++++++++++++++++++++++++++
hw/ppc/pnv.c | 55 ++++++++++++++++++++++++++++++++
hw/ppc/spapr.c | 54 +++++++++++++++++++++++++++++++
hw/ppc/spapr_events.c | 3 +-
monitor/hmp-cmds.c | 1 +
target/ppc/excp_helper.c | 7 +++++
target/ppc/ppc-qmp-cmds.c | 10 ++++++
hmp-commands.hx | 20 +++++++++++-
13 files changed, 233 insertions(+), 4 deletions(-)
--
2.42.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/4] nmi: add MCE class for implementing machine check injection commands
2024-01-18 14:34 [PATCH 0/4] ppc: add machine check injection HMP command Nicholas Piggin
@ 2024-01-18 14:34 ` Nicholas Piggin
2024-01-18 14:34 ` [PATCH 2/4] ppc/spapr: Implement mce injection Nicholas Piggin
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Nicholas Piggin @ 2024-01-18 14:34 UTC (permalink / raw)
To: qemu-ppc
Cc: Nicholas Piggin, Cédric Le Goater, Frédéric Barrat,
Daniel Henrique Barboza, David Gibson, Harsh Prateek Bora,
qemu-devel
Like commit 9cb805fd26 ("cpus: Define callback for QEMU "nmi" command")
this implements a machine check injection command framework and defines
a monitor command for ppc.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
include/hw/nmi.h | 20 ++++++++++++
include/monitor/hmp-target.h | 1 -
include/monitor/hmp.h | 1 +
hw/core/nmi.c | 61 ++++++++++++++++++++++++++++++++++++
monitor/hmp-cmds.c | 1 +
target/ppc/ppc-qmp-cmds.c | 10 ++++++
hmp-commands.hx | 20 +++++++++++-
7 files changed, 112 insertions(+), 2 deletions(-)
diff --git a/include/hw/nmi.h b/include/hw/nmi.h
index fff41bebc6..09f9ca122a 100644
--- a/include/hw/nmi.h
+++ b/include/hw/nmi.h
@@ -42,4 +42,24 @@ struct NMIClass {
void nmi_monitor_handle(int cpu_index, Error **errp);
+
+#define TYPE_MCE "mce"
+
+#define MCE_CLASS(klass) \
+ OBJECT_CLASS_CHECK(MCEClass, (klass), TYPE_MCE)
+#define MCE_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(MCEClass, (obj), TYPE_MCE)
+#define MCE(obj) \
+ INTERFACE_CHECK(MCEState, (obj), TYPE_MCE)
+
+typedef struct MCEState MCEState;
+
+typedef struct MCEClass {
+ InterfaceClass parent_class;
+
+ void (*mce_monitor_handler)(MCEState *n, const QDict *qdict, Error **errp);
+} MCEClass;
+
+void mce_monitor_handle(const QDict *qdict, Error **errp);
+
#endif /* NMI_H */
diff --git a/include/monitor/hmp-target.h b/include/monitor/hmp-target.h
index d78e979f05..dec6dba8e5 100644
--- a/include/monitor/hmp-target.h
+++ b/include/monitor/hmp-target.h
@@ -46,7 +46,6 @@ CPUState *mon_get_cpu(Monitor *mon);
void hmp_info_mem(Monitor *mon, const QDict *qdict);
void hmp_info_tlb(Monitor *mon, const QDict *qdict);
-void hmp_mce(Monitor *mon, const QDict *qdict);
void hmp_info_local_apic(Monitor *mon, const QDict *qdict);
void hmp_info_sev(Monitor *mon, const QDict *qdict);
void hmp_info_sgx(Monitor *mon, const QDict *qdict);
diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
index 13f9a2dedb..fe14a855a0 100644
--- a/include/monitor/hmp.h
+++ b/include/monitor/hmp.h
@@ -56,6 +56,7 @@ void hmp_ringbuf_read(Monitor *mon, const QDict *qdict);
void hmp_cont(Monitor *mon, const QDict *qdict);
void hmp_system_wakeup(Monitor *mon, const QDict *qdict);
void hmp_nmi(Monitor *mon, const QDict *qdict);
+void hmp_mce(Monitor *mon, const QDict *qdict);
void hmp_info_network(Monitor *mon, const QDict *qdict);
void hmp_set_link(Monitor *mon, const QDict *qdict);
void hmp_balloon(Monitor *mon, const QDict *qdict);
diff --git a/hw/core/nmi.c b/hw/core/nmi.c
index a7bce8a04a..d653f054eb 100644
--- a/hw/core/nmi.c
+++ b/hw/core/nmi.c
@@ -85,3 +85,64 @@ static void nmi_register_types(void)
}
type_init(nmi_register_types)
+
+struct do_mce_s {
+ const QDict *qdict;
+ Error *err;
+ bool handled;
+};
+
+static void mce_children(Object *o, struct do_mce_s *ns);
+
+static int do_mce(Object *o, void *opaque)
+{
+ struct do_mce_s *ms = opaque;
+ MCEState *m = (MCEState *) object_dynamic_cast(o, TYPE_MCE);
+
+ if (m) {
+ MCEClass *mc = MCE_GET_CLASS(m);
+
+ ms->handled = true;
+ mc->mce_monitor_handler(m, ms->qdict, &ms->err);
+ if (ms->err) {
+ return -1;
+ }
+ }
+ mce_children(o, ms);
+
+ return 0;
+}
+
+static void mce_children(Object *o, struct do_mce_s *ms)
+{
+ object_child_foreach(o, do_mce, ms);
+}
+
+void mce_monitor_handle(const QDict *qdict, Error **errp)
+{
+ struct do_mce_s ms = {
+ .qdict = qdict,
+ .err = NULL,
+ .handled = false
+ };
+
+ mce_children(object_get_root(), &ms);
+ if (ms.handled) {
+ error_propagate(errp, ms.err);
+ } else {
+ error_setg(errp, "machine does not provide MCEs");
+ }
+}
+
+static const TypeInfo mce_info = {
+ .name = TYPE_MCE,
+ .parent = TYPE_INTERFACE,
+ .class_size = sizeof(MCEClass),
+};
+
+static void mce_register_types(void)
+{
+ type_register_static(&mce_info);
+}
+
+type_init(mce_register_types)
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
index 871898ac46..0e46c107b6 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -28,6 +28,7 @@
#include "hw/intc/intc.h"
#include "qemu/log.h"
#include "sysemu/sysemu.h"
+#include "hw/nmi.h"
bool hmp_handle_error(Monitor *mon, Error *err)
{
diff --git a/target/ppc/ppc-qmp-cmds.c b/target/ppc/ppc-qmp-cmds.c
index ee0b99fce7..43fa5980d2 100644
--- a/target/ppc/ppc-qmp-cmds.c
+++ b/target/ppc/ppc-qmp-cmds.c
@@ -31,6 +31,7 @@
#include "qapi/qapi-commands-machine-target.h"
#include "cpu-models.h"
#include "cpu-qom.h"
+#include "hw/nmi.h"
static target_long monitor_get_ccr(Monitor *mon, const struct MonitorDef *md,
int val)
@@ -91,6 +92,15 @@ void hmp_info_tlb(Monitor *mon, const QDict *qdict)
dump_mmu(env1);
}
+void hmp_mce(Monitor *mon, const QDict *qdict)
+{
+ Error *err = NULL;
+
+ mce_monitor_handle(qdict, &err);
+
+ hmp_handle_error(mon, err);
+}
+
const MonitorDef monitor_defs[] = {
{ "fpscr", offsetof(CPUPPCState, fpscr) },
/* Next instruction pointer */
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 765349ed14..384cf5d0c4 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1509,12 +1509,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 a low-level MCE on the given CPU (PPC only).
+ERST
+
+#endif
+
#ifdef CONFIG_POSIX
{
.name = "getfd",
--
2.42.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/4] ppc/spapr: Implement mce injection
2024-01-18 14:34 [PATCH 0/4] ppc: add machine check injection HMP command Nicholas Piggin
2024-01-18 14:34 ` [PATCH 1/4] nmi: add MCE class for implementing machine check injection commands Nicholas Piggin
@ 2024-01-18 14:34 ` Nicholas Piggin
2024-01-18 14:34 ` [PATCH 3/4] target/ppc: Add machine check interrupt injection helper Nicholas Piggin
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Nicholas Piggin @ 2024-01-18 14:34 UTC (permalink / raw)
To: qemu-ppc
Cc: Nicholas Piggin, Cédric Le Goater, Frédéric Barrat,
Daniel Henrique Barboza, David Gibson, Harsh Prateek Bora,
qemu-devel
This implements mce injection for spapr.
(qemu) mce 0 0x200000 0x80 0xdeadbeef 0
Disabling lock debugging due to kernel taint
MCE: CPU0: machine check (Severe) Host SLB Multihit DAR: 00000000deadbeef [Recovered]
MCE: CPU0: machine check (Severe) Host SLB Multihit [Recovered]
MCE: CPU0: PID: 495 Comm: a NIP: [0000000130ee07c8]
MCE: CPU0: Initiator CPU
MCE: CPU0: Unknown
[ 71.567193] MCE: CPU0: NIP: [c0000000000d7f6c] plpar_hcall_norets+0x1c/0x28
[ 71.567249] MCE: CPU0: Initiator CPU
[ 71.567308] MCE: CPU0: Unknown
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
include/hw/ppc/spapr.h | 3 +++
hw/ppc/spapr.c | 54 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 57 insertions(+)
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 5b5ba9ef77..d8f925a391 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -1015,6 +1015,9 @@ void spapr_init_all_lpcrs(target_ulong value, target_ulong mask);
hwaddr spapr_get_rtas_addr(void);
bool spapr_memory_hot_unplug_supported(SpaprMachineState *spapr);
+void spapr_mce_inject(CPUState *cs, uint64_t srr1_mask, uint32_t dsisr,
+ uint64_t dar, bool recovered);
+
void spapr_vof_reset(SpaprMachineState *spapr, void *fdt, Error **errp);
void spapr_vof_quiesce(MachineState *ms);
bool spapr_vof_setprop(MachineState *ms, const char *path, const char *propname,
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 40fdbd5d12..641b763836 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -89,6 +89,7 @@
#include "hw/ppc/pef.h"
#include "monitor/monitor.h"
+#include "qapi/qmp/qdict.h"
#include <libfdt.h>
@@ -3584,6 +3585,56 @@ 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);
+
+ 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_mce(MCEState *m, const QDict *qdict, Error **errp)
+{
+ 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");
+ CPUState *cs;
+
+ cs = qemu_get_cpu(cpu_index);
+
+ if (cs != NULL) {
+ 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)
{
@@ -4689,6 +4740,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(oc);
FWPathProviderClass *fwc = FW_PATH_PROVIDER_CLASS(oc);
NMIClass *nc = NMI_CLASS(oc);
+ MCEClass *mcec = MCE_CLASS(oc);
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
PPCVirtualHypervisorClass *vhc = PPC_VIRTUAL_HYPERVISOR_CLASS(oc);
XICSFabricClass *xic = XICS_FABRIC_CLASS(oc);
@@ -4743,6 +4795,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
smc->resize_hpt_default = SPAPR_RESIZE_HPT_ENABLED;
fwc->get_dev_path = spapr_get_fw_dev_path;
nc->nmi_monitor_handler = spapr_nmi;
+ mcec->mce_monitor_handler = spapr_mce;
smc->phb_placement = spapr_phb_placement;
vhc->cpu_in_nested = spapr_cpu_in_nested;
vhc->deliver_hv_excp = spapr_exit_nested;
@@ -4810,6 +4863,7 @@ static const TypeInfo spapr_machine_info = {
.interfaces = (InterfaceInfo[]) {
{ TYPE_FW_PATH_PROVIDER },
{ TYPE_NMI },
+ { TYPE_MCE },
{ TYPE_HOTPLUG_HANDLER },
{ TYPE_PPC_VIRTUAL_HYPERVISOR },
{ TYPE_XICS_FABRIC },
--
2.42.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/4] target/ppc: Add machine check interrupt injection helper
2024-01-18 14:34 [PATCH 0/4] ppc: add machine check injection HMP command Nicholas Piggin
2024-01-18 14:34 ` [PATCH 1/4] nmi: add MCE class for implementing machine check injection commands Nicholas Piggin
2024-01-18 14:34 ` [PATCH 2/4] ppc/spapr: Implement mce injection Nicholas Piggin
@ 2024-01-18 14:34 ` Nicholas Piggin
2024-01-18 14:34 ` [PATCH 4/4] ppc/pnv: Implement mce injection Nicholas Piggin
2024-01-18 14:57 ` [PATCH 0/4] ppc: add machine check injection HMP command Cédric Le Goater
4 siblings, 0 replies; 6+ messages in thread
From: Nicholas Piggin @ 2024-01-18 14:34 UTC (permalink / raw)
To: qemu-ppc
Cc: Nicholas Piggin, Cédric Le Goater, Frédéric Barrat,
Daniel Henrique Barboza, David Gibson, Harsh Prateek Bora,
qemu-devel
This matches the NMI injection helper function.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
hw/ppc/spapr_events.c | 3 +--
target/ppc/excp_helper.c | 7 +++++++
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c
index cb0eeee587..4be9a5ba3a 100644
--- a/hw/ppc/spapr_events.c
+++ b/hw/ppc/spapr_events.c
@@ -875,8 +875,7 @@ void spapr_mce_req_event(PowerPCCPU *cpu, bool recovered)
if (spapr->fwnmi_machine_check_addr == -1) {
/* Non-FWNMI case, deliver it like an architected CPU interrupt. */
- cs->exception_index = POWERPC_EXCP_MCHECK;
- ppc_cpu_do_interrupt(cs);
+ ppc_cpu_do_machine_check(cs);
return;
}
diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 58fd08729a..133477acba 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -2601,6 +2601,13 @@ void ppc_cpu_do_system_reset(CPUState *cs)
powerpc_excp(cpu, POWERPC_EXCP_RESET);
}
+void ppc_cpu_do_machine_check(CPUState *cs)
+{
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+
+ powerpc_excp(cpu, POWERPC_EXCP_MCHECK);
+}
+
void ppc_cpu_do_fwnmi_machine_check(CPUState *cs, target_ulong vector)
{
PowerPCCPU *cpu = POWERPC_CPU(cs);
--
2.42.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 4/4] ppc/pnv: Implement mce injection
2024-01-18 14:34 [PATCH 0/4] ppc: add machine check injection HMP command Nicholas Piggin
` (2 preceding siblings ...)
2024-01-18 14:34 ` [PATCH 3/4] target/ppc: Add machine check interrupt injection helper Nicholas Piggin
@ 2024-01-18 14:34 ` Nicholas Piggin
2024-01-18 14:57 ` [PATCH 0/4] ppc: add machine check injection HMP command Cédric Le Goater
4 siblings, 0 replies; 6+ messages in thread
From: Nicholas Piggin @ 2024-01-18 14:34 UTC (permalink / raw)
To: qemu-ppc
Cc: Nicholas Piggin, Cédric Le Goater, Frédéric Barrat,
Daniel Henrique Barboza, David Gibson, Harsh Prateek Bora,
qemu-devel
This implements mce injection for pnv.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
target/ppc/cpu.h | 1 +
hw/ppc/pnv.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 56 insertions(+)
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index aa22523316..b046a12f8c 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1593,6 +1593,7 @@ void ppc_maybe_interrupt(CPUPPCState *env);
void ppc_cpu_do_interrupt(CPUState *cpu);
bool ppc_cpu_exec_interrupt(CPUState *cpu, int int_req);
void ppc_cpu_do_system_reset(CPUState *cs);
+void ppc_cpu_do_machine_check(CPUState *cs);
void ppc_cpu_do_fwnmi_machine_check(CPUState *cs, target_ulong vector);
extern const VMStateDescription vmstate_ppc_cpu;
#endif
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 427013fd60..2d18190aeb 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -38,6 +38,7 @@
#include "hw/loader.h"
#include "hw/nmi.h"
#include "qapi/visitor.h"
+#include "qapi/qmp/qdict.h"
#include "monitor/monitor.h"
#include "hw/intc/intc.h"
#include "hw/ipmi/ipmi.h"
@@ -2461,11 +2462,63 @@ static void pnv_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 pnv_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);
+
+ cpu_synchronize_state(cs);
+ ppc_cpu_do_machine_check(cs);
+
+ env->spr[SPR_SRR1] |= (params->srr1_mask & srr1_mce_bits);
+ if (params->dsisr) {
+ env->spr[SPR_DSISR] = params->dsisr;
+ env->spr[SPR_DAR] = params->dar;
+ }
+
+ if (!params->recovered) {
+ env->msr &= ~MSR_RI;
+ }
+}
+
+static void pnv_mce(MCEState *m, const QDict *qdict, Error **errp)
+{
+ 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");
+ CPUState *cs;
+
+ cs = qemu_get_cpu(cpu_index);
+
+ if (cs != NULL) {
+ MCEInjectionParams params = {
+ .srr1_mask = srr1_mask,
+ .dsisr = dsisr,
+ .dar = dar,
+ .recovered = recovered,
+ };
+
+ run_on_cpu(cs, pnv_do_mce_on_cpu, RUN_ON_CPU_HOST_PTR(¶ms));
+ }
+}
+
static void pnv_machine_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
InterruptStatsProviderClass *ispc = INTERRUPT_STATS_PROVIDER_CLASS(oc);
NMIClass *nc = NMI_CLASS(oc);
+ MCEClass *mcec = MCE_CLASS(oc);
mc->desc = "IBM PowerNV (Non-Virtualized)";
mc->init = pnv_init;
@@ -2483,6 +2536,7 @@ static void pnv_machine_class_init(ObjectClass *oc, void *data)
mc->default_ram_id = "pnv.ram";
ispc->print_info = pnv_pic_print_info;
nc->nmi_monitor_handler = pnv_nmi;
+ mcec->mce_monitor_handler = pnv_mce;
object_class_property_add_bool(oc, "hb-mode",
pnv_machine_get_hb, pnv_machine_set_hb);
@@ -2549,6 +2603,7 @@ static const TypeInfo types[] = {
.interfaces = (InterfaceInfo[]) {
{ TYPE_INTERRUPT_STATS_PROVIDER },
{ TYPE_NMI },
+ { TYPE_MCE },
{ },
},
},
--
2.42.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 0/4] ppc: add machine check injection HMP command
2024-01-18 14:34 [PATCH 0/4] ppc: add machine check injection HMP command Nicholas Piggin
` (3 preceding siblings ...)
2024-01-18 14:34 ` [PATCH 4/4] ppc/pnv: Implement mce injection Nicholas Piggin
@ 2024-01-18 14:57 ` Cédric Le Goater
4 siblings, 0 replies; 6+ messages in thread
From: Cédric Le Goater @ 2024-01-18 14:57 UTC (permalink / raw)
To: Nicholas Piggin, qemu-ppc
Cc: Frédéric Barrat, Daniel Henrique Barboza, David Gibson,
Harsh Prateek Bora, qemu-devel
Hello Nick,
On 1/18/24 15:34, Nicholas Piggin wrote:
> I'd like to resurrect this and get it merged, because it's quite
> useful for testing (has caught several Linux bugs in the past).
>
> IIRC the main concern David had last time it came up was that it
> should have QMP commands too. Which is valid. But I ended up
> deciding it wouldn't be nice to expose this low level interface too
> much, it would be better to use maybe a higher level error injection
> interface that would be emulated in more detail (e.g., not just a
> MCE, but would set relevant FIR registers and go through error
> handling logic).
>
> Since x86 has a low level 'mce' hmp command without qmp equivalent,
> and since better error injection might take some time, I'd like to
> just hold nose and take this for now.
I reworked this series some years ago :
https://lore.kernel.org/qemu-devel/20211013214042.618918-1-clg@kaod.org/
Did you take into account the changes ?
Thanks,
C.
> Thanks,
> Nick
>
> Nicholas Piggin (4):
> nmi: add MCE class for implementing machine check injection commands
> ppc/spapr: Implement mce injection
> target/ppc: Add machine check interrupt injection helper
> ppc/pnv: Implement mce injection
>
> include/hw/nmi.h | 20 ++++++++++++
> include/hw/ppc/spapr.h | 3 ++
> include/monitor/hmp-target.h | 1 -
> include/monitor/hmp.h | 1 +
> target/ppc/cpu.h | 1 +
> hw/core/nmi.c | 61 ++++++++++++++++++++++++++++++++++++
> hw/ppc/pnv.c | 55 ++++++++++++++++++++++++++++++++
> hw/ppc/spapr.c | 54 +++++++++++++++++++++++++++++++
> hw/ppc/spapr_events.c | 3 +-
> monitor/hmp-cmds.c | 1 +
> target/ppc/excp_helper.c | 7 +++++
> target/ppc/ppc-qmp-cmds.c | 10 ++++++
> hmp-commands.hx | 20 +++++++++++-
> 13 files changed, 233 insertions(+), 4 deletions(-)
>
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2024-01-18 14:58 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-01-18 14:34 [PATCH 0/4] ppc: add machine check injection HMP command Nicholas Piggin
2024-01-18 14:34 ` [PATCH 1/4] nmi: add MCE class for implementing machine check injection commands Nicholas Piggin
2024-01-18 14:34 ` [PATCH 2/4] ppc/spapr: Implement mce injection Nicholas Piggin
2024-01-18 14:34 ` [PATCH 3/4] target/ppc: Add machine check interrupt injection helper Nicholas Piggin
2024-01-18 14:34 ` [PATCH 4/4] ppc/pnv: Implement mce injection Nicholas Piggin
2024-01-18 14:57 ` [PATCH 0/4] ppc: add machine check injection HMP command Cédric Le Goater
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).