Message ID | 20090329141207.30481.33603.stgit@trex.usersys.redhat.com (mailing list archive) |
---|---|
State | Accepted |
Headers | show |
Gleb Natapov wrote: > Signed-off-by: Gleb Natapov <gleb@redhat.com> > This is actually not just a rewrite, but also a bugfix: > INTR_INFO); > @@ -3289,34 +3288,42 @@ static void vmx_complete_interrupts(struct vcpu_vmx *vmx) > vmx->vnmi_blocked_time += > ktime_to_ns(ktime_sub(ktime_get(), vmx->entry_time)); > > + vmx->vcpu.arch.nmi_injected = false; > + kvm_clear_exception_queue(&vmx->vcpu); > + kvm_clear_interrupt_queue(&vmx->vcpu); > + > + if (!idtv_info_valid) > + return; > + > vector = idt_vectoring_info & VECTORING_INFO_VECTOR_MASK; > type = idt_vectoring_info & VECTORING_INFO_TYPE_MASK; > - if (vmx->vcpu.arch.nmi_injected) { > + > + switch(type) { > + case INTR_TYPE_NMI_INTR: > + vmx->vcpu.arch.nmi_injected = true; > /* > The existing code would leave nmi_injected == false if we exit on NMI_INTR, so we drop an NMI here.
Avi Kivity wrote: > Gleb Natapov wrote: >> Signed-off-by: Gleb Natapov <gleb@redhat.com> >> > > This is actually not just a rewrite, but also a bugfix: > >> INTR_INFO); >> @@ -3289,34 +3288,42 @@ static void vmx_complete_interrupts(struct >> vcpu_vmx *vmx) >> vmx->vnmi_blocked_time += >> ktime_to_ns(ktime_sub(ktime_get(), vmx->entry_time)); >> >> + vmx->vcpu.arch.nmi_injected = false; >> + kvm_clear_exception_queue(&vmx->vcpu); >> + kvm_clear_interrupt_queue(&vmx->vcpu); >> + >> + if (!idtv_info_valid) >> + return; >> + >> vector = idt_vectoring_info & VECTORING_INFO_VECTOR_MASK; >> type = idt_vectoring_info & VECTORING_INFO_TYPE_MASK; >> - if (vmx->vcpu.arch.nmi_injected) { >> + >> + switch(type) { >> + case INTR_TYPE_NMI_INTR: >> + vmx->vcpu.arch.nmi_injected = true; >> /* >> > > The existing code would leave nmi_injected == false if we exit on > NMI_INTR, so we drop an NMI here. > I think NMI_INTR and nmi_injected always go together. However, the rework looks good and more logical to me, too. Will see that I can give this (more precisely -v2) a try with our scenarios ASAP. Jan
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 14e3f48..1017544 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -3264,7 +3264,6 @@ static void vmx_complete_interrupts(struct vcpu_vmx *vmx) u8 vector; int type; bool idtv_info_valid; - u32 error; idtv_info_valid = idt_vectoring_info & VECTORING_INFO_VALID_MASK; exit_intr_info = vmcs_read32(VM_EXIT_INTR_INFO); @@ -3289,34 +3288,42 @@ static void vmx_complete_interrupts(struct vcpu_vmx *vmx) vmx->vnmi_blocked_time += ktime_to_ns(ktime_sub(ktime_get(), vmx->entry_time)); + vmx->vcpu.arch.nmi_injected = false; + kvm_clear_exception_queue(&vmx->vcpu); + kvm_clear_interrupt_queue(&vmx->vcpu); + + if (!idtv_info_valid) + return; + vector = idt_vectoring_info & VECTORING_INFO_VECTOR_MASK; type = idt_vectoring_info & VECTORING_INFO_TYPE_MASK; - if (vmx->vcpu.arch.nmi_injected) { + + switch(type) { + case INTR_TYPE_NMI_INTR: + vmx->vcpu.arch.nmi_injected = true; /* * SDM 3: 27.7.1.2 (September 2008) - * Clear bit "block by NMI" before VM entry if a NMI delivery - * faulted. + * Clear bit "block by NMI" before VM entry if a NMI + * delivery faulted. */ - if (idtv_info_valid && type == INTR_TYPE_NMI_INTR) - vmcs_clear_bits(GUEST_INTERRUPTIBILITY_INFO, - GUEST_INTR_STATE_NMI); - else - vmx->vcpu.arch.nmi_injected = false; - } - kvm_clear_exception_queue(&vmx->vcpu); - if (idtv_info_valid && (type == INTR_TYPE_HARD_EXCEPTION || - type == INTR_TYPE_SOFT_EXCEPTION)) { + vmcs_clear_bits(GUEST_INTERRUPTIBILITY_INFO, + GUEST_INTR_STATE_NMI); + break; + case INTR_TYPE_HARD_EXCEPTION: + case INTR_TYPE_SOFT_EXCEPTION: if (idt_vectoring_info & VECTORING_INFO_DELIVER_CODE_MASK) { - error = vmcs_read32(IDT_VECTORING_ERROR_CODE); - kvm_queue_exception_e(&vmx->vcpu, vector, error); + u32 err = vmcs_read32(IDT_VECTORING_ERROR_CODE); + kvm_queue_exception_e(&vmx->vcpu, vector, err); } else kvm_queue_exception(&vmx->vcpu, vector); vmx->idt_vectoring_info = 0; - } - kvm_clear_interrupt_queue(&vmx->vcpu); - if (idtv_info_valid && type == INTR_TYPE_EXT_INTR) { + break; + case INTR_TYPE_EXT_INTR: kvm_queue_interrupt(&vmx->vcpu, vector); vmx->idt_vectoring_info = 0; + break; + default: + break; } }
Signed-off-by: Gleb Natapov <gleb@redhat.com> --- arch/x86/kvm/vmx.c | 43 +++++++++++++++++++++++++------------------ 1 files changed, 25 insertions(+), 18 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html