test(memory share): retrieve request from VM
The SPMC supports the case in which the hypervisor doesn't
track the operation. This is usable for multiple borrower operations,
with a VM. In this case, hypervisor/OS Kernel shall forward the
requests to retrieve memory into the SPMC. This patch adds such
case, as we lost this coverage in the Hafnium tests.
Change-Id: Ia217ababd6e4ae0a82bed781b6f217a52a0909e0
Signed-off-by: J-Alves <joao.alves@arm.com>
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 f160d21..a283f6a 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
@@ -1252,3 +1252,85 @@
return TEST_RESULT_SUCCESS;
}
+
+/**
+ * Base helper to prepare for tests that need to retrieve memory from the SPMC
+ * from a VM endpoint.
+ */
+static ffa_memory_handle_t base_memory_send_for_nwd_retrieve(struct mailbox_buffers *mb,
+ struct ffa_memory_access receivers[],
+ size_t receivers_count)
+{
+ ffa_memory_handle_t handle;
+ struct ffa_memory_region_constituent constituents[] = {
+ {(void *)four_share_pages, 4, 0},
+ {(void *)share_page, 1, 0}
+ };
+ const uint32_t constituents_count = ARRAY_SIZE(constituents);
+ struct ffa_value ret;
+
+ /* Prepare the composite offset for the comparison. */
+ for (uint32_t i = 0; i < receivers_count; i++) {
+ receivers[i].composite_memory_region_offset =
+ sizeof(struct ffa_memory_region) +
+ receivers_count *
+ sizeof(struct ffa_memory_access);
+ }
+
+ handle = memory_init_and_send(mb->send, MAILBOX_SIZE, SENDER, receivers,
+ receivers_count, constituents,
+ constituents_count, FFA_MEM_SHARE_SMC64, &ret);
+ return handle;
+}
+
+/**
+ * Test FF-A memory retrieve request from a VM into the SPMC.
+ * TFTF invokes all the FF-A calls expected from an hypervisor into the
+ * SPMC, even those that would be initiated by a VM, and then forwarded
+ * to the SPMC by the Hypervisor.
+ */
+test_result_t test_ffa_memory_retrieve_request_from_vm(void)
+{
+ struct mailbox_buffers mb;
+ struct ffa_memory_region *m;
+ struct ffa_memory_access receivers[2] = {
+ ffa_memory_access_init_permissions_from_mem_func(VM_ID(1),
+ FFA_MEM_SHARE_SMC64),
+ ffa_memory_access_init_permissions_from_mem_func(SP_ID(2),
+ FFA_MEM_SHARE_SMC64),
+ };
+ ffa_memory_handle_t handle;
+
+ GET_TFTF_MAILBOX(mb);
+
+ if (get_armv9_2_feat_rme_support() == 0U) {
+ return TEST_RESULT_SKIPPED;
+ }
+
+ CHECK_SPMC_TESTING_SETUP(1, 2, expected_sp_uuids);
+
+ handle = base_memory_send_for_nwd_retrieve(&mb, receivers, ARRAY_SIZE(receivers));
+
+ if (handle == FFA_MEMORY_HANDLE_INVALID) {
+ return TEST_RESULT_FAIL;
+ }
+
+ if (!memory_retrieve(&mb, &m, handle, 0, receivers, ARRAY_SIZE(receivers), 0)) {
+ ERROR("Failed to retrieve the memory.\n");
+ return TEST_RESULT_FAIL;
+ }
+
+ ffa_rx_release();
+
+ if (!memory_relinquish(mb.send, handle, VM_ID(1))) {
+ ERROR("%s: Failed to relinquish.\n", __func__);
+ return TEST_RESULT_FAIL;
+ }
+
+ if (is_ffa_call_error(ffa_mem_reclaim(handle, 0))) {
+ ERROR("%s: Failed to reclaim memory.\n", __func__);
+ return TEST_RESULT_FAIL;
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
diff --git a/tftf/tests/tests-spm.xml b/tftf/tests/tests-spm.xml
index 0434d4b..5658d62 100644
--- a/tftf/tests/tests-spm.xml
+++ b/tftf/tests/tests-spm.xml
@@ -139,6 +139,8 @@
function="test_share_forbidden_ranges" />
<testcase name="Donate consecutively"
function="test_consecutive_donate" />
+ <testcase name="Normal World VM retrieve request into SPMC"
+ function="test_ffa_memory_retrieve_request_from_vm" />
</testsuite>
<testsuite name="SIMD,SVE Registers context"