lkml.org 
[lkml]   [2021]   [Jun]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.12 101/110] KVM: SVM: Call SEV Guest Decommission if ASID binding fails
    Date
    From: Alper Gun <alpergun@google.com>

    commit 934002cd660b035b926438244b4294e647507e13 upstream.

    Send SEV_CMD_DECOMMISSION command to PSP firmware if ASID binding
    fails. If a failure happens after a successful LAUNCH_START command,
    a decommission command should be executed. Otherwise, guest context
    will be unfreed inside the AMD SP. After the firmware will not have
    memory to allocate more SEV guest context, LAUNCH_START command will
    begin to fail with SEV_RET_RESOURCE_LIMIT error.

    The existing code calls decommission inside sev_unbind_asid, but it is
    not called if a failure happens before guest activation succeeds. If
    sev_bind_asid fails, decommission is never called. PSP firmware has a
    limit for the number of guests. If sev_asid_binding fails many times,
    PSP firmware will not have resources to create another guest context.

    Cc: stable@vger.kernel.org
    Fixes: 59414c989220 ("KVM: SVM: Add support for KVM_SEV_LAUNCH_START command")
    Reported-by: Peter Gonda <pgonda@google.com>
    Signed-off-by: Alper Gun <alpergun@google.com>
    Reviewed-by: Marc Orr <marcorr@google.com>
    Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
    Message-Id: <20210610174604.2554090-1-alpergun@google.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    arch/x86/kvm/svm/sev.c | 32 +++++++++++++++++++++-----------
    1 file changed, 21 insertions(+), 11 deletions(-)

    diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
    index dbc6214d69de..8f3b438f6fd3 100644
    --- a/arch/x86/kvm/svm/sev.c
    +++ b/arch/x86/kvm/svm/sev.c
    @@ -143,9 +143,25 @@ static void sev_asid_free(int asid)
    mutex_unlock(&sev_bitmap_lock);
    }

    -static void sev_unbind_asid(struct kvm *kvm, unsigned int handle)
    +static void sev_decommission(unsigned int handle)
    {
    struct sev_data_decommission *decommission;
    +
    + if (!handle)
    + return;
    +
    + decommission = kzalloc(sizeof(*decommission), GFP_KERNEL);
    + if (!decommission)
    + return;
    +
    + decommission->handle = handle;
    + sev_guest_decommission(decommission, NULL);
    +
    + kfree(decommission);
    +}
    +
    +static void sev_unbind_asid(struct kvm *kvm, unsigned int handle)
    +{
    struct sev_data_deactivate *data;

    if (!handle)
    @@ -165,15 +181,7 @@ static void sev_unbind_asid(struct kvm *kvm, unsigned int handle)

    kfree(data);

    - decommission = kzalloc(sizeof(*decommission), GFP_KERNEL);
    - if (!decommission)
    - return;
    -
    - /* decommission handle */
    - decommission->handle = handle;
    - sev_guest_decommission(decommission, NULL);
    -
    - kfree(decommission);
    + sev_decommission(handle);
    }

    static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp)
    @@ -303,8 +311,10 @@ static int sev_launch_start(struct kvm *kvm, struct kvm_sev_cmd *argp)

    /* Bind ASID to this guest */
    ret = sev_bind_asid(kvm, start->handle, error);
    - if (ret)
    + if (ret) {
    + sev_decommission(start->handle);
    goto e_free_session;
    + }

    /* return handle to userspace */
    params.handle = start->handle;
    --
    2.30.2
    \
     
     \ /
      Last update: 2021-06-28 16:29    [W:2.473 / U:0.132 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site