aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/vmx.c
diff options
context:
space:
mode:
authorJan Kiszka <jan.kiszka@siemens.com>2010-04-14 09:51:09 -0400
committerAvi Kivity <avi@redhat.com>2010-05-17 05:17:46 -0400
commite269fb2189fb86d79d64c0ca74c6c1a549ad4aa3 (patch)
tree627c658efaec155d1f295d1fc7b8abded9d4f861 /arch/x86/kvm/vmx.c
parent0760d44868f351ba30fc9a08cf1830e46aa72466 (diff)
KVM: x86: Push potential exception error code on task switches
When a fault triggers a task switch, the error code, if existent, has to be pushed on the new task's stack. Implement the missing bits. Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch/x86/kvm/vmx.c')
-rw-r--r--arch/x86/kvm/vmx.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index fb4a8869bb99..1b38d8a88cf7 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -3271,6 +3271,8 @@ static int handle_task_switch(struct kvm_vcpu *vcpu)
3271{ 3271{
3272 struct vcpu_vmx *vmx = to_vmx(vcpu); 3272 struct vcpu_vmx *vmx = to_vmx(vcpu);
3273 unsigned long exit_qualification; 3273 unsigned long exit_qualification;
3274 bool has_error_code = false;
3275 u32 error_code = 0;
3274 u16 tss_selector; 3276 u16 tss_selector;
3275 int reason, type, idt_v; 3277 int reason, type, idt_v;
3276 3278
@@ -3293,6 +3295,13 @@ static int handle_task_switch(struct kvm_vcpu *vcpu)
3293 kvm_clear_interrupt_queue(vcpu); 3295 kvm_clear_interrupt_queue(vcpu);
3294 break; 3296 break;
3295 case INTR_TYPE_HARD_EXCEPTION: 3297 case INTR_TYPE_HARD_EXCEPTION:
3298 if (vmx->idt_vectoring_info &
3299 VECTORING_INFO_DELIVER_CODE_MASK) {
3300 has_error_code = true;
3301 error_code =
3302 vmcs_read32(IDT_VECTORING_ERROR_CODE);
3303 }
3304 /* fall through */
3296 case INTR_TYPE_SOFT_EXCEPTION: 3305 case INTR_TYPE_SOFT_EXCEPTION:
3297 kvm_clear_exception_queue(vcpu); 3306 kvm_clear_exception_queue(vcpu);
3298 break; 3307 break;
@@ -3307,7 +3316,8 @@ static int handle_task_switch(struct kvm_vcpu *vcpu)
3307 type != INTR_TYPE_NMI_INTR)) 3316 type != INTR_TYPE_NMI_INTR))
3308 skip_emulated_instruction(vcpu); 3317 skip_emulated_instruction(vcpu);
3309 3318
3310 if (!kvm_task_switch(vcpu, tss_selector, reason)) 3319 if (!kvm_task_switch(vcpu, tss_selector, reason, has_error_code,
3320 error_code))
3311 return 0; 3321 return 0;
3312 3322
3313 /* clear all local breakpoint enable flags */ 3323 /* clear all local breakpoint enable flags */