Few guest checks were done before entering the guest, for which there is
no reason.  Having them all in one place will be simpler.

Signed-off-by: Radim Krčmář <rkrc...@redhat.com>
---
 arch/x86/kvm/vmx.c | 72 +++++++++++++++++++++++++++++-------------------------
 1 file changed, 39 insertions(+), 33 deletions(-)

diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index ab65b31ce58c..050899431b5e 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -10499,39 +10499,6 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool 
launch)
                }
        }
 
-       if (!nested_guest_cr0_valid(vcpu, vmcs12->guest_cr0) ||
-           !nested_guest_cr4_valid(vcpu, vmcs12->guest_cr4)) {
-               nested_vmx_entry_failure(vcpu, vmcs12,
-                       EXIT_REASON_INVALID_STATE, ENTRY_FAIL_DEFAULT);
-               return 1;
-       }
-       if (vmcs12->vmcs_link_pointer != -1ull) {
-               nested_vmx_entry_failure(vcpu, vmcs12,
-                       EXIT_REASON_INVALID_STATE, ENTRY_FAIL_VMCS_LINK_PTR);
-               return 1;
-       }
-
-       /*
-        * If the load IA32_EFER VM-entry control is 1, the following checks
-        * are performed on the field for the IA32_EFER MSR:
-        * - Bits reserved in the IA32_EFER MSR must be 0.
-        * - Bit 10 (corresponding to IA32_EFER.LMA) must equal the value of
-        *   the IA-32e mode guest VM-exit control. It must also be identical
-        *   to bit 8 (LME) if bit 31 in the CR0 field (corresponding to
-        *   CR0.PG) is 1.
-        */
-       if (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_IA32_EFER) {
-               ia32e = (vmcs12->vm_entry_controls & VM_ENTRY_IA32E_MODE) != 0;
-               if (!kvm_valid_efer(vcpu, vmcs12->guest_ia32_efer) ||
-                   ia32e != !!(vmcs12->guest_ia32_efer & EFER_LMA) ||
-                   ((vmcs12->guest_cr0 & X86_CR0_PG) &&
-                    ia32e != !!(vmcs12->guest_ia32_efer & EFER_LME))) {
-                       nested_vmx_entry_failure(vcpu, vmcs12,
-                               EXIT_REASON_INVALID_STATE, ENTRY_FAIL_DEFAULT);
-                       return 1;
-               }
-       }
-
        /*
         * We're finally done with prerequisite checking, and can start with
         * the nested entry.
@@ -10561,6 +10528,45 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool 
launch)
 
        vmx_segment_cache_clear(vmx);
 
+       if (!nested_guest_cr0_valid(vcpu, vmcs12->guest_cr0) ||
+           !nested_guest_cr4_valid(vcpu, vmcs12->guest_cr4)) {
+               leave_guest_mode(vcpu);
+               vmx_load_vmcs01(vcpu);
+               nested_vmx_entry_failure(vcpu, vmcs12,
+                       EXIT_REASON_INVALID_STATE, ENTRY_FAIL_DEFAULT);
+               return 1;
+       }
+       if (vmcs12->vmcs_link_pointer != -1ull) {
+               leave_guest_mode(vcpu);
+               vmx_load_vmcs01(vcpu);
+               nested_vmx_entry_failure(vcpu, vmcs12,
+                       EXIT_REASON_INVALID_STATE, ENTRY_FAIL_VMCS_LINK_PTR);
+               return 1;
+       }
+
+       /*
+        * If the load IA32_EFER VM-entry control is 1, the following checks
+        * are performed on the field for the IA32_EFER MSR:
+        * - Bits reserved in the IA32_EFER MSR must be 0.
+        * - Bit 10 (corresponding to IA32_EFER.LMA) must equal the value of
+        *   the IA-32e mode guest VM-exit control. It must also be identical
+        *   to bit 8 (LME) if bit 31 in the CR0 field (corresponding to
+        *   CR0.PG) is 1.
+        */
+       if (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_IA32_EFER) {
+               ia32e = (vmcs12->vm_entry_controls & VM_ENTRY_IA32E_MODE) != 0;
+               if (!kvm_valid_efer(vcpu, vmcs12->guest_ia32_efer) ||
+                   ia32e != !!(vmcs12->guest_ia32_efer & EFER_LMA) ||
+                   ((vmcs12->guest_cr0 & X86_CR0_PG) &&
+                    ia32e != !!(vmcs12->guest_ia32_efer & EFER_LME))) {
+                       leave_guest_mode(vcpu);
+                       vmx_load_vmcs01(vcpu);
+                       nested_vmx_entry_failure(vcpu, vmcs12,
+                               EXIT_REASON_INVALID_STATE, ENTRY_FAIL_DEFAULT);
+                       return 1;
+               }
+       }
+
        if (prepare_vmcs02(vcpu, vmcs12, &exit_qualification)) {
                leave_guest_mode(vcpu);
                vmx_load_vmcs01(vcpu);
-- 
2.11.0

Reply via email to