aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorAvi Kivity <avi@qumranet.com>2008-07-03 07:50:12 -0400
committerAvi Kivity <avi@qumranet.com>2008-10-15 04:15:13 -0400
commit35920a356957eea9fd1f9da043f93469e8d72eab (patch)
tree941be8b75035690659f7d244f87e6d66ea6ec2f3 /arch
parent26eef70c3e8c76e73dff2579c792fc7355f8a291 (diff)
KVM: VMX: Fix pending exception processing
The vmx code assumes that IDT-Vectoring can only be set when an exception is injected due to the exception in question. That's not true, however: if the exception is injected correctly, and later another exception occurs but its delivery is blocked due to a fault, then we will incorrectly assume the first exception was not delivered. Fix by unconditionally dequeuing the pending exception, and requeuing it (or the second exception) if we see it in the IDT-Vectoring field. Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kvm/vmx.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index ce13b53d21c4..ed4fe8e72ad0 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -27,6 +27,7 @@
27#include <linux/sched.h> 27#include <linux/sched.h>
28#include <linux/moduleparam.h> 28#include <linux/moduleparam.h>
29#include "kvm_cache_regs.h" 29#include "kvm_cache_regs.h"
30#include "x86.h"
30 31
31#include <asm/io.h> 32#include <asm/io.h>
32#include <asm/desc.h> 33#include <asm/desc.h>
@@ -744,9 +745,7 @@ static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr,
744 745
745static bool vmx_exception_injected(struct kvm_vcpu *vcpu) 746static bool vmx_exception_injected(struct kvm_vcpu *vcpu)
746{ 747{
747 struct vcpu_vmx *vmx = to_vmx(vcpu); 748 return false;
748
749 return !(vmx->idt_vectoring_info & VECTORING_INFO_VALID_MASK);
750} 749}
751 750
752/* 751/*
@@ -2824,6 +2823,7 @@ static void vmx_complete_interrupts(struct vcpu_vmx *vmx)
2824 u8 vector; 2823 u8 vector;
2825 int type; 2824 int type;
2826 bool idtv_info_valid; 2825 bool idtv_info_valid;
2826 u32 error;
2827 2827
2828 exit_intr_info = vmcs_read32(VM_EXIT_INTR_INFO); 2828 exit_intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
2829 if (cpu_has_virtual_nmis()) { 2829 if (cpu_has_virtual_nmis()) {
@@ -2855,6 +2855,15 @@ static void vmx_complete_interrupts(struct vcpu_vmx *vmx)
2855 else 2855 else
2856 vmx->vcpu.arch.nmi_injected = false; 2856 vmx->vcpu.arch.nmi_injected = false;
2857 } 2857 }
2858 kvm_clear_exception_queue(&vmx->vcpu);
2859 if (idtv_info_valid && type == INTR_TYPE_EXCEPTION) {
2860 if (idt_vectoring_info & VECTORING_INFO_DELIVER_CODE_MASK) {
2861 error = vmcs_read32(IDT_VECTORING_ERROR_CODE);
2862 kvm_queue_exception_e(&vmx->vcpu, vector, error);
2863 } else
2864 kvm_queue_exception(&vmx->vcpu, vector);
2865 vmx->idt_vectoring_info = 0;
2866 }
2858} 2867}
2859 2868
2860static void vmx_intr_assist(struct kvm_vcpu *vcpu) 2869static void vmx_intr_assist(struct kvm_vcpu *vcpu)