]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
KVM: SVM: Add a helper to allocate and initialize permissions bitmaps
authorSean Christopherson <seanjc@google.com>
Tue, 10 Jun 2025 22:57:35 +0000 (15:57 -0700)
committerSean Christopherson <seanjc@google.com>
Fri, 20 Jun 2025 20:07:37 +0000 (13:07 -0700)
Add a helper to allocate and initialize an MSR or I/O permissions map, as
the logic is identical between the two map types, the only difference is
the size of the bitmap.  Opportunistically add a comment to explain why
the bitmaps are initialized with 0xff, e.g. instead of the more common
zero-initialized behavior, which is the main motivation for deduplicating
the code.

No functional change intended.

Link: https://lore.kernel.org/r/20250610225737.156318-31-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
arch/x86/kvm/svm/svm.c
arch/x86/kvm/svm/svm.h

index a55e9bc478856c9cb679bfee64362daa8999e8c8..b855b94c3aba774a8c68d7d4a9a26f6d4e9be43a 100644 (file)
@@ -722,19 +722,23 @@ void svm_enable_intercept_for_msr(struct kvm_vcpu *vcpu, u32 msr, int type)
        svm->nested.force_msr_bitmap_recalc = true;
 }
 
-void *svm_vcpu_alloc_msrpm(void)
+void *svm_alloc_permissions_map(unsigned long size, gfp_t gfp_mask)
 {
-       unsigned int order = get_order(MSRPM_SIZE);
-       struct page *pages = alloc_pages(GFP_KERNEL_ACCOUNT, order);
-       void *msrpm;
+       unsigned int order = get_order(size);
+       struct page *pages = alloc_pages(gfp_mask, order);
+       void *pm;
 
        if (!pages)
                return NULL;
 
-       msrpm = page_address(pages);
-       memset(msrpm, 0xff, PAGE_SIZE * (1 << order));
+       /*
+        * Set all bits in the permissions map so that all MSR and I/O accesses
+        * are intercepted by default.
+        */
+       pm = page_address(pages);
+       memset(pm, 0xff, PAGE_SIZE * (1 << order));
 
-       return msrpm;
+       return pm;
 }
 
 static void svm_recalc_lbr_msr_intercepts(struct kvm_vcpu *vcpu)
@@ -5314,11 +5318,8 @@ static __init void svm_set_cpu_caps(void)
 
 static __init int svm_hardware_setup(void)
 {
-       int cpu;
-       struct page *iopm_pages;
        void *iopm_va;
-       int r;
-       unsigned int order = get_order(IOPM_SIZE);
+       int cpu, r;
 
        /*
         * NX is required for shadow paging and for NPT if the NX huge pages
@@ -5399,13 +5400,11 @@ static __init int svm_hardware_setup(void)
                        pr_info("LBR virtualization supported\n");
        }
 
-       iopm_pages = alloc_pages(GFP_KERNEL, order);
-       if (!iopm_pages)
+       iopm_va = svm_alloc_permissions_map(IOPM_SIZE, GFP_KERNEL);
+       if (!iopm_va)
                return -ENOMEM;
 
-       iopm_va = page_address(iopm_pages);
-       memset(iopm_va, 0xff, PAGE_SIZE * (1 << order));
-       iopm_base = __sme_page_pa(iopm_pages);
+       iopm_base = __sme_set(__pa(iopm_va));
 
        /*
         * Note, SEV setup consumes npt_enabled and enable_mmio_caching (which
index 489adc2ca3f5c7a900f1bea54439f0f3cf23674e..8d32795632613e900541a3294893fb94eb91ee74 100644 (file)
@@ -667,7 +667,13 @@ BUILD_SVM_MSR_BITMAP_HELPERS(void, set, __set)
 /* svm.c */
 extern bool dump_invalid_vmcb;
 
-void *svm_vcpu_alloc_msrpm(void);
+void *svm_alloc_permissions_map(unsigned long size, gfp_t gfp_mask);
+
+static inline void *svm_vcpu_alloc_msrpm(void)
+{
+       return svm_alloc_permissions_map(MSRPM_SIZE, GFP_KERNEL_ACCOUNT);
+}
+
 void svm_vcpu_free_msrpm(void *msrpm);
 void svm_copy_lbrs(struct vmcb *to_vmcb, struct vmcb *from_vmcb);
 void svm_enable_lbrv(struct kvm_vcpu *vcpu);