aboutsummaryrefslogtreecommitdiff
path: root/tftf
diff options
context:
space:
mode:
authorOlivier Deprez <olivier.deprez@arm.com>2021-01-21 10:00:00 +0000
committerTrustedFirmware Code Review <review@review.trustedfirmware.org>2021-01-21 10:00:00 +0000
commit4904c8632c255b6ac3fb77109f807b3a11cb910b (patch)
tree86bf81fa9377e50cc9aa040c93bab7c213f525af /tftf
parent52387275bd4ab47aecaf101526e683134e0440fb (diff)
parentb9085f851d37d66276e85ad05e9be1a9f4bfb99a (diff)
downloadtf-a-tests-4904c8632c255b6ac3fb77109f807b3a11cb910b.tar.gz
Merge changes from topic "sp_to_sp_mem_share"
* changes: Cactus: cmd for mem share tests TFTF: tests to request SP-to-SP memory share cactus: test SP-to-SP memory share operations cactus: add command to request memory sharing between SPs TFTF: Refactor FF-A memory sharing tests
Diffstat (limited to 'tftf')
-rw-r--r--tftf/tests/runtime_services/secure_service/ffa_helpers.c86
-rw-r--r--tftf/tests/runtime_services/secure_service/test_ffa_memory_sharing.c165
-rw-r--r--tftf/tests/tests-spm.xml18
3 files changed, 180 insertions, 89 deletions
diff --git a/tftf/tests/runtime_services/secure_service/ffa_helpers.c b/tftf/tests/runtime_services/secure_service/ffa_helpers.c
index 8ee4ebc7..1b790188 100644
--- a/tftf/tests/runtime_services/secure_service/ffa_helpers.c
+++ b/tftf/tests/runtime_services/secure_service/ffa_helpers.c
@@ -310,6 +310,92 @@ uint32_t ffa_memory_retrieve_request_init(
memory_region->receiver_count * sizeof(struct ffa_memory_access);
}
+/**
+ * Helper to call memory send function whose func id is passed as a parameter.
+ * Returns a valid handle in case of successful operation or
+ * FFA_MEMORY_HANDLE_INVALID if something goes wrong.
+ *
+ * TODO: Do memory send with 'ffa_memory_region' taking multiple segments
+ */
+ffa_memory_handle_t ffa_memory_send(
+ struct ffa_memory_region *memory_region, uint32_t mem_func,
+ uint32_t fragment_length, uint32_t total_length)
+{
+ smc_ret_values ret;
+ ffa_vm_id_t receiver =
+ memory_region->receivers[0].receiver_permissions.receiver;
+
+ if (fragment_length != total_length) {
+ ERROR("For now, fragment_length and total_length need to be"
+ " equal");
+ return FFA_MEMORY_HANDLE_INVALID;
+ }
+
+ switch (mem_func) {
+ case FFA_MEM_SHARE_SMC32:
+ ret = ffa_mem_share(total_length, fragment_length);
+ break;
+ case FFA_MEM_LEND_SMC32:
+ ret = ffa_mem_lend(total_length, fragment_length);
+ break;
+ case FFA_MEM_DONATE_SMC32:
+ ret = ffa_mem_donate(total_length, fragment_length);
+ break;
+ default:
+ ERROR("TFTF - Invalid func id %x!\n", mem_func);
+ return FFA_MEMORY_HANDLE_INVALID;
+ }
+
+ if (ret.ret0 != FFA_SUCCESS_SMC32) {
+ ERROR("Failed to send memory to %x, error: %lx.\n",
+ receiver, ret.ret2);
+ return FFA_MEMORY_HANDLE_INVALID;
+ }
+
+ return ffa_mem_success_handle(ret);
+;
+}
+
+/**
+ * Helper that initializes and sends a memory region. The memory region's
+ * configuration is statically defined and is implementation specific. However,
+ * doing it in this file for simplicity and for testing purposes.
+ */
+ffa_memory_handle_t ffa_memory_init_and_send(
+ struct ffa_memory_region *memory_region, size_t memory_region_max_size,
+ ffa_vm_id_t sender, ffa_vm_id_t receiver,
+ const struct ffa_memory_region_constituent *constituents,
+ uint32_t constituents_count, uint32_t mem_func)
+{
+ uint32_t remaining_constituent_count;
+ 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;
+
+ 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,
+ FFA_MEMORY_NORMAL_MEM, FFA_MEMORY_CACHE_WRITE_BACK,
+ FFA_MEMORY_INNER_SHAREABLE, &total_length, &fragment_length
+ );
+
+ /*
+ * For simplicity of the test, and at least for the time being,
+ * the following condition needs to be true.
+ */
+ if (remaining_constituent_count != 0U) {
+ ERROR("Remaining constituent should be 0\n");
+ return FFA_MEMORY_HANDLE_INVALID;
+ }
+
+ return ffa_memory_send(memory_region, mem_func, fragment_length,
+ total_length);
+}
+
/*
* FFA Version ABI helper.
* Version fields:
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 fded1998..61f1aaa3 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
@@ -17,46 +17,44 @@
#define SENDER HYP_ID
#define RECEIVER SP_ID(1)
-/* Memory section to be sent over mem management ABIs */
+static const struct ffa_uuid expected_sp_uuids[] = {
+ {PRIMARY_UUID}, {SECONDARY_UUID}, {TERTIARY_UUID}
+ };
+
+/* Memory section to be used for memory share operations */
static __aligned(PAGE_SIZE) uint8_t share_page[PAGE_SIZE];
+/**
+ * Tests that it is possible to share memory with SWd from NWd.
+ * After calling the respective memory send API, it will expect a reply from
+ * cactus SP, at which point it will reclaim access to the memory region and
+ * check the memory region has been used by receiver SP.
+ *
+ * Accessing memory before a memory reclaim operation should only be possible
+ * in the context of a memory share operation.
+ * According to the FF-A spec, the owner is temporarily relinquishing
+ * access to the memory region on a memory lend operation, and on a
+ * memory donate operation the access is relinquished permanently.
+ * SPMC is positioned in S-EL2, and doesn't control stage-1 mapping for
+ * EL2. Therefore, it is impossible to enforce the expected access
+ * policy for a donate and lend operations within the SPMC.
+ * Current SPMC implementation is under the assumption of trust that
+ * Hypervisor (sitting in EL2) would relinquish access from EL1/EL0
+ * FF-A endpoint at relevant moment.
+ */
static test_result_t test_memory_send_sp(uint32_t mem_func)
{
smc_ret_values ret;
- uint32_t remaining_constituent_count;
- uint32_t total_length;
- uint32_t fragment_length;
- uint32_t sent_length;
ffa_memory_handle_t handle;
uint32_t *ptr;
struct mailbox_buffers mb;
- const uint32_t primary_uuid[] = PRIMARY_UUID;
- /**********************************************************************
- * Verify that FFA is there and that it has the correct version.
+ /***********************************************************************
+ * Check if SPMC has ffa_version and expected FFA endpoints are deployed.
**********************************************************************/
- SKIP_TEST_IF_FFA_VERSION_LESS_THAN(1, 0);
+ CHECK_HAFNIUM_SPMC_TESTING_SETUP(1, 0, expected_sp_uuids);
- /**********************************************************************
- * If OPTEE is SPMC skip this test.
- **********************************************************************/
- if (check_spmc_execution_level()) {
- VERBOSE("OPTEE as SPMC at S-EL1. Skipping test!\n");
- return TEST_RESULT_SKIPPED;
- }
-
- if (!get_tftf_mailbox(&mb)) {
- ERROR("Mailbox not configured!\n This test relies on"
- " test suite \"FF-A RXTX Mapping\" to map/configure"
- " RXTX buffers\n");
- return TEST_RESULT_FAIL;
- }
-
-
- /**********************************************************************
- * Verify that cactus primary SP is deployed in the system.
- **********************************************************************/
- SKIP_TEST_IF_FFA_ENDPOINT_NOT_DEPLOYED(mb, primary_uuid);
+ GET_TFTF_MAILBOX(mb);
struct ffa_memory_region_constituent constituents[] = {
{(void *)share_page, 1, 0}
@@ -65,68 +63,21 @@ static test_result_t test_memory_send_sp(uint32_t mem_func)
const uint32_t constituents_count = sizeof(constituents) /
sizeof(struct ffa_memory_region_constituent);
- enum ffa_data_access data_access = (mem_func == FFA_MEM_DONATE_SMC32) ?
- FFA_DATA_ACCESS_NOT_SPECIFIED :
- FFA_DATA_ACCESS_RW;
-
- /*
- * TODO: Revise shareability attribute in function call
- * below.
- * https://lists.trustedfirmware.org/pipermail/hafnium/2020-June/000023.html
- */
- remaining_constituent_count = ffa_memory_region_init(
- mb.send, MAILBOX_SIZE, SENDER, RECEIVER, constituents,
- constituents_count, 0, 0,
- data_access,
- FFA_INSTRUCTION_ACCESS_NOT_SPECIFIED,
- FFA_MEMORY_NORMAL_MEM,
- FFA_MEMORY_CACHE_WRITE_BACK,
- FFA_MEMORY_OUTER_SHAREABLE,
- &total_length,
- &fragment_length
- );
-
- switch (mem_func) {
- case FFA_MEM_SHARE_SMC32:
- ret = ffa_mem_share(total_length, fragment_length);
- break;
- case FFA_MEM_LEND_SMC32:
- ret = ffa_mem_lend(total_length, fragment_length);
- break;
- case FFA_MEM_DONATE_SMC32:
- ret = ffa_mem_donate(total_length, fragment_length);
- break;
- default:
- NOTICE("TFTF - Invalid func id!\n");
- return TEST_RESULT_FAIL;
- }
-
- sent_length = fragment_length;
-
- if (ret.ret0 != FFA_SUCCESS_SMC32) {
- tftf_testcase_printf("Failed to send memory to SP %x.\n",
- RECEIVER);
- return TEST_RESULT_FAIL;
- }
+ handle = ffa_memory_init_and_send((struct ffa_memory_region *)mb.send,
+ MAILBOX_SIZE, SENDER, RECEIVER,
+ constituents, constituents_count,
+ mem_func);
- if (sent_length != total_length) {
- tftf_testcase_printf("Sent and Total lengths must be equal!\n");
+ if (handle == FFA_MEMORY_HANDLE_INVALID) {
return TEST_RESULT_FAIL;
}
- if (remaining_constituent_count != 0) {
- tftf_testcase_printf("Remaining constituent should be 0\n");
- return TEST_RESULT_FAIL;
- }
-
- handle = ffa_mem_success_handle(ret);
-
VERBOSE("TFTF - Handle: %llx\nTFTF - Address: %p\n",
handle, constituents[0].address);
ptr = (uint32_t *)constituents[0].address;
- ret = CACTUS_MEM_SEND_CMD(SENDER, RECEIVER, mem_func, handle);
+ ret = CACTUS_MEM_SEND_CMD_SEND(SENDER, RECEIVER, mem_func, handle);
if (ret.ret0 != FFA_MSG_SEND_DIRECT_RESP_SMC32) {
ERROR("Failed to send message. error: %lx\n",
@@ -135,7 +86,7 @@ static test_result_t test_memory_send_sp(uint32_t mem_func)
}
if (CACTUS_GET_RESPONSE(ret) != CACTUS_SUCCESS) {
- tftf_testcase_printf("Failed memory send operation!\n");
+ ERROR("Failed memory send operation!\n");
return TEST_RESULT_FAIL;
}
@@ -174,3 +125,51 @@ test_result_t test_mem_donate_sp(void)
{
return test_memory_send_sp(FFA_MEM_DONATE_SMC32);
}
+
+/*
+ * Test requests a memory send operation between cactus SPs.
+ * Cactus SP should reply to TFTF on whether the test succeeded or not.
+ */
+static test_result_t test_req_mem_send_sp_to_sp(uint32_t mem_func,
+ ffa_vm_id_t sender_sp,
+ ffa_vm_id_t receiver_sp)
+{
+ smc_ret_values ret;
+
+ /***********************************************************************
+ * Check if SPMC's ffa_version and presence of expected FF-A endpoints.
+ **********************************************************************/
+ CHECK_HAFNIUM_SPMC_TESTING_SETUP(1, 0, expected_sp_uuids);
+
+ ret = CACTUS_REQ_MEM_SEND_SEND_CMD(HYP_ID, sender_sp, mem_func,
+ receiver_sp);
+
+ if (ret.ret0 != FFA_MSG_SEND_DIRECT_RESP_SMC32) {
+ ERROR("Failed to send message. error: %lx\n", ret.ret2);
+ return TEST_RESULT_FAIL;
+ }
+
+ if (CACTUS_IS_ERROR_RESP(ret)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
+
+test_result_t test_req_mem_share_sp_to_sp(void)
+{
+ return test_req_mem_send_sp_to_sp(FFA_MEM_SHARE_SMC32, SP_ID(3),
+ SP_ID(2));
+}
+
+test_result_t test_req_mem_lend_sp_to_sp(void)
+{
+ return test_req_mem_send_sp_to_sp(FFA_MEM_LEND_SMC32, SP_ID(2),
+ SP_ID(1));
+}
+
+test_result_t test_req_mem_donate_sp_to_sp(void)
+{
+ return test_req_mem_send_sp_to_sp(FFA_MEM_DONATE_SMC32, SP_ID(1),
+ SP_ID(3));
+}
diff --git a/tftf/tests/tests-spm.xml b/tftf/tests/tests-spm.xml
index 14be8ca5..2637acde 100644
--- a/tftf/tests/tests-spm.xml
+++ b/tftf/tests/tests-spm.xml
@@ -46,12 +46,18 @@
<testsuite name="FF-A Memory Sharing"
description="Test FF-A Memory Sharing ABIs" >
- <testcase name="Lend Memory to Secure World"
- function="test_mem_lend_sp" />
- <testcase name="Share Memory with Secure World"
- function="test_mem_share_sp" />
- <testcase name="Donate Memory to Secure World"
- function="test_mem_donate_sp"/>
+ <testcase name="Lend Memory to Secure World"
+ function="test_mem_lend_sp" />
+ <testcase name="Share Memory with Secure World"
+ function="test_mem_share_sp" />
+ <testcase name="Donate Memory to Secure World"
+ function="test_mem_donate_sp"/>
+ <testcase name="Request Share Memory SP-to-SP"
+ function="test_req_mem_share_sp_to_sp" />
+ <testcase name="Request Lend Memory SP-to-SP"
+ function="test_req_mem_lend_sp_to_sp" />
+ <testcase name="Request Donate Memory SP-to-SP"
+ function="test_req_mem_donate_sp_to_sp" />
</testsuite>
<testsuite name="FF-A features"