Enable the KVM capability KVM_CAP_PPC_FWNMI so that the KVM causes guest exit with NMI as exit reason when it encounters a machine check exception on the address belonging to a guest. Without this capability enabled, KVM redirects machine check exceptions to guest's 0x200 vector.
Signed-off-by: Aravinda Prasad <aravi...@linux.vnet.ibm.com> --- hw/ppc/spapr_rtas.c | 17 +++++++++++++++++ target/ppc/kvm.c | 2 ++ 2 files changed, 19 insertions(+) diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c index 2f3c47b..c2a361a 100644 --- a/hw/ppc/spapr_rtas.c +++ b/hw/ppc/spapr_rtas.c @@ -47,6 +47,8 @@ #include "trace.h" #include "hw/ppc/fdt.h" +extern int cap_fwnmi; + static void rtas_display_character(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, @@ -354,7 +356,22 @@ static void rtas_ibm_nmi_register(PowerPCCPU *cpu, target_ulong args, uint32_t nret, target_ulong rets) { + int ret; + CPUState *cs = CPU(cpu); + + if (!cap_fwnmi) { + rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED); + return; + } + spapr->guest_machine_check_addr = rtas_ld(args, 1); + + ret = kvm_vcpu_enable_cap(cs, KVM_CAP_PPC_FWNMI, 0); + if (ret < 0) { + rtas_st(rets, 0, RTAS_OUT_HW_ERROR); + return; + } + rtas_st(rets, 0, RTAS_OUT_SUCCESS); } diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c index e9ea45f..7d37dba 100644 --- a/target/ppc/kvm.c +++ b/target/ppc/kvm.c @@ -90,6 +90,7 @@ static int cap_htm; /* Hardware transactional memory support */ static int cap_mmu_radix; static int cap_mmu_hash_v3; static int cap_resize_hpt; +int cap_fwnmi; static uint32_t debug_inst_opcode; @@ -147,6 +148,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s) cap_mmu_radix = kvm_vm_check_extension(s, KVM_CAP_PPC_MMU_RADIX); cap_mmu_hash_v3 = kvm_vm_check_extension(s, KVM_CAP_PPC_MMU_HASH_V3); cap_resize_hpt = kvm_vm_check_extension(s, KVM_CAP_SPAPR_RESIZE_HPT); + cap_fwnmi = kvm_check_extension(s, KVM_CAP_PPC_FWNMI); if (!cap_interrupt_level) { fprintf(stderr, "KVM: Couldn't find level irq capability. Expect the "