KVM: nVMX: Reword comments about generating nested CR0/4 read shadows
authorSean Christopherson <seanjc@google.com>
Wed, 31 Aug 2022 00:07:21 +0000 (00:07 +0000)
committerSean Christopherson <seanjc@google.com>
Thu, 1 Dec 2022 00:27:17 +0000 (16:27 -0800)
Reword the comments that (attempt to) document nVMX's overrides of the
CR0/4 read shadows for L2 after calling vmx_set_cr0/4().  The important
behavior that needs to be documented is that KVM needs to override the
shadows to account for L1's masks even though the shadows are set by the
common helpers (and that setting the shadows first would result in the
correct shadows being clobbered).

Signed-off-by: Sean Christopherson <seanjc@google.com>
Reviewed-by: Jim Mattson <jmattson@google.com>
Link: https://lore.kernel.org/r/20220831000721.4066617-1-seanjc@google.com
arch/x86/kvm/vmx/nested.c
arch/x86/kvm/vmx/nested.h

index 61c8342..b6f4411 100644 (file)
@@ -2588,12 +2588,9 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
                nested_ept_init_mmu_context(vcpu);
 
        /*
-        * This sets GUEST_CR0 to vmcs12->guest_cr0, possibly modifying those
-        * bits which we consider mandatory enabled.
-        * The CR0_READ_SHADOW is what L2 should have expected to read given
-        * the specifications by L1; It's not enough to take
-        * vmcs12->cr0_read_shadow because on our cr0_guest_host_mask we
-        * have more bits than L1 expected.
+        * Override the CR0/CR4 read shadows after setting the effective guest
+        * CR0/CR4.  The common helpers also set the shadows, but they don't
+        * account for vmcs12's cr0/4_guest_host_mask.
         */
        vmx_set_cr0(vcpu, vmcs12->guest_cr0);
        vmcs_writel(CR0_READ_SHADOW, nested_read_cr0(vmcs12));
index 6312c95..9695226 100644 (file)
@@ -79,9 +79,10 @@ static inline bool nested_ept_ad_enabled(struct kvm_vcpu *vcpu)
 }
 
 /*
- * Return the cr0 value that a nested guest would read. This is a combination
- * of the real cr0 used to run the guest (guest_cr0), and the bits shadowed by
- * its hypervisor (cr0_read_shadow).
+ * Return the cr0/4 value that a nested guest would read. This is a combination
+ * of L1's "real" cr0 used to run the guest (guest_cr0), and the bits shadowed
+ * by the L1 hypervisor (cr0_read_shadow).  KVM must emulate CPU behavior as
+ * the value+mask loaded into vmcs02 may not match the vmcs12 fields.
  */
 static inline unsigned long nested_read_cr0(struct vmcs12 *fields)
 {