diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2020-03-18 15:07:57 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2020-03-18 15:07:57 +0000 |
commit | b319df553707a3d44c7d027a5d5562f672a768a9 (patch) | |
tree | 6a23d058509b70cf64d7c87ca96a252d3409e5dc /hw/ppc/spapr_events.c | |
parent | d649689a8ecb2e276cc20d3af6d416e3c299cb17 (diff) | |
parent | 6961eae79f58385482775dc0a6c3d553f633662d (diff) |
Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-5.0-20200317' into staging
ppc patch queue 2020-03-17
Here's my final pull request for the qemu-5.0 soft freeze. Sorry this
is just under the wire - I hit some last minute problems that took a
while to fix up and retest.
Highlights are:
* Numerous fixes for the FWNMI feature
* A handful of cleanups to the device tree construction code
* Numerous fixes for the spapr-vscsi device
* A number of fixes and cleanups for real mode (MMU off) softmmu
handling
* Fixes for handling of the PAPR RMA
* Better handling of hotplug/unplug events during boot
* Assorted other fixes
# gpg: Signature made Tue 17 Mar 2020 09:55:07 GMT
# gpg: using RSA key 75F46586AE61A66CC44E87DC6C38CACA20D9B392
# gpg: Good signature from "David Gibson <david@gibson.dropbear.id.au>" [full]
# gpg: aka "David Gibson (Red Hat) <dgibson@redhat.com>" [full]
# gpg: aka "David Gibson (ozlabs.org) <dgibson@ozlabs.org>" [full]
# gpg: aka "David Gibson (kernel.org) <dwg@kernel.org>" [unknown]
# Primary key fingerprint: 75F4 6586 AE61 A66C C44E 87DC 6C38 CACA 20D9 B392
* remotes/dgibson/tags/ppc-for-5.0-20200317: (45 commits)
pseries: Update SLOF firmware image
ppc/spapr: Ignore common "ibm,nmi-interlock" Linux bug
ppc/spapr: Implement FWNMI System Reset delivery
target/ppc: allow ppc_cpu_do_system_reset to take an alternate vector
ppc/spapr: Allow FWNMI on TCG
ppc/spapr: Fix FWNMI machine check interrupt delivery
ppc/spapr: Add FWNMI System Reset state
ppc/spapr: Change FWNMI names
ppc/spapr: Fix FWNMI machine check failure handling
spapr: Rename DT functions to newer naming convention
spapr: Move creation of ibm,architecture-vec-5 property
spapr: Move creation of ibm,dynamic-reconfiguration-memory dt node
spapr/rtas: Reserve space for RTAS blob and log
pseries: Update SLOF firmware image
ppc/spapr: Move GPRs setup to one place
target/ppc: Fix rlwinm on ppc64
spapr/xive: use SPAPR_IRQ_IPI to define IPI ranges exposed to the guest
hw/scsi/spapr_vscsi: Convert debug fprintf() to trace event
hw/scsi/spapr_vscsi: Prevent buffer overflow
hw/scsi/spapr_vscsi: Do not mix SRP IU size with DMA buffer size
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/ppc/spapr_events.c')
-rw-r--r-- | hw/ppc/spapr_events.c | 51 |
1 files changed, 23 insertions, 28 deletions
diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c index 8b32b7eea5..323fcef4aa 100644 --- a/hw/ppc/spapr_events.c +++ b/hw/ppc/spapr_events.c @@ -786,28 +786,12 @@ static void spapr_mce_dispatch_elog(PowerPCCPU *cpu, bool recovered) { SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); CPUState *cs = CPU(cpu); - uint64_t rtas_addr; CPUPPCState *env = &cpu->env; - PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); - target_ulong msr = 0; + uint64_t rtas_addr; struct rtas_error_log log; struct mc_extended_log *ext_elog; uint32_t summary; - /* - * Properly set bits in MSR before we invoke the handler. - * SRR0/1, DAR and DSISR are properly set by KVM - */ - if (!(*pcc->interrupts_big_endian)(cpu)) { - msr |= (1ULL << MSR_LE); - } - - if (env->msr & (1ULL << MSR_SF)) { - msr |= (1ULL << MSR_SF); - } - - msr |= (1ULL << MSR_ME); - ext_elog = g_malloc0(sizeof(*ext_elog)); summary = spapr_mce_get_elog_type(cpu, recovered, ext_elog); @@ -823,8 +807,7 @@ static void spapr_mce_dispatch_elog(PowerPCCPU *cpu, bool recovered) /* get rtas addr from fdt */ rtas_addr = spapr_get_rtas_addr(); if (!rtas_addr) { - /* Unable to fetch rtas_addr. Hence reset the guest */ - ppc_cpu_do_system_reset(cs); + qemu_system_guest_panicked(NULL); g_free(ext_elog); return; } @@ -836,12 +819,11 @@ static void spapr_mce_dispatch_elog(PowerPCCPU *cpu, bool recovered) cpu_physical_memory_write(rtas_addr + RTAS_ERROR_LOG_OFFSET + sizeof(env->gpr[3]) + sizeof(log), ext_elog, sizeof(*ext_elog)); + g_free(ext_elog); env->gpr[3] = rtas_addr + RTAS_ERROR_LOG_OFFSET; - env->msr = msr; - env->nip = spapr->guest_machine_check_addr; - g_free(ext_elog); + ppc_cpu_do_fwnmi_machine_check(cs, spapr->fwnmi_machine_check_addr); } void spapr_mce_req_event(PowerPCCPU *cpu, bool recovered) @@ -851,7 +833,7 @@ void spapr_mce_req_event(PowerPCCPU *cpu, bool recovered) int ret; Error *local_err = NULL; - if (spapr->guest_machine_check_addr == -1) { + if (spapr->fwnmi_machine_check_addr == -1) { /* * This implies that we have hit a machine check either when the * guest has not registered FWNMI (i.e., "ibm,nmi-register" not @@ -863,19 +845,19 @@ void spapr_mce_req_event(PowerPCCPU *cpu, bool recovered) return; } - while (spapr->mc_status != -1) { + while (spapr->fwnmi_machine_check_interlock != -1) { /* * Check whether the same CPU got machine check error * while still handling the mc error (i.e., before * that CPU called "ibm,nmi-interlock") */ - if (spapr->mc_status == cpu->vcpu_id) { + if (spapr->fwnmi_machine_check_interlock == cpu->vcpu_id) { qemu_system_guest_panicked(NULL); return; } - qemu_cond_wait_iothread(&spapr->mc_delivery_cond); + qemu_cond_wait_iothread(&spapr->fwnmi_machine_check_interlock_cond); /* Meanwhile if the system is reset, then just return */ - if (spapr->guest_machine_check_addr == -1) { + if (spapr->fwnmi_machine_check_addr == -1) { return; } } @@ -891,7 +873,7 @@ void spapr_mce_req_event(PowerPCCPU *cpu, bool recovered) warn_report("Received a fwnmi while migration was in progress"); } - spapr->mc_status = cpu->vcpu_id; + spapr->fwnmi_machine_check_interlock = cpu->vcpu_id; spapr_mce_dispatch_elog(cpu, recovered); } @@ -983,6 +965,19 @@ void spapr_clear_pending_events(SpaprMachineState *spapr) } } +void spapr_clear_pending_hotplug_events(SpaprMachineState *spapr) +{ + SpaprEventLogEntry *entry = NULL, *next_entry; + + QTAILQ_FOREACH_SAFE(entry, &spapr->pending_events, next, next_entry) { + if (spapr_event_log_entry_type(entry) == RTAS_LOG_TYPE_HOTPLUG) { + QTAILQ_REMOVE(&spapr->pending_events, entry, next); + g_free(entry->extended_log); + g_free(entry); + } + } +} + void spapr_events_init(SpaprMachineState *spapr) { int epow_irq = SPAPR_IRQ_EPOW; |