KVM: x86: Move FPU allocation to common x86 code
authorSean Christopherson <sean.j.christopherson@intel.com>
Wed, 18 Dec 2019 21:54:53 +0000 (13:54 -0800)
committerPaolo Bonzini <pbonzini@redhat.com>
Fri, 24 Jan 2020 08:18:56 +0000 (09:18 +0100)
The allocation of FPU structs is identical across VMX and SVM, move it
to common x86 code.  Somewhat arbitrarily place the allocation so that
it resides directly above the associated initialization via fx_init(),
e.g. instead of retaining its position with respect to the overall vcpu
creation flow.  Although the names names kvm_arch_vcpu_create() and
kvm_arch_vcpu_init() might suggest otherwise, x86 does not have a clean
split between 'create' and 'init'.  Allocating the struct immediately
prior to the first use arguably improves readability *now*, and will
yield even bigger improvements when kvm_arch_vcpu_init() is removed in
a future patch.

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

index 319c487e22223819d76ebc480533c1340ec2d13b..e8a5cd44dd59cab989a03e252b8d044325042290 100644 (file)
@@ -2200,25 +2200,9 @@ static int svm_create_vcpu(struct kvm *kvm, struct kvm_vcpu *vcpu,
        BUILD_BUG_ON(offsetof(struct vcpu_svm, vcpu) != 0);
        svm = to_svm(vcpu);
 
-       vcpu->arch.user_fpu = kmem_cache_zalloc(x86_fpu_cache,
-                                               GFP_KERNEL_ACCOUNT);
-       if (!vcpu->arch.user_fpu) {
-               printk(KERN_ERR "kvm: failed to allocate kvm userspace's fpu\n");
-               err = -ENOMEM;
-               goto out;
-       }
-
-       vcpu->arch.guest_fpu = kmem_cache_zalloc(x86_fpu_cache,
-                                                GFP_KERNEL_ACCOUNT);
-       if (!vcpu->arch.guest_fpu) {
-               printk(KERN_ERR "kvm: failed to allocate vcpu's fpu\n");
-               err = -ENOMEM;
-               goto free_user_fpu;
-       }
-
        err = kvm_vcpu_init(vcpu, kvm, id);
        if (err)
-               goto free_guest_fpu;
+               return err;
 
        err = -ENOMEM;
        page = alloc_page(GFP_KERNEL_ACCOUNT);
@@ -2274,11 +2258,6 @@ free_page1:
        __free_page(page);
 uninit:
        kvm_vcpu_uninit(vcpu);
-free_guest_fpu:
-       kmem_cache_free(x86_fpu_cache, vcpu->arch.guest_fpu);
-free_user_fpu:
-       kmem_cache_free(x86_fpu_cache, vcpu->arch.user_fpu);
-out:
        return err;
 }
 
@@ -2306,8 +2285,6 @@ static void svm_free_vcpu(struct kvm_vcpu *vcpu)
        __free_page(virt_to_page(svm->nested.hsave));
        __free_pages(virt_to_page(svm->nested.msrpm), MSRPM_ALLOC_ORDER);
        kvm_vcpu_uninit(vcpu);
-       kmem_cache_free(x86_fpu_cache, vcpu->arch.user_fpu);
-       kmem_cache_free(x86_fpu_cache, vcpu->arch.guest_fpu);
 }
 
 static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
index 2cbeb0a638aae57238d9d10eb91648d8df488a4a..40c47d2709bb76e82d096c4a68f763e9d658a946 100644 (file)
@@ -6682,8 +6682,6 @@ static void vmx_free_vcpu(struct kvm_vcpu *vcpu)
        nested_vmx_free_vcpu(vcpu);
        free_loaded_vmcs(vmx->loaded_vmcs);
        kvm_vcpu_uninit(vcpu);
-       kmem_cache_free(x86_fpu_cache, vcpu->arch.user_fpu);
-       kmem_cache_free(x86_fpu_cache, vcpu->arch.guest_fpu);
 }
 
 static int vmx_create_vcpu(struct kvm *kvm, struct kvm_vcpu *vcpu,
@@ -6696,25 +6694,9 @@ static int vmx_create_vcpu(struct kvm *kvm, struct kvm_vcpu *vcpu,
        BUILD_BUG_ON(offsetof(struct vcpu_vmx, vcpu) != 0);
        vmx = to_vmx(vcpu);
 
-       vcpu->arch.user_fpu = kmem_cache_zalloc(x86_fpu_cache,
-                                               GFP_KERNEL_ACCOUNT);
-       if (!vcpu->arch.user_fpu) {
-               printk(KERN_ERR "kvm: failed to allocate kvm userspace's fpu\n");
-               err = -ENOMEM;
-               goto out;
-       }
-
-       vcpu->arch.guest_fpu = kmem_cache_zalloc(x86_fpu_cache,
-                                                GFP_KERNEL_ACCOUNT);
-       if (!vcpu->arch.guest_fpu) {
-               printk(KERN_ERR "kvm: failed to allocate vcpu's fpu\n");
-               err = -ENOMEM;
-               goto free_user_fpu;
-       }
-
        err = kvm_vcpu_init(vcpu, kvm, id);
        if (err)
-               goto free_vcpu;
+               return err;
 
        err = -ENOMEM;
 
@@ -6831,11 +6813,6 @@ free_pml:
 uninit_vcpu:
        kvm_vcpu_uninit(vcpu);
        free_vpid(vmx->vpid);
-free_vcpu:
-       kmem_cache_free(x86_fpu_cache, vcpu->arch.guest_fpu);
-free_user_fpu:
-       kmem_cache_free(x86_fpu_cache, vcpu->arch.user_fpu);
-out:
        return err;
 }
 
index cfcefdbe2784699c1f718643fdd44c92b8ab50fc..29d058db3207ca5fec8204a1b66db3e375df6aa6 100644 (file)
@@ -9177,6 +9177,8 @@ void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu)
        kvm_x86_ops->vcpu_free(vcpu);
 
        free_cpumask_var(vcpu->arch.wbinvd_dirty_mask);
+       kmem_cache_free(x86_fpu_cache, vcpu->arch.user_fpu);
+       kmem_cache_free(x86_fpu_cache, vcpu->arch.guest_fpu);
        kmem_cache_free(kvm_vcpu_cache, vcpu);
 }
 
@@ -9543,6 +9545,21 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
                goto fail_free_mce_banks;
        }
 
+       vcpu->arch.user_fpu = kmem_cache_zalloc(x86_fpu_cache,
+                                               GFP_KERNEL_ACCOUNT);
+       if (!vcpu->arch.user_fpu) {
+               pr_err("kvm: failed to allocate userspace's fpu\n");
+               r = -ENOMEM;
+               goto free_wbinvd_dirty_mask;
+       }
+
+       vcpu->arch.guest_fpu = kmem_cache_zalloc(x86_fpu_cache,
+                                                GFP_KERNEL_ACCOUNT);
+       if (!vcpu->arch.guest_fpu) {
+               pr_err("kvm: failed to allocate vcpu's fpu\n");
+               r = -ENOMEM;
+               goto free_user_fpu;
+       }
        fx_init(vcpu);
 
        vcpu->arch.guest_xstate_size = XSAVE_HDR_SIZE + XSAVE_HDR_OFFSET;
@@ -9561,6 +9578,10 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
 
        return 0;
 
+free_user_fpu:
+       kmem_cache_free(x86_fpu_cache, vcpu->arch.user_fpu);
+free_wbinvd_dirty_mask:
+       free_cpumask_var(vcpu->arch.wbinvd_dirty_mask);
 fail_free_mce_banks:
        kfree(vcpu->arch.mce_banks);
 fail_free_lapic: