aboutsummaryrefslogtreecommitdiff
path: root/tftf
diff options
context:
space:
mode:
authorJ-Alves <joao.alves@arm.com>2021-03-29 15:25:19 +0100
committerJ-Alves <joao.alves@arm.com>2021-10-12 12:21:23 +0100
commitd63ae4bc3fb0b949fc88c31764b8dafada50772b (patch)
treefe46100666e1bd2f548b2dc8b190e31b7be2cff3 /tftf
parentab77591a017b6a7722c4fc03e7efc06161afd8c1 (diff)
downloadtf-a-tests-d63ae4bc3fb0b949fc88c31764b8dafada50772b.tar.gz
test(ff-a): notifications set and get interfaces
Signed-off-by: J-Alves <joao.alves@arm.com> Change-Id: Ibcfb415735ac7500752f70016c690457b13409b7
Diffstat (limited to 'tftf')
-rw-r--r--tftf/tests/runtime_services/secure_service/test_ffa_notifications.c288
-rw-r--r--tftf/tests/tests-spm.xml8
2 files changed, 296 insertions, 0 deletions
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 bc7e32b27..85a93a6f8 100644
--- a/tftf/tests/runtime_services/secure_service/test_ffa_notifications.c
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_notifications.c
@@ -362,3 +362,291 @@ test_result_t test_ffa_notifications_bind_unbind_zeroed(void)
return TEST_RESULT_SUCCESS;
}
+
+/**
+ * Helper function to test FFA_NOTIFICATION_GET interface.
+ * Receives all arguments to use 'cactus_notification_get_send_cmd', and returns
+ * the received response. Depending on the testing scenario, this will allow
+ * to validate if the returned bitmaps are as expected.
+ *
+ * Returns:
+ * - 'true' if response was obtained.
+ * - 'false' if there was an error sending the request.
+ */
+static bool request_notification_get(
+ ffa_id_t cmd_dest, ffa_id_t receiver, uint32_t vcpu_id,
+ uint32_t flags, smc_ret_values *response)
+{
+ VERBOSE("TFTF requesting SP to get notifications!\n");
+
+ *response = cactus_notification_get_send_cmd(HYP_ID, cmd_dest,
+ receiver, vcpu_id,
+ flags);
+
+ return is_ffa_direct_response(*response);
+}
+
+static bool request_notification_set(
+ ffa_id_t cmd_dest, ffa_id_t receiver, ffa_id_t sender, uint32_t flags,
+ ffa_notification_bitmap_t notifications, uint32_t exp_resp,
+ int32_t exp_error)
+{
+ smc_ret_values ret;
+
+ VERBOSE("TFTF requesting SP %x (as %x) to set notifications to %x\n",
+ cmd_dest, sender, receiver);
+
+ ret = cactus_notifications_set_send_cmd(HYP_ID, cmd_dest, receiver,
+ sender, flags, notifications);
+
+ return is_expected_cactus_response(ret, exp_resp, exp_error);
+}
+
+/**
+ * Check that SP's response to CACTUS_NOTIFICATION_GET_CMD is as expected.
+ */
+static bool is_notifications_get_as_expected(
+ smc_ret_values *ret, uint64_t exp_from_sp, uint64_t exp_from_vm,
+ ffa_id_t receiver)
+{
+ uint64_t from_sp;
+ uint64_t from_vm;
+ bool success_ret;
+
+ /**
+ * If receiver ID is SP, this is to evaluate the response to test
+ * command 'CACTUS_NOTIFICATION_GET_CMD'.
+ */
+ if (IS_SP_ID(receiver)) {
+ success_ret = (cactus_get_response(*ret) == CACTUS_SUCCESS);
+ from_sp = cactus_notifications_get_from_sp(*ret);
+ from_vm = cactus_notifications_get_from_vm(*ret);
+ } else {
+ /**
+ * Else, this is to evaluate the return of FF-A call:
+ * ffa_notification_get.
+ */
+ success_ret = (ffa_func_id(*ret) == FFA_SUCCESS_SMC32);
+ from_sp = ffa_notifications_get_from_sp(*ret);
+ from_vm = ffa_notifications_get_from_vm(*ret);
+ }
+
+ if (success_ret != true ||
+ exp_from_sp != from_sp ||
+ exp_from_vm != from_vm) {
+ VERBOSE("Notifications not as expected:\n"
+ " from sp: %llx exp: %llx\n"
+ " from vm: %llx exp: %llx\n",
+ from_sp, exp_from_sp, from_vm, exp_from_vm);
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * Helper to bind notification and set it.
+ * If receiver is SP it will request SP to perform the bind, else invokes
+ * FFA_NOTIFICATION_BIND.
+ * If Sender is SP it will request it to perform the set, else invokes
+ * FFA_NOTIFICATION_SET.
+ */
+static bool notification_bind_and_set(ffa_id_t sender,
+ ffa_id_t receiver, ffa_notification_bitmap_t notifications, uint32_t flags)
+{
+ smc_ret_values ret;
+ uint32_t flags_bind = flags & FFA_NOTIFICATIONS_FLAG_PER_VCPU;
+
+ /* Receiver binds notifications to sender. */
+ if (!IS_SP_ID(receiver)) {
+ ret = ffa_notification_bind(sender, receiver,
+ flags_bind, notifications);
+
+ if (is_ffa_call_error(ret)) {
+ return false;
+ }
+ } else {
+ if (!request_notification_bind(receiver, receiver, sender,
+ notifications, flags_bind,
+ CACTUS_SUCCESS,
+ 0)) {
+ return false;
+ }
+ }
+
+ /* Sender sets notifications to receiver. */
+ if (!IS_SP_ID(sender)) {
+ VERBOSE("VM %x Setting notifications %llx to receiver %x\n",
+ sender, notifications, receiver);
+ ret = ffa_notification_set(sender, receiver, flags, notifications);
+
+ return is_expected_ffa_return(ret, FFA_SUCCESS_SMC32);
+ }
+
+ return request_notification_set(sender, receiver, sender, flags,
+ notifications, CACTUS_SUCCESS, 0);
+}
+
+/**
+ * Helper to request SP to get the notifications and validate the return.
+ */
+static bool notification_get_and_validate(
+ ffa_id_t receiver, ffa_notification_bitmap_t exp_from_sp,
+ ffa_notification_bitmap_t exp_from_vm, uint32_t vcpu_id,
+ uint32_t flags)
+{
+ smc_ret_values ret;
+
+ /* Receiver gets pending notifications. */
+ if (IS_SP_ID(receiver)) {
+ request_notification_get(receiver, receiver, vcpu_id, flags,
+ &ret);
+ } else {
+ ret = ffa_notification_get(receiver, vcpu_id, flags);
+ }
+
+ return is_notifications_get_as_expected(&ret, exp_from_sp, exp_from_vm,
+ receiver);
+}
+
+/**
+ * Test to validate a VM can signal an SP.
+ */
+test_result_t test_ffa_notifications_vm_signals_sp(void)
+{
+ CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
+ const ffa_id_t sender = 1;
+ const ffa_id_t receiver = SP_ID(1);
+ ffa_notification_bitmap_t notifications = FFA_NOTIFICATION(1) | FFA_NOTIFICATION(60);
+ const uint32_t flags_get = FFA_NOTIFICATIONS_FLAG_BITMAP_VM;
+
+ if (!notification_bind_and_set(sender, receiver, notifications, 0)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ if (!notification_get_and_validate(receiver, 0, notifications, 0,
+ flags_get)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ if (!request_notification_unbind(receiver, receiver, sender,
+ notifications, CACTUS_SUCCESS, 0)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
+
+/**
+ * Test to validate an SP can signal an SP.
+ */
+test_result_t test_ffa_notifications_sp_signals_sp(void)
+{
+ CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
+ const ffa_id_t sender = SP_ID(1);
+ const ffa_id_t receiver = SP_ID(2);
+ uint32_t get_flags = FFA_NOTIFICATIONS_FLAG_BITMAP_SP;
+
+ /** Request receiver to bind a set of notifications to the sender */
+ if (!notification_bind_and_set(sender, receiver,
+ g_notifications, 0)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ if (!notification_get_and_validate(receiver, g_notifications, 0, 0,
+ get_flags)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ if (!request_notification_unbind(receiver, receiver, sender,
+ g_notifications, CACTUS_SUCCESS, 0)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
+
+/**
+ * Test to validate an SP can signal a VM.
+ */
+test_result_t test_ffa_notifications_sp_signals_vm(void)
+{
+ CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
+ const ffa_id_t sender = SP_ID(1);
+ const ffa_id_t receiver = 1;
+ uint32_t get_flags = FFA_NOTIFICATIONS_FLAG_BITMAP_SP;
+ smc_ret_values ret;
+
+ /* Ask SPMC to allocate notifications bitmap. */
+ if (!notifications_bitmap_create(receiver, 1)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ /* Request receiver to bind a set of notifications to the sender. */
+ if (!notification_bind_and_set(sender, receiver, g_notifications, 0)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ /* Get pending notifications, and retrieve response. */
+ if (!notification_get_and_validate(receiver, g_notifications, 0, 0,
+ get_flags)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ ret = ffa_notification_unbind(sender, receiver, g_notifications);
+
+ if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ if (!notifications_bitmap_destroy(receiver)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
+
+/**
+ * Test to validate it is not possible to unbind a pending notification.
+ */
+test_result_t test_ffa_notifications_unbind_pending(void)
+{
+ CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
+ const ffa_id_t receiver = SP_ID(1);
+ const ffa_id_t sender = 1;
+ const ffa_notification_bitmap_t notifications = FFA_NOTIFICATION(30) |
+ FFA_NOTIFICATION(35);
+ uint32_t get_flags = FFA_NOTIFICATIONS_FLAG_BITMAP_VM;
+
+ /* Request receiver to bind a set of notifications to the sender. */
+ if (!notification_bind_and_set(sender, receiver, notifications, 0)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ /*
+ * Attempt to unbind the pending notification, but expect error return
+ * given the notification is pending.
+ */
+ if (!request_notification_unbind(receiver, receiver, sender,
+ FFA_NOTIFICATION(30),
+ CACTUS_ERROR, FFA_ERROR_DENIED)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ /*
+ * Request receiver partition to get pending notifications from VMs.
+ * Only notification 30 is expected.
+ */
+ if (!notification_get_and_validate(receiver, 0, notifications, 0,
+ get_flags)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ /* Unbind all notifications, to not interfere with other tests. */
+ if (!request_notification_unbind(receiver, receiver, sender,
+ notifications, CACTUS_SUCCESS, 0)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
diff --git a/tftf/tests/tests-spm.xml b/tftf/tests/tests-spm.xml
index d5634d378..b59ca0b85 100644
--- a/tftf/tests/tests-spm.xml
+++ b/tftf/tests/tests-spm.xml
@@ -120,6 +120,14 @@
function="test_ffa_notifications_bind_unbind_spoofing" />
<testcase name="Notifications zeroed in bind and unbind"
function="test_ffa_notifications_bind_unbind_zeroed" />
+ <testcase name="Notifications VM signals SP"
+ function="test_ffa_notifications_vm_signals_sp" />
+ <testcase name="Notifications SP signals SP"
+ function="test_ffa_notifications_sp_signals_sp" />
+ <testcase name="Notifications SP signals VM"
+ function="test_ffa_notifications_sp_signals_vm" />
+ <testcase name="Notifications unbind while pending"
+ function="test_ffa_notifications_unbind_pending" />
</testsuite>
</testsuites>