]> git.baikalelectronics.ru Git - kernel.git/commitdiff
KVM: x86: nVMX: don't fail nested VM entry on invalid guest state if !from_vmentry
authorMaxim Levitsky <mlevitsk@redhat.com>
Mon, 13 Sep 2021 14:09:53 +0000 (17:09 +0300)
committerPaolo Bonzini <pbonzini@redhat.com>
Wed, 22 Sep 2021 14:47:50 +0000 (10:47 -0400)
It is possible that when non root mode is entered via special entry
(!from_vmentry), that is from SMM or from loading the nested state,
the L2 state could be invalid in regard to non unrestricted guest mode,
but later it can become valid.

(for example when RSM emulation restores segment registers from SMRAM)

Thus delay the check to VM entry, where we will check this and fail.

Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
Message-Id: <20210913140954.165665-7-mlevitsk@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/kvm/vmx/nested.c
arch/x86/kvm/vmx/vmx.c

index bc9c9cc228ea4ae3d24181dad88d51710fb6a07a..b89c78e952b7f82891c23e7476bfe715b2541e8b 100644 (file)
@@ -2583,8 +2583,13 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
         * Guest state is invalid and unrestricted guest is disabled,
         * which means L1 attempted VMEntry to L2 with invalid state.
         * Fail the VMEntry.
+        *
+        * However when force loading the guest state (SMM exit or
+        * loading nested state after migration, it is possible to
+        * have invalid guest state now, which will be later fixed by
+        * restoring L2 register state
         */
-       if (CC(!vmx_guest_state_valid(vcpu))) {
+       if (CC(from_vmentry && !vmx_guest_state_valid(vcpu))) {
                *entry_failure_code = ENTRY_FAIL_DEFAULT;
                return -EINVAL;
        }
index 1c2296fa7f2ba0901e341bfc341294d2d3e0c787..7df6f4b8931f7580ab4ef3f3749fe331a2c41e03 100644 (file)
@@ -6628,7 +6628,10 @@ static fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu)
         * consistency check VM-Exit due to invalid guest state and bail.
         */
        if (unlikely(vmx->emulation_required)) {
-               vmx->fail = 0;
+
+               /* We don't emulate invalid state of a nested guest */
+               vmx->fail = is_guest_mode(vcpu);
+
                vmx->exit_reason.full = EXIT_REASON_INVALID_STATE;
                vmx->exit_reason.failed_vmentry = 1;
                kvm_register_mark_available(vcpu, VCPU_EXREG_EXIT_INFO_1);