[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH 3/5] nmi: add MCE class for implementing machine check inject
From: |
Cédric Le Goater |
Subject: |
Re: [PATCH 3/5] nmi: add MCE class for implementing machine check injection commands |
Date: |
Wed, 25 Mar 2020 17:46:06 +0100 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.5.0 |
On 3/25/20 3:41 PM, Nicholas Piggin wrote:
> 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 <address@hidden>
Looks good to me,
Reviewed-by: Cédric Le Goater <address@hidden>
Tested-by: Cédric Le Goater <address@hidden>
Thanks,
C.
> ---
> hmp-commands.hx | 20 +++++++++++-
> hw/core/nmi.c | 61 ++++++++++++++++++++++++++++++++++++
> include/hw/nmi.h | 20 ++++++++++++
> include/monitor/hmp-target.h | 1 -
> include/monitor/hmp.h | 1 +
> monitor/hmp-cmds.c | 1 +
> target/ppc/monitor.c | 11 +++++++
> 7 files changed, 113 insertions(+), 2 deletions(-)
>
> 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/core/nmi.c b/hw/core/nmi.c
> index 481c4b3c7e..2a79500967 100644
> --- a/hw/core/nmi.c
> +++ b/hw/core/nmi.c
> @@ -86,3 +86,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, QERR_UNSUPPORTED);
> + }
> +}
> +
> +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/include/hw/nmi.h b/include/hw/nmi.h
> index fe37ce3ad8..de39d95c9a 100644
> --- a/include/hw/nmi.h
> +++ b/include/hw/nmi.h
> @@ -43,4 +43,24 @@ typedef 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 8b7820a3ad..afb8f5bca2 100644
> --- a/include/monitor/hmp-target.h
> +++ b/include/monitor/hmp-target.h
> @@ -45,7 +45,6 @@ CPUState *mon_get_cpu(void);
>
> 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_io_apic(Monitor *mon, const QDict *qdict);
>
> diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
> index e33ca5a911..f747a5e214 100644
> --- a/include/monitor/hmp.h
> +++ b/include/monitor/hmp.h
> @@ -54,6 +54,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_set_link(Monitor *mon, const QDict *qdict);
> void hmp_balloon(Monitor *mon, const QDict *qdict);
> void hmp_loadvm(Monitor *mon, const QDict *qdict);
> diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
> index 58724031ea..3664ef2a4f 100644
> --- a/monitor/hmp-cmds.c
> +++ b/monitor/hmp-cmds.c
> @@ -52,6 +52,7 @@
> #include "exec/ramlist.h"
> #include "hw/intc/intc.h"
> #include "hw/rdma/rdma.h"
> +#include "hw/nmi.h"
> #include "migration/snapshot.h"
> #include "migration/misc.h"
>
> diff --git a/target/ppc/monitor.c b/target/ppc/monitor.c
> index a5a177d717..6daf543efc 100644
> --- a/target/ppc/monitor.c
> +++ b/target/ppc/monitor.c
> @@ -28,6 +28,8 @@
> #include "qemu/ctype.h"
> #include "monitor/hmp-target.h"
> #include "monitor/hmp.h"
> +#include "qapi/qmp/qdict.h"
> +#include "hw/nmi.h"
>
> static target_long monitor_get_ccr(const struct MonitorDef *md, int val)
> {
> @@ -72,6 +74,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 */
>
- [PATCH 0/5] ppc: sreset and machine check injection, Nicholas Piggin, 2020/03/25
- [PATCH 1/5] ppc/spapr: tweak change system reset helper, Nicholas Piggin, 2020/03/25
- [PATCH 2/5] ppc/pnv: Add support for NMI interface, Nicholas Piggin, 2020/03/25
- [PATCH 3/5] nmi: add MCE class for implementing machine check injection commands, Nicholas Piggin, 2020/03/25
- [PATCH 4/5] ppc/spapr: Implement mce injection, Nicholas Piggin, 2020/03/25
- [PATCH 5/5] ppc/pnv: Implement mce injection, Nicholas Piggin, 2020/03/25
- Re: [PATCH 0/5] ppc: sreset and machine check injection, Cédric Le Goater, 2020/03/25