refactor(memory share): split check of hyp retrieve request
Section 17.4.3 of the FF-A v1.2 ALP0 spec states that the SPM should
distinguish between retrieve request originating from the hypervisor and
one originating from a Borrower VM, forwarded by the Hypervisor by
checking the endpoint memory access descriptor count. For the former
case the count should be 0 otherwise >=1. This patch separates this
check from the validation that the all other fields in the transaction
descriptor, except the handle, are 0.
Signed-off-by: Daniel Boulby <daniel.boulby@arm.com>
Change-Id: I1829069450633db560048cf0bc08d1ad055a8dcc
diff --git a/src/ffa_memory.c b/src/ffa_memory.c
index ef16f56..ca6de33 100644
--- a/src/ffa_memory.c
+++ b/src/ffa_memory.c
@@ -3042,23 +3042,34 @@
return (struct ffa_value){.func = FFA_SUCCESS_32};
}
-/*
- * According to section 16.4.3 of FF-A v1.1 EAC0 specification, the hypervisor
- * may issue an FFA_MEM_RETRIEVE_REQ to obtain the memory region description
- * of a pending memory sharing operation whose allocator is the SPM, for
- * validation purposes before forwarding an FFA_MEM_RECLAIM call. In doing so
- * the memory region descriptor of the retrieve request must be zeroed with the
- * exception of the sender ID and handle.
+/**
+ * According to section 17.4.3 of the FF-A v1.2 ALP0 specification, the
+ * hypervisor may issue an FFA_MEM_RETRIEVE_REQ to obtain the memory region
+ * description of a pending memory sharing operation whose allocator is the SPM,
+ * for validation purposes before forwarding an FFA_MEM_RECLAIM call. For a
+ * hypervisor retrieve request the endpoint memory access descriptor count must
+ * be 0 (for any other retrieve request it must be >= 1).
*/
-bool is_ffa_hypervisor_retrieve_request(struct ffa_memory_region *request,
- struct vm_locked to_locked)
+bool is_ffa_hypervisor_retrieve_request(struct ffa_memory_region *request)
{
- return to_locked.vm->id == HF_HYPERVISOR_VM_ID &&
+ return request->receiver_count == 0U;
+}
+
+/**
+ * An FFA_MEM_RETRIEVE_REQ from the hypervisor must specify the handle of the
+ * memory transaction it is querying and all other fields must be 0.
+ */
+static bool ffa_memory_hypervisor_retrieve_request_validate(
+ struct ffa_memory_region *request)
+{
+ return request->sender == 0U &&
request->attributes.shareability == 0U &&
request->attributes.cacheability == 0U &&
request->attributes.type == 0U &&
request->attributes.security == 0U && request->flags == 0U &&
- request->tag == 0U && request->receiver_count == 0U &&
+ request->tag == 0U && request->memory_access_desc_size == 0U &&
+ request->receiver_count == 0U &&
+ request->receivers_offset == 0U &&
plat_ffa_memory_handle_allocated_by_current_world(
request->handle);
}
@@ -3593,7 +3604,16 @@
goto out;
}
- if (is_ffa_hypervisor_retrieve_request(retrieve_request, to_locked)) {
+ if (is_ffa_hypervisor_retrieve_request(retrieve_request)) {
+ if (!ffa_memory_hypervisor_retrieve_request_validate(
+ retrieve_request)) {
+ dlog_verbose(
+ "All fields except the handle in the "
+ "memory access descriptor must be zero for a "
+ "hypervisor retrieve request.\n");
+ ret = ffa_error(FFA_INVALID_PARAMETERS);
+ goto out;
+ }
ret = ffa_hypervisor_retrieve_request(share_state, to_locked,
retrieve_request);
} else {