On Fri, Sep 18, 2009 at 03:00:28PM +0200, Alexander Graf wrote: > When injecting an NMI to the l1 guest while it was running the l2 guest, we > didn't #VMEXIT but just injected the NMI to the l2 guest. > > Let's be closer to real hardware and #VMEXIT if we're supposed to do so. > > Signed-off-by: Alexander Graf <agraf@xxxxxxx> > --- > arch/x86/kvm/svm.c | 38 ++++++++++++++++++++++++++++++++------ > 1 files changed, 32 insertions(+), 6 deletions(-) > > diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c > index 9a4daca..f12a669 100644 > --- a/arch/x86/kvm/svm.c > +++ b/arch/x86/kvm/svm.c > @@ -1375,6 +1375,21 @@ static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr, > return nested_svm_exit_handled(svm); > } > > +static inline int nested_svm_nmi(struct vcpu_svm *svm) > +{ > + if (!is_nested(svm)) > + return 0; > + > + svm->vmcb->control.exit_code = SVM_EXIT_NMI; > + > + if (nested_svm_exit_handled(svm)) { > + nsvm_printk("VMexit -> NMI\n"); > + return 1; > + } > + > + return 0; > +} > + > static inline int nested_svm_intr(struct vcpu_svm *svm) > { > if (!is_nested(svm)) > @@ -2462,7 +2477,9 @@ static int svm_nmi_allowed(struct kvm_vcpu *vcpu) > struct vcpu_svm *svm = to_svm(vcpu); > struct vmcb *vmcb = svm->vmcb; > return !(vmcb->control.int_state & SVM_INTERRUPT_SHADOW_MASK) && > - !(svm->vcpu.arch.hflags & HF_NMI_MASK); > + !(svm->vcpu.arch.hflags & HF_NMI_MASK) && > + gif_set(svm) && > + !is_nested(svm); This check is not sufficient. It assumes that the guest intercepts NMIs for its guests. > - if (gif_set(svm)) { > - svm_set_vintr(svm); > - svm_inject_irq(svm, 0x0); > - } > + if (!gif_set(svm)) > + return; > + > + svm_set_vintr(svm); > + svm_inject_irq(svm, 0x0); > } As Jan already wrote, please put this in a seperate patch. Joerg -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html