aboutsummaryrefslogtreecommitdiff
path: root/target/ppc
diff options
context:
space:
mode:
authorAravinda Prasad <arawinda.p@gmail.com>2020-01-31 00:14:19 +0530
committerDavid Gibson <david@gibson.dropbear.id.au>2020-02-03 11:33:10 +1100
commit9ac703ac5f9e830ab96d38dc77061bd4be76cf60 (patch)
treed8cf1c090e3b6329d842ca87a61dfa8cbe600317 /target/ppc
parent9d953ce44722eeb10d99c814478065bebbf7e1f6 (diff)
downloadqemu-9ac703ac5f9e830ab96d38dc77061bd4be76cf60.zip
qemu-9ac703ac5f9e830ab96d38dc77061bd4be76cf60.tar.gz
qemu-9ac703ac5f9e830ab96d38dc77061bd4be76cf60.tar.bz2
target/ppc: Handle NMI guest exit
Memory error such as bit flips that cannot be corrected by hardware are passed on to the kernel for handling. If the memory address in error belongs to guest then the guest kernel is responsible for taking suitable action. Patch [1] enhances KVM to exit guest with exit reason set to KVM_EXIT_NMI in such cases. This patch handles KVM_EXIT_NMI exit. [1] https://www.spinics.net/lists/kvm-ppc/msg12637.html (e20bbd3d and related commits) Signed-off-by: Aravinda Prasad <arawinda.p@gmail.com> Signed-off-by: Ganesh Goudar <ganeshgr@linux.ibm.com> Reviewed-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Greg Kurz <groug@kaod.org> Message-Id: <20200130184423.20519-4-ganeshgr@linux.ibm.com> [dwg: #ifdefs to fix compile for 32-bit target] Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'target/ppc')
-rw-r--r--target/ppc/kvm.c18
-rw-r--r--target/ppc/kvm_ppc.h2
-rw-r--r--target/ppc/trace-events1
3 files changed, 21 insertions, 0 deletions
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 4438d0c..56a6865 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -1705,6 +1705,13 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
ret = 0;
break;
+#if defined(TARGET_PPC64)
+ case KVM_EXIT_NMI:
+ trace_kvm_handle_nmi_exception();
+ ret = kvm_handle_nmi(cpu, run);
+ break;
+#endif
+
default:
fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason);
ret = -1;
@@ -2800,6 +2807,17 @@ int kvm_arch_msi_data_to_gsi(uint32_t data)
return data & 0xffff;
}
+#if defined(TARGET_PPC64)
+int kvm_handle_nmi(PowerPCCPU *cpu, struct kvm_run *run)
+{
+ cpu_synchronize_state(CPU(cpu));
+
+ spapr_mce_req_event(cpu);
+
+ return 0;
+}
+#endif
+
int kvmppc_enable_hwrng(void)
{
if (!kvm_enabled() || !kvm_check_extension(kvm_state, KVM_CAP_PPC_HWRNG)) {
diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h
index 2c60ded..9e4f235 100644
--- a/target/ppc/kvm_ppc.h
+++ b/target/ppc/kvm_ppc.h
@@ -84,6 +84,8 @@ void kvm_check_mmu(PowerPCCPU *cpu, Error **errp);
void kvmppc_set_reg_ppc_online(PowerPCCPU *cpu, unsigned int online);
void kvmppc_set_reg_tb_offset(PowerPCCPU *cpu, int64_t tb_offset);
+int kvm_handle_nmi(PowerPCCPU *cpu, struct kvm_run *run);
+
#else
static inline uint32_t kvmppc_get_tbfreq(void)
diff --git a/target/ppc/trace-events b/target/ppc/trace-events
index 3dc6740..6d15aa9 100644
--- a/target/ppc/trace-events
+++ b/target/ppc/trace-events
@@ -28,3 +28,4 @@ kvm_handle_papr_hcall(void) "handle PAPR hypercall"
kvm_handle_epr(void) "handle epr"
kvm_handle_watchdog_expiry(void) "handle watchdog expiry"
kvm_handle_debug_exception(void) "handle debug exception"
+kvm_handle_nmi_exception(void) "handle NMI exception"