diff options
author | J-Alves <joao.alves@arm.com> | 2021-03-29 15:25:19 +0100 |
---|---|---|
committer | J-Alves <joao.alves@arm.com> | 2021-10-12 12:21:23 +0100 |
commit | d63ae4bc3fb0b949fc88c31764b8dafada50772b (patch) | |
tree | fe46100666e1bd2f548b2dc8b190e31b7be2cff3 /tftf | |
parent | ab77591a017b6a7722c4fc03e7efc06161afd8c1 (diff) | |
download | tf-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.c | 288 | ||||
-rw-r--r-- | tftf/tests/tests-spm.xml | 8 |
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> |