KVM: x86: Handle emulation failure directly in kvm_task_switch()
Consolidate the reporting of emulation failure into kvm_task_switch() so that it can return EMULATE_USER_EXIT. This helps pave the way for removing EMULATE_FAIL altogether. This also fixes a theoretical bug where task switch interception could suppress an EMULATE_USER_EXIT return. Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
738fece46d
commit
1051778f6e
|
@ -3892,17 +3892,10 @@ static int task_switch_interception(struct vcpu_svm *svm)
|
|||
if (int_type != SVM_EXITINTINFO_TYPE_SOFT)
|
||||
int_vec = -1;
|
||||
|
||||
if (kvm_task_switch(&svm->vcpu, tss_selector, int_vec, reason,
|
||||
has_error_code, error_code) == EMULATE_FAIL)
|
||||
goto fail;
|
||||
|
||||
return 1;
|
||||
|
||||
fail:
|
||||
svm->vcpu.run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
|
||||
svm->vcpu.run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION;
|
||||
svm->vcpu.run->internal.ndata = 0;
|
||||
return 0;
|
||||
return kvm_task_switch(&svm->vcpu, tss_selector, int_vec, reason,
|
||||
has_error_code, error_code) != EMULATE_USER_EXIT;
|
||||
}
|
||||
|
||||
static int cpuid_interception(struct vcpu_svm *svm)
|
||||
|
|
|
@ -5074,21 +5074,13 @@ static int handle_task_switch(struct kvm_vcpu *vcpu)
|
|||
type != INTR_TYPE_NMI_INTR))
|
||||
skip_emulated_instruction(vcpu);
|
||||
|
||||
if (kvm_task_switch(vcpu, tss_selector,
|
||||
type == INTR_TYPE_SOFT_INTR ? idt_index : -1, reason,
|
||||
has_error_code, error_code) == EMULATE_FAIL) {
|
||||
vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
|
||||
vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION;
|
||||
vcpu->run->internal.ndata = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: What about debug traps on tss switch?
|
||||
* Are we supposed to inject them and update dr6?
|
||||
*/
|
||||
|
||||
return 1;
|
||||
return kvm_task_switch(vcpu, tss_selector,
|
||||
type == INTR_TYPE_SOFT_INTR ? idt_index : -1,
|
||||
reason, has_error_code, error_code) != EMULATE_USER_EXIT;
|
||||
}
|
||||
|
||||
static int handle_ept_violation(struct kvm_vcpu *vcpu)
|
||||
|
|
|
@ -8693,9 +8693,12 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int idt_index,
|
|||
|
||||
ret = emulator_task_switch(ctxt, tss_selector, idt_index, reason,
|
||||
has_error_code, error_code);
|
||||
|
||||
if (ret)
|
||||
return EMULATE_FAIL;
|
||||
if (ret) {
|
||||
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_rip_write(vcpu, ctxt->eip);
|
||||
kvm_set_rflags(vcpu, ctxt->eflags);
|
||||
|
|
Loading…
Reference in New Issue