Improve FF-A memory share testing
* Testing SPMC error handling by sending various invalid memory
transaction descriptors to the SPMC via FFA_MEM_SHARE.
* Validate memory transaction type flag in retrieve response
* Fix error logging in tests
Signed-off-by: Imre Kis <imre.kis@arm.com>
Change-Id: If4c4f4084306ec26a7b3033c3efa9ded2a6a52f0
diff --git a/components/service/spm_test/sp.c b/components/service/spm_test/sp.c
index 0b75d94..37aa939 100644
--- a/components/service/spm_test/sp.c
+++ b/components/service/spm_test/sp.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -496,7 +496,13 @@
&out_region_count, handle);
if (res) {
- DMSG("Failed retrieving me share");
+ DMSG("Failed retrieving shared memory");
+ return_error((uint32_t)ERR_MEM_RETRIEVE, msg);
+ return;
+ }
+
+ if (descriptor.flags.transaction_type != sp_memory_transaction_type_share) {
+ EMSG("Invalid transaction type");
return_error((uint32_t)ERR_MEM_RETRIEVE, msg);
return;
}
@@ -564,9 +570,7 @@
res = sp_memory_share(&desc, &acc_desc, 1, ®ion, 1, &handle);
if (res != FFA_OK) {
- EMSG("test_mem_sharing(): error % in %s:%d"PRId32, res,
- __FILE__,
- __LINE__);
+ EMSG("Failed to share memory: %"PRId32, res);
return_error((uint32_t)ERR_SP_SHARE, msg);
return;
}
@@ -576,9 +580,7 @@
handle >> 32, own_id, 0, msg);
if (res != FFA_OK) {
- EMSG("test_mem_sharing(): error % in %s:%d"PRId32, res,
- __FILE__,
- __LINE__);
+ EMSG("Failed to send retrieve command: %"PRId32, res);
return_error((uint32_t)ERR_SP_SHARE, msg);
return;
}
@@ -588,9 +590,7 @@
0, 0, 0, msg);
if (res != FFA_OK) {
- EMSG("test_mem_sharing(): error % in %s:%d"PRId32, res,
- __FILE__,
- __LINE__);
+ EMSG("Failed to send TRY_W_ACCESS command: %"PRId32, res);
return_error((uint32_t)ERR_SP_SHARE, msg);
return;
}
@@ -599,9 +599,7 @@
EP_RELINQUISH, handle & 0xffffffff,
handle >> 32, 0, 0, msg);
if (res != FFA_OK) {
- EMSG("test_mem_sharing(): error % in %s:%d"PRId32, res,
- __FILE__,
- __LINE__);
+ EMSG("Failed to send relinquish command: %"PRId32, res);
return_error((uint32_t)ERR_SP_SHARE, msg);
return;
}
@@ -609,9 +607,7 @@
res = ffa_mem_reclaim(handle, 0);
if (res != FFA_OK) {
- EMSG("test_mem_sharing(): error % in %s:%d"PRId32, res,
- __FILE__,
- __LINE__);
+ EMSG("Failed to reclaim memory: %"PRId32, res);
return_error((uint32_t)ERR_SP_SHARE, msg);
return;
}
@@ -629,7 +625,7 @@
uint64_t handle = 0;
struct ffa_mem_transaction_buffer t_buf = {0};
uint16_t own_id = 0;
- uint16_t src_id = msg->source_id = 0;
+ uint16_t src_id = msg->source_id;
struct sp_memory_access_descriptor acc_desc[2] = { };
uint32_t err = 0;
uint16_t endpoint2 = msg->args.args64[1];
@@ -659,7 +655,7 @@
res = sp_memory_share(&desc, acc_desc, 2, ®ion, 1, &handle);
if (res != FFA_OK) {
- EMSG("ffa_memory_share(): error %"PRId32, res);
+ EMSG("Failed to share memory: %"PRId32, res);
err = (uint32_t)ERR_SP_SHARE;
goto err;
}
@@ -669,9 +665,7 @@
handle >> 32, own_id, 0, msg);
if (res != FFA_OK) {
- EMSG("test_mem_multi_sharing(): error % in %s:%d"PRId32, res,
- __FILE__,
- __LINE__);
+ EMSG("Failed to send retrieve command: %"PRId32, res);
return_error((uint32_t)ERR_SP_SHARE, msg);
return;
}
@@ -681,9 +675,7 @@
0, 0, 0, msg);
if (res != FFA_OK) {
- EMSG("test_mem_multi_sharing(): error % in %s:%d"PRId32, res,
- __FILE__,
- __LINE__);
+ EMSG("Failed to send TRY_W_ACCESS command: %"PRId32, res);
return_error((uint32_t)ERR_SP_SHARE, msg);
return;
}
@@ -699,9 +691,7 @@
handle >> 32, 0, 0, msg);
if (res != FFA_OK) {
- EMSG("test_mem_multi_sharing(): error % in %s:%d"PRId32, res,
- __FILE__,
- __LINE__);
+ EMSG("Failed to send relinquish command: %"PRId32, res);
return_error((uint32_t)ERR_SP_SHARE, msg);
return;
}
@@ -712,9 +702,7 @@
handle >> 32, own_id, 0, msg);
if (res != FFA_OK) {
- EMSG("test_mem_multi_sharing(): error % in %s:%d"PRId32, res,
- __FILE__,
- __LINE__);
+ EMSG("Failed to send retrieve command: %"PRId32, res);
return_error((uint32_t)ERR_SP_SHARE, msg);
return;
}
@@ -724,9 +712,7 @@
0, 0, 0, msg);
if (res != FFA_OK) {
- EMSG("test_mem_multi_sharing(): error % in %s:%d"PRId32, res,
- __FILE__,
- __LINE__);
+ EMSG("Failed to send TRY_W_ACCESS command: %"PRId32, res);
return_error((uint32_t)ERR_SP_SHARE, msg);
return;
}
@@ -748,15 +734,13 @@
handle >> 32, 0, 0, msg);
if (res != FFA_OK) {
- EMSG("test_mem_multi_sharing(): error % in %s:%d"PRId32, res,
- __FILE__,
- __LINE__);
+ EMSG("Failed to send relinquish command: %"PRId32, res);
return_error((uint32_t)ERR_SP_SHARE, msg);
return;
}
if (ffa_mem_reclaim(handle, 0) != FFA_OK) {
- EMSG("All memory should have been relinquished!");
+ EMSG("Failed to reclaim memory: %"PRId32, res);
err = (uint32_t)ERR_SP_SHARE;
goto err;
}
@@ -771,6 +755,104 @@
return_error(err, msg);
}
+#define TEST_FFA_MEM_SHARE(len, handle, expected) \
+do { \
+ ffa_result res = FFA_OK; \
+ res = ffa_mem_share_rxtx(len, len, handle); \
+ if (res != expected) { \
+ EMSG("Invalid FFA_MEM_SHARE result: expected = %d, actual = %d", \
+ expected, res); \
+ return -1; \
+ } \
+} while (0)
+
+static int test_mem_sharing_invalid(uint16_t service_ep_id)
+{
+ uint64_t handle = 0;
+ uint16_t own_id = 0;
+ size_t len = 0;
+ struct ffa_mem_transaction_desc *transaction = NULL;
+ struct ffa_mem_access_desc *acc_desc = NULL;
+ struct ffa_composite_mem_region_desc *comp_desc = NULL;
+ struct ffa_constituent_mem_region_desc *region = NULL;
+
+ memset((void *)tx_buffer, 0x00, sizeof(tx_buffer));
+
+ transaction = (struct ffa_mem_transaction_desc *)tx_buffer;
+
+ ffa_id_get(&own_id);
+
+ transaction->sender_id = own_id;
+ transaction->mem_region_attr = 0x24;
+ transaction->flags = 0;
+ transaction->handle = 0;
+ transaction->tag = 0;
+
+ len = sizeof(*transaction);
+
+ /* Zero offset, size and count */
+ TEST_FFA_MEM_SHARE(len, &handle, FFA_INVALID_PARAMETERS);
+
+#if CFG_FFA_VERSION >= FFA_VERSION_1_1
+ /* Zero count */
+ transaction->mem_access_desc_size = sizeof(struct ffa_mem_access_desc);
+ transaction->mem_access_desc_offset = sizeof(*transaction);
+#endif /* CFG_FFA_VERSION */
+
+ /* Too many mem access desc */
+ transaction->mem_access_desc_count = sizeof(tx_buffer);
+ TEST_FFA_MEM_SHARE(len, &handle, FFA_INVALID_PARAMETERS);
+
+ transaction->mem_access_desc_count = 1;
+
+#if CFG_FFA_VERSION >= FFA_VERSION_1_1
+ /* Invalid offset */
+ transaction->mem_access_desc_offset = sizeof(tx_buffer);
+ TEST_FFA_MEM_SHARE(len, &handle, FFA_INVALID_PARAMETERS);
+
+ transaction->mem_access_desc_offset = sizeof(*transaction);
+#endif /* CFG_FFA_VERSION */
+
+ acc_desc = (struct ffa_mem_access_desc *)(tx_buffer + len);
+ len += sizeof(*acc_desc);
+
+ acc_desc->mem_access_perm_desc.endpoint_id = service_ep_id;
+ acc_desc->mem_access_perm_desc.mem_access_permissions = 0x06; /* RWnX */
+
+ /* Too large memory region descriptor offset */
+ acc_desc->composite_mem_region_desc_offset = sizeof(tx_buffer);
+ TEST_FFA_MEM_SHARE(len, &handle, FFA_INVALID_PARAMETERS);
+
+ acc_desc->composite_mem_region_desc_offset = len;
+ comp_desc = (struct ffa_composite_mem_region_desc *)(tx_buffer + len);
+ len += sizeof(*comp_desc);
+
+ /* Zero pages and address ranges */
+ TEST_FFA_MEM_SHARE(len, &handle, FFA_INVALID_PARAMETERS);
+
+ region = (struct ffa_constituent_mem_region_desc *)(tx_buffer + len);
+ len += sizeof(*region);
+
+ /* One region with zero pages */
+ region->address = (uint64_t)shared_buffer;
+ comp_desc->address_range_count = 1;
+ TEST_FFA_MEM_SHARE(len, &handle, FFA_INVALID_PARAMETERS);
+
+ /* One region with not matching sum pages */
+ region->address = (uint64_t)shared_buffer;
+ comp_desc->address_range_count = 1;
+ comp_desc->total_page_count = 2;
+ region->page_count = 1;
+ TEST_FFA_MEM_SHARE(len, &handle, FFA_INVALID_PARAMETERS);
+
+ /* Too many regions */
+ comp_desc->total_page_count = sizeof(tx_buffer);
+ comp_desc->address_range_count = sizeof(tx_buffer);
+ TEST_FFA_MEM_SHARE(len, &handle, FFA_INVALID_PARAMETERS);
+
+ return 0;
+}
+
static void test_mem_sharing_inccorrect_access(uint16_t service_ep_id,
struct ffa_direct_msg *msg)
{
@@ -780,7 +862,7 @@
uint64_t handle = 0;
struct ffa_mem_transaction_buffer t_buf = {0};
uint16_t own_id = 0;
- uint16_t src_id = msg->source_id = 0;
+ uint16_t src_id = msg->source_id;
struct sp_memory_access_descriptor acc_desc = { };
set_rxtx_buf(&t_buf, NULL);
@@ -807,6 +889,11 @@
return;
}
+ if (test_mem_sharing_invalid(service_ep_id)) {
+ return_error((uint32_t)ERR_SP_SHARE, msg);
+ return;
+ }
+
msg->destination_id = own_id;
msg->source_id = src_id;
return_ok(msg);
@@ -822,7 +909,7 @@
uint64_t handle2 = 0;
struct ffa_mem_transaction_buffer t_buf = {0};
uint16_t own_id = 0;
- uint16_t src_id = msg->source_id = 0;
+ uint16_t src_id = msg->source_id;
struct sp_memory_access_descriptor acc_desc = { };
uint32_t err = 0;