KVM: nVMX: Allocate and configure VM{READ,WRITE} bitmaps iff enable_shadow_vmcs
authorSean Christopherson <sean.j.christopherson@intel.com>
Mon, 3 Dec 2018 21:52:52 +0000 (13:52 -0800)
committerPaolo Bonzini <pbonzini@redhat.com>
Fri, 14 Dec 2018 11:34:21 +0000 (12:34 +0100)
...and make enable_shadow_vmcs depend on nested.  Aside from the obvious
memory savings, this will allow moving the relevant code out of vmx.c in
the future, e.g. to a nested specific file.

Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/kvm/vmx.c

index 3ec47b7a94d63e59eef51c37ec522db936b6624b..49c5b155e07d0b49b176770794e8bc13c544fdee 100644 (file)
@@ -4862,6 +4862,9 @@ static void init_vmcs_shadow_fields(void)
 {
        int i, j;
 
+       memset(vmx_vmread_bitmap, 0xff, PAGE_SIZE);
+       memset(vmx_vmwrite_bitmap, 0xff, PAGE_SIZE);
+
        for (i = j = 0; i < max_shadow_read_only_fields; i++) {
                u16 field = shadow_read_only_fields[i];
                if (vmcs_field_width(field) == VMCS_FIELD_WIDTH_U64 &&
@@ -7904,19 +7907,8 @@ static __init int hardware_setup(void)
        for (i = 0; i < ARRAY_SIZE(vmx_msr_index); ++i)
                kvm_define_shared_msr(i, vmx_msr_index[i]);
 
-       for (i = 0; i < VMX_BITMAP_NR; i++) {
-               vmx_bitmap[i] = (unsigned long *)__get_free_page(GFP_KERNEL);
-               if (!vmx_bitmap[i])
-                       goto out;
-       }
-
-       memset(vmx_vmread_bitmap, 0xff, PAGE_SIZE);
-       memset(vmx_vmwrite_bitmap, 0xff, PAGE_SIZE);
-
-       if (setup_vmcs_config(&vmcs_config) < 0) {
-               r = -EIO;
-               goto out;
-       }
+       if (setup_vmcs_config(&vmcs_config) < 0)
+               return -EIO;
 
        if (boot_cpu_has(X86_FEATURE_NX))
                kvm_enable_efer_bits(EFER_NX);
@@ -8027,10 +8019,18 @@ static __init int hardware_setup(void)
                kvm_x86_ops->cancel_hv_timer = NULL;
        }
 
-       if (!cpu_has_vmx_shadow_vmcs())
+       if (!cpu_has_vmx_shadow_vmcs() || !nested)
                enable_shadow_vmcs = 0;
-       if (enable_shadow_vmcs)
+       if (enable_shadow_vmcs) {
+               for (i = 0; i < VMX_BITMAP_NR; i++) {
+                       vmx_bitmap[i] = (unsigned long *)
+                               __get_free_page(GFP_KERNEL);
+                       if (!vmx_bitmap[i])
+                               goto out;
+               }
+
                init_vmcs_shadow_fields();
+       }
 
        kvm_set_posted_intr_wakeup_handler(wakeup_handler);
        nested_vmx_setup_ctls_msrs(&vmcs_config.nested, enable_apicv);
@@ -8043,9 +8043,10 @@ static __init int hardware_setup(void)
        return 0;
 
 out:
-       for (i = 0; i < VMX_BITMAP_NR; i++)
-               free_page((unsigned long)vmx_bitmap[i]);
-
+       if (enable_shadow_vmcs) {
+               for (i = 0; i < VMX_BITMAP_NR; i++)
+                       free_page((unsigned long)vmx_bitmap[i]);
+       }
        return r;
 }
 
@@ -8053,8 +8054,10 @@ static __exit void hardware_unsetup(void)
 {
        int i;
 
-       for (i = 0; i < VMX_BITMAP_NR; i++)
-               free_page((unsigned long)vmx_bitmap[i]);
+       if (enable_shadow_vmcs) {
+               for (i = 0; i < VMX_BITMAP_NR; i++)
+                       free_page((unsigned long)vmx_bitmap[i]);
+       }
 
        free_kvm_area();
 }