aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGleb Natapov <gleb@redhat.com>2013-09-25 05:51:34 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2013-09-30 03:14:24 -0400
commit851eb6677cb14f7fada8735041b12f5add0c247e (patch)
treeb7d34edf7b6d61c93c48fdedadbdad09c751d53f
parente0b890d35cdff506b72129b55a166d22fc9bfa64 (diff)
KVM: nVMX: Do not put exception that caused vmexit to IDT_VECTORING_INFO
If an exception causes vmexit directly it should not be reported in IDT_VECTORING_INFO during the exit. For that we need to be able to distinguish between exception that is injected into nested VM and one that is reinjected because its delivery failed. Fortunately we already have mechanism to do so for nested SVM, so here we just use correct function to requeue exceptions and make sure that reinjected exception is not moved to IDT_VECTORING_INFO during vmexit emulation and not re-checked for interception during delivery. Signed-off-by: Gleb Natapov <gleb@redhat.com> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--arch/x86/kvm/vmx.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 7eb05126b44c..663bc5e4d7da 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -1921,7 +1921,7 @@ static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr,
1921 struct vcpu_vmx *vmx = to_vmx(vcpu); 1921 struct vcpu_vmx *vmx = to_vmx(vcpu);
1922 u32 intr_info = nr | INTR_INFO_VALID_MASK; 1922 u32 intr_info = nr | INTR_INFO_VALID_MASK;
1923 1923
1924 if (nr == PF_VECTOR && is_guest_mode(vcpu) && 1924 if (!reinject && nr == PF_VECTOR && is_guest_mode(vcpu) &&
1925 !vmx->nested.nested_run_pending && nested_pf_handled(vcpu)) 1925 !vmx->nested.nested_run_pending && nested_pf_handled(vcpu))
1926 return; 1926 return;
1927 1927
@@ -7053,9 +7053,9 @@ static void __vmx_complete_interrupts(struct kvm_vcpu *vcpu,
7053 case INTR_TYPE_HARD_EXCEPTION: 7053 case INTR_TYPE_HARD_EXCEPTION:
7054 if (idt_vectoring_info & VECTORING_INFO_DELIVER_CODE_MASK) { 7054 if (idt_vectoring_info & VECTORING_INFO_DELIVER_CODE_MASK) {
7055 u32 err = vmcs_read32(error_code_field); 7055 u32 err = vmcs_read32(error_code_field);
7056 kvm_queue_exception_e(vcpu, vector, err); 7056 kvm_requeue_exception_e(vcpu, vector, err);
7057 } else 7057 } else
7058 kvm_queue_exception(vcpu, vector); 7058 kvm_requeue_exception(vcpu, vector);
7059 break; 7059 break;
7060 case INTR_TYPE_SOFT_INTR: 7060 case INTR_TYPE_SOFT_INTR:
7061 vcpu->arch.event_exit_inst_len = vmcs_read32(instr_len_field); 7061 vcpu->arch.event_exit_inst_len = vmcs_read32(instr_len_field);
@@ -8013,7 +8013,7 @@ static void vmcs12_save_pending_event(struct kvm_vcpu *vcpu,
8013 u32 idt_vectoring; 8013 u32 idt_vectoring;
8014 unsigned int nr; 8014 unsigned int nr;
8015 8015
8016 if (vcpu->arch.exception.pending) { 8016 if (vcpu->arch.exception.pending && vcpu->arch.exception.reinject) {
8017 nr = vcpu->arch.exception.nr; 8017 nr = vcpu->arch.exception.nr;
8018 idt_vectoring = nr | VECTORING_INFO_VALID_MASK; 8018 idt_vectoring = nr | VECTORING_INFO_VALID_MASK;
8019 8019