Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bf653b78 authored by Tao Xu's avatar Tao Xu Committed by Paolo Bonzini
Browse files

KVM: vmx: Introduce handle_unexpected_vmexit and handle WAITPKG vmexit



As the latest Intel 64 and IA-32 Architectures Software Developer's
Manual, UMWAIT and TPAUSE instructions cause a VM exit if the
RDTSC exiting and enable user wait and pause VM-execution
controls are both 1.

Because KVM never enable RDTSC exiting, the vm-exit for UMWAIT and TPAUSE
should never happen. Considering EXIT_REASON_XSAVES and
EXIT_REASON_XRSTORS is also unexpected VM-exit for KVM. Introduce a common
exit helper handle_unexpected_vmexit() to handle these unexpected VM-exit.

Suggested-by: default avatarSean Christopherson <sean.j.christopherson@intel.com>
Co-developed-by: default avatarJingqi Liu <jingqi.liu@intel.com>
Signed-off-by: default avatarJingqi Liu <jingqi.liu@intel.com>
Signed-off-by: default avatarTao Xu <tao3.xu@intel.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 6e3ba4ab
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -86,6 +86,8 @@
#define EXIT_REASON_PML_FULL            62
#define EXIT_REASON_XSAVES              63
#define EXIT_REASON_XRSTORS             64
#define EXIT_REASON_UMWAIT              67
#define EXIT_REASON_TPAUSE              68

#define VMX_EXIT_REASONS \
	{ EXIT_REASON_EXCEPTION_NMI,         "EXCEPTION_NMI" }, \
@@ -144,7 +146,9 @@
	{ EXIT_REASON_RDSEED,                "RDSEED" }, \
	{ EXIT_REASON_PML_FULL,              "PML_FULL" }, \
	{ EXIT_REASON_XSAVES,                "XSAVES" }, \
	{ EXIT_REASON_XRSTORS,               "XRSTORS" }
	{ EXIT_REASON_XRSTORS,               "XRSTORS" }, \
	{ EXIT_REASON_UMWAIT,                "UMWAIT" }, \
	{ EXIT_REASON_TPAUSE,                "TPAUSE" }

#define VMX_ABORT_SAVE_GUEST_MSR_FAIL        1
#define VMX_ABORT_LOAD_HOST_PDPTE_FAIL       2
+4 −0
Original line number Diff line number Diff line
@@ -5470,6 +5470,10 @@ bool nested_vmx_exit_reflected(struct kvm_vcpu *vcpu, u32 exit_reason)
	case EXIT_REASON_ENCLS:
		/* SGX is never exposed to L1 */
		return false;
	case EXIT_REASON_UMWAIT:
	case EXIT_REASON_TPAUSE:
		return nested_cpu_has2(vmcs12,
			SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE);
	default:
		return true;
	}
+12 −16
Original line number Diff line number Diff line
@@ -5007,20 +5007,6 @@ static int handle_xsetbv(struct kvm_vcpu *vcpu)
	return 1;
}

static int handle_xsaves(struct kvm_vcpu *vcpu)
{
	kvm_skip_emulated_instruction(vcpu);
	WARN(1, "this should never happen\n");
	return 1;
}

static int handle_xrstors(struct kvm_vcpu *vcpu)
{
	kvm_skip_emulated_instruction(vcpu);
	WARN(1, "this should never happen\n");
	return 1;
}

static int handle_apic_access(struct kvm_vcpu *vcpu)
{
	if (likely(fasteoi)) {
@@ -5514,6 +5500,14 @@ static int handle_encls(struct kvm_vcpu *vcpu)
	return 1;
}

static int handle_unexpected_vmexit(struct kvm_vcpu *vcpu)
{
	kvm_skip_emulated_instruction(vcpu);
	WARN_ONCE(1, "Unexpected VM-Exit Reason = 0x%x",
		vmcs_read32(VM_EXIT_REASON));
	return 1;
}

/*
 * The exit handlers return 1 if the exit was handled fully and guest execution
 * may resume.  Otherwise they set the kvm_run parameter to indicate what needs
@@ -5565,13 +5559,15 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = {
	[EXIT_REASON_INVVPID]                 = handle_vmx_instruction,
	[EXIT_REASON_RDRAND]                  = handle_invalid_op,
	[EXIT_REASON_RDSEED]                  = handle_invalid_op,
	[EXIT_REASON_XSAVES]                  = handle_xsaves,
	[EXIT_REASON_XRSTORS]                 = handle_xrstors,
	[EXIT_REASON_XSAVES]                  = handle_unexpected_vmexit,
	[EXIT_REASON_XRSTORS]                 = handle_unexpected_vmexit,
	[EXIT_REASON_PML_FULL]		      = handle_pml_full,
	[EXIT_REASON_INVPCID]                 = handle_invpcid,
	[EXIT_REASON_VMFUNC]		      = handle_vmx_instruction,
	[EXIT_REASON_PREEMPTION_TIMER]	      = handle_preemption_timer,
	[EXIT_REASON_ENCLS]		      = handle_encls,
	[EXIT_REASON_UMWAIT]                  = handle_unexpected_vmexit,
	[EXIT_REASON_TPAUSE]                  = handle_unexpected_vmexit,
};

static const int kvm_vmx_max_exit_handlers =