ANDROID: KVM: arm64: Reland split the host ffa handle store
Reserve an ffa handle entry before we commit the memory transfer to TZ to avoid rolling back the memory transaction with TZ in case we have no space the accomodate the handle. Bug: 440584506 Bug: 357781595 Fixes: Ifbdc82adb2675f5e7d1ee16ec5356c6f24b031bb Change-Id: Ie5307769e5e3913de4b974d8f3d829cacc84aa9e Signed-off-by: Sebastian Ene <sebastianene@google.com> Reported-by: Arve Hjønnevåg <arve@android.com> (cherry picked from commit 6c400c2e2e46f3a1117ce5da316ecdc1dbb1a031) Signed-off-by: Lee Jones <joneslee@google.com>
This commit is contained in:
@@ -113,33 +113,27 @@ static struct kvm_ffa_buffers *ffa_get_buffers(struct pkvm_hyp_vcpu *hyp_vcpu)
|
||||
|
||||
DECLARE_STATIC_KEY_FALSE(kvm_ffa_unmap_on_lend);
|
||||
|
||||
static int ffa_host_store_handle(u64 ffa_handle, bool is_lend)
|
||||
static struct ffa_handle *ffa_host_alloc_handle(void)
|
||||
{
|
||||
u32 i;
|
||||
struct ffa_handle *free_handle = NULL;
|
||||
|
||||
if (!static_branch_unlikely(&kvm_ffa_unmap_on_lend))
|
||||
return 0;
|
||||
struct ffa_handle *handle;
|
||||
|
||||
if (spm_free_handle) {
|
||||
WARN_ON(spm_free_handle < spm_handles ||
|
||||
spm_free_handle >= (spm_handles + num_spm_handles));
|
||||
free_handle = spm_free_handle;
|
||||
handle = spm_free_handle;
|
||||
spm_free_handle = NULL;
|
||||
} else {
|
||||
for (i = 0; i < num_spm_handles; i++)
|
||||
if (spm_handles[i].handle == FFA_INVALID_SPM_HANDLE)
|
||||
break;
|
||||
|
||||
if (i == num_spm_handles)
|
||||
return -ENOSPC;
|
||||
|
||||
free_handle = &spm_handles[i];
|
||||
return handle;
|
||||
}
|
||||
|
||||
free_handle->handle = ffa_handle;
|
||||
free_handle->is_lend = is_lend;
|
||||
return 0;
|
||||
for (i = 0; i < num_spm_handles; i++)
|
||||
if (spm_handles[i].handle == FFA_INVALID_SPM_HANDLE)
|
||||
break;
|
||||
|
||||
if (i == num_spm_handles)
|
||||
return NULL;
|
||||
|
||||
return &spm_handles[i];
|
||||
}
|
||||
|
||||
static struct ffa_handle *ffa_host_get_handle(u64 ffa_handle)
|
||||
@@ -909,6 +903,7 @@ static int __do_ffa_mem_xfer(const u64 func_id,
|
||||
struct ffa_mem_transfer *transfer = NULL;
|
||||
u64 ffa_handle;
|
||||
bool is_lend = func_id == FFA_FN64_MEM_LEND;
|
||||
struct ffa_handle *handle = NULL;
|
||||
|
||||
if (addr_mbz || npages_mbz || fraglen > len ||
|
||||
fraglen > KVM_FFA_MBOX_NR_PAGES * PAGE_SIZE) {
|
||||
@@ -1009,6 +1004,14 @@ static int __do_ffa_mem_xfer(const u64 func_id,
|
||||
if (ret)
|
||||
goto out_unlock;
|
||||
|
||||
if (!hyp_vcpu && static_branch_unlikely(&kvm_ffa_unmap_on_lend)) {
|
||||
handle = ffa_host_alloc_handle();
|
||||
if (!handle) {
|
||||
ret = -ENOSPC;
|
||||
goto out_unlock;
|
||||
}
|
||||
}
|
||||
|
||||
ffa_mem_xfer(res, func_id, len, fraglen);
|
||||
if (fraglen != len) {
|
||||
if (res->a0 != FFA_MEM_FRAG_RX)
|
||||
@@ -1027,10 +1030,9 @@ static int __do_ffa_mem_xfer(const u64 func_id,
|
||||
if (hyp_vcpu && transfer) {
|
||||
transfer->ffa_handle = ffa_handle;
|
||||
list_add(&transfer->node, &ffa_buf->xfer_list);
|
||||
} else if (!hyp_vcpu) {
|
||||
ret = ffa_host_store_handle(ffa_handle, is_lend);
|
||||
if (ret)
|
||||
goto err_unshare;
|
||||
} else if (handle) {
|
||||
handle->handle = ffa_handle;
|
||||
handle->is_lend = is_lend;
|
||||
}
|
||||
hyp_spin_unlock(&kvm_ffa_hyp_lock);
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user