KVM: nVMX: Leave most VM-Exit info fields unmodified on failed VM-Entry
authorSean Christopherson <seanjc@google.com>
Thu, 7 Apr 2022 00:23:14 +0000 (00:23 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 9 Jun 2022 08:23:05 +0000 (10:23 +0200)
[ Upstream commit c3634d25fbee88e2368a8e0903ae0d0670eb9e71 ]

Don't modify vmcs12 exit fields except EXIT_REASON and EXIT_QUALIFICATION
when performing a nested VM-Exit due to failed VM-Entry.  Per the SDM,
only the two aformentioned fields are filled and "All other VM-exit
information fields are unmodified".

Fixes: 4704d0befb07 ("KVM: nVMX: Exiting from L2 to L1")
Signed-off-by: Sean Christopherson <seanjc@google.com>
Message-Id: <20220407002315.78092-3-seanjc@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
arch/x86/kvm/vmx/nested.c

index 5eae69c..e0b5a4a 100644 (file)
@@ -4185,12 +4185,12 @@ static void prepare_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
        if (to_vmx(vcpu)->exit_reason.enclave_mode)
                vmcs12->vm_exit_reason |= VMX_EXIT_REASONS_SGX_ENCLAVE_MODE;
        vmcs12->exit_qualification = exit_qualification;
-       vmcs12->vm_exit_intr_info = exit_intr_info;
-
-       vmcs12->idt_vectoring_info_field = 0;
-       vmcs12->vm_exit_instruction_len = vmcs_read32(VM_EXIT_INSTRUCTION_LEN);
-       vmcs12->vmx_instruction_info = vmcs_read32(VMX_INSTRUCTION_INFO);
 
+       /*
+        * On VM-Exit due to a failed VM-Entry, the VMCS isn't marked launched
+        * and only EXIT_REASON and EXIT_QUALIFICATION are updated, all other
+        * exit info fields are unmodified.
+        */
        if (!(vmcs12->vm_exit_reason & VMX_EXIT_REASONS_FAILED_VMENTRY)) {
                vmcs12->launch_state = 1;
 
@@ -4202,8 +4202,13 @@ static void prepare_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
                 * Transfer the event that L0 or L1 may wanted to inject into
                 * L2 to IDT_VECTORING_INFO_FIELD.
                 */
+               vmcs12->idt_vectoring_info_field = 0;
                vmcs12_save_pending_event(vcpu, vmcs12);
 
+               vmcs12->vm_exit_intr_info = exit_intr_info;
+               vmcs12->vm_exit_instruction_len = vmcs_read32(VM_EXIT_INSTRUCTION_LEN);
+               vmcs12->vmx_instruction_info = vmcs_read32(VMX_INSTRUCTION_INFO);
+
                /*
                 * According to spec, there's no need to store the guest's
                 * MSRs if the exit is due to a VM-entry failure that occurs