test(spm): tests for RXTX_MAP/RXTX_UNMAP

Tests to check that RXTX_MAP and RXTX_UNMAP properly unmap/map the RX
and TX pages from the NWd stage 2 page tables.
Specifically:
* RXTX_MAP should fail when using secure memory
* RXTX_MAP should fail when using non-secure memory outside the regions
  specified in SPMC nodes
* Memory sharing functions (lend, share, donate) should fail when using
  memory that has been mapped by RXTX_MAP
* RXTX_UNMAP should fail when using different VM IDs
* Forwarded RXTX_MAP should succeed when the region is not mapped
* Two consecutive forwarded RXTX_MAPs should succeed when the regions
  don't overlap and the endpoint IDs are different
* Forwarded RXTX_MAP should fail when the region is already mapped
* Memory sharing functions (lend, share, donate) should fail when using
  memory that has been mapped by forwarded RXTX_MAP

Change-Id: I006681ab54f5ff602e862ae09438d0d174c8d0b0
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 0f19827..3ae43d2 100644
--- a/include/runtime_services/ffa_helpers.h
+++ b/include/runtime_services/ffa_helpers.h
@@ -497,6 +497,34 @@
 	ffa_memory_receiver_flags_t flags;
 };
 
+/**
+ * Endpoint RX/TX descriptor, as defined by Table 13.27 in FF-A v1.1 EAC0.
+ * It's used by the Hypervisor to describe the RX/TX buffers mapped by a VM
+ * to the SPMC, in order to allow indirect messaging.
+ */
+struct ffa_endpoint_rxtx_descriptor {
+	ffa_id_t endpoint_id;
+	uint16_t reserved;
+
+	/*
+	 * 8-byte aligned offset from the base address of this descriptor to the
+	 * `ffa_composite_memory_region` describing the RX buffer.
+	 */
+	uint32_t rx_offset;
+
+	/*
+	 * 8-byte aligned offset from the base address of this descriptor to the
+	 * `ffa_composite_memory_region` describing the TX buffer.
+	 */
+	uint32_t tx_offset;
+
+	/* Pad to align on 16-byte boundary. */
+	uint32_t pad;
+};
+
+_Static_assert(sizeof(struct ffa_endpoint_rxtx_descriptor) == 16,
+	       "ffa_endpoint_rx_tx_descriptor must be 16 bytes wide");
+
 /** Flags to control the behaviour of a memory sharing transaction. */
 typedef uint32_t ffa_memory_region_flags_t;
 
@@ -759,6 +787,7 @@
 struct ffa_value ffa_partition_info_get(const struct ffa_uuid uuid);
 struct ffa_value ffa_rx_release(void);
 struct ffa_value ffa_rxtx_map(uintptr_t send, uintptr_t recv, uint32_t pages);
+struct ffa_value ffa_rxtx_unmap_with_id(uint32_t id);
 struct ffa_value ffa_rxtx_unmap(void);
 struct ffa_value ffa_mem_donate(uint32_t descriptor_length,
 				uint32_t fragment_length);
@@ -800,6 +829,14 @@
 	ffa_memory_receiver_flags_t flags,
 	struct ffa_memory_access_impdef *impdef);
 
+void ffa_endpoint_rxtx_descriptor_init(
+    struct ffa_endpoint_rxtx_descriptor *desc, ffa_id_t endpoint_id,
+    void *rx_address, void *tx_address);
+
+struct ffa_value ffa_rxtx_map_forward(
+	struct ffa_endpoint_rxtx_descriptor *desc, ffa_id_t endpoint_id,
+	void *rx_address, void *tx_address);
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* FFA_HELPERS_H */
diff --git a/tftf/tests/runtime_services/secure_service/ffa_helpers.c b/tftf/tests/runtime_services/secure_service/ffa_helpers.c
index 8b53bb0..6db193c 100644
--- a/tftf/tests/runtime_services/secure_service/ffa_helpers.c
+++ b/tftf/tests/runtime_services/secure_service/ffa_helpers.c
@@ -495,15 +495,20 @@
 /* Unmap the RXTX buffer allocated by the given FF-A component */
 struct ffa_value ffa_rxtx_unmap(void)
 {
+	return ffa_rxtx_unmap_with_id(0);
+}
+
+struct ffa_value ffa_rxtx_unmap_with_id(uint32_t id)
+{
 	struct ffa_value args = {
 		.fid = FFA_RXTX_UNMAP,
-		.arg1 = FFA_PARAM_MBZ,
+		.arg1 = id << 16,
 		.arg2 = FFA_PARAM_MBZ,
 		.arg3 = FFA_PARAM_MBZ,
 		.arg4 = FFA_PARAM_MBZ,
 		.arg5 = FFA_PARAM_MBZ,
 		.arg6 = FFA_PARAM_MBZ,
-		.arg7 = FFA_PARAM_MBZ
+		.arg7 = FFA_PARAM_MBZ,
 	};
 
 	return ffa_service_call(&args);
@@ -806,3 +811,76 @@
 
 	return access;
 }
+
+/**
+ * Initialises the given `ffa_composite_memory_region` to be used for an
+ * `FFA_RXTX_MAP` forwarding in the case when Hypervisor needs the SPMC to map a
+ * VM's RXTX pair.
+ */
+static void
+ffa_composite_memory_region_init(struct ffa_composite_memory_region *composite,
+				 void *address, uint32_t page_count)
+{
+	composite->page_count = page_count;
+	composite->constituent_count = 1;
+	composite->reserved_0 = 0;
+
+	composite->constituents[0].page_count = page_count;
+	composite->constituents[0].address = (void *)address;
+	composite->constituents[0].reserved = 0;
+}
+
+/**
+ * Initialises the given `ffa_endpoint_rx_tx_descriptor` to be used for an
+ * `FFA_RXTX_MAP` forwarding in the case when Hypervisor needs the SPMC to map a
+ * VM's RXTX pair.
+ *
+ * Each buffer is described by an `ffa_composite_memory_region` containing
+ * one `ffa_memory_region_constituent`.
+ */
+void ffa_endpoint_rxtx_descriptor_init(
+	struct ffa_endpoint_rxtx_descriptor *desc, ffa_id_t endpoint_id,
+	void *rx_address, void *tx_address)
+{
+	desc->endpoint_id = endpoint_id;
+	desc->reserved = 0;
+	desc->pad = 0;
+
+	/*
+	 * RX's composite descriptor is allocated after the enpoint descriptor.
+	 * `sizeof(struct ffa_endpoint_rx_tx_descriptor)` is guaranteed to be
+	 * 16-byte aligned.
+	 */
+	desc->rx_offset = sizeof(struct ffa_endpoint_rxtx_descriptor);
+
+	ffa_composite_memory_region_init(
+		(struct ffa_composite_memory_region *)((uintptr_t)desc +
+						       desc->rx_offset),
+		rx_address, 1);
+
+	/*
+	 * TX's composite descriptor is allocated after the RX descriptor.
+	 * `sizeof(struct ffa_composite_memory_region)`  and
+	 * `sizeof(struct ffa_memory_region_constituent)` are guaranteed to be
+	 * 16-byte aligned in ffa_memory.c.
+	 */
+	desc->tx_offset = desc->rx_offset +
+			  sizeof(struct ffa_composite_memory_region) +
+			  sizeof(struct ffa_memory_region_constituent);
+
+	ffa_composite_memory_region_init(
+		(struct ffa_composite_memory_region *)((uintptr_t)desc +
+						       desc->tx_offset),
+		tx_address, 1);
+}
+
+/**
+ * Mimics a forwarded FFA_RXTX_MAP call from a hypervisor.
+ */
+struct ffa_value ffa_rxtx_map_forward(struct ffa_endpoint_rxtx_descriptor *desc,
+				ffa_id_t endpoint_id,
+				void *rx_address, void *tx_address)
+{
+	ffa_endpoint_rxtx_descriptor_init(desc, endpoint_id, rx_address, tx_address);
+	return ffa_rxtx_map(0, 0, 0);
+}
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_setup_and_discovery.c b/tftf/tests/runtime_services/secure_service/test_ffa_setup_and_discovery.c
index 567ac48..3c03d5f 100644
--- a/tftf/tests/runtime_services/secure_service/test_ffa_setup_and_discovery.c
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_setup_and_discovery.c
@@ -17,6 +17,20 @@
 
 static bool should_skip_version_test;
 
+/*
+ * Used as the RX/TX buffers belonging to VM 1 in the forwarding FFA_RXTX_MAP
+ * tests.
+ */
+static __aligned(PAGE_SIZE) uint8_t vm1_rx_buffer[PAGE_SIZE];
+static __aligned(PAGE_SIZE) uint8_t vm1_tx_buffer[PAGE_SIZE];
+
+/*
+ * Used as the RX/TX buffers belonging to VM 2 in the forwarding FFA_RXTX_MAP
+ * tests.
+ */
+static __aligned(PAGE_SIZE) uint8_t vm2_rx_buffer[PAGE_SIZE];
+static __aligned(PAGE_SIZE) uint8_t vm2_tx_buffer[PAGE_SIZE];
+
 static struct mailbox_buffers mb;
 
 static const struct ffa_uuid sp_uuids[] = {
@@ -125,17 +139,15 @@
 static test_result_t test_ffa_version(uint32_t input_version,
 					uint32_t expected_return)
 {
-	if (should_skip_version_test) {
+	if (should_skip_version_test)
 		return TEST_RESULT_SKIPPED;
-	}
 
 	struct ffa_value ret_values = ffa_version(input_version);
 
 	uint32_t spm_version = (uint32_t)(0xFFFFFFFF & ret_values.fid);
 
-	if (spm_version == expected_return) {
+	if (spm_version == expected_return)
 		return TEST_RESULT_SUCCESS;
-	}
 
 	tftf_testcase_printf("Input Version: 0x%x\n"
 			     "Return: 0x%x\nExpected: 0x%x\n",
@@ -251,6 +263,281 @@
 	return test_ffa_rxtx_map(FFA_ERROR);
 }
 
+/**
+ * Test to verify that call to FFA_RXTX_MAP should fail when using
+ * secure memory.
+ */
+test_result_t test_ffa_rxtx_map_secure_memory_fail(void)
+{
+	uintptr_t send = 0x7200000;
+	uintptr_t recv = send + PAGE_SIZE;
+	struct ffa_value ret;
+
+	SKIP_TEST_IF_FFA_VERSION_LESS_THAN(1, 2);
+
+	/* Unmap mailbox to remove state from previous tests. */
+	reset_tftf_mailbox();
+
+	ret = ffa_rxtx_map(send, recv, 1);
+	if (!is_expected_ffa_error(ret, FFA_ERROR_DENIED))
+		return TEST_RESULT_FAIL;
+
+	return TEST_RESULT_SUCCESS;
+}
+
+/**
+ * Test to verify that call to FFA_RXTX_MAP should fail when using non-secure
+ * memory outside the non-secure regions specified in the SPMC manifest nodes.
+ */
+test_result_t test_ffa_rxtx_map_nonsecure_memory_fail(void)
+{
+	uintptr_t send = 0x0000880080001000;
+	uintptr_t recv = send + PAGE_SIZE;
+	struct ffa_value ret;
+
+	SKIP_TEST_IF_FFA_VERSION_LESS_THAN(1, 2);
+
+	/* Unmap mailbox to remove state from previous tests. */
+	reset_tftf_mailbox();
+
+	ret = ffa_rxtx_map(send, recv, 1);
+	if (!is_expected_ffa_error(ret, FFA_ERROR_DENIED))
+		return TEST_RESULT_FAIL;
+
+	return TEST_RESULT_SUCCESS;
+}
+
+/**
+ * Test to verify that calls to memory sharing functions should fail when the
+ * ranges have been mapped by FFA_RXTX_MAP.
+ */
+test_result_t test_ffa_rxtx_map_memory_share_fail(void)
+{
+
+	struct ffa_memory_region_constituent constituent = {
+		.page_count = 1,
+		.reserved = 0,
+	};
+	uint32_t mem_funcs[] = {
+		FFA_MEM_LEND_SMC32,
+		FFA_MEM_SHARE_SMC32,
+		FFA_MEM_DONATE_SMC32,
+	};
+	struct ffa_value ret;
+
+	SKIP_TEST_IF_FFA_VERSION_LESS_THAN(1, 2);
+	CONFIGURE_AND_MAP_MAILBOX(mb, PAGE_SIZE, ret);
+	if (is_ffa_call_error(ret))
+		return TEST_RESULT_FAIL;
+
+	constituent.address = mb.send;
+
+	for (uint32_t i = 0; i < ARRAY_SIZE(mem_funcs); i++) {
+		uint32_t mem_func = mem_funcs[i];
+		struct ffa_memory_access receiver =
+			ffa_memory_access_init_permissions_from_mem_func(
+				SP_ID(1), mem_func);
+		memory_init_and_send(mb.send, PAGE_SIZE, HYP_ID, &receiver, 1,
+				     &constituent, 1, mem_func, &ret);
+		if (!is_expected_ffa_error(ret, FFA_ERROR_DENIED))
+			return TEST_RESULT_FAIL;
+	}
+
+	return TEST_RESULT_SUCCESS;
+}
+
+/**
+ * Test to verify that call to FFA_RXTX_UNMAP should fail when using a
+ * non-existent VM ID.
+ */
+test_result_t test_ffa_rxtx_unmap_nonexistent_vm_id_fail(void)
+{
+	struct ffa_value ret;
+
+	SKIP_TEST_IF_FFA_VERSION_LESS_THAN(1, 2);
+	reset_tftf_mailbox();
+
+	ret = ffa_rxtx_map((uintptr_t)vm1_tx_buffer, (uintptr_t)vm1_rx_buffer,
+			   1);
+	if (is_ffa_call_error(ret))
+		return TEST_RESULT_FAIL;
+
+	ret = ffa_rxtx_unmap_with_id(HYP_ID + 1);
+	if (!is_expected_ffa_error(ret, FFA_ERROR_INVALID_PARAMETER))
+		return TEST_RESULT_FAIL;
+
+	return TEST_RESULT_SUCCESS;
+}
+
+/**
+ * Test to verify that a forwarded FFA_RXTX_MAP call succeeds when the RX/TX
+ * regions have not already been mapped.
+ */
+test_result_t test_ffa_rxtx_map_forward_success(void)
+{
+	struct ffa_value ret;
+
+	SKIP_TEST_IF_FFA_VERSION_LESS_THAN(1, 2);
+	CONFIGURE_AND_MAP_MAILBOX(mb, PAGE_SIZE, ret);
+	if (is_ffa_call_error(ret))
+		return TEST_RESULT_FAIL;
+
+	ret = ffa_rxtx_map_forward(mb.send, VM_ID(1), vm1_rx_buffer,
+				   vm1_tx_buffer);
+	if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32))
+		return TEST_RESULT_FAIL;
+
+	ret = ffa_rxtx_unmap_with_id(VM_ID(1));
+	if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32))
+		return TEST_RESULT_FAIL;
+
+	ret = ffa_rxtx_unmap();
+	if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32))
+		return TEST_RESULT_FAIL;
+
+	return TEST_RESULT_SUCCESS;
+}
+
+/**
+ * Test to verify that consecutive forwarding of the FFA_RXTX_MAP call succeeds
+ * if using different VM IDs and different addresses.
+ */
+test_result_t test_ffa_rxtx_map_forward_consecutive_success(void)
+{
+	struct ffa_value ret;
+
+	SKIP_TEST_IF_FFA_VERSION_LESS_THAN(1, 2);
+	CONFIGURE_AND_MAP_MAILBOX(mb, PAGE_SIZE, ret);
+	if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32))
+		return TEST_RESULT_FAIL;
+
+	ret = ffa_rxtx_map_forward(mb.send, VM_ID(1), vm1_rx_buffer,
+				   vm1_tx_buffer);
+	if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32))
+		return TEST_RESULT_FAIL;
+
+	ret = ffa_rxtx_map_forward(mb.send, VM_ID(2), vm2_rx_buffer,
+				   vm2_tx_buffer);
+	if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32))
+		return TEST_RESULT_FAIL;
+
+	ret = ffa_rxtx_unmap_with_id(VM_ID(1));
+	if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32))
+		return TEST_RESULT_FAIL;
+
+	ret = ffa_rxtx_unmap_with_id(VM_ID(2));
+	if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32))
+		return TEST_RESULT_FAIL;
+
+	ret = ffa_rxtx_unmap();
+	if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32))
+		return TEST_RESULT_FAIL;
+
+	return TEST_RESULT_SUCCESS;
+}
+
+/**
+ * Test to verify that forwarding of the FFA_RXTX_MAP call with the VM's buffers
+ * fails if the hypervisor's RXTX buffers are not mapped.
+ */
+test_result_t test_ffa_rxtx_map_forward_unmapped_buffers_fail(void)
+{
+	struct ffa_value ret;
+
+	SKIP_TEST_IF_FFA_VERSION_LESS_THAN(1, 2);
+	/*
+	 * Unmap mailbox to recreate case where hypervisor's buffers aren't
+	 * mapped.
+	 */
+	reset_tftf_mailbox();
+
+	ret = ffa_rxtx_map_forward(mb.send, VM_ID(1), vm1_rx_buffer,
+				   vm1_tx_buffer);
+	if (!is_expected_ffa_error(ret, FFA_ERROR_INVALID_PARAMETER))
+		return TEST_RESULT_FAIL;
+
+	return TEST_RESULT_SUCCESS;
+}
+
+/**
+ * Test to verify that FFA_RXTX_MAP forwarding fails if trying to forward
+ * buffers that have already been forwarded.
+ */
+test_result_t test_ffa_rxtx_map_forward_different_ids_fail(void)
+{
+	struct ffa_value ret;
+
+	SKIP_TEST_IF_FFA_VERSION_LESS_THAN(1, 2);
+
+	CONFIGURE_AND_MAP_MAILBOX(mb, PAGE_SIZE, ret);
+	if (is_ffa_call_error(ret))
+		return TEST_RESULT_FAIL;
+
+	ret = ffa_rxtx_map_forward(mb.send, VM_ID(1), vm1_rx_buffer,
+				   vm1_tx_buffer);
+	if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32))
+		return TEST_RESULT_FAIL;
+
+	ret = ffa_rxtx_map_forward(mb.send, VM_ID(2), vm1_rx_buffer,
+				   vm1_tx_buffer);
+	if (!is_expected_ffa_error(ret, FFA_ERROR_DENIED))
+		return TEST_RESULT_FAIL;
+
+	ret = ffa_rxtx_unmap_with_id(VM_ID(1));
+	if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32))
+		return TEST_RESULT_FAIL;
+
+	return TEST_RESULT_SUCCESS;
+}
+
+/**
+ * Test to verify that calls to memory sharing functions should fail when the
+ * ranges have been mapped by a forwarded FFA_RXTX_MAP.
+ */
+test_result_t test_ffa_rxtx_map_forward_memory_share_fail(void)
+{
+
+	struct ffa_memory_region_constituent constituent = {
+		.page_count = 1,
+		.reserved = 0,
+		.address = vm1_tx_buffer,
+	};
+	uint32_t mem_funcs[] = {
+		FFA_MEM_LEND_SMC32,
+		FFA_MEM_SHARE_SMC32,
+		FFA_MEM_DONATE_SMC32,
+	};
+	struct ffa_value ret;
+
+	SKIP_TEST_IF_FFA_VERSION_LESS_THAN(1, 2);
+
+	ret = ffa_rxtx_map_forward(mb.send, VM_ID(1), vm1_rx_buffer,
+				   vm1_tx_buffer);
+	if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32))
+		return TEST_RESULT_FAIL;
+
+	for (uint32_t i = 0; i < ARRAY_SIZE(mem_funcs); i++) {
+		uint32_t mem_func = mem_funcs[i];
+		struct ffa_memory_access receiver =
+			ffa_memory_access_init_permissions_from_mem_func(
+				SP_ID(1), mem_func);
+		memory_init_and_send(mb.send, PAGE_SIZE, HYP_ID, &receiver, 1,
+				     &constituent, 1, mem_func, &ret);
+		if (!is_expected_ffa_error(ret, FFA_ERROR_DENIED))
+			return TEST_RESULT_FAIL;
+	}
+
+	ret = ffa_rxtx_unmap_with_id(VM_ID(1));
+	if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32))
+		return TEST_RESULT_FAIL;
+
+	ret = ffa_rxtx_unmap();
+	if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32))
+		return TEST_RESULT_FAIL;
+
+	return TEST_RESULT_SUCCESS;
+}
+
 static test_result_t test_ffa_rxtx_unmap(uint32_t expected_return)
 {
 	struct ffa_value ret;
@@ -319,23 +606,11 @@
 test_result_t test_ffa_rxtx_unmap_fail_if_sp(void)
 {
 	struct ffa_value ret;
-	struct ffa_value args;
 
 	CHECK_SPMC_TESTING_SETUP(1, 1, sp_uuids);
 
 	/* Invoked FFA_RXTX_UNMAP, providing the ID of an SP in w1. */
-	args = (struct ffa_value) {
-		.fid = FFA_RXTX_UNMAP,
-		.arg1 = SP_ID(1) << 16,
-		.arg2 = FFA_PARAM_MBZ,
-		.arg3 = FFA_PARAM_MBZ,
-		.arg4 = FFA_PARAM_MBZ,
-		.arg5 = FFA_PARAM_MBZ,
-		.arg6 = FFA_PARAM_MBZ,
-		.arg7 = FFA_PARAM_MBZ
-	};
-
-	ret = ffa_service_call(&args);
+	ret = ffa_rxtx_unmap_with_id(SP_ID(1));
 
 	if (!is_expected_ffa_error(ret, FFA_ERROR_INVALID_PARAMETER)) {
 		return TEST_RESULT_FAIL;
diff --git a/tftf/tests/tests-spm.xml b/tftf/tests/tests-spm.xml
index 09e0fd7..69b656e 100644
--- a/tftf/tests/tests-spm.xml
+++ b/tftf/tests/tests-spm.xml
@@ -25,12 +25,30 @@
                function="test_ffa_rxtx_map_success" />
      <testcase name="FF-A RXTX Map API consecutive"
                function="test_ffa_rxtx_map_fail" />
+     <testcase name="FF-A RXTX Map API secure memory"
+               function="test_ffa_rxtx_map_secure_memory_fail"/>
+     <testcase name="FF-A RXTX Map API non-secure memory"
+               function="test_ffa_rxtx_map_nonsecure_memory_fail"/>
+     <testcase name="FF-A RXTX Map API memory sharing"
+               function="test_ffa_rxtx_map_memory_share_fail"/>
+     <testcase name="FF-A RXTX Unmap API ID nonexistent"
+               function="test_ffa_rxtx_unmap_nonexistent_vm_id_fail"/>
      <testcase name="FF-A RXTX Unmap API success"
 	       function="test_ffa_rxtx_unmap_success" />
      <testcase name="FF-A RXTX Unmap API consecutive"
 	       function="test_ffa_rxtx_unmap_fail" />
      <testcase name="FF-A RXTX remap unmapped region success"
 	     function="test_ffa_rxtx_map_unmapped_success" />
+     <testcase name="FF-A RXTX map forward success"
+	     function="test_ffa_rxtx_map_forward_success" />
+     <testcase name="FF-A RXTX map forward consecutive success"
+	     function="test_ffa_rxtx_map_forward_consecutive_success" />
+     <testcase name="FF-A RXTX map forward with unmapped buffers fail"
+	     function="test_ffa_rxtx_map_forward_unmapped_buffers_fail" />
+     <testcase name="FF-A RXTX map forward with different IDs fail"
+	     function="test_ffa_rxtx_map_forward_different_ids_fail" />
+     <testcase name="FF-A RXTX map forward memory share fail"
+	     function="test_ffa_rxtx_map_forward_memory_share_fail" />
      <testcase name="FF-A RXTX unmap SP rxtx buffer"
 	     function="test_ffa_rxtx_unmap_fail_if_sp" />
      <testcase name="Test FFA_SPM_ID_GET"