Commit b2e02f82 authored by Vitaly Kuznetsov's avatar Vitaly Kuznetsov Committed by Sean Christopherson
Browse files

KVM: nVMX: Split off helper for emulating VMCLEAR on Hyper-V eVMCS



To avoid overloading handle_vmclear() with Hyper-V specific details and to
prepare the code to making Hyper-V emulation optional, create a dedicated
nested_evmcs_handle_vmclear() helper.

No functional change intended.

Suggested-by: default avatarSean Christopherson <seanjc@google.com>
Tested-by: default avatarJeremi Piotrowski <jpiotrowski@linux.microsoft.com>
Signed-off-by: default avatarVitaly Kuznetsov <vkuznets@redhat.com>
Reviewed-by: default avatarMaxim Levitsky <mlevitsk@redhat.com>
Link: https://lore.kernel.org/r/20231205103630.1391318-9-vkuznets@redhat.com


Signed-off-by: default avatarSean Christopherson <seanjc@google.com>
parent af9d544a
Loading
Loading
Loading
Loading
+24 −14
Original line number Diff line number Diff line
@@ -243,6 +243,29 @@ static inline void nested_release_evmcs(struct kvm_vcpu *vcpu)
	}
}

static bool nested_evmcs_handle_vmclear(struct kvm_vcpu *vcpu, gpa_t vmptr)
{
	struct vcpu_vmx *vmx = to_vmx(vcpu);
	/*
	 * When Enlightened VMEntry is enabled on the calling CPU we treat
	 * memory area pointer by vmptr as Enlightened VMCS (as there's no good
	 * way to distinguish it from VMCS12) and we must not corrupt it by
	 * writing to the non-existent 'launch_state' field. The area doesn't
	 * have to be the currently active EVMCS on the calling CPU and there's
	 * nothing KVM has to do to transition it from 'active' to 'non-active'
	 * state. It is possible that the area will stay mapped as
	 * vmx->nested.hv_evmcs but this shouldn't be a problem.
	 */
	if (!guest_cpuid_has_evmcs(vcpu) ||
	    !evmptr_is_valid(nested_get_evmptr(vcpu)))
		return false;

	if (vmx->nested.hv_evmcs && vmptr == vmx->nested.hv_evmcs_vmptr)
		nested_release_evmcs(vcpu);

	return true;
}

static void vmx_sync_vmcs_host_state(struct vcpu_vmx *vmx,
				     struct loaded_vmcs *prev)
{
@@ -5286,18 +5309,7 @@ static int handle_vmclear(struct kvm_vcpu *vcpu)
	if (vmptr == vmx->nested.vmxon_ptr)
		return nested_vmx_fail(vcpu, VMXERR_VMCLEAR_VMXON_POINTER);

	/*
	 * When Enlightened VMEntry is enabled on the calling CPU we treat
	 * memory area pointer by vmptr as Enlightened VMCS (as there's no good
	 * way to distinguish it from VMCS12) and we must not corrupt it by
	 * writing to the non-existent 'launch_state' field. The area doesn't
	 * have to be the currently active EVMCS on the calling CPU and there's
	 * nothing KVM has to do to transition it from 'active' to 'non-active'
	 * state. It is possible that the area will stay mapped as
	 * vmx->nested.hv_evmcs but this shouldn't be a problem.
	 */
	if (likely(!guest_cpuid_has_evmcs(vcpu) ||
		   !evmptr_is_valid(nested_get_evmptr(vcpu)))) {
	if (likely(!nested_evmcs_handle_vmclear(vcpu, vmptr))) {
		if (vmptr == vmx->nested.current_vmptr)
			nested_release_vmcs12(vcpu);

@@ -5314,8 +5326,6 @@ static int handle_vmclear(struct kvm_vcpu *vcpu)
					   vmptr + offsetof(struct vmcs12,
							    launch_state),
					   &zero, sizeof(zero));
	} else if (vmx->nested.hv_evmcs && vmptr == vmx->nested.hv_evmcs_vmptr) {
		nested_release_evmcs(vcpu);
	}

	return nested_vmx_succeed(vcpu);