aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/vmx.c
diff options
context:
space:
mode:
authorGleb Natapov <gleb@redhat.com>2010-05-10 04:16:56 -0400
committerAvi Kivity <avi@redhat.com>2010-08-01 03:35:40 -0400
commit6d77dbfc88e37c9efd5c5dd18445cfe819ae17ea (patch)
tree96a3afb750d254a99dd43fa4730fd6ff187eb2a0 /arch/x86/kvm/vmx.c
parent57bc24cfd655c912498983130326b312e0404db1 (diff)
KVM: inject #UD if instruction emulation fails and exit to userspace
Do not kill VM when instruction emulation fails. Inject #UD and report failure to userspace instead. Userspace may choose to reenter guest if vcpu is in userspace (cpl == 3) in which case guest OS will kill offending process and continue running. Signed-off-by: Gleb Natapov <gleb@redhat.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch/x86/kvm/vmx.c')
-rw-r--r--arch/x86/kvm/vmx.c28
1 files changed, 4 insertions, 24 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 598931734251..a82cfa1e2a40 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -3070,7 +3070,7 @@ static int handle_io(struct kvm_vcpu *vcpu)
3070 ++vcpu->stat.io_exits; 3070 ++vcpu->stat.io_exits;
3071 3071
3072 if (string || in) 3072 if (string || in)
3073 return !(emulate_instruction(vcpu, 0, 0, 0) == EMULATE_DO_MMIO); 3073 return emulate_instruction(vcpu, 0, 0, 0) == EMULATE_DONE;
3074 3074
3075 port = exit_qualification >> 16; 3075 port = exit_qualification >> 16;
3076 size = (exit_qualification & 7) + 1; 3076 size = (exit_qualification & 7) + 1;
@@ -3327,22 +3327,7 @@ static int handle_wbinvd(struct kvm_vcpu *vcpu)
3327 3327
3328static int handle_apic_access(struct kvm_vcpu *vcpu) 3328static int handle_apic_access(struct kvm_vcpu *vcpu)
3329{ 3329{
3330 unsigned long exit_qualification; 3330 return emulate_instruction(vcpu, 0, 0, 0) == EMULATE_DONE;
3331 enum emulation_result er;
3332 unsigned long offset;
3333
3334 exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
3335 offset = exit_qualification & 0xffful;
3336
3337 er = emulate_instruction(vcpu, 0, 0, 0);
3338
3339 if (er != EMULATE_DONE) {
3340 printk(KERN_ERR
3341 "Fail to handle apic access vmexit! Offset is 0x%lx\n",
3342 offset);
3343 return -ENOEXEC;
3344 }
3345 return 1;
3346} 3331}
3347 3332
3348static int handle_task_switch(struct kvm_vcpu *vcpu) 3333static int handle_task_switch(struct kvm_vcpu *vcpu)
@@ -3554,13 +3539,8 @@ static int handle_invalid_guest_state(struct kvm_vcpu *vcpu)
3554 goto out; 3539 goto out;
3555 } 3540 }
3556 3541
3557 if (err != EMULATE_DONE) { 3542 if (err != EMULATE_DONE)
3558 vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR; 3543 return 0;
3559 vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION;
3560 vcpu->run->internal.ndata = 0;
3561 ret = 0;
3562 goto out;
3563 }
3564 3544
3565 if (signal_pending(current)) 3545 if (signal_pending(current))
3566 goto out; 3546 goto out;