]> git.itanic.dy.fi Git - linux-stable/commitdiff
KVM: nVMX: add missing consistency checks for CR0 and CR4
authorPaolo Bonzini <pbonzini@redhat.com>
Fri, 10 Mar 2023 16:10:56 +0000 (11:10 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 20 Apr 2023 10:04:41 +0000 (12:04 +0200)
commit 112e66017bff7f2837030f34c2bc19501e9212d5 upstream.

The effective values of the guest CR0 and CR4 registers may differ from
those included in the VMCS12.  In particular, disabling EPT forces
CR4.PAE=1 and disabling unrestricted guest mode forces CR0.PG=CR0.PE=1.

Therefore, checks on these bits cannot be delegated to the processor
and must be performed by KVM.

Reported-by: Reima ISHII <ishiir@g.ecc.u-tokyo.ac.jp>
Cc: stable@vger.kernel.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
[OP: drop CC() macro calls, as tracing is not implemented in 4.19]
[OP: adjust "return -EINVAL" -> "return 1" to match current return logic]
Signed-off-by: Ovidiu Panait <ovidiu.panait@windriver.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/x86/kvm/vmx/vmx.c

index ec821a5d131a0190f6477a5af1a8e3b4c0be18dd..265e70b0eb79e13dc47ee13755dfd6f961a067e9 100644 (file)
@@ -12752,7 +12752,7 @@ static int nested_vmx_check_vmcs_link_ptr(struct kvm_vcpu *vcpu,
 static int check_vmentry_postreqs(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
                                  u32 *exit_qual)
 {
-       bool ia32e;
+       bool ia32e = !!(vmcs12->vm_entry_controls & VM_ENTRY_IA32E_MODE);
 
        *exit_qual = ENTRY_FAIL_DEFAULT;
 
@@ -12765,6 +12765,13 @@ static int check_vmentry_postreqs(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
                return 1;
        }
 
+       if ((vmcs12->guest_cr0 & (X86_CR0_PG | X86_CR0_PE)) == X86_CR0_PG)
+               return 1;
+
+       if ((ia32e && !(vmcs12->guest_cr4 & X86_CR4_PAE)) ||
+           (ia32e && !(vmcs12->guest_cr0 & X86_CR0_PG)))
+               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:
@@ -12776,7 +12783,6 @@ static int check_vmentry_postreqs(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
         */
        if (to_vmx(vcpu)->nested.nested_run_pending &&
            (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) &&