[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 3/3] ppc/pnv: Implement mce injection
From: |
Cédric Le Goater |
Subject: |
[PATCH 3/3] ppc/pnv: Implement mce injection |
Date: |
Wed, 13 Oct 2021 23:40:42 +0200 |
From: Nicholas Piggin <npiggin@gmail.com>
This implements mce injection for pnv.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
[ clg: - simplified injection and moved code under pnv_core.c
- removed superfluous cpu_synchronize_state()
- clear previous setting in SPR_SRR1 ]
Message-Id: <20200325144147.221875-6-npiggin@gmail.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
include/hw/ppc/pnv_core.h | 4 ++++
target/ppc/cpu.h | 1 +
hw/ppc/pnv.c | 3 +++
hw/ppc/pnv_core.c | 27 +++++++++++++++++++++++++++
target/ppc/excp_helper.c | 12 ++++++++++++
5 files changed, 47 insertions(+)
diff --git a/include/hw/ppc/pnv_core.h b/include/hw/ppc/pnv_core.h
index c22eab2e1f69..7ed7a52077ea 100644
--- a/include/hw/ppc/pnv_core.h
+++ b/include/hw/ppc/pnv_core.h
@@ -23,6 +23,7 @@
#include "hw/cpu/core.h"
#include "target/ppc/cpu.h"
#include "qom/object.h"
+#include "hw/ppc/mce.h"
#define TYPE_PNV_CORE "powernv-cpu-core"
OBJECT_DECLARE_TYPE(PnvCore, PnvCoreClass,
@@ -70,4 +71,7 @@ struct PnvQuad {
uint32_t quad_id;
MemoryRegion xscom_regs;
};
+
+void pnv_cpu_inject_mce(CPUState *cs, PPCMceInjectionParams *p);
+
#endif /* PPC_PNV_CORE_H */
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index baa4e7c34d30..e0757e287718 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1273,6 +1273,7 @@ int ppc32_cpu_write_elf32_note(WriteCoreDumpFunction f,
CPUState *cs,
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 71e45515f136..374f48ea7f1b 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -2001,6 +2001,7 @@ 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);
+ PPCMceInjectionClass *mcec = PPC_MCE_INJECTION_CLASS(oc);
mc->desc = "IBM PowerNV (Non-Virtualized)";
mc->init = pnv_init;
@@ -2018,6 +2019,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->inject_mce = pnv_cpu_inject_mce;
object_class_property_add_bool(oc, "hb-mode",
pnv_machine_get_hb, pnv_machine_set_hb);
@@ -2080,6 +2082,7 @@ static const TypeInfo types[] = {
.interfaces = (InterfaceInfo[]) {
{ TYPE_INTERRUPT_STATS_PROVIDER },
{ TYPE_NMI },
+ { TYPE_PPC_MCE_INJECTION },
{ },
},
},
diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c
index 19e8eb885f71..868b361f99e5 100644
--- a/hw/ppc/pnv_core.c
+++ b/hw/ppc/pnv_core.c
@@ -25,12 +25,39 @@
#include "target/ppc/cpu.h"
#include "hw/ppc/ppc.h"
#include "hw/ppc/pnv.h"
+#include "hw/ppc/mce.h"
#include "hw/ppc/pnv_core.h"
#include "hw/ppc/pnv_xscom.h"
#include "hw/ppc/xics.h"
#include "hw/qdev-properties.h"
#include "helper_regs.h"
+static void pnv_cpu_inject_mce_on_cpu(CPUState *cs, run_on_cpu_data data)
+{
+ PPCMceInjectionParams *params = (PPCMceInjectionParams *) data.host_ptr;
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ CPUPPCState *env = &cpu->env;
+ uint64_t srr1_mce_bits = PPC_BITMASK(42, 45) | PPC_BIT(36);
+
+ ppc_cpu_do_machine_check(cs);
+
+ 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;
+ }
+
+ if (!params->recovered) {
+ env->msr &= ~MSR_RI;
+ }
+}
+
+void pnv_cpu_inject_mce(CPUState *cs, PPCMceInjectionParams *p)
+{
+ run_on_cpu(cs, pnv_cpu_inject_mce_on_cpu, RUN_ON_CPU_HOST_PTR(p));
+}
+
static const char *pnv_core_cpu_typename(PnvCore *pc)
{
const char *core_type =
object_class_get_name(object_get_class(OBJECT(pc)));
diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index b7d176792098..f383f1646cc3 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -379,6 +379,10 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int
excp_model, int excp)
cs->halted = 1;
cpu_interrupt_exittb(cs);
}
+ if (msr_pow) {
+ /* indicate that we resumed from power save mode */
+ msr |= 0x10000;
+ }
if (env->msr_mask & MSR_HVB) {
/*
* ISA specifies HV, but can be delivered to guest with HV
@@ -1071,6 +1075,14 @@ void ppc_cpu_do_system_reset(CPUState *cs)
powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_RESET);
}
+void ppc_cpu_do_machine_check(CPUState *cs)
+{
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ CPUPPCState *env = &cpu->env;
+
+ powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_MCHECK);
+}
+
void ppc_cpu_do_fwnmi_machine_check(CPUState *cs, target_ulong vector)
{
PowerPCCPU *cpu = POWERPC_CPU(cs);
--
2.31.1