feat(memory share): continue memory retrieve between worlds
Hypervisor can forward retrieve requests to the SPMC in two cases:
- For the retrieve request from the hypervisor, as part of its handling
of the FFA_MEM_RECLAIM to obtain the full memory descriptor, validate it
and conclude the operation.
- For the retrieve request from a NWd VM borrower.
The SPMC distinguishes both cases when the current VM is the
`other_world_vm`. For the first case the retrieve request would have
followed a specific format, whose response needs to be fragmented.
In this case the SPMC would increment the number of fragments retrieved
by the hypervisor. At the handling of FFA_MEM_FRAG_RX, if the counting
of fragments retrieved by the hypervisor is not zero, the SPMC considers
it needs to continue the retrieve operation from the hypervisor,
otherwise continues the retrieve request from the NWd VM.
Change-Id: I4a7ec597d6629fadbc16731037c6015023b19359
Signed-off-by: J-Alves <joao.alves@arm.com>
diff --git a/src/api.c b/src/api.c
index 658ed7c..461fdd3 100644
--- a/src/api.c
+++ b/src/api.c
@@ -3009,7 +3009,7 @@
* Can't retrieve memory information if the mailbox is not
* available.
*/
- dlog_verbose("RX buffer not ready.\n");
+ dlog_verbose("%s: RX buffer not ready.\n", __func__);
ret = ffa_error(FFA_BUSY);
goto out;
}
@@ -3117,8 +3117,11 @@
struct ffa_value ret;
/* Sender ID MBZ at virtual instance. */
- if (sender_vm_id != 0) {
- return ffa_error(FFA_INVALID_PARAMETERS);
+ if (vm_id_is_current_world(to->id)) {
+ if (sender_vm_id != 0) {
+ dlog_verbose("%s: Invalid sender.\n", __func__);
+ return ffa_error(FFA_INVALID_PARAMETERS);
+ }
}
to_locked = vm_lock(to);
@@ -3128,14 +3131,14 @@
* Can't retrieve memory information if the mailbox is not
* available.
*/
- dlog_verbose("RX buffer not ready.\n");
+ dlog_verbose("%s: RX buffer not ready partition %x.\n",
+ __func__, to_locked.vm->id);
ret = ffa_error(FFA_BUSY);
goto out;
}
ret = ffa_memory_retrieve_continue(to_locked, handle, fragment_offset,
- &api_page_pool);
-
+ sender_vm_id, &api_page_pool);
out:
vm_unlock(&to_locked);
return ret;
@@ -3168,6 +3171,7 @@
sl_unlock(&from->lock);
if (from_msg == NULL) {
+ dlog_verbose("Mailbox from %x is not set.\n", from->id);
return ffa_error(FFA_INVALID_PARAMETERS);
}