提交 c395d904 编写于 作者: A Alper Gun 提交者: Zheng Zengkai

KVM: SVM: Call SEV Guest Decommission if ASID binding fails

stable inclusion
from stable-5.10.47
commit 7570a8b5dd493eebda5c0c826f3a87e2e6117791
bugzilla: 172973 https://gitee.com/openeuler/kernel/issues/I4DAKB

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=7570a8b5dd493eebda5c0c826f3a87e2e6117791

--------------------------------

commit 934002cd 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: 59414c98 ("KVM: SVM: Add support for KVM_SEV_LAUNCH_START command")
Reported-by: NPeter Gonda <pgonda@google.com>
Signed-off-by: NAlper Gun <alpergun@google.com>
Reviewed-by: NMarc Orr <marcorr@google.com>
Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
Message-Id: <20210610174604.2554090-1-alpergun@google.com>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: NChen Jun <chenjun102@huawei.com>
Acked-by: NWeilong Chen <chenweilong@huawei.com>
Signed-off-by: NChen Jun <chenjun102@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 f65fc2e9
...@@ -130,9 +130,25 @@ static void sev_asid_free(int asid) ...@@ -130,9 +130,25 @@ static void sev_asid_free(int asid)
mutex_unlock(&sev_bitmap_lock); 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; 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; struct sev_data_deactivate *data;
if (!handle) if (!handle)
...@@ -152,15 +168,7 @@ static void sev_unbind_asid(struct kvm *kvm, unsigned int handle) ...@@ -152,15 +168,7 @@ static void sev_unbind_asid(struct kvm *kvm, unsigned int handle)
kfree(data); kfree(data);
decommission = kzalloc(sizeof(*decommission), GFP_KERNEL); sev_decommission(handle);
if (!decommission)
return;
/* decommission handle */
decommission->handle = handle;
sev_guest_decommission(decommission, NULL);
kfree(decommission);
} }
static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp) static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp)
...@@ -288,8 +296,10 @@ static int sev_launch_start(struct kvm *kvm, struct kvm_sev_cmd *argp) ...@@ -288,8 +296,10 @@ static int sev_launch_start(struct kvm *kvm, struct kvm_sev_cmd *argp)
/* Bind ASID to this guest */ /* Bind ASID to this guest */
ret = sev_bind_asid(kvm, start->handle, error); ret = sev_bind_asid(kvm, start->handle, error);
if (ret) if (ret) {
sev_decommission(start->handle);
goto e_free_session; goto e_free_session;
}
/* return handle to userspace */ /* return handle to userspace */
params.handle = start->handle; params.handle = start->handle;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册