test(memory share): lend device memory region to sp
Add test to check that a device memory region can be successfully
lent to an sp.
This requires some refactoring of the memory sharing test flow so
as to use the correct memory type and cachebility attributes for
the memory being lent. Also limit the words being written to 1
word for device memory so we only write to the data register of the
device.
Also only map device regions from UART2 so that UART0 can be used
by TFTF in the device sharing test.
Signed-off-by: Daniel Boulby <daniel.boulby@arm.com>
Change-Id: I9f31769679883f34e0444db75a873765776a85e9
diff --git a/include/runtime_services/cactus_test_cmds.h b/include/runtime_services/cactus_test_cmds.h
index 0630753..282cfbe 100644
--- a/include/runtime_services/cactus_test_cmds.h
+++ b/include/runtime_services/cactus_test_cmds.h
@@ -201,10 +201,12 @@
static inline struct ffa_value cactus_mem_send_cmd(
ffa_id_t source, ffa_id_t dest, uint32_t mem_func,
ffa_memory_handle_t handle, ffa_memory_region_flags_t retrieve_flags,
- uint16_t word_to_write, bool expect_exception)
+ uint16_t word_to_write, bool expect_exception, bool is_normal_memory)
{
uint64_t _expect_exception = expect_exception ? (1ULL << 32) : 0;
- uint64_t packed = (uint64_t)word_to_write | _expect_exception;
+ uint64_t _is_normal_memory = is_normal_memory ? (1ULL << 33) : 0;
+ uint64_t packed = (uint64_t)word_to_write | _expect_exception |
+ _is_normal_memory;
return cactus_send_cmd(source, dest, CACTUS_MEM_SEND_CMD, mem_func,
handle, retrieve_flags, packed);
@@ -229,7 +231,12 @@
static inline bool cactus_mem_send_expect_exception(struct ffa_value ret)
{
- return (bool)(ret.arg7 >> 32);
+ return (bool)((ret.arg7 >> 32) & 0x1);
+}
+
+static inline bool cactus_mem_send_is_normal_memory(struct ffa_value ret)
+{
+ return (bool)((ret.arg7 >> 33) & 0x1);
}
/**
diff --git a/include/runtime_services/spm_common.h b/include/runtime_services/spm_common.h
index 6c01751..3fe154a 100644
--- a/include/runtime_services/spm_common.h
+++ b/include/runtime_services/spm_common.h
@@ -113,7 +113,8 @@
bool memory_retrieve(struct mailbox_buffers *mb,
struct ffa_memory_region **retrieved, uint64_t handle,
ffa_id_t sender, struct ffa_memory_access receivers[],
- uint32_t receiver_count, ffa_memory_region_flags_t flags);
+ uint32_t receiver_count, ffa_memory_region_flags_t flags,
+ bool is_normal_memory);
bool hypervisor_retrieve_request(struct mailbox_buffers *mb, uint64_t handle,
void *out, uint32_t out_size);
diff --git a/spm/cactus/cactus_main.c b/spm/cactus/cactus_main.c
index 1d5cd97..cc17da9 100644
--- a/spm/cactus/cactus_main.c
+++ b/spm/cactus/cactus_main.c
@@ -111,9 +111,9 @@
}
static const mmap_region_t cactus_mmap[] __attribute__((used)) = {
- /* PLAT_ARM_DEVICE0 area includes UART2 necessary to console */
- MAP_REGION_FLAT(PLAT_ARM_DEVICE0_BASE, PLAT_ARM_DEVICE0_SIZE,
+ MAP_REGION_FLAT(PLAT_CACTUS_DEVICE_BASE, PLAT_CACTUS_DEVICE_SIZE,
MT_DEVICE | MT_RW),
+
/* scratch memory allocated to be used for running SMMU tests */
MAP_REGION_FLAT(PLAT_CACTUS_MEMCPY_BASE, PLAT_CACTUS_MEMCPY_RANGE,
MT_MEMORY | MT_RW),
diff --git a/spm/cactus/cactus_tests/cactus_test_memory_sharing.c b/spm/cactus/cactus_tests/cactus_test_memory_sharing.c
index 811c79f..570c648 100644
--- a/spm/cactus/cactus_tests/cactus_test_memory_sharing.c
+++ b/spm/cactus/cactus_tests/cactus_test_memory_sharing.c
@@ -114,6 +114,8 @@
cactus_mem_send_get_retrv_flags(*args);
uint32_t words_to_write = cactus_mem_send_words_to_write(*args);
bool expect_exception = cactus_mem_send_expect_exception(*args);
+ bool is_normal_memory = cactus_mem_send_is_normal_memory(*args);
+
struct ffa_memory_access receiver = ffa_memory_access_init(
vm_id, FFA_DATA_ACCESS_RW,
@@ -123,7 +125,7 @@
0, NULL);
EXPECT(memory_retrieve(mb, &m, handle, source, &receiver, 1,
- retrv_flags),
+ retrv_flags, is_normal_memory),
true);
composite = ffa_memory_region_get_composite(m, 0);
@@ -337,7 +339,7 @@
}
ffa_ret = cactus_mem_send_cmd(vm_id, receiver_id, mem_func, handle,
- 0, 10, false);
+ 0, 10, false, true);
if (!is_ffa_direct_response(ffa_ret)) {
return cactus_error_resp(vm_id, source, CACTUS_ERROR_FFA_CALL);
diff --git a/spm/cactus/plat/arm/fvp/include/sp_platform_def.h b/spm/cactus/plat/arm/fvp/include/sp_platform_def.h
index bb57ce8..390294f 100644
--- a/spm/cactus/plat/arm/fvp/include/sp_platform_def.h
+++ b/spm/cactus/plat/arm/fvp/include/sp_platform_def.h
@@ -18,8 +18,13 @@
#define PLAT_SP_RX_BASE ULL(0x7300000)
#define PLAT_SP_CORE_COUNT U(8)
-#define PLAT_ARM_DEVICE0_BASE DEVICE0_BASE
-#define PLAT_ARM_DEVICE0_SIZE DEVICE0_SIZE
+/*
+ * Map the device memory starting from UART2
+ * so UART0 can be lent by tftf in the device memory sharing tests.
+ */
+#define PLAT_CACTUS_DEVICE_BASE PL011_UART2_BASE
+#define PLAT_CACTUS_DEVICE_SIZE DEVICE0_SIZE - \
+ (PLAT_CACTUS_DEVICE_BASE - DEVICE0_BASE)
/* Scratch memory used for SMMUv3 driver testing purposes in Cactus SP */
#define PLAT_CACTUS_MEMCPY_BASE ULL(0x7400000)
diff --git a/tftf/tests/runtime_services/secure_service/spm_common.c b/tftf/tests/runtime_services/secure_service/spm_common.c
index 53f4981..06e76db 100644
--- a/tftf/tests/runtime_services/secure_service/spm_common.c
+++ b/tftf/tests/runtime_services/secure_service/spm_common.c
@@ -270,12 +270,17 @@
bool memory_retrieve(struct mailbox_buffers *mb,
struct ffa_memory_region **retrieved, uint64_t handle,
ffa_id_t sender, struct ffa_memory_access receivers[],
- uint32_t receiver_count, ffa_memory_region_flags_t flags)
+ uint32_t receiver_count, ffa_memory_region_flags_t flags,
+ bool is_normal_memory)
{
struct ffa_value ret;
uint32_t fragment_size;
uint32_t total_size;
uint32_t descriptor_size;
+ enum ffa_memory_type memory_type = is_normal_memory ?
+ FFA_MEMORY_NORMAL_MEM : FFA_MEMORY_DEVICE_MEM;
+ enum ffa_memory_cacheability memory_cacheability = is_normal_memory ?
+ FFA_MEMORY_CACHE_WRITE_BACK : FFA_MEMORY_DEV_NGNRNE;
if (retrieved == NULL || mb == NULL) {
ERROR("Invalid parameters!\n");
@@ -284,8 +289,7 @@
descriptor_size = ffa_memory_retrieve_request_init(
mb->send, handle, sender, receivers, receiver_count, 0, flags,
- FFA_MEMORY_NORMAL_MEM, FFA_MEMORY_CACHE_WRITE_BACK,
- FFA_MEMORY_INNER_SHAREABLE);
+ memory_type, memory_cacheability, FFA_MEMORY_INNER_SHAREABLE);
ret = ffa_mem_retrieve_req(descriptor_size, descriptor_size);
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_exceptions.c b/tftf/tests/runtime_services/secure_service/test_ffa_exceptions.c
index cda7d22..552d2f9 100644
--- a/tftf/tests/runtime_services/secure_service/test_ffa_exceptions.c
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_exceptions.c
@@ -90,7 +90,7 @@
* Tell SP to expect an exception.
*/
ret = cactus_mem_send_cmd(SENDER, RECEIVER, FFA_MEM_SHARE_SMC64,
- handle, 0, 1, true);
+ handle, 0, 1, true, true);
/* Undelegate the shared page. */
retmm = host_rmi_granule_undelegate((u_register_t)&share_page);
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 3f7e270..ba6e72a 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
@@ -177,7 +177,7 @@
*/
static test_result_t test_memory_send_sp(uint32_t mem_func, ffa_id_t borrower,
struct ffa_memory_region_constituent *constituents,
- size_t constituents_count)
+ size_t constituents_count, bool is_normal_memory)
{
struct ffa_value ret;
ffa_memory_handle_t handle;
@@ -186,10 +186,13 @@
unsigned int rme_supported = get_armv9_2_feat_rme_support();
const bool check_gpc_fault =
mem_func != FFA_MEM_SHARE_SMC64 &&
- rme_supported != 0U;
+ rme_supported != 0U && is_normal_memory;
- /* Arbitrarily write 5 words after using memory. */
- const uint32_t nr_words_to_write = 5;
+ /*
+ * For normal memory arbitrarilty write 5 words after using memory.
+ * For device just write 1 so we only write in the data register of the device.
+ */
+ const uint32_t nr_words_to_write = is_normal_memory ? 5 : 1;
struct ffa_memory_access receiver =
ffa_memory_access_init_permissions_from_mem_func(borrower,
@@ -232,7 +235,7 @@
ptr = (uint32_t *)constituents[0].address;
ret = cactus_mem_send_cmd(SENDER, borrower, mem_func, handle, 0,
- nr_words_to_write, false);
+ nr_words_to_write, false, is_normal_memory);
if (!is_ffa_direct_response(ret) ||
cactus_get_response(ret) != CACTUS_SUCCESS) {
@@ -295,7 +298,7 @@
sizeof(struct ffa_memory_region_constituent);
return test_memory_send_sp(FFA_MEM_SHARE_SMC64, RECEIVER, constituents,
- constituents_count);
+ constituents_count, true);
}
test_result_t test_mem_lend_sp(void)
@@ -309,7 +312,7 @@
sizeof(struct ffa_memory_region_constituent);
return test_memory_send_sp(FFA_MEM_LEND_SMC64, RECEIVER, constituents,
- constituents_count);
+ constituents_count, true);
}
test_result_t test_mem_donate_sp(void)
@@ -320,7 +323,7 @@
const uint32_t constituents_count = sizeof(constituents) /
sizeof(struct ffa_memory_region_constituent);
return test_memory_send_sp(FFA_MEM_DONATE_SMC64, RECEIVER, constituents,
- constituents_count);
+ constituents_count, true);
}
test_result_t test_consecutive_donate(void)
@@ -335,7 +338,7 @@
test_result_t ret = test_memory_send_sp(FFA_MEM_DONATE_SMC64, SP_ID(1),
constituents,
- constituents_count);
+ constituents_count, true);
if (ret != TEST_RESULT_SUCCESS) {
ERROR("Failed at first attempting of sharing.\n");
@@ -362,6 +365,24 @@
}
/*
+ * Lend device memory to the Secure Partition.
+ */
+test_result_t test_ffa_mem_lend_device_memory_sp(void)
+{
+ struct ffa_memory_region_constituent constituents[] = {
+ {(void *)0x1c090000, 1, 0},
+ };
+
+ const uint32_t constituents_count = sizeof(constituents) /
+ sizeof(struct ffa_memory_region_constituent);
+
+ return test_memory_send_sp(FFA_MEM_LEND_SMC64, RECEIVER, constituents,
+ constituents_count, false);
+
+}
+
+
+/*
* Test requests a memory send operation between cactus SPs.
* Cactus SP should reply to TFTF on whether the test succeeded or not.
*/
@@ -527,7 +548,7 @@
ret = cactus_mem_send_cmd(SENDER, RECEIVER, FFA_MEM_LEND_SMC64, handle,
FFA_MEMORY_REGION_FLAG_CLEAR,
- nr_words_to_write, false);
+ nr_words_to_write, false, true);
if (!is_ffa_direct_response(ret)) {
return TEST_RESULT_FAIL;
@@ -1322,7 +1343,8 @@
return TEST_RESULT_FAIL;
}
- if (!memory_retrieve(&mb, &m, handle, 0, receivers, ARRAY_SIZE(receivers), 0)) {
+ if (!memory_retrieve(&mb, &m, handle, 0, receivers, ARRAY_SIZE(receivers),
+ 0, true)) {
ERROR("Failed to retrieve the memory.\n");
return TEST_RESULT_FAIL;
}
@@ -1503,7 +1525,8 @@
return TEST_RESULT_FAIL;
}
- if (!memory_retrieve(&mb, &m, handle, 0, receivers, ARRAY_SIZE(receivers), 0)) {
+ if (!memory_retrieve(&mb, &m, handle, 0, receivers, ARRAY_SIZE(receivers),
+ 0, true)) {
ERROR("Failed to retrieve the memory.\n");
return TEST_RESULT_FAIL;
}
diff --git a/tftf/tests/tests-memory-access.xml b/tftf/tests/tests-memory-access.xml
index 49965a0..200c5dd 100644
--- a/tftf/tests/tests-memory-access.xml
+++ b/tftf/tests/tests-memory-access.xml
@@ -18,6 +18,8 @@
function="test_mem_share_sp" />
<testcase name="Donate Memory to Secure World"
function="test_mem_donate_sp"/>
+ <testcase name="Lend Device Memory to Secure World"
+ function="test_ffa_mem_lend_device_memory_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"