test(ff-a): bind and unbind notifications
Added tests to FFA_NOTIFICATION_BIND and FFA_NOTIFICATION_UNBIND calls:
- Cactus is requested to perform bind and unbind operations, using
test commands from previous commits.
- Use both calls in TFTF, to test use from VMs.
Signed-off-by: J-Alves <joao.alves@arm.com>
Change-Id: I970882a8f5de960e661f1c7fba01fc4870d8c40f
diff --git a/include/runtime_services/ffa_svc.h b/include/runtime_services/ffa_svc.h
index 621b000..df19f98 100644
--- a/include/runtime_services/ffa_svc.h
+++ b/include/runtime_services/ffa_svc.h
@@ -133,6 +133,8 @@
FFA_FID(SMC_32, FFA_FNUM_NOTIFICATION_BITMAP_DESTROY)
#define FFA_NOTIFICATION_BIND FFA_FID(SMC_32, FFA_FNUM_NOTIFICATION_BIND)
#define FFA_NOTIFICATION_UNBIND FFA_FID(SMC_32, FFA_FNUM_NOTIFICATION_UNBIND)
+#define FFA_NOTIFICATION_SET FFA_FID(SMC_32, FFA_FNUM_NOTIFICATION_SET)
+#define FFA_NOTIFICATION_GET FFA_FID(SMC_32, FFA_FNUM_NOTIFICATION_GET)
#define FFA_SPM_ID_GET FFA_FID(SMC_32, FFA_FNUM_SPM_ID_GET)
/* FFA SMC64 FIDs */
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_notifications.c b/tftf/tests/runtime_services/secure_service/test_ffa_notifications.c
index fb71f48..bc7e32b 100644
--- a/tftf/tests/runtime_services/secure_service/test_ffa_notifications.c
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_notifications.c
@@ -15,6 +15,16 @@
#include <spm_common.h>
#include <test_helpers.h>
+static const struct ffa_uuid expected_sp_uuids[] = {
+ {PRIMARY_UUID}, {SECONDARY_UUID}, {TERTIARY_UUID}
+};
+
+static ffa_notification_bitmap_t g_notifications = FFA_NOTIFICATION(0) |
+ FFA_NOTIFICATION(1) |
+ FFA_NOTIFICATION(30) |
+ FFA_NOTIFICATION(50) |
+ FFA_NOTIFICATION(63);
+
/**
* Helper to create bitmap for NWd VMs.
*/
@@ -120,3 +130,235 @@
return TEST_RESULT_SUCCESS;
}
+
+/**
+ * Helper function to test FFA_NOTIFICATION_BIND interface.
+ * Receives all arguments to use 'cactus_notification_bind_send_cmd', and
+ * expected response for the test command.
+ *
+ * Returns:
+ * - 'true' if response was obtained and it was as expected;
+ * - 'false' if there was an error with use of FFA_MSG_SEND_DIRECT_REQ, or
+ * the obtained response was not as expected.
+ */
+static bool request_notification_bind(
+ ffa_id_t cmd_dest, ffa_id_t receiver, ffa_id_t sender,
+ ffa_notification_bitmap_t notifications, uint32_t flags,
+ uint32_t expected_resp, uint32_t error_code)
+{
+ smc_ret_values ret;
+
+ VERBOSE("TFTF requesting SP to bind notifications!\n");
+
+ ret = cactus_notification_bind_send_cmd(HYP_ID, cmd_dest, receiver,
+ sender, notifications, flags);
+
+ return is_expected_cactus_response(ret, expected_resp, error_code);
+}
+
+/**
+ * Helper function to test FFA_NOTIFICATION_UNBIND interface.
+ * Receives all arguments to use 'cactus_notification_unbind_send_cmd', and
+ * expected response for the test command.
+ *
+ * Returns:
+ * - 'true' if response was obtained and it was as expected;
+ * - 'false' if there was an error with use of FFA_MSG_SEND_DIRECT_REQ, or
+ * the obtained response was not as expected.
+ */
+static bool request_notification_unbind(
+ ffa_id_t cmd_dest, ffa_id_t receiver, ffa_id_t sender,
+ ffa_notification_bitmap_t notifications, uint32_t expected_resp,
+ uint32_t error_code)
+{
+ smc_ret_values ret;
+
+ VERBOSE("TFTF requesting SP to unbind notifications!\n");
+
+ ret = cactus_notification_unbind_send_cmd(HYP_ID, cmd_dest, receiver,
+ sender, notifications);
+
+ return is_expected_cactus_response(ret, expected_resp, error_code);
+}
+
+/**
+ * Test calls from SPs to the bind and unbind interfaces, expecting success
+ * returns.
+ * This test issues a request via direct messaging to the SP, which executes
+ * the test and responds with the result of the call.
+ */
+test_result_t test_ffa_notifications_sp_bind_unbind(void)
+{
+ CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
+
+ /** First bind... */
+ if (!request_notification_bind(SP_ID(1), SP_ID(1), SP_ID(2),
+ g_notifications, 0, CACTUS_SUCCESS, 0)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ if (!request_notification_bind(SP_ID(1), SP_ID(1), 1,
+ g_notifications, 0, CACTUS_SUCCESS, 0)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ /** ... then unbind using the same arguments. */
+ if (!request_notification_unbind(SP_ID(1), SP_ID(1), SP_ID(2),
+ g_notifications, CACTUS_SUCCESS, 0)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ if (!request_notification_unbind(SP_ID(1), SP_ID(1), 1,
+ g_notifications, CACTUS_SUCCESS, 0)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
+
+/**
+ * Test successful attempt of doing bind and unbind of the same set of
+ * notifications.
+ */
+test_result_t test_ffa_notifications_vm_bind_unbind(void)
+{
+ CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
+ const ffa_id_t vm_id = 1;
+ smc_ret_values ret;
+
+ if (!notifications_bitmap_create(vm_id, 1)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ ret = ffa_notification_bind(SP_ID(2), vm_id, 0, g_notifications);
+
+ if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ ret = ffa_notification_unbind(SP_ID(2), vm_id, g_notifications);
+
+ if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ if (!notifications_bitmap_destroy(vm_id)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
+
+/**
+ * Test expected failure of using a NS FF-A ID for the sender.
+ */
+test_result_t test_ffa_notifications_vm_bind_vm(void)
+{
+ CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
+ const ffa_id_t vm_id = 1;
+ const ffa_id_t sender_id = 2;
+ smc_ret_values ret;
+
+ if (!notifications_bitmap_create(vm_id, 1)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ ret = ffa_notification_bind(sender_id, vm_id, 0, g_notifications);
+
+ if (!is_expected_ffa_error(ret, FFA_ERROR_INVALID_PARAMETER)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ if (!notifications_bitmap_destroy(vm_id)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
+
+/**
+ * Test failure of both bind and unbind in case at least one notification is
+ * already bound to another FF-A endpoint.
+ * Expect error code FFA_ERROR_DENIED.
+ */
+test_result_t test_ffa_notifications_already_bound(void)
+{
+ CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
+
+ /** Bind first to test */
+ if (!request_notification_bind(SP_ID(1), SP_ID(1), SP_ID(2),
+ g_notifications, 0, CACTUS_SUCCESS, 0)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ /** Attempt to bind notifications bound in above request. */
+ if (!request_notification_bind(SP_ID(1), SP_ID(1), SP_ID(3),
+ g_notifications, 0, CACTUS_ERROR,
+ FFA_ERROR_DENIED)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ /** Attempt to unbind notifications bound in initial request. */
+ if (!request_notification_unbind(SP_ID(1), SP_ID(1), SP_ID(3),
+ g_notifications, CACTUS_ERROR,
+ FFA_ERROR_DENIED)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ /** Reset the state the SP's notifications state. */
+ if (!request_notification_unbind(SP_ID(1), SP_ID(1), SP_ID(2),
+ g_notifications, CACTUS_SUCCESS, 0)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
+
+/**
+ * Try to bind/unbind notifications spoofing the identity of the receiver.
+ * Commands will be sent to SP_ID(1), which will use SP_ID(3) as the receiver.
+ * Expect error code FFA_ERROR_INVALID_PARAMETER.
+ */
+test_result_t test_ffa_notifications_bind_unbind_spoofing(void)
+{
+ ffa_notification_bitmap_t notifications = FFA_NOTIFICATION(8);
+
+ CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
+
+ if (!request_notification_bind(SP_ID(1), SP_ID(3), SP_ID(2),
+ notifications, 0, CACTUS_ERROR,
+ FFA_ERROR_INVALID_PARAMETER)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ if (!request_notification_unbind(SP_ID(1), SP_ID(3), SP_ID(2),
+ notifications, CACTUS_ERROR,
+ FFA_ERROR_INVALID_PARAMETER)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
+
+/**
+ * Call FFA_NOTIFICATION_BIND with notifications bitmap zeroed.
+ * Expecting error code FFA_ERROR_INVALID_PARAMETER.
+ */
+test_result_t test_ffa_notifications_bind_unbind_zeroed(void)
+{
+ CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
+
+ if (!request_notification_bind(SP_ID(1), SP_ID(1), SP_ID(2),
+ 0, 0, CACTUS_ERROR,
+ FFA_ERROR_INVALID_PARAMETER)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ if (!request_notification_unbind(SP_ID(1), SP_ID(1), SP_ID(2),
+ 0, CACTUS_ERROR,
+ FFA_ERROR_INVALID_PARAMETER)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
diff --git a/tftf/tests/tests-spm.xml b/tftf/tests/tests-spm.xml
index 9746599..d5634d3 100644
--- a/tftf/tests/tests-spm.xml
+++ b/tftf/tests/tests-spm.xml
@@ -108,6 +108,18 @@
function="test_ffa_notifications_destroy_not_created" />
<testcase name="Notifications bitmap create after create"
function="test_ffa_notifications_create_after_create" />
+ <testcase name="SP Notifications bind and unbind"
+ function="test_ffa_notifications_sp_bind_unbind" />
+ <testcase name="VM Notifications bind and unbind"
+ function="test_ffa_notifications_vm_bind_unbind" />
+ <testcase name="VM Notifications bind NS Sender"
+ function="test_ffa_notifications_vm_bind_vm" />
+ <testcase name="Notifications bind/unbind of bound Notifications"
+ function="test_ffa_notifications_already_bound" />
+ <testcase name="Notifications bind/unbind SPs spoofing receiver"
+ function="test_ffa_notifications_bind_unbind_spoofing" />
+ <testcase name="Notifications zeroed in bind and unbind"
+ function="test_ffa_notifications_bind_unbind_zeroed" />
</testsuite>
</testsuites>