feat(memory share): handle GPF in FFA_MEM_FRAG_RX
In handling the FFA_MEM_FRAG_RX ABI the SPMC copies
memory sharing descriptor fragments to the NWd
RX buffer.
The RX buffer could inadvertently or advertently be put
in the wrong PAS space. This would result in a GPF,
which the SPMC should handle and smoothly return
FFA_ERROR_ABORTED.
Signed-off-by: J-Alves <joao.alves@arm.com>
Change-Id: I63735d5f8cb6a1344323ef768828de053c250ee2
diff --git a/src/api.c b/src/api.c
index f8c3d69..db7c538 100644
--- a/src/api.c
+++ b/src/api.c
@@ -3988,8 +3988,21 @@
goto out;
}
- ret = ffa_memory_retrieve_continue(to_locked, handle, fragment_offset,
- sender_vm_id, &api_page_pool);
+ /*
+ * Whilst copying the fragments, initialize the remaining constituents
+ * in the CPU's internal structure, and later copy from the CPU buffer
+ * into the partition's RX buffer. In the case SPMC is doing a retrieve
+ * request for a VM/Hypervisor in an RME enabled system, there is no
+ * guarantee the RX buffer is in the NS PAS. Accessing the buffer with
+ * the wrong security state attribute would then result in an GPF.
+ * The fragment is initialized in an internal buffer, and is later
+ * copied to the RX buffer using the 'memcpy_trapped' which allows to
+ * smoothly terminate the operation if the access has been preempted by
+ * a GPF exception.
+ */
+ ret = ffa_memory_retrieve_continue(
+ to_locked, handle, fragment_offset, sender_vm_id,
+ cpu_get_buffer(current->cpu), &api_page_pool);
out:
vm_unlock(&to_locked);
return ret;