test(indirect message): aborted send from SP to VM
Test that if the RX buffer of VM is put on the realm
PAS and an SP attempts to send a message to it, the
operation terminates smoothly.
Change-Id: Ie7fd316a6256b1c3445dfb7cb8fe1bbd09fffb6e
Signed-off-by: J-Alves <joao.alves@arm.com>
diff --git a/spm/cactus/cactus_tests/cactus_test_indirect_message.c b/spm/cactus/cactus_tests/cactus_test_indirect_message.c
index 3b8b46c..085d72f 100644
--- a/spm/cactus/cactus_tests/cactus_test_indirect_message.c
+++ b/spm/cactus/cactus_tests/cactus_test_indirect_message.c
@@ -31,7 +31,7 @@
ERROR("Failed to send indirect message.\n");
return cactus_error_resp(vm_id,
source,
- CACTUS_ERROR_TEST);
+ ffa_error_code(ret));
}
return cactus_success_resp(vm_id, source, 0);
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_indirect_messaging.c b/tftf/tests/runtime_services/secure_service/test_ffa_indirect_messaging.c
index cb1029e..35c8301 100644
--- a/tftf/tests/runtime_services/secure_service/test_ffa_indirect_messaging.c
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_indirect_messaging.c
@@ -13,6 +13,7 @@
#include <cactus_test_cmds.h>
#include <ffa_endpoints.h>
#include <ffa_svc.h>
+#include <host_realm_helper.h>
#include <platform.h>
#include <spm_test_helpers.h>
#include <test_helpers.h>
@@ -21,6 +22,8 @@
{PRIMARY_UUID},
};
+const char expected_msg[] = "Testing FF-A message.";
+
/*
*
* Used as the RX/TX buffers belonging to VM 1 in the forwarding FFA_RXTX_MAP
@@ -36,7 +39,6 @@
ffa_id_t header_sender;
const ffa_id_t vm_id = 1;
const ffa_id_t sender = SP_ID(1);
- const char expected_msg[] = "Testing FF-A message.";
char msg[300];
/**********************************************************************
@@ -99,3 +101,134 @@
return TEST_RESULT_SUCCESS;
}
+
+/**
+ * Test message sent from SP to VM when VM's RX is realm, the operation fails
+ * smoothly.
+ */
+test_result_t test_ffa_indirect_message_sp_to_vm_rx_realm_fail(void)
+{
+ struct ffa_value ret;
+ struct mailbox_buffers mb;
+ const ffa_id_t vm_id = 1;
+ const ffa_id_t sender = SP_ID(1);
+ ffa_id_t header_sender;
+ u_register_t ret_rmm;
+ char msg[300];
+
+ if (get_armv9_2_feat_rme_support() == 0U) {
+ return TEST_RESULT_SKIPPED;
+ }
+
+ /**********************************************************************
+ * Check SPMC has ffa_version and expected FF-A endpoints are deployed.
+ **********************************************************************/
+ CHECK_SPMC_TESTING_SETUP(1, 2, expected_sp_uuids);
+
+ GET_TFTF_MAILBOX(mb);
+
+ /* Map RXTX buffers into SPMC translation. */
+ ret = ffa_rxtx_map_forward(mb.send, vm_id, vm1_rx_buffer,
+ vm1_tx_buffer);
+
+ if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32)) {
+ ERROR("Failed to map buffers RX %p TX %p for VM %x\n",
+ vm1_rx_buffer, vm1_tx_buffer, vm_id);
+ return TEST_RESULT_FAIL;
+ }
+
+ /*
+ * Create bitmap only to then demonstrate that the message can't
+ * be sent, as there are no pending notifications to the VM.
+ */
+ ret = ffa_notification_bitmap_create(vm_id, PLATFORM_CORE_COUNT);
+
+ if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32)) {
+ ERROR("Failed to create bitmap for vm %x\n", vm_id);
+ return TEST_RESULT_FAIL;
+ }
+
+ /*
+ * Delegate RX buffer of VM to realm.
+ */
+ ret_rmm = host_rmi_granule_delegate((u_register_t)vm1_rx_buffer);
+
+ if (ret_rmm != 0UL) {
+ INFO("Delegate operation returns %#lx for address %p\n",
+ ret_rmm, mb.send);
+ return TEST_RESULT_FAIL;
+ }
+
+ /* Request SP to send message. */
+ ret = cactus_req_ind_msg_send_cmd(
+ HYP_ID, sender, vm_id, sender, 0);
+
+ if (!is_ffa_direct_response(ret) &&
+ cactus_get_response(ret) != FFA_ERROR_ABORTED) {
+ return TEST_RESULT_FAIL;
+ }
+
+ /* Undelegate to reestablish the same security state for PAS. */
+ ret_rmm = host_rmi_granule_undelegate((u_register_t)vm1_rx_buffer);
+
+ if (ret_rmm != 0UL) {
+ INFO("Undelegate operation returns %#lx for address %p\n",
+ ret_rmm, mb.send);
+ return TEST_RESULT_FAIL;
+ }
+
+ /* Expect that attempting to receive message shall fail. */
+ if (receive_indirect_message(&msg, ARRAY_SIZE(msg), (void *)vm1_rx_buffer,
+ NULL, vm_id, 0)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ /*
+ * Redo the test so we check after undelegating the memory.
+ * After undelegating, the SPMC should be able to complete the
+ * operation.
+ */
+ ret = cactus_req_ind_msg_send_cmd(
+ HYP_ID, sender, vm_id, sender, 0);
+
+ if (!is_ffa_direct_response(ret) &&
+ cactus_get_response(ret) != CACTUS_SUCCESS) {
+ return TEST_RESULT_FAIL;
+ }
+
+ if (!receive_indirect_message(&msg, ARRAY_SIZE(msg), (void *)vm1_rx_buffer,
+ &header_sender, vm_id, 0)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ if (strncmp(msg, expected_msg, ARRAY_SIZE(expected_msg)) != 0) {
+ ERROR("Unexpected message: %s, expected: %s\n", msg, expected_msg);
+ return TEST_RESULT_FAIL;
+ }
+
+ if (header_sender != sender) {
+ ERROR("Unexpected endpoints. Sender: %x Expected: %x\n",
+ header_sender, sender);
+ return TEST_RESULT_FAIL;
+ }
+
+ /* Cleaning up after the test: */
+
+ /* Destroy bitmap of VM. */
+ ret = ffa_notification_bitmap_destroy(vm_id);
+
+ if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32)) {
+ ERROR("Failed to destroy bitmap for vm %x\n", vm_id);
+ return TEST_RESULT_FAIL;
+ }
+
+ /* Unmap RXTX buffers into SPMC translation. */
+ ret = ffa_rxtx_unmap_with_id(vm_id);
+
+ if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32)) {
+ ERROR("Failed to unmap RXTX for vm %x\n", vm_id);
+ return TEST_RESULT_FAIL;
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
diff --git a/tftf/tests/tests-memory-access.mk b/tftf/tests/tests-memory-access.mk
index 82ea094..5c71b2e 100644
--- a/tftf/tests/tests-memory-access.mk
+++ b/tftf/tests/tests-memory-access.mk
@@ -28,4 +28,5 @@
test_ffa_setup_and_discovery.c \
spm_test_helpers.c \
test_ffa_exceptions.c \
+ test_ffa_indirect_messaging.c \
)
diff --git a/tftf/tests/tests-memory-access.xml b/tftf/tests/tests-memory-access.xml
index 3ed3bfa..360e07f 100644
--- a/tftf/tests/tests-memory-access.xml
+++ b/tftf/tests/tests-memory-access.xml
@@ -65,6 +65,8 @@
function="test_ffa_mem_lend_sp_realm_memory_separate_constituent" />
<testcase name="FF-A partition info get after NWd RX is in realm PAS"
function="test_ffa_rxtx_to_realm_pas" />
+ <testcase name="FF-A Indirect message fails if VM RX is realm"
+ function="test_ffa_indirect_message_sp_to_vm_rx_realm_fail" />
</testsuite>
</testsuites>