]> git.itanic.dy.fi Git - linux-stable/commitdiff
KVM: nVMX: Split off helper for emulating VMCLEAR on Hyper-V eVMCS
authorVitaly Kuznetsov <vkuznets@redhat.com>
Tue, 5 Dec 2023 10:36:22 +0000 (11:36 +0100)
committerSean Christopherson <seanjc@google.com>
Thu, 7 Dec 2023 17:34:27 +0000 (09:34 -0800)
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>
Tested-by: Jeremi Piotrowski <jpiotrowski@linux.microsoft.com>
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
Link: https://lore.kernel.org/r/20231205103630.1391318-9-vkuznets@redhat.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
arch/x86/kvm/vmx/nested.c

index 382c0746d0693628ad7541ca55d17a26c06860d0..903b6f9ea2bdf9fadc2c23fc194bcce8116bbcb2 100644 (file)
@@ -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);