diff mbox series

[v2,08/16] KVM: x86: hyper-v: Split off nested_evmcs_handle_vmclear()

Message ID 20231205103630.1391318-9-vkuznets@redhat.com (mailing list archive)
State New, archived
Headers show
Series KVM: x86: Make Hyper-V emulation optional | expand

Commit Message

Vitaly Kuznetsov Dec. 5, 2023, 10:36 a.m. UTC
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: Sean Christopherson <seanjc@google.com>
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
 arch/x86/kvm/vmx/nested.c | 38 ++++++++++++++++++++++++--------------
 1 file changed, 24 insertions(+), 14 deletions(-)

Comments

Maxim Levitsky Dec. 5, 2023, 12:06 p.m. UTC | #1
On Tue, 2023-12-05 at 11:36 +0100, Vitaly Kuznetsov wrote:
> 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: Sean Christopherson <seanjc@google.com>
> Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
> ---
>  arch/x86/kvm/vmx/nested.c | 38 ++++++++++++++++++++++++--------------
>  1 file changed, 24 insertions(+), 14 deletions(-)
> 
> diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
> index 382c0746d069..903b6f9ea2bd 100644
> --- a/arch/x86/kvm/vmx/nested.c
> +++ b/arch/x86/kvm/vmx/nested.c
> @@ -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);

Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>


Best regards,
	Maxim Levitsky
diff mbox series

Patch

diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
index 382c0746d069..903b6f9ea2bd 100644
--- a/arch/x86/kvm/vmx/nested.c
+++ b/arch/x86/kvm/vmx/nested.c
@@ -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);