KVM: prevent spurious exit to userspace during task switch emulation.
If kvm_task_switch() fails code exits to userspace without specifying exit reason, so the previous exit reason is reused by userspace. Fix this by specifying exit reason correctly.
---
Changelog:
v1->v2:
- report emulation error to userspace instead of ignoring it silently.
Signed-off-by Gleb Natapov<[email protected]>
arch/x86/kvm/svm.c +8 -2
@@ -2265,8 +2265,14 @@ static int task_switch_interception(struct vcpu_svm *svm) (int_vec == OF_VECTOR || int_vec == BP_VECTOR)))skip_emulated_instruction (&svm->vcpu); -return kvm_task_switch (&svm->vcpu, tss_selector, reason, - has_error_code, error_code); +if (kvm_task_switch (&svm->vcpu, tss_selector, reason, + has_error_code, error_code) ==EMULATE_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 1 ; }static int cpuid_interception (struct vcpu_svm *svm)
arch/x86/kvm/vmx.c +6 -2
@@ -3315,9 +3315,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, reason, has_error_code, - error_code)) +if (kvm_task_switch (vcpu, tss_selector, 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 ; + }/* clear all local breakpoint enable flags */ vmcs_writel (GUEST_DR7 ,vmcs_readl (GUEST_DR7 ) & ~55 );
--
Gleb.