Message ID | 20200325142906.221248-2-npiggin@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | FWNMI follow up patches | expand |
On Thu, 26 Mar 2020 00:29:03 +1000 Nicholas Piggin <npiggin@gmail.com> wrote: > The KVM FWNMI capability should be enabled with the "ibm,nmi-register" > rtas call. Although MCEs from KVM will be delivered as architected > interrupts to the guest before "ibm,nmi-register" is called, KVM has > different behaviour depending on whether the guest has enabled FWNMI > (it attempts to do more recovery on behalf of a non-FWNMI guest). > > Signed-off-by: Nicholas Piggin <npiggin@gmail.com> > --- Reviewed-by: Greg Kurz <groug@kaod.org> > hw/ppc/spapr_caps.c | 7 ++++--- > hw/ppc/spapr_rtas.c | 7 +++++++ > target/ppc/kvm.c | 7 +++++++ > target/ppc/kvm_ppc.h | 6 ++++++ > 4 files changed, 24 insertions(+), 3 deletions(-) > > diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c > index 679ae7959f..eb54f94227 100644 > --- a/hw/ppc/spapr_caps.c > +++ b/hw/ppc/spapr_caps.c > @@ -517,9 +517,10 @@ static void cap_fwnmi_apply(SpaprMachineState *spapr, uint8_t val, > } > > if (kvm_enabled()) { > - if (kvmppc_set_fwnmi() < 0) { > - error_setg(errp, "Firmware Assisted Non-Maskable Interrupts(FWNMI) " > - "not supported by KVM"); > + if (!kvmppc_get_fwnmi()) { > + error_setg(errp, > +"Firmware Assisted Non-Maskable Interrupts(FWNMI) not supported by KVM."); > + error_append_hint(errp, "Try appending -machine cap-fwnmi=off\n"); > } > } > } > diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c > index 9fb8c8632a..29abe66d01 100644 > --- a/hw/ppc/spapr_rtas.c > +++ b/hw/ppc/spapr_rtas.c > @@ -437,6 +437,13 @@ static void rtas_ibm_nmi_register(PowerPCCPU *cpu, > return; > } > > + if (kvm_enabled()) { > + if (kvmppc_set_fwnmi() < 0) { > + rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED); > + return; > + } > + } > + > spapr->fwnmi_system_reset_addr = sreset_addr; > spapr->fwnmi_machine_check_addr = mce_addr; > > diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c > index 597f72be1b..03d0667e8f 100644 > --- a/target/ppc/kvm.c > +++ b/target/ppc/kvm.c > @@ -88,6 +88,7 @@ static int cap_ppc_safe_indirect_branch; > static int cap_ppc_count_cache_flush_assist; > static int cap_ppc_nested_kvm_hv; > static int cap_large_decr; > +static int cap_fwnmi; > > static uint32_t debug_inst_opcode; > > @@ -136,6 +137,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s) > kvmppc_get_cpu_characteristics(s); > cap_ppc_nested_kvm_hv = kvm_vm_check_extension(s, KVM_CAP_PPC_NESTED_HV); > cap_large_decr = kvmppc_get_dec_bits(); > + cap_fwnmi = kvm_vm_check_extension(s, KVM_CAP_PPC_FWNMI); > /* > * Note: setting it to false because there is not such capability > * in KVM at this moment. > @@ -2064,6 +2066,11 @@ void kvmppc_set_mpic_proxy(PowerPCCPU *cpu, int mpic_proxy) > } > } > > +bool kvmppc_get_fwnmi(void) > +{ > + return cap_fwnmi; > +} > + > int kvmppc_set_fwnmi(void) > { > PowerPCCPU *cpu = POWERPC_CPU(first_cpu); > diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h > index 332fa0aa1c..fcaf745516 100644 > --- a/target/ppc/kvm_ppc.h > +++ b/target/ppc/kvm_ppc.h > @@ -27,6 +27,7 @@ void kvmppc_enable_h_page_init(void); > void kvmppc_set_papr(PowerPCCPU *cpu); > int kvmppc_set_compat(PowerPCCPU *cpu, uint32_t compat_pvr); > void kvmppc_set_mpic_proxy(PowerPCCPU *cpu, int mpic_proxy); > +bool kvmppc_get_fwnmi(void); > int kvmppc_set_fwnmi(void); > int kvmppc_smt_threads(void); > void kvmppc_error_append_smt_possible_hint(Error *const *errp); > @@ -163,6 +164,11 @@ static inline void kvmppc_set_mpic_proxy(PowerPCCPU *cpu, int mpic_proxy) > { > } > > +static inline bool kvmppc_get_fwnmi(void) > +{ > + return false; > +} > + > static inline int kvmppc_set_fwnmi(void) > { > return -1;
On Thu, Mar 26, 2020 at 12:29:03AM +1000, Nicholas Piggin wrote: 65;5803;1c> The KVM FWNMI capability should be enabled with the "ibm,nmi-register" > rtas call. Although MCEs from KVM will be delivered as architected > interrupts to the guest before "ibm,nmi-register" is called, KVM has > different behaviour depending on whether the guest has enabled FWNMI > (it attempts to do more recovery on behalf of a non-FWNMI guest). > > Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Applied to ppc-for-5.0. > --- > hw/ppc/spapr_caps.c | 7 ++++--- > hw/ppc/spapr_rtas.c | 7 +++++++ > target/ppc/kvm.c | 7 +++++++ > target/ppc/kvm_ppc.h | 6 ++++++ > 4 files changed, 24 insertions(+), 3 deletions(-) > > diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c > index 679ae7959f..eb54f94227 100644 > --- a/hw/ppc/spapr_caps.c > +++ b/hw/ppc/spapr_caps.c > @@ -517,9 +517,10 @@ static void cap_fwnmi_apply(SpaprMachineState *spapr, uint8_t val, > } > > if (kvm_enabled()) { > - if (kvmppc_set_fwnmi() < 0) { > - error_setg(errp, "Firmware Assisted Non-Maskable Interrupts(FWNMI) " > - "not supported by KVM"); > + if (!kvmppc_get_fwnmi()) { > + error_setg(errp, > +"Firmware Assisted Non-Maskable Interrupts(FWNMI) not supported by KVM."); > + error_append_hint(errp, "Try appending -machine cap-fwnmi=off\n"); > } > } > } > diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c > index 9fb8c8632a..29abe66d01 100644 > --- a/hw/ppc/spapr_rtas.c > +++ b/hw/ppc/spapr_rtas.c > @@ -437,6 +437,13 @@ static void rtas_ibm_nmi_register(PowerPCCPU *cpu, > return; > } > > + if (kvm_enabled()) { > + if (kvmppc_set_fwnmi() < 0) { > + rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED); > + return; > + } > + } > + > spapr->fwnmi_system_reset_addr = sreset_addr; > spapr->fwnmi_machine_check_addr = mce_addr; > > diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c > index 597f72be1b..03d0667e8f 100644 > --- a/target/ppc/kvm.c > +++ b/target/ppc/kvm.c > @@ -88,6 +88,7 @@ static int cap_ppc_safe_indirect_branch; > static int cap_ppc_count_cache_flush_assist; > static int cap_ppc_nested_kvm_hv; > static int cap_large_decr; > +static int cap_fwnmi; > > static uint32_t debug_inst_opcode; > > @@ -136,6 +137,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s) > kvmppc_get_cpu_characteristics(s); > cap_ppc_nested_kvm_hv = kvm_vm_check_extension(s, KVM_CAP_PPC_NESTED_HV); > cap_large_decr = kvmppc_get_dec_bits(); > + cap_fwnmi = kvm_vm_check_extension(s, KVM_CAP_PPC_FWNMI); > /* > * Note: setting it to false because there is not such capability > * in KVM at this moment. > @@ -2064,6 +2066,11 @@ void kvmppc_set_mpic_proxy(PowerPCCPU *cpu, int mpic_proxy) > } > } > > +bool kvmppc_get_fwnmi(void) > +{ > + return cap_fwnmi; > +} > + > int kvmppc_set_fwnmi(void) > { > PowerPCCPU *cpu = POWERPC_CPU(first_cpu); > diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h > index 332fa0aa1c..fcaf745516 100644 > --- a/target/ppc/kvm_ppc.h > +++ b/target/ppc/kvm_ppc.h > @@ -27,6 +27,7 @@ void kvmppc_enable_h_page_init(void); > void kvmppc_set_papr(PowerPCCPU *cpu); > int kvmppc_set_compat(PowerPCCPU *cpu, uint32_t compat_pvr); > void kvmppc_set_mpic_proxy(PowerPCCPU *cpu, int mpic_proxy); > +bool kvmppc_get_fwnmi(void); > int kvmppc_set_fwnmi(void); > int kvmppc_smt_threads(void); > void kvmppc_error_append_smt_possible_hint(Error *const *errp); > @@ -163,6 +164,11 @@ static inline void kvmppc_set_mpic_proxy(PowerPCCPU *cpu, int mpic_proxy) > { > } > > +static inline bool kvmppc_get_fwnmi(void) > +{ > + return false; > +} > + > static inline int kvmppc_set_fwnmi(void) > { > return -1;
diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c index 679ae7959f..eb54f94227 100644 --- a/hw/ppc/spapr_caps.c +++ b/hw/ppc/spapr_caps.c @@ -517,9 +517,10 @@ static void cap_fwnmi_apply(SpaprMachineState *spapr, uint8_t val, } if (kvm_enabled()) { - if (kvmppc_set_fwnmi() < 0) { - error_setg(errp, "Firmware Assisted Non-Maskable Interrupts(FWNMI) " - "not supported by KVM"); + if (!kvmppc_get_fwnmi()) { + error_setg(errp, +"Firmware Assisted Non-Maskable Interrupts(FWNMI) not supported by KVM."); + error_append_hint(errp, "Try appending -machine cap-fwnmi=off\n"); } } } diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c index 9fb8c8632a..29abe66d01 100644 --- a/hw/ppc/spapr_rtas.c +++ b/hw/ppc/spapr_rtas.c @@ -437,6 +437,13 @@ static void rtas_ibm_nmi_register(PowerPCCPU *cpu, return; } + if (kvm_enabled()) { + if (kvmppc_set_fwnmi() < 0) { + rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED); + return; + } + } + spapr->fwnmi_system_reset_addr = sreset_addr; spapr->fwnmi_machine_check_addr = mce_addr; diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c index 597f72be1b..03d0667e8f 100644 --- a/target/ppc/kvm.c +++ b/target/ppc/kvm.c @@ -88,6 +88,7 @@ static int cap_ppc_safe_indirect_branch; static int cap_ppc_count_cache_flush_assist; static int cap_ppc_nested_kvm_hv; static int cap_large_decr; +static int cap_fwnmi; static uint32_t debug_inst_opcode; @@ -136,6 +137,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s) kvmppc_get_cpu_characteristics(s); cap_ppc_nested_kvm_hv = kvm_vm_check_extension(s, KVM_CAP_PPC_NESTED_HV); cap_large_decr = kvmppc_get_dec_bits(); + cap_fwnmi = kvm_vm_check_extension(s, KVM_CAP_PPC_FWNMI); /* * Note: setting it to false because there is not such capability * in KVM at this moment. @@ -2064,6 +2066,11 @@ void kvmppc_set_mpic_proxy(PowerPCCPU *cpu, int mpic_proxy) } } +bool kvmppc_get_fwnmi(void) +{ + return cap_fwnmi; +} + int kvmppc_set_fwnmi(void) { PowerPCCPU *cpu = POWERPC_CPU(first_cpu); diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h index 332fa0aa1c..fcaf745516 100644 --- a/target/ppc/kvm_ppc.h +++ b/target/ppc/kvm_ppc.h @@ -27,6 +27,7 @@ void kvmppc_enable_h_page_init(void); void kvmppc_set_papr(PowerPCCPU *cpu); int kvmppc_set_compat(PowerPCCPU *cpu, uint32_t compat_pvr); void kvmppc_set_mpic_proxy(PowerPCCPU *cpu, int mpic_proxy); +bool kvmppc_get_fwnmi(void); int kvmppc_set_fwnmi(void); int kvmppc_smt_threads(void); void kvmppc_error_append_smt_possible_hint(Error *const *errp); @@ -163,6 +164,11 @@ static inline void kvmppc_set_mpic_proxy(PowerPCCPU *cpu, int mpic_proxy) { } +static inline bool kvmppc_get_fwnmi(void) +{ + return false; +} + static inline int kvmppc_set_fwnmi(void) { return -1;
The KVM FWNMI capability should be enabled with the "ibm,nmi-register" rtas call. Although MCEs from KVM will be delivered as architected interrupts to the guest before "ibm,nmi-register" is called, KVM has different behaviour depending on whether the guest has enabled FWNMI (it attempts to do more recovery on behalf of a non-FWNMI guest). Signed-off-by: Nicholas Piggin <npiggin@gmail.com> --- hw/ppc/spapr_caps.c | 7 ++++--- hw/ppc/spapr_rtas.c | 7 +++++++ target/ppc/kvm.c | 7 +++++++ target/ppc/kvm_ppc.h | 6 ++++++ 4 files changed, 24 insertions(+), 3 deletions(-)