[Devel] [PATCH RHEL7 COMMIT] ms/KVM: nVMX: fix guest CR4 loading when emulating L2 to L1 exit

Konstantin Khorenko khorenko at virtuozzo.com
Fri Apr 6 18:44:47 MSK 2018


The commit is pushed to "branch-rh7-3.10.0-693.21.1.vz7.46.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-693.21.1.vz7.46.4
------>
commit 1fe163fc588b6c30e6dbb6d8301336fa09c2b1e2
Author: Haozhong Zhang <haozhong.zhang at intel.com>
Date:   Fri Apr 6 18:44:47 2018 +0300

    ms/KVM: nVMX: fix guest CR4 loading when emulating L2 to L1 exit
    
    When KVM emulates an exit from L2 to L1, it loads L1 CR4 into the
    guest CR4. Before this CR4 loading, the guest CR4 refers to L2
    CR4. Because these two CR4's are in different levels of guest, we
    should vmx_set_cr4() rather than kvm_set_cr4() here. The latter, which
    is used to handle guest writes to its CR4, checks the guest change to
    CR4 and may fail if the change is invalid.
    
    The failure may cause trouble. Consider we start
      a L1 guest with non-zero L1 PCID in use,
         (i.e. L1 CR4.PCIDE == 1 && L1 CR3.PCID != 0)
    and
      a L2 guest with L2 PCID disabled,
         (i.e. L2 CR4.PCIDE == 0)
    and following events may happen:
    
    1. If kvm_set_cr4() is used in load_vmcs12_host_state() to load L1 CR4
       into guest CR4 (in VMCS01) for L2 to L1 exit, it will fail because
       of PCID check. As a result, the guest CR4 recorded in L0 KVM (i.e.
       vcpu->arch.cr4) is left to the value of L2 CR4.
    
    2. Later, if L1 attempts to change its CR4, e.g., clearing VMXE bit,
       kvm_set_cr4() in L0 KVM will think L1 also wants to enable PCID,
       because the wrong L2 CR4 is used by L0 KVM as L1 CR4. As L1
       CR3.PCID != 0, L0 KVM will inject GP to L1 guest.
    
    Fixes: 4704d0befb072 ("KVM: nVMX: Exiting from L2 to L1")
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Haozhong Zhang <haozhong.zhang at intel.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    
    https://jira.sw.ru/browse/PSBM-83005
    (cherry picked from commit 8eb3f87d903168bdbd1222776a6b1e281f50513e)
    Signed-off-by: Jan Dakinevich <jan.dakinevich at virtuozzo.com>
    
    ==========================================
    Patchset description:
    kernel fixes after kvm-unit-tests
    
    https://jira.sw.ru/browse/PSBM-83005
    
    patch 1
      Chao Gao (1):
        KVM: nVMX: Don't halt vcpu when L1 is injecting events to L2
      fixes 'vmx_cr_load_test':
        FAIL: Test return 3 code: FAIL: x86/vmx_tests.c:3912: Assertion failed:
            !write_cr4_checking(cr4 | X86_CR4_MCE)
    
    patch 2
      Haozhong Zhang (1):
        KVM: nVMX: Don't halt vcpu when L1 is injecting events to L2
      fixes 'vmx_interrupt'
        FAIL: QEMU command timed out
---
 arch/x86/kvm/vmx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 7606c6cf3774..7d7f0fae475b 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -10457,7 +10457,7 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu,
 	 * (KVM doesn't change it)- no reason to call set_cr4_guest_host_mask();
 	 */
 	vcpu->arch.cr4_guest_owned_bits = ~vmcs_readl(CR4_GUEST_HOST_MASK);
-	kvm_set_cr4(vcpu, vmcs12->host_cr4);
+	vmx_set_cr4(vcpu, vmcs12->host_cr4);
 
 	nested_ept_uninit_mmu_context(vcpu);
 


More information about the Devel mailing list