KVM: x86: Add & use kvm_vcpu_is_legal_cr3() to check CR3's legality
authorBinbin Wu <binbin.wu@linux.intel.com>
Wed, 13 Sep 2023 12:42:17 +0000 (20:42 +0800)
committerSean Christopherson <seanjc@google.com>
Wed, 29 Nov 2023 01:54:04 +0000 (17:54 -0800)
Add and use kvm_vcpu_is_legal_cr3() to check CR3's legality to provide
a clear distinction between CR3 and GPA checks.  This will allow exempting
bits from kvm_vcpu_is_legal_cr3() without affecting general GPA checks,
e.g. for upcoming features that will use high bits in CR3 for feature
enabling.

No functional change intended.

Signed-off-by: Binbin Wu <binbin.wu@linux.intel.com>
Tested-by: Xuelian Guo <xuelian.guo@intel.com>
Link: https://lore.kernel.org/r/20230913124227.12574-7-binbin.wu@linux.intel.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
arch/x86/kvm/cpuid.h
arch/x86/kvm/svm/nested.c
arch/x86/kvm/vmx/nested.c
arch/x86/kvm/x86.c

index 0b90532b6e261430c7997e933f59f5531312d627..5fd3f2d1ca148d02b3d2e6feaaaa775ef234f5ee 100644 (file)
@@ -279,4 +279,9 @@ static __always_inline bool guest_can_use(struct kvm_vcpu *vcpu,
                        vcpu->arch.governed_features.enabled);
 }
 
+static inline bool kvm_vcpu_is_legal_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
+{
+       return kvm_vcpu_is_legal_gpa(vcpu, cr3);
+}
+
 #endif
index 3fea8c47679e6899742c6f5aa08046da041439a2..90ca9489aab63e4ef3b778d05afe6f2208b1fa1f 100644 (file)
@@ -311,7 +311,7 @@ static bool __nested_vmcb_check_save(struct kvm_vcpu *vcpu,
        if ((save->efer & EFER_LME) && (save->cr0 & X86_CR0_PG)) {
                if (CC(!(save->cr4 & X86_CR4_PAE)) ||
                    CC(!(save->cr0 & X86_CR0_PE)) ||
-                   CC(kvm_vcpu_is_illegal_gpa(vcpu, save->cr3)))
+                   CC(!kvm_vcpu_is_legal_cr3(vcpu, save->cr3)))
                        return false;
        }
 
@@ -520,7 +520,7 @@ static void nested_svm_transition_tlb_flush(struct kvm_vcpu *vcpu)
 static int nested_svm_load_cr3(struct kvm_vcpu *vcpu, unsigned long cr3,
                               bool nested_npt, bool reload_pdptrs)
 {
-       if (CC(kvm_vcpu_is_illegal_gpa(vcpu, cr3)))
+       if (CC(!kvm_vcpu_is_legal_cr3(vcpu, cr3)))
                return -EINVAL;
 
        if (reload_pdptrs && !nested_npt && is_pae_paging(vcpu) &&
index c5ec0ef51ff78fa3baae19092d12057c07476394..db61cf8e3128fe4e637fe11935f161d1f47fad5e 100644 (file)
@@ -1085,7 +1085,7 @@ static int nested_vmx_load_cr3(struct kvm_vcpu *vcpu, unsigned long cr3,
                               bool nested_ept, bool reload_pdptrs,
                               enum vm_entry_failure_code *entry_failure_code)
 {
-       if (CC(kvm_vcpu_is_illegal_gpa(vcpu, cr3))) {
+       if (CC(!kvm_vcpu_is_legal_cr3(vcpu, cr3))) {
                *entry_failure_code = ENTRY_FAIL_DEFAULT;
                return -EINVAL;
        }
@@ -2912,7 +2912,7 @@ static int nested_vmx_check_host_state(struct kvm_vcpu *vcpu,
 
        if (CC(!nested_host_cr0_valid(vcpu, vmcs12->host_cr0)) ||
            CC(!nested_host_cr4_valid(vcpu, vmcs12->host_cr4)) ||
-           CC(kvm_vcpu_is_illegal_gpa(vcpu, vmcs12->host_cr3)))
+           CC(!kvm_vcpu_is_legal_cr3(vcpu, vmcs12->host_cr3)))
                return -EINVAL;
 
        if (CC(is_noncanonical_address(vmcs12->host_ia32_sysenter_esp, vcpu)) ||
index 6d0772b47041345119d0b69dbecaa952de0eb3fe..3a648b6e632d3e86e61bd290a6dd1d0e530e3138 100644 (file)
@@ -1284,7 +1284,7 @@ int kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
         * stuff CR3, e.g. for RSM emulation, and there is no guarantee that
         * the current vCPU mode is accurate.
         */
-       if (kvm_vcpu_is_illegal_gpa(vcpu, cr3))
+       if (!kvm_vcpu_is_legal_cr3(vcpu, cr3))
                return 1;
 
        if (is_pae_paging(vcpu) && !load_pdptrs(vcpu, cr3))
@@ -11612,7 +11612,7 @@ static bool kvm_is_valid_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
                 */
                if (!(sregs->cr4 & X86_CR4_PAE) || !(sregs->efer & EFER_LMA))
                        return false;
-               if (kvm_vcpu_is_illegal_gpa(vcpu, sregs->cr3))
+               if (!kvm_vcpu_is_legal_cr3(vcpu, sregs->cr3))
                        return false;
        } else {
                /*