]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
KVM: SVM: do not allocate struct svm_cpu_data dynamically
authorPaolo Bonzini <pbonzini@redhat.com>
Wed, 9 Nov 2022 14:07:55 +0000 (09:07 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 26 Nov 2022 08:27:23 +0000 (09:27 +0100)
[ Upstream commit 73412dfeea724e6bd775ba64d21157ff322eac9a ]

The svm_data percpu variable is a pointer, but it is allocated via
svm_hardware_setup() when KVM is loaded.  Unlike hardware_enable()
this means that it is never NULL for the whole lifetime of KVM, and
static allocation does not waste any memory compared to the status quo.
It is also more efficient and more easily handled from assembly code,
so do it and don't look back.

Reviewed-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Stable-dep-of: e287bd005ad9 ("KVM: SVM: restore host save area from assembly")
Signed-off-by: Sasha Levin <sashal@kernel.org>
arch/x86/kvm/svm/sev.c
arch/x86/kvm/svm/svm.c
arch/x86/kvm/svm/svm.h

index c9c9bd453a97d2c5159ffb859a2d4b5f63316e93..efaaef2b7ae11b280da39abf027107ed242fd1b2 100644 (file)
@@ -196,7 +196,7 @@ static void sev_asid_free(struct kvm_sev_info *sev)
        __set_bit(sev->asid, sev_reclaim_asid_bitmap);
 
        for_each_possible_cpu(cpu) {
-               sd = per_cpu(svm_data, cpu);
+               sd = per_cpu_ptr(&svm_data, cpu);
                sd->sev_vmcbs[sev->asid] = NULL;
        }
 
@@ -2600,7 +2600,7 @@ void sev_es_unmap_ghcb(struct vcpu_svm *svm)
 
 void pre_sev_run(struct vcpu_svm *svm, int cpu)
 {
-       struct svm_cpu_data *sd = per_cpu(svm_data, cpu);
+       struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, cpu);
        int asid = sev_get_asid(svm->vcpu.kvm);
 
        /* Assign the asid allocated with this SEV guest */
index ecf4d8233e49e0e77975a450ebf681faed73df6f..6b2f332f5d54b8feb84479e490b02a5c7eeed5a3 100644 (file)
@@ -245,7 +245,7 @@ struct kvm_ldttss_desc {
        u32 zero1;
 } __attribute__((packed));
 
-DEFINE_PER_CPU(struct svm_cpu_data *, svm_data);
+DEFINE_PER_CPU(struct svm_cpu_data, svm_data);
 
 /*
  * Only MSR_TSC_AUX is switched via the user return hook.  EFER is switched via
@@ -583,12 +583,7 @@ static int svm_hardware_enable(void)
                pr_err("%s: err EOPNOTSUPP on %d\n", __func__, me);
                return -EINVAL;
        }
-       sd = per_cpu(svm_data, me);
-       if (!sd) {
-               pr_err("%s: svm_data is NULL on %d\n", __func__, me);
-               return -EINVAL;
-       }
-
+       sd = per_cpu_ptr(&svm_data, me);
        sd->asid_generation = 1;
        sd->max_asid = cpuid_ebx(SVM_CPUID_FUNC) - 1;
        sd->next_asid = sd->max_asid + 1;
@@ -648,41 +643,35 @@ static int svm_hardware_enable(void)
 
 static void svm_cpu_uninit(int cpu)
 {
-       struct svm_cpu_data *sd = per_cpu(svm_data, cpu);
+       struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, cpu);
 
-       if (!sd)
+       if (!sd->save_area)
                return;
 
-       per_cpu(svm_data, cpu) = NULL;
        kfree(sd->sev_vmcbs);
        __free_page(sd->save_area);
-       kfree(sd);
+       sd->save_area = NULL;
 }
 
 static int svm_cpu_init(int cpu)
 {
-       struct svm_cpu_data *sd;
+       struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, cpu);
        int ret = -ENOMEM;
 
-       sd = kzalloc(sizeof(struct svm_cpu_data), GFP_KERNEL);
-       if (!sd)
-               return ret;
+       memset(sd, 0, sizeof(struct svm_cpu_data));
        sd->save_area = alloc_page(GFP_KERNEL | __GFP_ZERO);
        if (!sd->save_area)
-               goto free_cpu_data;
+               return ret;
 
        ret = sev_cpu_init(sd);
        if (ret)
                goto free_save_area;
 
-       per_cpu(svm_data, cpu) = sd;
-
        return 0;
 
 free_save_area:
        __free_page(sd->save_area);
-free_cpu_data:
-       kfree(sd);
+       sd->save_area = NULL;
        return ret;
 
 }
@@ -1426,7 +1415,7 @@ static void svm_clear_current_vmcb(struct vmcb *vmcb)
        int i;
 
        for_each_online_cpu(i)
-               cmpxchg(&per_cpu(svm_data, i)->current_vmcb, vmcb, NULL);
+               cmpxchg(per_cpu_ptr(&svm_data.current_vmcb, i), vmcb, NULL);
 }
 
 static void svm_vcpu_free(struct kvm_vcpu *vcpu)
@@ -1451,7 +1440,7 @@ static void svm_vcpu_free(struct kvm_vcpu *vcpu)
 static void svm_prepare_switch_to_guest(struct kvm_vcpu *vcpu)
 {
        struct vcpu_svm *svm = to_svm(vcpu);
-       struct svm_cpu_data *sd = per_cpu(svm_data, vcpu->cpu);
+       struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, vcpu->cpu);
 
        if (sev_es_guest(vcpu->kvm))
                sev_es_unmap_ghcb(svm);
@@ -1488,7 +1477,7 @@ static void svm_prepare_host_switch(struct kvm_vcpu *vcpu)
 static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 {
        struct vcpu_svm *svm = to_svm(vcpu);
-       struct svm_cpu_data *sd = per_cpu(svm_data, cpu);
+       struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, cpu);
 
        if (sd->current_vmcb != svm->vmcb) {
                sd->current_vmcb = svm->vmcb;
@@ -3443,7 +3432,7 @@ static int svm_handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath)
 
 static void reload_tss(struct kvm_vcpu *vcpu)
 {
-       struct svm_cpu_data *sd = per_cpu(svm_data, vcpu->cpu);
+       struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, vcpu->cpu);
 
        sd->tss_desc->type = 9; /* available 32/64-bit TSS */
        load_TR_desc();
@@ -3451,7 +3440,7 @@ static void reload_tss(struct kvm_vcpu *vcpu)
 
 static void pre_svm_run(struct kvm_vcpu *vcpu)
 {
-       struct svm_cpu_data *sd = per_cpu(svm_data, vcpu->cpu);
+       struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, vcpu->cpu);
        struct vcpu_svm *svm = to_svm(vcpu);
 
        /*
@@ -3920,7 +3909,7 @@ static noinstr void svm_vcpu_enter_exit(struct kvm_vcpu *vcpu)
        if (sev_es_guest(vcpu->kvm)) {
                __svm_sev_es_vcpu_run(svm);
        } else {
-               struct svm_cpu_data *sd = per_cpu(svm_data, vcpu->cpu);
+               struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, vcpu->cpu);
 
                __svm_vcpu_run(svm);
                vmload(__sme_page_pa(sd->save_area));
index 8a8894d948a029aead747ef98ed44f4ee80df1a4..f1483209e186b2a32e68d92f61a96fb4e09f7077 100644 (file)
@@ -294,7 +294,7 @@ struct svm_cpu_data {
        struct vmcb **sev_vmcbs;
 };
 
-DECLARE_PER_CPU(struct svm_cpu_data *, svm_data);
+DECLARE_PER_CPU(struct svm_cpu_data, svm_data);
 
 void recalc_intercepts(struct vcpu_svm *svm);