summaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/x86.c
diff options
context:
space:
mode:
authorSean Christopherson <sean.j.christopherson@intel.com>2019-08-27 23:40:34 +0200
committerPaolo Bonzini <pbonzini@redhat.com>2019-09-24 14:31:07 +0200
commit738fece46dc5e1bb1309a827a2b69056143b3d13 (patch)
tree33246d9a226b6b7953d686a9eaf9d1a1b674e964 /arch/x86/kvm/x86.c
parentKVM: x86: Move #UD injection for failed emulation into emulation code (diff)
downloadlinux-738fece46dc5e1bb1309a827a2b69056143b3d13.tar.xz
linux-738fece46dc5e1bb1309a827a2b69056143b3d13.zip
KVM: x86: Exit to userspace on emulation skip failure
Kill a few birds with one stone by forcing an exit to userspace on skip emulation failure. This removes a reference to EMULATE_FAIL, fixes a bug in handle_ept_misconfig() where it would exit to userspace without setting run->exit_reason, and fixes a theoretical bug in SVM's task_switch_interception() where it would overwrite run->exit_reason on a return of EMULATE_USER_EXIT. Note, this technically doesn't fully fix task_switch_interception() as it now incorrectly handles EMULATE_FAIL, but in practice there is no bug as EMULATE_FAIL will never be returned for EMULTYPE_SKIP. Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to '')
-rw-r--r--arch/x86/kvm/x86.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 64d584d48c60..802dfb926ca7 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -6306,6 +6306,13 @@ static int handle_emulation_failure(struct kvm_vcpu *vcpu, int emulation_type)
return EMULATE_DONE;
}
+ if (emulation_type & EMULTYPE_SKIP) {
+ vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
+ vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION;
+ vcpu->run->internal.ndata = 0;
+ return EMULATE_USER_EXIT;
+ }
+
kvm_queue_exception(vcpu, UD_VECTOR);
if (!is_guest_mode(vcpu) && kvm_x86_ops->get_cpl(vcpu) == 0) {
@@ -6641,8 +6648,6 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu,
inject_emulated_exception(vcpu);
return EMULATE_DONE;
}
- if (emulation_type & EMULTYPE_SKIP)
- return EMULATE_FAIL;
return handle_emulation_failure(vcpu, emulation_type);
}
}