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 {