Commit 738fece4 authored by Sean Christopherson's avatar Sean Christopherson Committed by Paolo Bonzini

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: default avatarSean Christopherson <sean.j.christopherson@intel.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent c83fad65
...@@ -3885,8 +3885,8 @@ static int task_switch_interception(struct vcpu_svm *svm) ...@@ -3885,8 +3885,8 @@ static int task_switch_interception(struct vcpu_svm *svm)
int_type == SVM_EXITINTINFO_TYPE_SOFT || int_type == SVM_EXITINTINFO_TYPE_SOFT ||
(int_type == SVM_EXITINTINFO_TYPE_EXEPT && (int_type == SVM_EXITINTINFO_TYPE_EXEPT &&
(int_vec == OF_VECTOR || int_vec == BP_VECTOR))) { (int_vec == OF_VECTOR || int_vec == BP_VECTOR))) {
if (skip_emulated_instruction(&svm->vcpu) != EMULATE_DONE) if (skip_emulated_instruction(&svm->vcpu) == EMULATE_USER_EXIT)
goto fail; return 0;
} }
if (int_type != SVM_EXITINTINFO_TYPE_SOFT) if (int_type != SVM_EXITINTINFO_TYPE_SOFT)
......
...@@ -6306,6 +6306,13 @@ static int handle_emulation_failure(struct kvm_vcpu *vcpu, int emulation_type) ...@@ -6306,6 +6306,13 @@ static int handle_emulation_failure(struct kvm_vcpu *vcpu, int emulation_type)
return EMULATE_DONE; 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); kvm_queue_exception(vcpu, UD_VECTOR);
if (!is_guest_mode(vcpu) && kvm_x86_ops->get_cpl(vcpu) == 0) { if (!is_guest_mode(vcpu) && kvm_x86_ops->get_cpl(vcpu) == 0) {
...@@ -6641,8 +6648,6 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu, ...@@ -6641,8 +6648,6 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu,
inject_emulated_exception(vcpu); inject_emulated_exception(vcpu);
return EMULATE_DONE; return EMULATE_DONE;
} }
if (emulation_type & EMULTYPE_SKIP)
return EMULATE_FAIL;
return handle_emulation_failure(vcpu, emulation_type); return handle_emulation_failure(vcpu, emulation_type);
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment