test(memory share): hypervisor retrieve request fails

Test that an hypervisor retrieve request fails smoothly
if either the TX or the RX buffer are in the realm PAS.

Signed-off-by: J-Alves <joao.alves@arm.com>
Change-Id: I07e4aa2e07cfd1b5132e82bfbf5a2f76a6f34c14
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 9a526ce..bf9be88 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
@@ -1335,7 +1335,8 @@
 	return TEST_RESULT_SUCCESS;
 }
 
-test_result_t base_ffa_memory_retrieve_request_fail_buffer_realm(bool delegate_rx)
+test_result_t base_ffa_memory_retrieve_request_fail_buffer_realm(bool delegate_rx,
+								 bool is_hypervisor_retrieve_req)
 {
 	struct mailbox_buffers mb;
 	struct ffa_memory_access receivers[2] = {
@@ -1366,11 +1367,17 @@
 		return TEST_RESULT_FAIL;
 	}
 
-	/* Prepare the descriptor before delegating the TX buffer. */
-	descriptor_size = ffa_memory_retrieve_request_init(
-		mb.send, handle, SENDER, receivers, ARRAY_SIZE(receivers), 0, 0,
-		FFA_MEMORY_NORMAL_MEM, FFA_MEMORY_CACHE_WRITE_BACK,
-		FFA_MEMORY_INNER_SHAREABLE);
+	if (is_hypervisor_retrieve_req) {
+		/* Prepare the hypervisor retrieve request. */
+		ffa_hypervisor_retrieve_request_init(mb.send, handle);
+		descriptor_size = sizeof(struct ffa_memory_region);
+	} else {
+		/* Prepare the descriptor before delegating the buffer. */
+		descriptor_size = ffa_memory_retrieve_request_init(
+			mb.send, handle, SENDER, receivers, ARRAY_SIZE(receivers),
+			0, 0, FFA_MEMORY_NORMAL_MEM, FFA_MEMORY_CACHE_WRITE_BACK,
+			FFA_MEMORY_INNER_SHAREABLE);
+	}
 
 	/* Delegate buffer to realm. */
 	ret_rmm = host_rmi_granule_delegate((u_register_t)to_delegate);
@@ -1405,7 +1412,8 @@
 
 	ffa_rx_release();
 
-	if (!memory_relinquish(mb.send, handle, VM_ID(1))) {
+	if (!is_hypervisor_retrieve_req &&
+	    !memory_relinquish(mb.send, handle, VM_ID(1))) {
 		ERROR("%s: Failed to relinquish.\n", __func__);
 		return TEST_RESULT_FAIL;
 	}
@@ -1426,7 +1434,7 @@
  */
 test_result_t test_ffa_memory_retrieve_request_fail_tx_realm(void)
 {
-	return base_ffa_memory_retrieve_request_fail_buffer_realm(false);
+	return base_ffa_memory_retrieve_request_fail_buffer_realm(false, false);
 }
 
 /**
@@ -1440,7 +1448,7 @@
  */
 test_result_t test_ffa_memory_retrieve_request_fail_rx_realm(void)
 {
-	return base_ffa_memory_retrieve_request_fail_buffer_realm(true);
+	return base_ffa_memory_retrieve_request_fail_buffer_realm(true, false);
 }
 
 /**
@@ -1525,3 +1533,27 @@
 
 	return TEST_RESULT_SUCCESS;
 }
+
+/**
+ * Test that a hypervisor retrieve request would fail if the TX buffer
+ * was in realm PAS.
+ * The hypervisor retrieve request normally happens during an FFA_MEM_RECLAIM.
+ * This validates that the SPMC is able to recover from a GPF from accessing the
+ * TX buffer when reading the hypervisor retrieve request message.
+ */
+test_result_t test_ffa_hypervisor_retrieve_request_fail_tx_realm(void)
+{
+	return base_ffa_memory_retrieve_request_fail_buffer_realm(false, true);
+}
+
+/**
+ * Test that a hypervisor retrieve request would fail if the RX buffer
+ * was in realm PAS.
+ * The hypervisor retrieve request normally happens during an FFA_MEM_RECLAIM.
+ * This validates the SPMC is able to recover from a GPF from accessing the RX
+ * buffer when preparing the retrieve response.
+ */
+test_result_t test_ffa_hypervisor_retrieve_request_fail_rx_realm(void)
+{
+	return base_ffa_memory_retrieve_request_fail_buffer_realm(true, true);
+}
diff --git a/tftf/tests/tests-memory-access.xml b/tftf/tests/tests-memory-access.xml
index a0e9f42..49965a0 100644
--- a/tftf/tests/tests-memory-access.xml
+++ b/tftf/tests/tests-memory-access.xml
@@ -75,6 +75,10 @@
                 function="test_ffa_memory_retrieve_request_fail_rx_realm" />
       <testcase name="FF-A Memory Retrieve, NWd TX buffer is in realm PAS"
                 function="test_ffa_memory_retrieve_request_fail_tx_realm" />
+      <testcase name="FF-A Hypervisor Retrieve, NWd RX buffer is in realm PAS"
+                function="test_ffa_hypervisor_retrieve_request_fail_rx_realm" />
+      <testcase name="FF-A Hypervisor Retrieve, NWd TX buffer is in realm PAS"
+                function="test_ffa_hypervisor_retrieve_request_fail_tx_realm" />
       <testcase name="FF-A Memory Relinquish, NWd TX buffer is in realm PAS"
                 function="test_ffa_memory_relinquish_fail_tx_realm" />
   </testsuite>