feat(memory share): send multiple receiver regions

Updates `memory_init_and_send` to allow passing more than one receiver.
Tests for this functionality will be added in the next commit.

Change-Id: I51d92d74f64bfebfa3d49ff6d5066050087b44ef
Signed-off-by: Karl Meakin <karl.meakin@arm.com>
diff --git a/include/runtime_services/ffa_helpers.h b/include/runtime_services/ffa_helpers.h
index 90bb30f..f265fe8 100644
--- a/include/runtime_services/ffa_helpers.h
+++ b/include/runtime_services/ffa_helpers.h
@@ -641,9 +641,8 @@
 
 uint32_t ffa_memory_retrieve_request_init(
 	struct ffa_memory_region *memory_region, ffa_memory_handle_t handle,
-	ffa_id_t sender, ffa_id_t receiver, uint32_t tag,
-	ffa_memory_region_flags_t flags, enum ffa_data_access data_access,
-	enum ffa_instruction_access instruction_access,
+	ffa_id_t sender, struct ffa_memory_access receivers[],
+	uint32_t receiver_count, uint32_t tag, ffa_memory_region_flags_t flags,
 	enum ffa_memory_type type, enum ffa_memory_cacheability cacheability,
 	enum ffa_memory_shareability shareability);
 
@@ -652,12 +651,12 @@
 
 uint32_t ffa_memory_region_init(
 	struct ffa_memory_region *memory_region, size_t memory_region_max_size,
-	ffa_id_t sender, ffa_id_t receiver,
+	ffa_id_t sender, struct ffa_memory_access receivers[],
+	uint32_t receiver_count,
 	const struct ffa_memory_region_constituent constituents[],
 	uint32_t constituent_count, uint32_t tag,
-	ffa_memory_region_flags_t flags, enum ffa_data_access data_access,
-	enum ffa_instruction_access instruction_access,
-	enum ffa_memory_type type, enum ffa_memory_cacheability cacheability,
+	ffa_memory_region_flags_t flags, enum ffa_memory_type type,
+	enum ffa_memory_cacheability cacheability,
 	enum ffa_memory_shareability shareability, uint32_t *total_length,
 	uint32_t *fragment_length);
 
diff --git a/include/runtime_services/spm_common.h b/include/runtime_services/spm_common.h
index e9c845d..6494947 100644
--- a/include/runtime_services/spm_common.h
+++ b/include/runtime_services/spm_common.h
@@ -109,8 +109,9 @@
  */
 bool memory_retrieve(struct mailbox_buffers *mb,
 		     struct ffa_memory_region **retrieved, uint64_t handle,
-		     ffa_id_t sender, ffa_id_t receiver,
-		     ffa_memory_region_flags_t flags, uint32_t mem_func);
+		     ffa_id_t sender, struct ffa_memory_access receivers[],
+		     uint32_t receiver_count, ffa_memory_region_flags_t flags,
+		     uint32_t mem_func);
 
 bool hypervisor_retrieve_request(struct mailbox_buffers *mb, uint64_t handle,
 				 void *out, uint32_t out_size);
@@ -128,8 +129,9 @@
 
 ffa_memory_handle_t memory_init_and_send(
 	struct ffa_memory_region *memory_region, size_t memory_region_max_size,
-	ffa_id_t sender, ffa_id_t receiver,
-	const struct ffa_memory_region_constituent* constituents,
+	ffa_id_t sender, struct ffa_memory_access receivers[],
+	uint32_t receiver_count,
+	const struct ffa_memory_region_constituent *constituents,
 	uint32_t constituents_count, uint32_t mem_func, struct ffa_value *ret);
 
 bool ffa_partition_info_helper(struct mailbox_buffers *mb,
diff --git a/spm/cactus/cactus_tests/cactus_test_memory_sharing.c b/spm/cactus/cactus_tests/cactus_test_memory_sharing.c
index 294f577..ef49d21 100644
--- a/spm/cactus/cactus_tests/cactus_test_memory_sharing.c
+++ b/spm/cactus/cactus_tests/cactus_test_memory_sharing.c
@@ -81,8 +81,16 @@
 					 cactus_mem_send_get_retrv_flags(*args);
 	uint32_t words_to_write = cactus_mem_send_words_to_write(*args);
 
-	expect(memory_retrieve(mb, &m, handle, source, vm_id,
-			       retrv_flags, mem_func), true);
+	struct ffa_memory_access receiver = ffa_memory_access_init_permissions(
+		vm_id, FFA_DATA_ACCESS_RW,
+		(mem_func == FFA_MEM_SHARE_SMC32)
+			? FFA_INSTRUCTION_ACCESS_NOT_SPECIFIED
+			: FFA_INSTRUCTION_ACCESS_NX,
+		0);
+
+	expect(memory_retrieve(mb, &m, handle, source, &receiver, 1,
+			       retrv_flags, mem_func),
+	       true);
 
 	composite = ffa_memory_region_get_composite(m, 0);
 
@@ -180,7 +188,7 @@
 {
 	struct ffa_value ffa_ret;
 	uint32_t mem_func = cactus_req_mem_send_get_mem_func(*args);
-	ffa_id_t receiver = cactus_req_mem_send_get_receiver(*args);
+	ffa_id_t receiver_id = cactus_req_mem_send_get_receiver(*args);
 	ffa_memory_handle_t handle;
 	ffa_id_t vm_id = ffa_dir_msg_dest(*args);
 	ffa_id_t source = ffa_dir_msg_source(*args);
@@ -190,6 +198,10 @@
 	unsigned int mem_attrs;
 	int ret;
 
+	struct ffa_memory_access receiver =
+		ffa_memory_access_init_permissions_from_mem_func(receiver_id,
+								 mem_func);
+
 	VERBOSE("%x requested to send memory to %x (func: %x), page: %llx\n",
 		source, receiver, mem_func, (uint64_t)share_page_addr);
 
@@ -220,10 +232,10 @@
 					 CACTUS_ERROR_TEST);
 	}
 
-	handle = memory_init_and_send(
-		(struct ffa_memory_region *)mb->send, PAGE_SIZE,
-		vm_id, receiver, constituents,
-		constituents_count, mem_func, &ffa_ret);
+	handle = memory_init_and_send((struct ffa_memory_region *)mb->send,
+				      PAGE_SIZE, vm_id, &receiver, 1,
+				      constituents, constituents_count,
+				      mem_func, &ffa_ret);
 
 	/*
 	 * If returned an invalid handle, we should break the test.
@@ -234,8 +246,8 @@
 					 ffa_error_code(ffa_ret));
 	}
 
-	ffa_ret = cactus_mem_send_cmd(vm_id, receiver, mem_func, handle,
-				      0, 10);
+	ffa_ret = cactus_mem_send_cmd(vm_id, receiver_id, mem_func, handle, 0,
+				      10);
 
 	if (!is_ffa_direct_response(ffa_ret)) {
 		return cactus_error_resp(vm_id, source, CACTUS_ERROR_FFA_CALL);
diff --git a/tftf/tests/misc_tests/test_invalid_access.c b/tftf/tests/misc_tests/test_invalid_access.c
index 343a553..353162b 100644
--- a/tftf/tests/misc_tests/test_invalid_access.c
+++ b/tftf/tests/misc_tests/test_invalid_access.c
@@ -1,9 +1,10 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include "ffa_helpers.h"
 #include <plat/common/platform.h>
 
 #include <arch.h>
@@ -293,6 +294,10 @@
 	struct mailbox_buffers mb;
 	struct ffa_value ret;
 
+	struct ffa_memory_access receiver =
+		ffa_memory_access_init_permissions_from_mem_func(
+			RECEIVER, FFA_MEM_SHARE_SMC32);
+
 	if (get_armv9_2_feat_rme_support() == 0U) {
 		return TEST_RESULT_SKIPPED;
 	}
@@ -302,9 +307,9 @@
 	GET_TFTF_MAILBOX(mb);
 
 	handle = memory_init_and_send((struct ffa_memory_region *)mb.send,
-					PAGE_SIZE, SENDER, RECEIVER,
-					constituents, constituents_count,
-					FFA_MEM_SHARE_SMC32, &ret);
+				      PAGE_SIZE, SENDER, &receiver, 1,
+				      constituents, constituents_count,
+				      FFA_MEM_SHARE_SMC32, &ret);
 
 	if (handle == FFA_MEMORY_HANDLE_INVALID) {
 		return TEST_RESULT_SUCCESS;
diff --git a/tftf/tests/runtime_services/secure_service/ffa_helpers.c b/tftf/tests/runtime_services/secure_service/ffa_helpers.c
index e5f93f1..82413a2 100644
--- a/tftf/tests/runtime_services/secure_service/ffa_helpers.c
+++ b/tftf/tests/runtime_services/secure_service/ffa_helpers.c
@@ -142,16 +142,12 @@
 	return ffa_service_call(&args);
 }
 
-
-/**
- * Initialises the header of the given `ffa_memory_region`, not including the
- * composite memory region offset.
- */
-static void ffa_memory_region_init_header(
-	struct ffa_memory_region *memory_region, ffa_id_t sender,
-	ffa_memory_attributes_t attributes, ffa_memory_region_flags_t flags,
-	ffa_memory_handle_t handle, uint32_t tag, ffa_id_t receiver,
-	ffa_memory_access_permissions_t permissions)
+void ffa_memory_region_init_header(struct ffa_memory_region *memory_region,
+				   ffa_id_t sender,
+				   ffa_memory_attributes_t attributes,
+				   ffa_memory_region_flags_t flags,
+				   ffa_memory_handle_t handle, uint32_t tag,
+				   uint32_t receiver_count)
 {
 	memory_region->sender = sender;
 	memory_region->attributes = attributes;
@@ -160,66 +156,47 @@
 	memory_region->tag = tag;
 	memory_region->memory_access_desc_size =
 		sizeof(struct ffa_memory_access);
-	memory_region->receiver_count = 1;
-	memory_region->receivers[0].receiver_permissions.receiver = receiver;
-	memory_region->receivers[0].receiver_permissions.permissions =
-		permissions;
-	memory_region->receivers[0].receiver_permissions.flags = 0;
-	memory_region->receivers[0].reserved_0 = 0;
-	/* Receivers at the end of the `ffa_memory_region` structure. */
-	memory_region->receivers_offset = sizeof(struct ffa_memory_region);
+	memory_region->receiver_count = receiver_count;
+	memory_region->receivers_offset =
+		offsetof(struct ffa_memory_region, receivers);
 	memset(memory_region->reserved, 0, sizeof(memory_region->reserved));
 }
 
 /**
- * Initialises the given `ffa_memory_region` and copies as many as possible of
- * the given constituents to it.
+ * Copies as many as possible of the given constituents to the respective
+ * memory region and sets the respective offset.
  *
  * Returns the number of constituents remaining which wouldn't fit, and (via
  * return parameters) the size in bytes of the first fragment of data copied to
  * `memory_region` (attributes, constituents and memory region header size), and
  * the total size of the memory sharing message including all constituents.
  */
-uint32_t ffa_memory_region_init(
+static uint32_t ffa_memory_region_init_constituents(
 	struct ffa_memory_region *memory_region, size_t memory_region_max_size,
-	ffa_id_t sender, ffa_id_t receiver,
 	const struct ffa_memory_region_constituent constituents[],
-	uint32_t constituent_count, uint32_t tag,
-	ffa_memory_region_flags_t flags, enum ffa_data_access data_access,
-	enum ffa_instruction_access instruction_access,
-	enum ffa_memory_type type, enum ffa_memory_cacheability cacheability,
-	enum ffa_memory_shareability shareability, uint32_t *total_length,
+	uint32_t constituent_count, uint32_t *total_length,
 	uint32_t *fragment_length)
 {
 	struct ffa_composite_memory_region *composite_memory_region;
 	uint32_t fragment_max_constituents;
-	uint32_t count_to_copy;
-	uint32_t i;
 	uint32_t constituents_offset;
+	uint32_t count_to_copy;
 
-	ffa_memory_access_permissions_t permissions = {
-		.data_access = data_access,
-		.instruction_access = instruction_access,
-	};
-	ffa_memory_attributes_t attributes = {
-		.type = type,
-		.cacheability = cacheability,
-		.shareability = shareability,
-	};
-
-	ffa_memory_region_init_header(memory_region, sender, attributes, flags,
-				      0, tag, receiver, permissions);
 	/*
 	 * Note that `sizeof(struct_ffa_memory_region)` and `sizeof(struct
 	 * ffa_memory_access)` must both be multiples of 16 (as verified by the
 	 * asserts in `ffa_memory.c`, so it is guaranteed that the offset we
 	 * calculate here is aligned to a 64-bit boundary and so 64-bit values
 	 * can be copied without alignment faults.
+	 * If there are multiple receiver endpoints, their respective access
+	 * structure should point to the same offset value.
 	 */
-	memory_region->receivers[0].composite_memory_region_offset =
-		sizeof(struct ffa_memory_region) +
-		memory_region->receiver_count *
-			sizeof(struct ffa_memory_access);
+	for (uint32_t i = 0; i < memory_region->receiver_count; i++) {
+		memory_region->receivers[i].composite_memory_region_offset =
+			sizeof(struct ffa_memory_region) +
+			memory_region->receiver_count *
+				sizeof(struct ffa_memory_access);
+	}
 
 	composite_memory_region =
 		ffa_memory_region_get_composite(memory_region, 0);
@@ -239,7 +216,7 @@
 		count_to_copy = fragment_max_constituents;
 	}
 
-	for (i = 0; i < constituent_count; ++i) {
+	for (uint32_t i = 0; i < constituent_count; ++i) {
 		if (i < count_to_copy) {
 			composite_memory_region->constituents[i] =
 				constituents[i];
@@ -267,22 +244,25 @@
 /**
  * Initialises the given `ffa_memory_region` to be used for an
  * `FFA_MEM_RETRIEVE_REQ` by the receiver of a memory transaction.
+ * Initialises the given `ffa_memory_region` and copies as many as possible of
+ * the given constituents to it.
  *
- * Returns the size of the message written.
+ * Returns the number of constituents remaining which wouldn't fit, and (via
+ * return parameters) the size in bytes of the first fragment of data copied to
+ * `memory_region` (attributes, constituents and memory region header size), and
+ * the total size of the memory sharing message including all constituents.
  */
-uint32_t ffa_memory_retrieve_request_init(
-	struct ffa_memory_region *memory_region, ffa_memory_handle_t handle,
-	ffa_id_t sender, ffa_id_t receiver, uint32_t tag,
-	ffa_memory_region_flags_t flags, enum ffa_data_access data_access,
-	enum ffa_instruction_access instruction_access,
-	enum ffa_memory_type type, enum ffa_memory_cacheability cacheability,
-	enum ffa_memory_shareability shareability)
+uint32_t ffa_memory_region_init(
+	struct ffa_memory_region *memory_region, size_t memory_region_max_size,
+	ffa_id_t sender, struct ffa_memory_access receivers[],
+	uint32_t receiver_count,
+	const struct ffa_memory_region_constituent constituents[],
+	uint32_t constituent_count, uint32_t tag,
+	ffa_memory_region_flags_t flags, enum ffa_memory_type type,
+	enum ffa_memory_cacheability cacheability,
+	enum ffa_memory_shareability shareability, uint32_t *total_length,
+	uint32_t *fragment_length)
 {
-	ffa_memory_access_permissions_t permissions = {
-		.data_access = data_access,
-		.instruction_access = instruction_access,
-	};
-
 	ffa_memory_attributes_t attributes = {
 		.type = type,
 		.cacheability = cacheability,
@@ -290,14 +270,50 @@
 	};
 
 	ffa_memory_region_init_header(memory_region, sender, attributes, flags,
-					handle, tag, receiver, permissions);
+				      0, tag, receiver_count);
+
+	memcpy(memory_region->receivers, receivers,
+	       receiver_count * sizeof(struct ffa_memory_access));
+
+	return ffa_memory_region_init_constituents(
+		memory_region, memory_region_max_size, constituents,
+		constituent_count, total_length, fragment_length);
+}
+
+/**
+ * Initialises the given `ffa_memory_region` to be used for an
+ * `FFA_MEM_RETRIEVE_REQ` by the receiver of a memory transaction.
+ *
+ * Returns the size of the message written.
+ */
+uint32_t ffa_memory_retrieve_request_init(
+	struct ffa_memory_region *memory_region, ffa_memory_handle_t handle,
+	ffa_id_t sender, struct ffa_memory_access receivers[],
+	uint32_t receiver_count, uint32_t tag, ffa_memory_region_flags_t flags,
+	enum ffa_memory_type type, enum ffa_memory_cacheability cacheability,
+	enum ffa_memory_shareability shareability)
+{
+	ffa_memory_attributes_t attributes = {
+		.type = type,
+		.cacheability = cacheability,
+		.shareability = shareability,
+	};
+
+	ffa_memory_region_init_header(memory_region, sender, attributes, flags,
+				      handle, tag, receiver_count);
+
+	memcpy(memory_region->receivers, receivers,
+	       receiver_count * sizeof(struct ffa_memory_access));
+
 	/*
 	 * Offset 0 in this case means that the hypervisor should allocate the
 	 * address ranges. This is the only configuration supported by Hafnium,
 	 * as it enforces 1:1 mappings in the stage 2 page tables.
 	 */
-	memory_region->receivers[0].composite_memory_region_offset = 0;
-	memory_region->receivers[0].reserved_0 = 0;
+	for (uint32_t i = 0; i < receiver_count; i++) {
+		memory_region->receivers[i].composite_memory_region_offset = 0;
+		memory_region->receivers[i].reserved_0 = 0;
+	}
 
 	return sizeof(struct ffa_memory_region) +
 	       memory_region->receiver_count * sizeof(struct ffa_memory_access);
diff --git a/tftf/tests/runtime_services/secure_service/spm_common.c b/tftf/tests/runtime_services/secure_service/spm_common.c
index c4323e0..e75be35 100644
--- a/tftf/tests/runtime_services/secure_service/spm_common.c
+++ b/tftf/tests/runtime_services/secure_service/spm_common.c
@@ -211,18 +211,14 @@
 
 bool memory_retrieve(struct mailbox_buffers *mb,
 		     struct ffa_memory_region **retrieved, uint64_t handle,
-		     ffa_id_t sender, ffa_id_t receiver,
-		     ffa_memory_region_flags_t flags,
+		     ffa_id_t sender, struct ffa_memory_access receivers[],
+		     uint32_t receiver_count, ffa_memory_region_flags_t flags,
 		     uint32_t mem_func)
 {
 	struct ffa_value ret;
 	uint32_t fragment_size;
 	uint32_t total_size;
 	uint32_t descriptor_size;
-	const enum ffa_instruction_access inst_access =
-				(mem_func == FFA_MEM_SHARE_SMC32)
-					? FFA_INSTRUCTION_ACCESS_NOT_SPECIFIED
-					: FFA_INSTRUCTION_ACCESS_NX;
 
 	if (retrieved == NULL || mb == NULL) {
 		ERROR("Invalid parameters!\n");
@@ -230,12 +226,9 @@
 	}
 
 	descriptor_size = ffa_memory_retrieve_request_init(
-	    mb->send, handle, sender, receiver, 0, flags,
-	    FFA_DATA_ACCESS_RW,
-	    inst_access,
-	    FFA_MEMORY_NORMAL_MEM,
-	    FFA_MEMORY_CACHE_WRITE_BACK,
-	    FFA_MEMORY_INNER_SHAREABLE);
+		mb->send, handle, sender, receivers, receiver_count, 0, flags,
+		FFA_MEMORY_NORMAL_MEM, FFA_MEMORY_CACHE_WRITE_BACK,
+		FFA_MEMORY_INNER_SHAREABLE);
 
 	ret = ffa_mem_retrieve_req(descriptor_size, descriptor_size);
 
@@ -422,7 +415,8 @@
  */
 ffa_memory_handle_t memory_init_and_send(
 	struct ffa_memory_region *memory_region, size_t memory_region_max_size,
-	ffa_id_t sender, ffa_id_t receiver,
+	ffa_id_t sender, struct ffa_memory_access receivers[],
+	uint32_t receiver_count,
 	const struct ffa_memory_region_constituent *constituents,
 	uint32_t constituents_count, uint32_t mem_func, struct ffa_value *ret)
 {
@@ -430,23 +424,14 @@
 	uint32_t total_length;
 	uint32_t fragment_length;
 
-	enum ffa_data_access data_access = (mem_func == FFA_MEM_DONATE_SMC32) ?
-						FFA_DATA_ACCESS_NOT_SPECIFIED :
-						FFA_DATA_ACCESS_RW;
+	enum ffa_memory_type type =
+		(receiver_count == 1 && mem_func != FFA_MEM_SHARE_SMC32)
+			? FFA_MEMORY_NOT_SPECIFIED_MEM
+			: FFA_MEMORY_NORMAL_MEM;
 
-	/*
-	 * Initialize memory region structure for the respective memory send
-	 * operation. Note that memory type shall only be specified for memory
-	 * share, for memory lend and memory donate these shall remain
-	 * unspecified.
-	 */
 	remaining_constituent_count = ffa_memory_region_init(
-		memory_region, memory_region_max_size, sender, receiver, constituents,
-		constituents_count, 0, 0, data_access,
-		FFA_INSTRUCTION_ACCESS_NOT_SPECIFIED,
-		mem_func == FFA_MEM_SHARE_SMC32
-			? FFA_MEMORY_NORMAL_MEM
-			: FFA_MEMORY_NOT_SPECIFIED_MEM,
+		memory_region, memory_region_max_size, sender, receivers,
+		receiver_count, constituents, constituents_count, 0, 0, type,
 		FFA_MEMORY_CACHE_WRITE_BACK, FFA_MEMORY_INNER_SHAREABLE,
 		&total_length, &fragment_length);
 
@@ -460,7 +445,7 @@
 	}
 
 	return memory_send(memory_region, mem_func, fragment_length,
-			       total_length, ret);
+			   total_length, ret);
 }
 
 static bool ffa_uuid_equal(const struct ffa_uuid uuid1,
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_exceptions.c b/tftf/tests/runtime_services/secure_service/test_ffa_exceptions.c
index 5cb6dd4..6b16da4 100644
--- a/tftf/tests/runtime_services/secure_service/test_ffa_exceptions.c
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_exceptions.c
@@ -1,10 +1,11 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <arch_helpers.h>
+#include "ffa_helpers.h"
 #include <cactus_test_cmds.h>
 #include <debug.h>
 #include <ffa_endpoints.h>
@@ -51,6 +52,10 @@
 	struct ffa_value ret;
 	u_register_t retmm;
 
+	struct ffa_memory_access receiver =
+		ffa_memory_access_init_permissions_from_mem_func(
+			RECEIVER, FFA_MEM_SHARE_SMC32);
+
 	if (get_armv9_2_feat_rme_support() == 0U) {
 		return TEST_RESULT_SKIPPED;
 	}
@@ -60,9 +65,9 @@
 	GET_TFTF_MAILBOX(mb);
 
 	handle = memory_init_and_send((struct ffa_memory_region *)mb.send,
-					PAGE_SIZE, SENDER, RECEIVER,
-					constituents, constituents_count,
-					FFA_MEM_SHARE_SMC32, &ret);
+				      PAGE_SIZE, SENDER, &receiver, 1,
+				      constituents, constituents_count,
+				      FFA_MEM_SHARE_SMC32, &ret);
 
 	if (handle == FFA_MEMORY_HANDLE_INVALID) {
 		return TEST_RESULT_FAIL;
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_memory_sharing.c b/tftf/tests/runtime_services/secure_service/test_ffa_memory_sharing.c
index 5b80825..42e1948 100644
--- a/tftf/tests/runtime_services/secure_service/test_ffa_memory_sharing.c
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_memory_sharing.c
@@ -56,10 +56,15 @@
 
 	const uint32_t constituents_count = sizeof(constituents) /
 			sizeof(struct ffa_memory_region_constituent);
+
+	struct ffa_memory_access receiver =
+		ffa_memory_access_init_permissions_from_mem_func(borrower,
+								 mem_func);
+
 	GET_TFTF_MAILBOX(mb);
 
 	handle = memory_init_and_send((struct ffa_memory_region *)mb.send,
-					MAILBOX_SIZE, SENDER, borrower,
+					MAILBOX_SIZE, SENDER, &receiver, 1,
 					constituents, constituents_count,
 					mem_func, &ret);
 
@@ -134,6 +139,10 @@
 	/* Arbitrarily write 5 words after using memory. */
 	const uint32_t nr_words_to_write = 5;
 
+	struct ffa_memory_access receiver =
+		ffa_memory_access_init_permissions_from_mem_func(borrower,
+								 mem_func);
+
 	/***********************************************************************
 	 * Check if SPMC has ffa_version and expected FFA endpoints are deployed.
 	 **********************************************************************/
@@ -150,7 +159,7 @@
 	}
 
 	handle = memory_init_and_send((struct ffa_memory_region *)mb.send,
-					MAILBOX_SIZE, SENDER, borrower,
+					MAILBOX_SIZE, SENDER, &receiver, 1,
 					constituents, constituents_count,
 					mem_func, &ret);
 
@@ -404,15 +413,18 @@
 	/* Arbitrarily write 10 words after using shared memory. */
 	const uint32_t nr_words_to_write = 10U;
 
+	struct ffa_memory_access receiver =
+		ffa_memory_access_init_permissions_from_mem_func(
+			RECEIVER, FFA_MEM_LEND_SMC32);
+
 	CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
 
 	GET_TFTF_MAILBOX(mb);
 
 	remaining_constituent_count = ffa_memory_region_init(
 		(struct ffa_memory_region *)mb.send, MAILBOX_SIZE, SENDER,
-		RECEIVER, constituents, constituents_count, 0,
-		FFA_MEMORY_REGION_FLAG_CLEAR, FFA_DATA_ACCESS_RW,
-		FFA_INSTRUCTION_ACCESS_NOT_SPECIFIED,
+		&receiver, 1, constituents, constituents_count, 0,
+		FFA_MEMORY_REGION_FLAG_CLEAR,
 		FFA_MEMORY_NOT_SPECIFIED_MEM, 0, 0,
 		&total_length, &fragment_length);
 
@@ -644,6 +656,9 @@
 				: FFA_MEMORY_NORMAL_MEM,
 	};
 
+	struct ffa_memory_access receiver =
+		ffa_memory_access_init_permissions_from_mem_func(SP_ID(1), mem_func);
+
 	CHECK_SPMC_TESTING_SETUP(1, 2, expected_sp_uuids);
 	GET_TFTF_MAILBOX(mb);
 
@@ -662,7 +677,7 @@
 		panic();
 	}
 
-	handle = memory_init_and_send(mb.send, MAILBOX_SIZE, SENDER, RECEIVER,
+	handle = memory_init_and_send(mb.send, MAILBOX_SIZE, SENDER, &receiver, 1,
 				      sent_constituents,
 				      sent_constituents_count, mem_func, &ret);
 	if (handle == FFA_MEMORY_HANDLE_INVALID) {