Commit acb54517 authored by Gleb Natapov's avatar Gleb Natapov Committed by Avi Kivity
Browse files

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.

Signed-off-by: default avatarGleb Natapov <gleb@redhat.com>
Signed-off-by: default avatarMarcelo Tosatti <mtosatti@redhat.com>
parent 6b18493d
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -2266,8 +2266,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)
+6 −2
Original line number Diff line number Diff line
@@ -3316,9 +3316,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);