[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 43/45] ppc/spapr: Implement FWNMI System Reset delivery
From: |
David Gibson |
Subject: |
[PULL 43/45] ppc/spapr: Implement FWNMI System Reset delivery |
Date: |
Tue, 17 Mar 2020 21:04:21 +1100 |
From: Nicholas Piggin <address@hidden>
PAPR requires that if "ibm,nmi-register" succeeds, then the hypervisor
delivers all system reset and machine check exceptions to the registered
addresses.
System Resets are delivered with registers set to the architected state,
and with no interlock.
Signed-off-by: Nicholas Piggin <address@hidden>
Message-Id: <address@hidden>
Signed-off-by: David Gibson <address@hidden>
---
hw/ppc/spapr.c | 46 ++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 44 insertions(+), 2 deletions(-)
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 6d65c0797b..8fcd21ac7b 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -951,7 +951,29 @@ static void spapr_dt_rtas(SpaprMachineState *spapr, void
*fdt)
_FDT(fdt_setprop(fdt, rtas, "ibm,max-associativity-domains",
maxdomains, sizeof(maxdomains)));
- _FDT(fdt_setprop_cell(fdt, rtas, "rtas-size", RTAS_SIZE));
+ /*
+ * FWNMI reserves RTAS_ERROR_LOG_MAX for the machine check error log,
+ * and 16 bytes per CPU for system reset error log plus an extra 8 bytes.
+ *
+ * The system reset requirements are driven by existing Linux and PowerVM
+ * implementation which (contrary to PAPR) saves r3 in the error log
+ * structure like machine check, so Linux expects to find the saved r3
+ * value at the address in r3 upon FWNMI-enabled sreset interrupt (and
+ * does not look at the error value).
+ *
+ * System reset interrupts are not subject to interlock like machine
+ * check, so this memory area could be corrupted if the sreset is
+ * interrupted by a machine check (or vice versa) if it was shared. To
+ * prevent this, system reset uses per-CPU areas for the sreset save
+ * area. A system reset that interrupts a system reset handler could
+ * still overwrite this area, but Linux doesn't try to recover in that
+ * case anyway.
+ *
+ * The extra 8 bytes is required because Linux's FWNMI error log check
+ * is off-by-one.
+ */
+ _FDT(fdt_setprop_cell(fdt, rtas, "rtas-size", RTAS_ERROR_LOG_MAX +
+ ms->smp.max_cpus * sizeof(uint64_t)*2 +
sizeof(uint64_t)));
_FDT(fdt_setprop_cell(fdt, rtas, "rtas-error-log-max",
RTAS_ERROR_LOG_MAX));
_FDT(fdt_setprop_cell(fdt, rtas, "rtas-event-scan-rate",
@@ -3384,8 +3406,28 @@ static void spapr_machine_finalizefn(Object *obj)
void spapr_do_system_reset_on_cpu(CPUState *cs, run_on_cpu_data arg)
{
+ SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
+
cpu_synchronize_state(cs);
- ppc_cpu_do_system_reset(cs, -1);
+ /* If FWNMI is inactive, addr will be -1, which will deliver to 0x100 */
+ if (spapr->fwnmi_system_reset_addr != -1) {
+ uint64_t rtas_addr, addr;
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ CPUPPCState *env = &cpu->env;
+
+ /* get rtas addr from fdt */
+ rtas_addr = spapr_get_rtas_addr();
+ if (!rtas_addr) {
+ qemu_system_guest_panicked(NULL);
+ return;
+ }
+
+ addr = rtas_addr + RTAS_ERROR_LOG_MAX + cs->cpu_index *
sizeof(uint64_t)*2;
+ stq_be_phys(&address_space_memory, addr, env->gpr[3]);
+ stq_be_phys(&address_space_memory, addr + sizeof(uint64_t), 0);
+ env->gpr[3] = addr;
+ }
+ ppc_cpu_do_system_reset(cs, spapr->fwnmi_system_reset_addr);
}
static void spapr_nmi(NMIState *n, int cpu_index, Error **errp)
--
2.24.1
- [PULL 25/45] hw/scsi/spapr_vscsi: Introduce req_iu() helper, (continued)
- [PULL 25/45] hw/scsi/spapr_vscsi: Introduce req_iu() helper, David Gibson, 2020/03/17
- [PULL 29/45] spapr/xive: use SPAPR_IRQ_IPI to define IPI ranges exposed to the guest, David Gibson, 2020/03/17
- [PULL 22/45] hw/scsi/viosrp: Add missing 'hw/scsi/srp.h' include, David Gibson, 2020/03/17
- [PULL 28/45] hw/scsi/spapr_vscsi: Convert debug fprintf() to trace event, David Gibson, 2020/03/17
- [PULL 26/45] hw/scsi/spapr_vscsi: Do not mix SRP IU size with DMA buffer size, David Gibson, 2020/03/17
- [PULL 36/45] spapr: Rename DT functions to newer naming convention, David Gibson, 2020/03/17
- [PULL 30/45] target/ppc: Fix rlwinm on ppc64, David Gibson, 2020/03/17
- [PULL 40/45] ppc/spapr: Fix FWNMI machine check interrupt delivery, David Gibson, 2020/03/17
- [PULL 37/45] ppc/spapr: Fix FWNMI machine check failure handling, David Gibson, 2020/03/17
- [PULL 35/45] spapr: Move creation of ibm,architecture-vec-5 property, David Gibson, 2020/03/17
- [PULL 43/45] ppc/spapr: Implement FWNMI System Reset delivery,
David Gibson <=
- [PULL 33/45] spapr/rtas: Reserve space for RTAS blob and log, David Gibson, 2020/03/17
- [PULL 39/45] ppc/spapr: Add FWNMI System Reset state, David Gibson, 2020/03/17
- [PULL 41/45] ppc/spapr: Allow FWNMI on TCG, David Gibson, 2020/03/17
- [PULL 38/45] ppc/spapr: Change FWNMI names, David Gibson, 2020/03/17
- [PULL 34/45] spapr: Move creation of ibm, dynamic-reconfiguration-memory dt node, David Gibson, 2020/03/17
- [PULL 44/45] ppc/spapr: Ignore common "ibm,nmi-interlock" Linux bug, David Gibson, 2020/03/17
- [PULL 32/45] pseries: Update SLOF firmware image, David Gibson, 2020/03/17
- [PULL 42/45] target/ppc: allow ppc_cpu_do_system_reset to take an alternate vector, David Gibson, 2020/03/17
- [PULL 45/45] pseries: Update SLOF firmware image, David Gibson, 2020/03/17
- Re: [PULL 00/45] ppc-for-5.0 queue 20200317, Paolo Bonzini, 2020/03/17