blob: 4b615654e0efa8126ef6f77da3d18afb2cfbb3d4 [file] [log] [blame]
J-Alvesbb467d12021-03-18 11:49:35 +00001/*
Daniel Boulbyce386b12022-03-29 18:36:36 +01002 * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
J-Alvesbb467d12021-03-18 11:49:35 +00003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <debug.h>
J-Alves269118a2021-09-22 09:46:11 +01008#include <irq.h>
J-Alvesbb467d12021-03-18 11:49:35 +00009#include <smccc.h>
10
11#include <arch_helpers.h>
12#include <cactus_test_cmds.h>
13#include <ffa_endpoints.h>
14#include <ffa_svc.h>
15#include <platform.h>
16#include <spm_common.h>
Daniel Boulby82bf3392023-07-28 18:32:27 +010017#include <spm_test_helpers.h>
J-Alvesbb467d12021-03-18 11:49:35 +000018#include <test_helpers.h>
19
J-Alves44ec4f72021-07-27 12:07:14 +010020/**
21 * Defining variables to test the per-vCPU notifications.
22 * The conceived test follows the same logic, despite the sender receiver type
23 * of endpoint (VM or secure partition).
24 * Using global variables because these need to be accessed in the cpu on handler
25 * function 'request_notification_get_per_vcpu_on_handler'.
26 * In each specific test function, change 'per_vcpu_receiver' and
27 * 'per_vcpu_sender' have the logic work for:
28 * - NWd to SP;
29 * - SP to NWd;
30 * - SP to SP.
31 */
32static ffa_id_t per_vcpu_receiver;
33static ffa_id_t per_vcpu_sender;
34uint32_t per_vcpu_flags_get;
35static event_t per_vcpu_finished[PLATFORM_CORE_COUNT];
36
J-Alvese5f3fe62021-03-18 11:51:20 +000037static const struct ffa_uuid expected_sp_uuids[] = {
38 {PRIMARY_UUID}, {SECONDARY_UUID}, {TERTIARY_UUID}
39};
40
41static ffa_notification_bitmap_t g_notifications = FFA_NOTIFICATION(0) |
42 FFA_NOTIFICATION(1) |
43 FFA_NOTIFICATION(30) |
44 FFA_NOTIFICATION(50) |
45 FFA_NOTIFICATION(63);
46
J-Alvesbb467d12021-03-18 11:49:35 +000047/**
J-Alves4439ece2021-11-05 11:52:54 +000048 * Use FFA_FEATURES to retrieve the ID of:
49 * - Schedule Receiver Interrupt
50 * - Notification Pending Interrupt
51 * - Managed Exit Interrupt
52 * Validate the call works as expected, and they match the used int ID in the
53 * remainder of the tests.
54 */
55test_result_t test_notifications_retrieve_int_ids(void)
56{
Daniel Boulbyce386b12022-03-29 18:36:36 +010057 struct ffa_value ret;
J-Alves4439ece2021-11-05 11:52:54 +000058
59 SKIP_TEST_IF_FFA_VERSION_LESS_THAN(1, 1);
60
61 /* Check if SPMC is OP-TEE at S-EL1 */
62 if (check_spmc_execution_level()) {
63 /* FFA_FEATURES is not yet supported in OP-TEE */
64 return TEST_RESULT_SUCCESS;
65 }
66
67 ret = ffa_features(FFA_FEATURE_NPI);
Karl Meakin0569cc02024-04-17 17:32:35 +010068 if (!is_expected_ffa_error(ret, FFA_ERROR_NOT_SUPPORTED))
J-Alves4439ece2021-11-05 11:52:54 +000069 return TEST_RESULT_FAIL;
J-Alves4439ece2021-11-05 11:52:54 +000070
71 ret = ffa_features(FFA_FEATURE_SRI);
72 if (is_ffa_call_error(ret) ||
73 ffa_feature_intid(ret) != FFA_SCHEDULE_RECEIVER_INTERRUPT_ID) {
74 ERROR("Failed to retrieved SRI (exp: %u, got: %u)\n",
75 FFA_SCHEDULE_RECEIVER_INTERRUPT_ID,
76 ffa_feature_intid(ret));
77
78 return TEST_RESULT_FAIL;
79 }
80
81 ret = ffa_features(FFA_FEATURE_MEI);
Karl Meakin0569cc02024-04-17 17:32:35 +010082 if (!is_expected_ffa_error(ret, FFA_ERROR_NOT_SUPPORTED))
J-Alves4439ece2021-11-05 11:52:54 +000083 return TEST_RESULT_FAIL;
J-Alves4439ece2021-11-05 11:52:54 +000084
85 return TEST_RESULT_SUCCESS;
86}
87
88/**
J-Alvesbb467d12021-03-18 11:49:35 +000089 * Helper to create bitmap for NWd VMs.
90 */
91static bool notifications_bitmap_create(ffa_id_t vm_id,
92 ffa_vcpu_count_t vcpu_count)
93{
94 VERBOSE("Creating bitmap for VM %x; cpu count: %u.\n",
95 vm_id, vcpu_count);
Daniel Boulbyce386b12022-03-29 18:36:36 +010096 struct ffa_value ret = ffa_notification_bitmap_create(vm_id,
97 vcpu_count);
J-Alvesbb467d12021-03-18 11:49:35 +000098
99 return !is_ffa_call_error(ret);
100}
101
102/**
103 * Helper to destroy bitmap for NWd VMs.
104 */
105static bool notifications_bitmap_destroy(ffa_id_t vm_id)
106{
107 VERBOSE("Destroying bitmap of VM %x.\n", vm_id);
Daniel Boulbyce386b12022-03-29 18:36:36 +0100108 struct ffa_value ret = ffa_notification_bitmap_destroy(vm_id);
J-Alvesbb467d12021-03-18 11:49:35 +0000109
110 return !is_ffa_call_error(ret);
111}
112
113/**
114 * Test notifications bitmap create and destroy interfaces.
115 */
116test_result_t test_ffa_notifications_bitmap_create_destroy(void)
117{
J-Alvesd5d87152021-10-29 11:48:37 +0100118 const ffa_id_t vm_id = VM_ID(1);
J-Alvesbb467d12021-03-18 11:49:35 +0000119
120 SKIP_TEST_IF_FFA_VERSION_LESS_THAN(1, 1);
121
122 if (check_spmc_execution_level()) {
123 VERBOSE("OPTEE as SPMC at S-EL1. Skipping test!\n");
124 return TEST_RESULT_SKIPPED;
125 }
126
127 if (!notifications_bitmap_create(vm_id, PLATFORM_CORE_COUNT)) {
128 return TEST_RESULT_FAIL;
129 }
130
131 if (!notifications_bitmap_destroy(vm_id)) {
132 return TEST_RESULT_FAIL;
133 }
134
135 return TEST_RESULT_SUCCESS;
136}
137
138/**
139 * Test notifications bitmap destroy in a case the bitmap hasn't been created.
140 */
141test_result_t test_ffa_notifications_destroy_not_created(void)
142{
143 SKIP_TEST_IF_FFA_VERSION_LESS_THAN(1, 1);
144
145 if (check_spmc_execution_level()) {
146 VERBOSE("OPTEE as SPMC at S-EL1. Skipping test!\n");
147 return TEST_RESULT_SKIPPED;
148 }
149
Daniel Boulbyce386b12022-03-29 18:36:36 +0100150 struct ffa_value ret = ffa_notification_bitmap_destroy(VM_ID(1));
J-Alvesbb467d12021-03-18 11:49:35 +0000151
152 if (!is_expected_ffa_error(ret, FFA_ERROR_DENIED)) {
153 return TEST_RESULT_FAIL;
154 }
155
156 return TEST_RESULT_SUCCESS;
157}
158
159/**
160 * Test attempt to create notifications bitmap for NWd VM if it had been
161 * already created.
162 */
163test_result_t test_ffa_notifications_create_after_create(void)
164{
Daniel Boulbyce386b12022-03-29 18:36:36 +0100165 struct ffa_value ret;
J-Alvesd5d87152021-10-29 11:48:37 +0100166 const ffa_id_t vm_id = VM_ID(2);
J-Alvesbb467d12021-03-18 11:49:35 +0000167
168 SKIP_TEST_IF_FFA_VERSION_LESS_THAN(1, 1);
169
170 if (check_spmc_execution_level()) {
171 VERBOSE("OPTEE as SPMC at S-EL1. Skipping test!\n");
172 return TEST_RESULT_SKIPPED;
173 }
174
175 /* First successfully create a notifications bitmap */
176 if (!notifications_bitmap_create(vm_id, 1)) {
177 return TEST_RESULT_FAIL;
178 }
179
180 /* Attempt to do the same to the same VM. */
181 ret = ffa_notification_bitmap_create(vm_id, 1);
182
183 if (!is_expected_ffa_error(ret, FFA_ERROR_DENIED)) {
184 return TEST_RESULT_FAIL;
185 }
186
187 /* Destroy to not affect other tests */
188 if (!notifications_bitmap_destroy(vm_id)) {
189 return TEST_RESULT_FAIL;
190 }
191
192 return TEST_RESULT_SUCCESS;
193}
J-Alvese5f3fe62021-03-18 11:51:20 +0000194
195/**
196 * Helper function to test FFA_NOTIFICATION_BIND interface.
197 * Receives all arguments to use 'cactus_notification_bind_send_cmd', and
198 * expected response for the test command.
199 *
200 * Returns:
201 * - 'true' if response was obtained and it was as expected;
202 * - 'false' if there was an error with use of FFA_MSG_SEND_DIRECT_REQ, or
203 * the obtained response was not as expected.
204 */
205static bool request_notification_bind(
206 ffa_id_t cmd_dest, ffa_id_t receiver, ffa_id_t sender,
207 ffa_notification_bitmap_t notifications, uint32_t flags,
208 uint32_t expected_resp, uint32_t error_code)
209{
Daniel Boulbyce386b12022-03-29 18:36:36 +0100210 struct ffa_value ret;
J-Alvese5f3fe62021-03-18 11:51:20 +0000211
212 VERBOSE("TFTF requesting SP to bind notifications!\n");
213
214 ret = cactus_notification_bind_send_cmd(HYP_ID, cmd_dest, receiver,
215 sender, notifications, flags);
216
J-Alvese5554332021-11-04 17:24:57 +0000217 if (!is_expected_cactus_response(ret, expected_resp, error_code)) {
218 ERROR("Failed notifications bind. receiver: %x; sender: %x\n",
219 receiver, sender);
220 return false;
221 }
222
223 return true;
J-Alvese5f3fe62021-03-18 11:51:20 +0000224}
225
226/**
227 * Helper function to test FFA_NOTIFICATION_UNBIND interface.
228 * Receives all arguments to use 'cactus_notification_unbind_send_cmd', and
229 * expected response for the test command.
230 *
231 * Returns:
232 * - 'true' if response was obtained and it was as expected;
233 * - 'false' if there was an error with use of FFA_MSG_SEND_DIRECT_REQ, or
234 * the obtained response was not as expected.
235 */
236static bool request_notification_unbind(
237 ffa_id_t cmd_dest, ffa_id_t receiver, ffa_id_t sender,
238 ffa_notification_bitmap_t notifications, uint32_t expected_resp,
239 uint32_t error_code)
240{
Daniel Boulbyce386b12022-03-29 18:36:36 +0100241 struct ffa_value ret;
J-Alvese5f3fe62021-03-18 11:51:20 +0000242
243 VERBOSE("TFTF requesting SP to unbind notifications!\n");
244
245 ret = cactus_notification_unbind_send_cmd(HYP_ID, cmd_dest, receiver,
246 sender, notifications);
247
J-Alvese5554332021-11-04 17:24:57 +0000248 if (!is_expected_cactus_response(ret, expected_resp, error_code)) {
249 ERROR("Failed notifications unbind. receiver: %x; sender: %x\n",
250 receiver, sender);
251 return false;
252 }
253
254 return true;
J-Alvese5f3fe62021-03-18 11:51:20 +0000255}
256
257/**
258 * Test calls from SPs to the bind and unbind interfaces, expecting success
259 * returns.
260 * This test issues a request via direct messaging to the SP, which executes
261 * the test and responds with the result of the call.
262 */
263test_result_t test_ffa_notifications_sp_bind_unbind(void)
264{
265 CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
266
267 /** First bind... */
268 if (!request_notification_bind(SP_ID(1), SP_ID(1), SP_ID(2),
269 g_notifications, 0, CACTUS_SUCCESS, 0)) {
270 return TEST_RESULT_FAIL;
271 }
272
273 if (!request_notification_bind(SP_ID(1), SP_ID(1), 1,
274 g_notifications, 0, CACTUS_SUCCESS, 0)) {
275 return TEST_RESULT_FAIL;
276 }
277
278 /** ... then unbind using the same arguments. */
279 if (!request_notification_unbind(SP_ID(1), SP_ID(1), SP_ID(2),
280 g_notifications, CACTUS_SUCCESS, 0)) {
281 return TEST_RESULT_FAIL;
282 }
283
284 if (!request_notification_unbind(SP_ID(1), SP_ID(1), 1,
285 g_notifications, CACTUS_SUCCESS, 0)) {
286 return TEST_RESULT_FAIL;
287 }
288
289 return TEST_RESULT_SUCCESS;
290}
291
292/**
293 * Test successful attempt of doing bind and unbind of the same set of
294 * notifications.
295 */
296test_result_t test_ffa_notifications_vm_bind_unbind(void)
297{
298 CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
J-Alvesd5d87152021-10-29 11:48:37 +0100299 const ffa_id_t vm_id = VM_ID(1);
Daniel Boulbyce386b12022-03-29 18:36:36 +0100300 struct ffa_value ret;
J-Alvese5f3fe62021-03-18 11:51:20 +0000301
302 if (!notifications_bitmap_create(vm_id, 1)) {
303 return TEST_RESULT_FAIL;
304 }
305
306 ret = ffa_notification_bind(SP_ID(2), vm_id, 0, g_notifications);
307
308 if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32)) {
309 return TEST_RESULT_FAIL;
310 }
311
312 ret = ffa_notification_unbind(SP_ID(2), vm_id, g_notifications);
313
314 if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32)) {
315 return TEST_RESULT_FAIL;
316 }
317
318 if (!notifications_bitmap_destroy(vm_id)) {
319 return TEST_RESULT_FAIL;
320 }
321
322 return TEST_RESULT_SUCCESS;
323}
324
325/**
326 * Test expected failure of using a NS FF-A ID for the sender.
327 */
328test_result_t test_ffa_notifications_vm_bind_vm(void)
329{
330 CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
J-Alvesd5d87152021-10-29 11:48:37 +0100331 const ffa_id_t vm_id = VM_ID(1);
332 const ffa_id_t sender_id = VM_ID(2);
Daniel Boulbyce386b12022-03-29 18:36:36 +0100333 struct ffa_value ret;
J-Alvese5f3fe62021-03-18 11:51:20 +0000334
335 if (!notifications_bitmap_create(vm_id, 1)) {
336 return TEST_RESULT_FAIL;
337 }
338
339 ret = ffa_notification_bind(sender_id, vm_id, 0, g_notifications);
340
341 if (!is_expected_ffa_error(ret, FFA_ERROR_INVALID_PARAMETER)) {
342 return TEST_RESULT_FAIL;
343 }
344
345 if (!notifications_bitmap_destroy(vm_id)) {
346 return TEST_RESULT_FAIL;
347 }
348
349 return TEST_RESULT_SUCCESS;
350}
351
352/**
353 * Test failure of both bind and unbind in case at least one notification is
354 * already bound to another FF-A endpoint.
355 * Expect error code FFA_ERROR_DENIED.
356 */
357test_result_t test_ffa_notifications_already_bound(void)
358{
359 CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
360
361 /** Bind first to test */
362 if (!request_notification_bind(SP_ID(1), SP_ID(1), SP_ID(2),
363 g_notifications, 0, CACTUS_SUCCESS, 0)) {
364 return TEST_RESULT_FAIL;
365 }
366
367 /** Attempt to bind notifications bound in above request. */
368 if (!request_notification_bind(SP_ID(1), SP_ID(1), SP_ID(3),
369 g_notifications, 0, CACTUS_ERROR,
370 FFA_ERROR_DENIED)) {
371 return TEST_RESULT_FAIL;
372 }
373
374 /** Attempt to unbind notifications bound in initial request. */
375 if (!request_notification_unbind(SP_ID(1), SP_ID(1), SP_ID(3),
376 g_notifications, CACTUS_ERROR,
377 FFA_ERROR_DENIED)) {
378 return TEST_RESULT_FAIL;
379 }
380
381 /** Reset the state the SP's notifications state. */
382 if (!request_notification_unbind(SP_ID(1), SP_ID(1), SP_ID(2),
383 g_notifications, CACTUS_SUCCESS, 0)) {
384 return TEST_RESULT_FAIL;
385 }
386
387 return TEST_RESULT_SUCCESS;
388}
389
390/**
391 * Try to bind/unbind notifications spoofing the identity of the receiver.
392 * Commands will be sent to SP_ID(1), which will use SP_ID(3) as the receiver.
393 * Expect error code FFA_ERROR_INVALID_PARAMETER.
394 */
395test_result_t test_ffa_notifications_bind_unbind_spoofing(void)
396{
397 ffa_notification_bitmap_t notifications = FFA_NOTIFICATION(8);
398
399 CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
400
401 if (!request_notification_bind(SP_ID(1), SP_ID(3), SP_ID(2),
402 notifications, 0, CACTUS_ERROR,
403 FFA_ERROR_INVALID_PARAMETER)) {
404 return TEST_RESULT_FAIL;
405 }
406
407 if (!request_notification_unbind(SP_ID(1), SP_ID(3), SP_ID(2),
408 notifications, CACTUS_ERROR,
409 FFA_ERROR_INVALID_PARAMETER)) {
410 return TEST_RESULT_FAIL;
411 }
412
413 return TEST_RESULT_SUCCESS;
414}
415
416/**
417 * Call FFA_NOTIFICATION_BIND with notifications bitmap zeroed.
418 * Expecting error code FFA_ERROR_INVALID_PARAMETER.
419 */
420test_result_t test_ffa_notifications_bind_unbind_zeroed(void)
421{
422 CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
423
424 if (!request_notification_bind(SP_ID(1), SP_ID(1), SP_ID(2),
425 0, 0, CACTUS_ERROR,
426 FFA_ERROR_INVALID_PARAMETER)) {
427 return TEST_RESULT_FAIL;
428 }
429
430 if (!request_notification_unbind(SP_ID(1), SP_ID(1), SP_ID(2),
431 0, CACTUS_ERROR,
432 FFA_ERROR_INVALID_PARAMETER)) {
433 return TEST_RESULT_FAIL;
434 }
435
436 return TEST_RESULT_SUCCESS;
437}
J-Alvesd63ae4b2021-03-29 15:25:19 +0100438
439/**
440 * Helper function to test FFA_NOTIFICATION_GET interface.
441 * Receives all arguments to use 'cactus_notification_get_send_cmd', and returns
442 * the received response. Depending on the testing scenario, this will allow
443 * to validate if the returned bitmaps are as expected.
444 *
445 * Returns:
446 * - 'true' if response was obtained.
447 * - 'false' if there was an error sending the request.
448 */
449static bool request_notification_get(
J-Alvesc08db422021-10-19 16:15:06 +0100450 ffa_id_t cmd_dest, ffa_id_t receiver, uint32_t vcpu_id, uint32_t flags,
Daniel Boulbyce386b12022-03-29 18:36:36 +0100451 bool check_npi_handled, struct ffa_value *response)
J-Alvesd63ae4b2021-03-29 15:25:19 +0100452{
453 VERBOSE("TFTF requesting SP to get notifications!\n");
454
455 *response = cactus_notification_get_send_cmd(HYP_ID, cmd_dest,
456 receiver, vcpu_id,
J-Alvesc08db422021-10-19 16:15:06 +0100457 flags, check_npi_handled);
J-Alvesd63ae4b2021-03-29 15:25:19 +0100458
459 return is_ffa_direct_response(*response);
460}
461
462static bool request_notification_set(
463 ffa_id_t cmd_dest, ffa_id_t receiver, ffa_id_t sender, uint32_t flags,
J-Alvesf0328472021-09-21 18:32:02 +0100464 ffa_notification_bitmap_t notifications, ffa_id_t echo_dest,
465 uint32_t exp_resp, int32_t exp_error)
J-Alvesd63ae4b2021-03-29 15:25:19 +0100466{
Daniel Boulbyce386b12022-03-29 18:36:36 +0100467 struct ffa_value ret;
J-Alvesd63ae4b2021-03-29 15:25:19 +0100468
469 VERBOSE("TFTF requesting SP %x (as %x) to set notifications to %x\n",
470 cmd_dest, sender, receiver);
471
472 ret = cactus_notifications_set_send_cmd(HYP_ID, cmd_dest, receiver,
J-Alvesf0328472021-09-21 18:32:02 +0100473 sender, flags, notifications,
474 echo_dest);
J-Alvesd63ae4b2021-03-29 15:25:19 +0100475
J-Alvese5554332021-11-04 17:24:57 +0000476 if (!is_expected_cactus_response(ret, exp_resp, exp_error)) {
477 ERROR("Failed notifications set. receiver: %x; sender: %x\n",
478 receiver, sender);
479 return false;
480 }
481
482 return true;
J-Alvesd63ae4b2021-03-29 15:25:19 +0100483}
484
485/**
J-Alves4849c8c2021-10-27 18:49:54 +0100486 * Helper to set notification. If sender is VM, the function will call directly
487 * FFA_NOTIFICATION_SET, if it is an SP it will request the SP to set
488 * notifications. In both cases it is expected a successful outcome.
489 */
490static bool notification_set(ffa_id_t receiver, ffa_id_t sender,
491 uint32_t flags,
492 ffa_notification_bitmap_t notifications)
493{
Daniel Boulbyce386b12022-03-29 18:36:36 +0100494 struct ffa_value ret;
J-Alves4849c8c2021-10-27 18:49:54 +0100495
496 /* Sender sets notifications to receiver. */
497 if (!IS_SP_ID(sender)) {
498 VERBOSE("VM %x Setting notifications %llx to receiver %x\n",
499 sender, notifications, receiver);
500 ret = ffa_notification_set(sender, receiver, flags, notifications);
501
502 if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32)) {
503 ERROR("Failed notifications set. receiver: %x; sender: %x\n",
504 receiver, sender);
505 return false;
506 }
507 return true;
508 }
509
510 return request_notification_set(sender, receiver, sender, flags,
511 notifications, 0, CACTUS_SUCCESS, 0);
512}
513
514/**
J-Alvesd63ae4b2021-03-29 15:25:19 +0100515 * Check that SP's response to CACTUS_NOTIFICATION_GET_CMD is as expected.
516 */
517static bool is_notifications_get_as_expected(
Daniel Boulbyce386b12022-03-29 18:36:36 +0100518 struct ffa_value *ret, uint64_t exp_from_sp, uint64_t exp_from_vm,
J-Alvesd63ae4b2021-03-29 15:25:19 +0100519 ffa_id_t receiver)
520{
521 uint64_t from_sp;
522 uint64_t from_vm;
523 bool success_ret;
524
525 /**
526 * If receiver ID is SP, this is to evaluate the response to test
527 * command 'CACTUS_NOTIFICATION_GET_CMD'.
528 */
529 if (IS_SP_ID(receiver)) {
530 success_ret = (cactus_get_response(*ret) == CACTUS_SUCCESS);
531 from_sp = cactus_notifications_get_from_sp(*ret);
532 from_vm = cactus_notifications_get_from_vm(*ret);
533 } else {
534 /**
535 * Else, this is to evaluate the return of FF-A call:
536 * ffa_notification_get.
537 */
538 success_ret = (ffa_func_id(*ret) == FFA_SUCCESS_SMC32);
J-Alvesc6b92d52024-04-05 14:16:00 +0100539 from_sp = ffa_notification_get_from_sp(*ret);
540 from_vm = ffa_notification_get_from_vm(*ret);
J-Alvesd63ae4b2021-03-29 15:25:19 +0100541 }
542
543 if (success_ret != true ||
544 exp_from_sp != from_sp ||
545 exp_from_vm != from_vm) {
546 VERBOSE("Notifications not as expected:\n"
547 " from sp: %llx exp: %llx\n"
548 " from vm: %llx exp: %llx\n",
549 from_sp, exp_from_sp, from_vm, exp_from_vm);
550 return false;
551 }
552
553 return true;
554}
555
J-Alves16d52d52021-06-14 14:29:37 +0100556static bool is_notifications_info_get_as_expected(
Daniel Boulbyce386b12022-03-29 18:36:36 +0100557 struct ffa_value *ret, uint16_t *ids, uint32_t *lists_sizes,
J-Alves16d52d52021-06-14 14:29:37 +0100558 const uint32_t max_ids_count, uint32_t lists_count, bool more_pending)
559{
J-Alvesc6b92d52024-04-05 14:16:00 +0100560 if (lists_count != ffa_notification_info_get_lists_count(*ret) ||
561 more_pending != ffa_notification_info_get_more_pending(*ret)) {
J-Alves16d52d52021-06-14 14:29:37 +0100562 ERROR("Notification info get not as expected.\n"
563 " Lists counts: %u; more pending %u\n",
J-Alvesc6b92d52024-04-05 14:16:00 +0100564 ffa_notification_info_get_lists_count(*ret),
565 ffa_notification_info_get_more_pending(*ret));
Daniel Boulbyce386b12022-03-29 18:36:36 +0100566 dump_ffa_value(*ret);
J-Alves16d52d52021-06-14 14:29:37 +0100567 return false;
568 }
569
570 for (uint32_t i = 0; i < lists_count; i++) {
571 uint32_t cur_size =
J-Alvesc6b92d52024-04-05 14:16:00 +0100572 ffa_notification_info_get_list_size(*ret,
J-Alves16d52d52021-06-14 14:29:37 +0100573 i + 1);
574
575 if (lists_sizes[i] != cur_size) {
576 ERROR("Expected list size[%u] %u != %u\n", i,
577 lists_sizes[i], cur_size);
578 return false;
579 }
580 }
581
582 /* Compare the IDs list */
Daniel Boulbyce386b12022-03-29 18:36:36 +0100583 if (memcmp(&ret->arg3, ids, sizeof(ids[0]) * max_ids_count) != 0) {
J-Alves16d52d52021-06-14 14:29:37 +0100584 ERROR("List of IDs not as expected\n");
585 return false;
586 }
587
588 return true;
589}
590
J-Alvesd63ae4b2021-03-29 15:25:19 +0100591/**
592 * Helper to bind notification and set it.
593 * If receiver is SP it will request SP to perform the bind, else invokes
594 * FFA_NOTIFICATION_BIND.
595 * If Sender is SP it will request it to perform the set, else invokes
596 * FFA_NOTIFICATION_SET.
597 */
598static bool notification_bind_and_set(ffa_id_t sender,
599 ffa_id_t receiver, ffa_notification_bitmap_t notifications, uint32_t flags)
600{
Daniel Boulbyce386b12022-03-29 18:36:36 +0100601 struct ffa_value ret;
J-Alvesd63ae4b2021-03-29 15:25:19 +0100602 uint32_t flags_bind = flags & FFA_NOTIFICATIONS_FLAG_PER_VCPU;
603
604 /* Receiver binds notifications to sender. */
605 if (!IS_SP_ID(receiver)) {
606 ret = ffa_notification_bind(sender, receiver,
607 flags_bind, notifications);
608
609 if (is_ffa_call_error(ret)) {
610 return false;
611 }
612 } else {
613 if (!request_notification_bind(receiver, receiver, sender,
614 notifications, flags_bind,
615 CACTUS_SUCCESS,
616 0)) {
617 return false;
618 }
619 }
620
J-Alves4849c8c2021-10-27 18:49:54 +0100621 return notification_set(receiver, sender, flags, notifications);
J-Alvesd63ae4b2021-03-29 15:25:19 +0100622}
623
624/**
625 * Helper to request SP to get the notifications and validate the return.
626 */
627static bool notification_get_and_validate(
628 ffa_id_t receiver, ffa_notification_bitmap_t exp_from_sp,
629 ffa_notification_bitmap_t exp_from_vm, uint32_t vcpu_id,
J-Alvesc08db422021-10-19 16:15:06 +0100630 uint32_t flags, bool check_npi_handled)
J-Alvesd63ae4b2021-03-29 15:25:19 +0100631{
Daniel Boulbyce386b12022-03-29 18:36:36 +0100632 struct ffa_value ret;
J-Alvesd63ae4b2021-03-29 15:25:19 +0100633
634 /* Receiver gets pending notifications. */
635 if (IS_SP_ID(receiver)) {
636 request_notification_get(receiver, receiver, vcpu_id, flags,
J-Alvesc08db422021-10-19 16:15:06 +0100637 check_npi_handled, &ret);
J-Alvesd63ae4b2021-03-29 15:25:19 +0100638 } else {
639 ret = ffa_notification_get(receiver, vcpu_id, flags);
640 }
641
642 return is_notifications_get_as_expected(&ret, exp_from_sp, exp_from_vm,
643 receiver);
644}
645
J-Alves16d52d52021-06-14 14:29:37 +0100646static bool notifications_info_get(
647 uint16_t *expected_ids, uint32_t expected_lists_count,
648 uint32_t *expected_lists_sizes, const uint32_t max_ids_count,
649 bool expected_more_pending)
650{
Daniel Boulbyce386b12022-03-29 18:36:36 +0100651 struct ffa_value ret;
J-Alves16d52d52021-06-14 14:29:37 +0100652
653 VERBOSE("Getting pending notification's info.\n");
654
655 ret = ffa_notification_info_get();
656
657 return !is_ffa_call_error(ret) &&
658 is_notifications_info_get_as_expected(&ret, expected_ids,
659 expected_lists_sizes,
660 max_ids_count,
661 expected_lists_count,
662 expected_more_pending);
663}
664
J-Alves269118a2021-09-22 09:46:11 +0100665static volatile int schedule_receiver_interrupt_received;
666
667static int schedule_receiver_interrupt_handler(void *data)
668{
669 assert(schedule_receiver_interrupt_received == 0);
670 schedule_receiver_interrupt_received = 1;
671 return 0;
672}
673
674/**
675 * Enable the Schedule Receiver Interrupt and register the respective
676 * handler.
677 */
678static void schedule_receiver_interrupt_init(void)
679{
680 tftf_irq_register_handler(FFA_SCHEDULE_RECEIVER_INTERRUPT_ID,
681 schedule_receiver_interrupt_handler);
J-Alves269118a2021-09-22 09:46:11 +0100682}
683
684/**
685 * Disable the Schedule Receiver Interrupt and unregister the respective
686 * handler.
687 */
688static void schedule_receiver_interrupt_deinit(void)
689{
J-Alves269118a2021-09-22 09:46:11 +0100690 tftf_irq_unregister_handler(FFA_SCHEDULE_RECEIVER_INTERRUPT_ID);
691 schedule_receiver_interrupt_received = 0;
692}
693
694bool check_schedule_receiver_interrupt_handled(void)
695{
696 if (schedule_receiver_interrupt_received == 1) {
697 VERBOSE("Schedule Receiver Interrupt handled!\n");
698 schedule_receiver_interrupt_received = 0;
699 return true;
700 }
701 VERBOSE("Schedule Receiver Interrupt NOT handled!\n");
702 return false;
703}
704
J-Alvesd63ae4b2021-03-29 15:25:19 +0100705/**
J-Alvesbd909ac2021-10-19 16:37:02 +0100706 * Base function to test notifications signaling with an SP as a receiver.
J-Alvesd63ae4b2021-03-29 15:25:19 +0100707 */
J-Alvesbd909ac2021-10-19 16:37:02 +0100708static test_result_t base_test_global_notifications_signal_sp(
709 const ffa_id_t sender, const ffa_id_t receiver,
J-Alveseb378792024-06-19 13:17:44 +0100710 const ffa_notification_bitmap_t notifications, const uint32_t flags_get,
711 const uint32_t flags_set)
J-Alvesd63ae4b2021-03-29 15:25:19 +0100712{
J-Alves16d52d52021-06-14 14:29:37 +0100713 /* Variables to validate calls to FFA_NOTIFICATION_INFO_GET. */
714 uint16_t ids[FFA_NOTIFICATIONS_INFO_GET_MAX_IDS] = {0};
715 uint32_t lists_count;
716 uint32_t lists_sizes[FFA_NOTIFICATIONS_INFO_GET_MAX_IDS] = {0};
717
718 CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
719
J-Alveseb378792024-06-19 13:17:44 +0100720 if (!IS_SP_ID(receiver)) {
721 ERROR("Receiver is expected to be an SP ID!\n");
722 return TEST_RESULT_FAIL;
723 }
724
J-Alves269118a2021-09-22 09:46:11 +0100725 schedule_receiver_interrupt_init();
726
J-Alvesbd909ac2021-10-19 16:37:02 +0100727 if (!notification_bind_and_set(sender, receiver, notifications,
J-Alveseb378792024-06-19 13:17:44 +0100728 flags_set)) {
J-Alvesd63ae4b2021-03-29 15:25:19 +0100729 return TEST_RESULT_FAIL;
730 }
731
J-Alves5fb14212021-09-21 13:04:48 +0100732 if (!check_schedule_receiver_interrupt_handled()) {
733 return TEST_RESULT_FAIL;
734 }
J-Alves269118a2021-09-22 09:46:11 +0100735
J-Alves16d52d52021-06-14 14:29:37 +0100736 /**
737 * Simple list of IDs expected on return from FFA_NOTIFICATION_INFO_GET.
738 */
739 ids[0] = receiver;
740 lists_count = 1;
741
742 if (!notifications_info_get(ids, lists_count, lists_sizes,
743 FFA_NOTIFICATIONS_INFO_GET_MAX_IDS,
J-Alvesbd909ac2021-10-19 16:37:02 +0100744 false)) {
J-Alves16d52d52021-06-14 14:29:37 +0100745 return TEST_RESULT_FAIL;
746 }
747
J-Alvesbd909ac2021-10-19 16:37:02 +0100748 if (!notification_get_and_validate(
749 receiver, IS_SP_ID(sender) ? notifications : 0,
750 !IS_SP_ID(sender) ? notifications : 0, 0, flags_get, true)) {
J-Alvesd63ae4b2021-03-29 15:25:19 +0100751 return TEST_RESULT_FAIL;
752 }
753
754 if (!request_notification_unbind(receiver, receiver, sender,
755 notifications, CACTUS_SUCCESS, 0)) {
756 return TEST_RESULT_FAIL;
757 }
758
J-Alves269118a2021-09-22 09:46:11 +0100759 schedule_receiver_interrupt_deinit();
760
J-Alvesd63ae4b2021-03-29 15:25:19 +0100761 return TEST_RESULT_SUCCESS;
762}
763
764/**
J-Alvesbd909ac2021-10-19 16:37:02 +0100765 * Test to validate a VM can signal an SP.
766 */
767test_result_t test_ffa_notifications_vm_signals_sp(void)
768{
769 return base_test_global_notifications_signal_sp(
770 1, SP_ID(1), FFA_NOTIFICATION(1) | FFA_NOTIFICATION(60),
J-Alveseb378792024-06-19 13:17:44 +0100771 FFA_NOTIFICATIONS_FLAG_BITMAP_VM, 0);
772}
773
774test_result_t test_ffa_notifications_vm_signals_sp_delay_sri_fail(void)
775{
776 const ffa_id_t sender = 1;
777 const ffa_id_t receiver = SP_ID(1);
778 const ffa_notification_bitmap_t notif = (1LU << 34);
779 struct ffa_value ret;
780
781 CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
782
783 if (!request_notification_bind(receiver, receiver,
784 sender, notif, 0,
785 CACTUS_SUCCESS, 0)) {
786 return TEST_RESULT_FAIL;
787 }
788
789 ret = ffa_notification_set(sender, receiver,
790 FFA_NOTIFICATIONS_FLAG_DELAY_SRI, notif);
791
792 if (!is_expected_ffa_error(ret, FFA_ERROR_INVALID_PARAMETER)) {
793 return TEST_RESULT_FAIL;
794 }
795
796 if (!request_notification_unbind(receiver, receiver, sender,
797 notif, CACTUS_SUCCESS, 0)) {
798 return TEST_RESULT_FAIL;
799 }
800
801 return TEST_RESULT_SUCCESS;
J-Alvesbd909ac2021-10-19 16:37:02 +0100802}
803
804/**
J-Alvesd63ae4b2021-03-29 15:25:19 +0100805 * Test to validate an SP can signal an SP.
806 */
807test_result_t test_ffa_notifications_sp_signals_sp(void)
808{
J-Alvesbd909ac2021-10-19 16:37:02 +0100809 return base_test_global_notifications_signal_sp(
810 SP_ID(1), SP_ID(2), g_notifications,
J-Alveseb378792024-06-19 13:17:44 +0100811 FFA_NOTIFICATIONS_FLAG_BITMAP_SP,
812 FFA_NOTIFICATIONS_FLAG_DELAY_SRI);
J-Alvesd63ae4b2021-03-29 15:25:19 +0100813}
814
815/**
816 * Test to validate an SP can signal a VM.
817 */
818test_result_t test_ffa_notifications_sp_signals_vm(void)
819{
820 CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
821 const ffa_id_t sender = SP_ID(1);
J-Alvesd5d87152021-10-29 11:48:37 +0100822 const ffa_id_t receiver = VM_ID(1);
J-Alvesd63ae4b2021-03-29 15:25:19 +0100823 uint32_t get_flags = FFA_NOTIFICATIONS_FLAG_BITMAP_SP;
Daniel Boulbyce386b12022-03-29 18:36:36 +0100824 struct ffa_value ret;
J-Alves269118a2021-09-22 09:46:11 +0100825 test_result_t result = TEST_RESULT_SUCCESS;
J-Alvesd63ae4b2021-03-29 15:25:19 +0100826
J-Alves16d52d52021-06-14 14:29:37 +0100827 /* Variables to validate calls to FFA_NOTIFICATION_INFO_GET. */
828 uint16_t ids[FFA_NOTIFICATIONS_INFO_GET_MAX_IDS] = {0};
829 uint32_t lists_count;
830 uint32_t lists_sizes[FFA_NOTIFICATIONS_INFO_GET_MAX_IDS] = {0};
831
J-Alvesd63ae4b2021-03-29 15:25:19 +0100832 /* Ask SPMC to allocate notifications bitmap. */
833 if (!notifications_bitmap_create(receiver, 1)) {
J-Alves269118a2021-09-22 09:46:11 +0100834 result = TEST_RESULT_FAIL;
J-Alvesd63ae4b2021-03-29 15:25:19 +0100835 }
836
J-Alves269118a2021-09-22 09:46:11 +0100837 schedule_receiver_interrupt_init();
838
J-Alvesd63ae4b2021-03-29 15:25:19 +0100839 /* Request receiver to bind a set of notifications to the sender. */
J-Alvesfbbbf622021-07-30 16:43:36 +0100840 if (!notification_bind_and_set(sender, receiver, g_notifications,
841 FFA_NOTIFICATIONS_FLAG_DELAY_SRI)) {
J-Alves5fb14212021-09-21 13:04:48 +0100842 result = TEST_RESULT_FAIL;
J-Alvesd63ae4b2021-03-29 15:25:19 +0100843 }
844
J-Alves5fb14212021-09-21 13:04:48 +0100845 if (!check_schedule_receiver_interrupt_handled()) {
846 result = TEST_RESULT_FAIL;
847 }
J-Alves269118a2021-09-22 09:46:11 +0100848
J-Alves16d52d52021-06-14 14:29:37 +0100849 /*
850 * FFA_NOTIFICATION_INFO_GET return list should be simple, containing
851 * only the receiver's ID.
852 */
853 ids[0] = receiver;
854 lists_count = 1;
855
856 if (!notifications_info_get(ids, lists_count, lists_sizes,
857 FFA_NOTIFICATIONS_INFO_GET_MAX_IDS,
858 false)) {
J-Alves269118a2021-09-22 09:46:11 +0100859 result = TEST_RESULT_FAIL;
J-Alves16d52d52021-06-14 14:29:37 +0100860 }
861
J-Alvesd63ae4b2021-03-29 15:25:19 +0100862 /* Get pending notifications, and retrieve response. */
863 if (!notification_get_and_validate(receiver, g_notifications, 0, 0,
J-Alvesc08db422021-10-19 16:15:06 +0100864 get_flags, false)) {
J-Alves5fb14212021-09-21 13:04:48 +0100865 result = TEST_RESULT_FAIL;
J-Alvesd63ae4b2021-03-29 15:25:19 +0100866 }
867
868 ret = ffa_notification_unbind(sender, receiver, g_notifications);
869
870 if (!is_expected_ffa_return(ret, FFA_SUCCESS_SMC32)) {
J-Alves269118a2021-09-22 09:46:11 +0100871 result = TEST_RESULT_FAIL;
J-Alvesd63ae4b2021-03-29 15:25:19 +0100872 }
873
874 if (!notifications_bitmap_destroy(receiver)) {
J-Alves269118a2021-09-22 09:46:11 +0100875 result = TEST_RESULT_FAIL;
J-Alvesd63ae4b2021-03-29 15:25:19 +0100876 }
877
J-Alves269118a2021-09-22 09:46:11 +0100878 schedule_receiver_interrupt_deinit();
879
880 return result;
J-Alvesd63ae4b2021-03-29 15:25:19 +0100881}
882
883/**
884 * Test to validate it is not possible to unbind a pending notification.
885 */
886test_result_t test_ffa_notifications_unbind_pending(void)
887{
888 CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
889 const ffa_id_t receiver = SP_ID(1);
J-Alvesd5d87152021-10-29 11:48:37 +0100890 const ffa_id_t sender = VM_ID(1);
J-Alvesd63ae4b2021-03-29 15:25:19 +0100891 const ffa_notification_bitmap_t notifications = FFA_NOTIFICATION(30) |
892 FFA_NOTIFICATION(35);
893 uint32_t get_flags = FFA_NOTIFICATIONS_FLAG_BITMAP_VM;
894
J-Alves269118a2021-09-22 09:46:11 +0100895 schedule_receiver_interrupt_init();
896
J-Alvesd63ae4b2021-03-29 15:25:19 +0100897 /* Request receiver to bind a set of notifications to the sender. */
898 if (!notification_bind_and_set(sender, receiver, notifications, 0)) {
899 return TEST_RESULT_FAIL;
900 }
901
902 /*
903 * Attempt to unbind the pending notification, but expect error return
904 * given the notification is pending.
905 */
906 if (!request_notification_unbind(receiver, receiver, sender,
907 FFA_NOTIFICATION(30),
908 CACTUS_ERROR, FFA_ERROR_DENIED)) {
909 return TEST_RESULT_FAIL;
910 }
911
J-Alves269118a2021-09-22 09:46:11 +0100912 if (!check_schedule_receiver_interrupt_handled()) {
913 return TEST_RESULT_FAIL;
914 }
915
J-Alvesd63ae4b2021-03-29 15:25:19 +0100916 /*
917 * Request receiver partition to get pending notifications from VMs.
918 * Only notification 30 is expected.
919 */
920 if (!notification_get_and_validate(receiver, 0, notifications, 0,
J-Alvesc08db422021-10-19 16:15:06 +0100921 get_flags, false)) {
J-Alvesd63ae4b2021-03-29 15:25:19 +0100922 return TEST_RESULT_FAIL;
923 }
924
925 /* Unbind all notifications, to not interfere with other tests. */
926 if (!request_notification_unbind(receiver, receiver, sender,
927 notifications, CACTUS_SUCCESS, 0)) {
928 return TEST_RESULT_FAIL;
929 }
930
J-Alves269118a2021-09-22 09:46:11 +0100931 schedule_receiver_interrupt_deinit();
932
J-Alvesd63ae4b2021-03-29 15:25:19 +0100933 return TEST_RESULT_SUCCESS;
934}
J-Alves16d52d52021-06-14 14:29:37 +0100935
936/**
937 * Test the result of a call to FFA_NOTIFICATION_INFO_GET if no pending
938 * notifications.
939 */
940test_result_t test_ffa_notifications_info_get_none(void)
941{
942 SKIP_TEST_IF_FFA_VERSION_LESS_THAN(1, 1);
943
944 if (check_spmc_execution_level()) {
945 VERBOSE("OPTEE as SPMC at S-EL1. Skipping test!\n");
946 return TEST_RESULT_SKIPPED;
947 }
948
Daniel Boulbyce386b12022-03-29 18:36:36 +0100949 struct ffa_value ret;
J-Alves16d52d52021-06-14 14:29:37 +0100950
951 ret = ffa_notification_info_get();
952
953 if (!is_expected_ffa_error(ret, FFA_ERROR_NO_DATA)) {
954 return TEST_RESULT_FAIL;
955 }
956
957 return TEST_RESULT_SUCCESS;
958}
J-Alves44ec4f72021-07-27 12:07:14 +0100959
960/**
961 * CPU_ON handler for testing per-vCPU notifications to SPs (either from VMs
962 * or from SPs). It requests the SP to retrieve its pending notifications
963 * within its current Execution Context. The SP shall obtain all per-vCPU
964 * targeted to the running vCPU.
965 */
966static test_result_t request_notification_get_per_vcpu_on_handler(void)
967{
J-Alves79c08f12021-10-27 15:15:16 +0100968 unsigned int core_pos = get_current_core_id();
J-Alves44ec4f72021-07-27 12:07:14 +0100969 test_result_t result = TEST_RESULT_FAIL;
970
971 uint64_t exp_from_vm = 0;
972 uint64_t exp_from_sp = 0;
973
974 if (IS_SP_ID(per_vcpu_sender)) {
975 exp_from_sp = FFA_NOTIFICATION(core_pos);
976 } else {
977 exp_from_vm = FFA_NOTIFICATION(core_pos);
978 }
979
980 VERBOSE("Request get per-vCPU notification to %x, core: %u.\n",
981 per_vcpu_receiver, core_pos);
982
983 /*
984 * Secure Partitions secondary ECs need one round of ffa_run to reach
985 * the message loop.
986 */
J-Alves79c08f12021-10-27 15:15:16 +0100987 if (!spm_core_sp_init(per_vcpu_receiver)) {
988 goto out;
J-Alves44ec4f72021-07-27 12:07:14 +0100989 }
990
J-Alves4849c8c2021-10-27 18:49:54 +0100991 /*
992 * Request to get notifications sent to the respective vCPU.
993 * Check also if NPI was handled by the receiver. It should have been
994 * pended at notifications set, in the respective vCPU.
995 */
J-Alves44ec4f72021-07-27 12:07:14 +0100996 if (!notification_get_and_validate(
997 per_vcpu_receiver, exp_from_sp, exp_from_vm, core_pos,
J-Alves4849c8c2021-10-27 18:49:54 +0100998 per_vcpu_flags_get, true)) {
J-Alves44ec4f72021-07-27 12:07:14 +0100999 goto out;
1000 }
1001
1002 result = TEST_RESULT_SUCCESS;
1003
1004out:
1005 /* Tell the lead CPU that the calling CPU has completed the test. */
1006 tftf_send_event(&per_vcpu_finished[core_pos]);
1007
1008 return result;
1009}
1010
J-Alves4849c8c2021-10-27 18:49:54 +01001011static test_result_t base_npi_enable_per_cpu(bool enable)
1012{
1013 test_result_t result = TEST_RESULT_FAIL;
1014 uint32_t core_pos = get_current_core_id();
1015
1016 VERBOSE("Request SP %x to enable NPI in core %u\n",
1017 per_vcpu_receiver, core_pos);
1018
1019 /*
1020 * Secure Partitions secondary ECs need one round of ffa_run to reach
1021 * the message loop.
1022 */
1023 if (!spm_core_sp_init(per_vcpu_receiver)) {
1024 goto out;
1025 }
1026
J-Alves4849c8c2021-10-27 18:49:54 +01001027 result = TEST_RESULT_SUCCESS;
1028
1029out:
1030 /* Tell the lead CPU that the calling CPU has completed the test. */
1031 tftf_send_event(&per_vcpu_finished[core_pos]);
1032
1033 return result;
1034}
1035
1036static test_result_t npi_enable_per_vcpu_on_handler(void)
1037{
1038 return base_npi_enable_per_cpu(true);
1039}
1040
1041static test_result_t npi_disable_per_vcpu_on_handler(void)
1042{
1043 return base_npi_enable_per_cpu(false);
1044}
J-Alves44ec4f72021-07-27 12:07:14 +01001045/**
1046 * Base function to test signaling of per-vCPU notifications.
1047 * Test whole flow between two FF-A endpoints: binding, getting notification
1048 * info, and getting pending notifications.
1049 * Each vCPU will receive a notification whose ID is the same as the core
1050 * position.
1051 */
1052static test_result_t base_test_per_vcpu_notifications(ffa_id_t sender,
1053 ffa_id_t receiver)
1054{
J-Alves44ec4f72021-07-27 12:07:14 +01001055 /*
1056 * Manually set variables to validate what should be the return of to
1057 * FFA_NOTIFICATION_INFO_GET.
1058 */
1059 uint16_t exp_ids[FFA_NOTIFICATIONS_INFO_GET_MAX_IDS] = {
1060 receiver, 0, 1, 2,
1061 receiver, 3, 4, 5,
1062 receiver, 6, 7, 0,
1063 0, 0, 0, 0,
1064 0, 0, 0, 0,
1065 };
1066 uint32_t exp_lists_count = 3;
1067 uint32_t exp_lists_sizes[FFA_NOTIFICATIONS_INFO_GET_MAX_IDS] = {
1068 3, 3, 2, 0, 0, 0, 0, 0, 0, 0,
1069 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1070 };
1071
1072 const bool exp_more_notif_pending = false;
1073 test_result_t result = TEST_RESULT_SUCCESS;
1074 uint64_t notifications_to_unbind = 0;
1075
J-Alves4849c8c2021-10-27 18:49:54 +01001076 CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
1077
J-Alves44ec4f72021-07-27 12:07:14 +01001078 per_vcpu_flags_get = IS_SP_ID(sender)
1079 ? FFA_NOTIFICATIONS_FLAG_BITMAP_SP
1080 : FFA_NOTIFICATIONS_FLAG_BITMAP_VM;
1081
J-Alves4849c8c2021-10-27 18:49:54 +01001082 /* Setting global variables to be accessed by the cpu_on handler. */
1083 per_vcpu_receiver = receiver;
1084 per_vcpu_sender = sender;
1085
1086 /* Boot all cores and enable the NPI in all of them. */
1087 if (spm_run_multi_core_test(
1088 (uintptr_t)npi_enable_per_vcpu_on_handler,
1089 per_vcpu_finished) != TEST_RESULT_SUCCESS) {
1090 return TEST_RESULT_FAIL;
1091 }
1092
J-Alves44ec4f72021-07-27 12:07:14 +01001093 /*
1094 * Prepare notifications bitmap to request Cactus to bind them as
1095 * per-vCPU.
1096 */
1097 for (unsigned int i = 0; i < PLATFORM_CORE_COUNT; i++) {
1098 notifications_to_unbind |= FFA_NOTIFICATION(i);
1099
J-Alveseb378792024-06-19 13:17:44 +01001100 uint32_t flags = FFA_NOTIFICATIONS_FLAG_PER_VCPU |
J-Alves44ec4f72021-07-27 12:07:14 +01001101 FFA_NOTIFICATIONS_FLAGS_VCPU_ID((uint16_t)i);
1102
J-Alveseb378792024-06-19 13:17:44 +01001103 flags |= (IS_SP_ID(sender))
1104 ? FFA_NOTIFICATIONS_FLAG_DELAY_SRI
1105 : 0;
1106
J-Alves44ec4f72021-07-27 12:07:14 +01001107 if (!notification_bind_and_set(sender,
1108 receiver,
1109 FFA_NOTIFICATION(i),
1110 flags)) {
1111 return TEST_RESULT_FAIL;
1112 }
1113 }
1114
1115 /* Call FFA_NOTIFICATION_INFO_GET and validate return. */
1116 if (!notifications_info_get(exp_ids, exp_lists_count, exp_lists_sizes,
1117 FFA_NOTIFICATIONS_INFO_GET_MAX_IDS,
1118 exp_more_notif_pending)) {
1119 ERROR("Info Get Failed....\n");
1120 result = TEST_RESULT_FAIL;
1121 goto out;
1122 }
1123
1124 /*
1125 * Request SP to get notifications in core 0, as this is not iterated
1126 * at the CPU ON handler.
J-Alves4849c8c2021-10-27 18:49:54 +01001127 * Set `check_npi_handled` to true, as the receiver is supposed to be
1128 * preempted by the NPI.
J-Alves44ec4f72021-07-27 12:07:14 +01001129 */
1130 if (!notification_get_and_validate(
J-Alvesc08db422021-10-19 16:15:06 +01001131 receiver, IS_SP_ID(sender) ? FFA_NOTIFICATION(0) : 0,
1132 !IS_SP_ID(sender) ? FFA_NOTIFICATION(0) : 0, 0,
J-Alves4849c8c2021-10-27 18:49:54 +01001133 per_vcpu_flags_get, true)) {
J-Alves44ec4f72021-07-27 12:07:14 +01001134 result = TEST_RESULT_FAIL;
1135 }
1136
J-Alves44ec4f72021-07-27 12:07:14 +01001137 /*
1138 * Bring up all the cores, and request the receiver to get notifications
1139 * in each one of them.
1140 */
1141 if (spm_run_multi_core_test(
1142 (uintptr_t)request_notification_get_per_vcpu_on_handler,
1143 per_vcpu_finished) != TEST_RESULT_SUCCESS) {
1144 result = TEST_RESULT_FAIL;
1145 }
1146
1147out:
1148 /* As a clean-up, unbind notifications. */
1149 if (!request_notification_unbind(receiver, receiver,
1150 sender,
1151 notifications_to_unbind,
1152 CACTUS_SUCCESS, 0)) {
1153 result = TEST_RESULT_FAIL;
1154 }
1155
J-Alves4849c8c2021-10-27 18:49:54 +01001156 /* Boot all cores and DISABLE the NPI in all of them. */
1157 if (spm_run_multi_core_test(
1158 (uintptr_t)npi_disable_per_vcpu_on_handler,
1159 per_vcpu_finished) != TEST_RESULT_SUCCESS) {
1160 return TEST_RESULT_FAIL;
1161 }
1162
J-Alves44ec4f72021-07-27 12:07:14 +01001163 return result;
1164}
1165
1166/**
1167 * Test to validate a VM can signal a per-vCPU notification to an SP.
1168 */
1169test_result_t test_ffa_notifications_vm_signals_sp_per_vcpu(void)
1170{
1171 return base_test_per_vcpu_notifications(0, SP_ID(1));
1172}
1173
1174/**
1175 * Test to validate an SP can signal a per-vCPU notification to an SP.
1176 */
1177test_result_t test_ffa_notifications_sp_signals_sp_per_vcpu(void)
1178{
1179 return base_test_per_vcpu_notifications(SP_ID(1), SP_ID(2));
1180}
J-Alvesb0cb5d02021-07-08 11:19:33 +01001181
1182static test_result_t notification_get_per_vcpu_on_handler(void)
1183{
J-Alves79c08f12021-10-27 15:15:16 +01001184 unsigned int core_pos = get_current_core_id();
J-Alvesb0cb5d02021-07-08 11:19:33 +01001185 test_result_t result = TEST_RESULT_SUCCESS;
1186
1187 VERBOSE("Getting per-vCPU notifications from %x, core: %u.\n",
1188 per_vcpu_receiver, core_pos);
1189
J-Alves79c08f12021-10-27 15:15:16 +01001190 if (!spm_core_sp_init(per_vcpu_sender)) {
J-Alvesb0cb5d02021-07-08 11:19:33 +01001191 goto out;
1192 }
1193
1194 if (!notification_get_and_validate(per_vcpu_receiver,
1195 FFA_NOTIFICATION(core_pos), 0,
1196 core_pos,
J-Alvesc08db422021-10-19 16:15:06 +01001197 FFA_NOTIFICATIONS_FLAG_BITMAP_SP,
1198 false)) {
J-Alvesb0cb5d02021-07-08 11:19:33 +01001199 result = TEST_RESULT_FAIL;
J-Alvesb0cb5d02021-07-08 11:19:33 +01001200 }
1201
1202out:
1203 /* Tell the lead CPU that the calling CPU has completed the test. */
1204 tftf_send_event(&per_vcpu_finished[core_pos]);
1205
1206 return result;
1207}
1208
1209/**
1210 * Test whole flow from binding, to getting notifications' info, and getting
1211 * pending notifications, namely signaling of notifications from SP to a VM.
1212 * Each vCPU will receive a notification whose ID is the same as the core
1213 * position.
1214 */
1215test_result_t test_ffa_notifications_sp_signals_vm_per_vcpu(void)
1216{
1217 /* Making a VM the receiver, and an SP the sender */
J-Alvesd5d87152021-10-29 11:48:37 +01001218 per_vcpu_receiver = VM_ID(1);
J-Alvesb0cb5d02021-07-08 11:19:33 +01001219 per_vcpu_sender = SP_ID(2);
1220
1221 /**
1222 * Manually set variables to validate what should be the return of to
1223 * FFA_NOTIFICATION_INFO_GET.
1224 */
1225 uint16_t exp_ids[FFA_NOTIFICATIONS_INFO_GET_MAX_IDS] = {
1226 per_vcpu_receiver, 0, 1, 2,
1227 per_vcpu_receiver, 3, 4, 5,
1228 per_vcpu_receiver, 6, 7, 0,
1229 0, 0, 0, 0,
1230 0, 0, 0, 0,
1231 };
1232 uint32_t exp_lists_count = 3;
1233 uint32_t exp_lists_sizes[FFA_NOTIFICATIONS_INFO_GET_MAX_IDS] = {
1234 3, 3, 2, 0, 0, 0, 0, 0, 0, 0,
1235 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1236 };
1237
1238 const bool exp_more_notif_pending = false;
1239 test_result_t result = TEST_RESULT_SUCCESS;
1240 uint64_t notifications_to_unbind = 0;
Daniel Boulbyce386b12022-03-29 18:36:36 +01001241 struct ffa_value ret;
J-Alvesb0cb5d02021-07-08 11:19:33 +01001242
1243 CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
1244
1245 /* Create bitmap for receiver. */
1246 if (!notifications_bitmap_create(per_vcpu_receiver,
1247 PLATFORM_CORE_COUNT)) {
1248 return TEST_RESULT_FAIL;
1249 }
1250
1251 /* Bind notifications, and request Cactus SP to set them. */
1252 for (uint32_t i = 0U; i < PLATFORM_CORE_COUNT; i++) {
1253 notifications_to_unbind |= FFA_NOTIFICATION(i);
1254
1255 uint32_t flags = FFA_NOTIFICATIONS_FLAG_DELAY_SRI |
1256 FFA_NOTIFICATIONS_FLAG_PER_VCPU |
1257 FFA_NOTIFICATIONS_FLAGS_VCPU_ID((uint16_t)i);
1258
1259 if (!notification_bind_and_set(per_vcpu_sender,
1260 per_vcpu_receiver,
1261 FFA_NOTIFICATION(i),
1262 flags)) {
1263 return TEST_RESULT_FAIL;
1264 };
1265 }
1266
1267 /* Call FFA_NOTIFICATION_INFO_GET and validate return. */
1268 if (!notifications_info_get(exp_ids, exp_lists_count, exp_lists_sizes,
1269 FFA_NOTIFICATIONS_INFO_GET_MAX_IDS,
1270 exp_more_notif_pending)) {
1271 ERROR("Info Get Failed....\n");
1272 return TEST_RESULT_FAIL;
1273 }
1274
1275 /*
1276 * Get notifications in core 0, as it is not iterated at the CPU ON
1277 * handler.
1278 */
1279 if (!notification_get_and_validate(per_vcpu_receiver,
1280 FFA_NOTIFICATION(0), 0, 0,
J-Alvesc08db422021-10-19 16:15:06 +01001281 FFA_NOTIFICATIONS_FLAG_BITMAP_SP,
1282 false)) {
J-Alvesb0cb5d02021-07-08 11:19:33 +01001283 result = TEST_RESULT_FAIL;
1284 }
1285
1286 /* Bring up all the cores, and get notifications in each one of them. */
1287 if (spm_run_multi_core_test(
1288 (uintptr_t)notification_get_per_vcpu_on_handler,
1289 per_vcpu_finished) != TEST_RESULT_SUCCESS) {
1290 ERROR("Failed to get per-vCPU notifications\n");
1291 result = TEST_RESULT_FAIL;
1292 }
1293
1294 /* As a clean-up, unbind notifications. */
1295 ret = ffa_notification_unbind(per_vcpu_sender, per_vcpu_receiver,
1296 notifications_to_unbind);
1297 if (is_ffa_call_error(ret)) {
1298 result = TEST_RESULT_FAIL;
1299 }
1300
J-Alvesdf2deb32024-04-22 15:17:45 +01001301 if (!notifications_bitmap_destroy(per_vcpu_receiver)) {
1302 result = TEST_RESULT_FAIL;
1303 }
1304
J-Alvesb0cb5d02021-07-08 11:19:33 +01001305 return result;
1306}
J-Alves5fb14212021-09-21 13:04:48 +01001307
1308/**
1309 * Test to validate behavior in SWd if the SRI is not delayed. If the
1310 * notification setter handled a managed exit it is indicative the SRI was
1311 * sent immediately.
1312 */
1313test_result_t test_ffa_notifications_sp_signals_sp_immediate_sri(void)
1314{
1315 CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
1316 const ffa_id_t sender = SP_ID(1);
1317 const ffa_id_t receiver = SP_ID(2);
1318 uint32_t get_flags = FFA_NOTIFICATIONS_FLAG_BITMAP_SP;
Daniel Boulbyce386b12022-03-29 18:36:36 +01001319 struct ffa_value ret;
J-Alves5fb14212021-09-21 13:04:48 +01001320 test_result_t result = TEST_RESULT_SUCCESS;
1321
1322 /** Variables to validate calls to FFA_NOTIFICATION_INFO_GET. */
1323 uint16_t ids[FFA_NOTIFICATIONS_INFO_GET_MAX_IDS] = {0};
1324 uint32_t lists_count;
1325 uint32_t lists_sizes[FFA_NOTIFICATIONS_INFO_GET_MAX_IDS] = {0};
1326
1327 ids[0] = receiver;
1328 lists_count = 1;
1329
J-Alves5fb14212021-09-21 13:04:48 +01001330 schedule_receiver_interrupt_init();
1331
1332 /* Request receiver to bind a set of notifications to the sender. */
1333 if (!request_notification_bind(receiver, receiver, sender,
1334 g_notifications, 0, CACTUS_SUCCESS, 0)) {
1335 result = TEST_RESULT_FAIL;
1336 }
1337
1338 /*
1339 * Request sender to set notification, and expect the response is
1340 * MANAGED_EXIT_INTERRUPT_ID.
1341 */
1342 if (!request_notification_set(sender, receiver, sender, 0,
J-Alvesf0328472021-09-21 18:32:02 +01001343 g_notifications, 0,
1344 MANAGED_EXIT_INTERRUPT_ID, 0)) {
J-Alves5fb14212021-09-21 13:04:48 +01001345 ERROR("SRI not handled immediately!\n");
1346 result = TEST_RESULT_FAIL;
1347 } else {
1348 VERBOSE("SP %x did a managed exit.\n", sender);
1349 }
1350
1351 if (!check_schedule_receiver_interrupt_handled()) {
1352 result = TEST_RESULT_FAIL;
1353 }
1354
1355 /* Call FFA_NOTIFICATION_INFO_GET and validate return. */
1356 if (!notifications_info_get(ids, lists_count, lists_sizes,
1357 FFA_NOTIFICATIONS_INFO_GET_MAX_IDS,
1358 false)) {
1359 result = TEST_RESULT_FAIL;
1360 }
1361
1362 /* Validate notification get. */
J-Alvesc08db422021-10-19 16:15:06 +01001363 if (!request_notification_get(receiver, receiver, 0, get_flags, false, &ret) ||
J-Alves5fb14212021-09-21 13:04:48 +01001364 !is_notifications_get_as_expected(&ret, g_notifications, 0,
1365 receiver)) {
1366 result = TEST_RESULT_FAIL;
1367 }
1368
1369 /*
1370 * Resume setter Cactus in the handling of CACTUS_NOTIFICATIONS_SET_CMD.
1371 */
Madhukar Pappireddy92d2e812022-09-19 13:48:13 -05001372 ret = cactus_resume_after_managed_exit(HYP_ID, sender);
J-Alves5fb14212021-09-21 13:04:48 +01001373
1374 /* Expected result to CACTUS_NOTIFICATIONS_SET_CMD. */
1375 if (!is_expected_cactus_response(ret, CACTUS_SUCCESS, 0)) {
1376 result = TEST_RESULT_FAIL;
1377 }
1378
1379 /* Unbind for clean-up. */
1380 if (!request_notification_unbind(receiver, receiver, sender,
1381 g_notifications, CACTUS_SUCCESS, 0)) {
1382 result = TEST_RESULT_FAIL;
1383 }
1384
1385 schedule_receiver_interrupt_deinit();
1386
J-Alves5fb14212021-09-21 13:04:48 +01001387 return result;
1388}
J-Alvesf0328472021-09-21 18:32:02 +01001389
1390/**
1391 * Test to validate behavior in SWd if the SRI is delayed.
1392 */
1393test_result_t test_ffa_notifications_sp_signals_sp_delayed_sri(void)
1394{
1395 CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
1396 const ffa_id_t sender = SP_ID(3);
1397 const ffa_id_t receiver = SP_ID(2);
1398 const ffa_id_t echo_dest = SP_ID(1);
1399 uint32_t echo_dest_cmd_count = 0;
1400 uint32_t get_flags = FFA_NOTIFICATIONS_FLAG_BITMAP_SP;
Daniel Boulbyce386b12022-03-29 18:36:36 +01001401 struct ffa_value ret;
J-Alvesf0328472021-09-21 18:32:02 +01001402 test_result_t result = TEST_RESULT_SUCCESS;
1403
1404 /** Variables to validate calls to FFA_NOTIFICATION_INFO_GET. */
1405 uint16_t ids[FFA_NOTIFICATIONS_INFO_GET_MAX_IDS] = {0};
1406 uint32_t lists_count;
1407 uint32_t lists_sizes[FFA_NOTIFICATIONS_INFO_GET_MAX_IDS] = {0};
1408
1409 ids[0] = receiver;
1410 lists_count = 1;
1411
J-Alvesf0328472021-09-21 18:32:02 +01001412 schedule_receiver_interrupt_init();
1413
1414 /* Request receiver to bind a set of notifications to the sender. */
1415 if (!request_notification_bind(receiver, receiver, sender,
1416 g_notifications, 0, CACTUS_SUCCESS, 0)) {
1417 result = TEST_RESULT_FAIL;
1418 }
1419
1420 ret = cactus_get_req_count_send_cmd(HYP_ID, echo_dest);
1421
1422 if (cactus_get_response(ret) == CACTUS_SUCCESS) {
1423 /*
1424 * Save the command count from the echo_dest, to validate it
1425 * has been incremented after the request to set notifications.
1426 */
1427 echo_dest_cmd_count = cactus_get_req_count(ret);
1428 VERBOSE("Partition %x command count %u.\n", echo_dest,
1429 echo_dest_cmd_count);
1430 } else {
1431 VERBOSE("Failed to get cmds count from %u\n", echo_dest);
1432 result = TEST_RESULT_FAIL;
1433 }
1434
1435 /*
1436 * Request sender to set notification with Delay SRI flag, and specify
1437 * echo destination.
1438 */
1439 if (!request_notification_set(sender, receiver, sender,
1440 FFA_NOTIFICATIONS_FLAG_DELAY_SRI,
1441 g_notifications, echo_dest,
1442 CACTUS_SUCCESS, 0)) {
1443 VERBOSE("Failed to set notifications!\n");
1444 result = TEST_RESULT_FAIL;
1445 }
1446
1447 if (!check_schedule_receiver_interrupt_handled()) {
1448 result = TEST_RESULT_FAIL;
1449 }
1450
1451 /*
1452 * Get command count again from echo_dest, to validate that it has been
1453 * incremented by one. This should indicate the notification setter has
1454 * issued a request to echo_dest right after the notification set, thus
1455 * proving the SRI hasn't been sent right after FFA_NOTIFICATION_SET.
1456 */
1457 ret = cactus_get_req_count_send_cmd(HYP_ID, echo_dest);
1458 if (cactus_get_response(ret) == CACTUS_SUCCESS) {
1459 if (cactus_get_req_count(ret) == echo_dest_cmd_count + 1) {
1460 VERBOSE("SRI successfully delayed.\n");
1461 } else {
1462 VERBOSE("Failed to get cmds count from %u.\n",
1463 echo_dest);
1464 result = TEST_RESULT_FAIL;
1465 }
1466 } else {
1467 VERBOSE("Failed to get cmds count from %x\n", echo_dest);
1468 result = TEST_RESULT_FAIL;
1469 }
1470
1471 /* Call FFA_NOTIFICATION_INFO_GET and validate return. */
1472 if (!notifications_info_get(ids, lists_count, lists_sizes,
1473 FFA_NOTIFICATIONS_INFO_GET_MAX_IDS,
1474 false)) {
1475 result = TEST_RESULT_FAIL;
1476 }
1477
1478 /* Validate notification get. */
J-Alvesc08db422021-10-19 16:15:06 +01001479 if (!request_notification_get(receiver, receiver, 0, get_flags, false, &ret) ||
J-Alvesf0328472021-09-21 18:32:02 +01001480 !is_notifications_get_as_expected(&ret, g_notifications, 0,
1481 receiver)) {
1482 result = TEST_RESULT_FAIL;
1483 }
1484
1485 /* Unbind for clean-up. */
1486 if (!request_notification_unbind(receiver, receiver, sender,
1487 g_notifications, CACTUS_SUCCESS, 0)) {
1488 result = TEST_RESULT_FAIL;
1489 }
1490
1491 schedule_receiver_interrupt_deinit();
1492
J-Alvesf0328472021-09-21 18:32:02 +01001493 return result;
1494}
J-Alvesbe2daa62021-11-04 17:06:57 +00001495
1496test_result_t notifications_set_per_vcpu_on_handler(void)
1497{
1498 unsigned int core_pos = get_current_core_id();
1499 test_result_t result = TEST_RESULT_FAIL;
1500
1501 if (!spm_core_sp_init(per_vcpu_sender)) {
1502 goto out;
1503 }
1504
1505 if (!notification_set(per_vcpu_receiver, per_vcpu_sender,
1506 FFA_NOTIFICATIONS_FLAG_DELAY_SRI |
1507 FFA_NOTIFICATIONS_FLAG_PER_VCPU |
1508 FFA_NOTIFICATIONS_FLAGS_VCPU_ID(0),
1509 FFA_NOTIFICATION(core_pos))) {
1510 goto out;
1511 }
1512
1513 result = TEST_RESULT_SUCCESS;
1514
1515out:
1516 /* Tell the lead CPU that the calling CPU has completed the test. */
1517 tftf_send_event(&per_vcpu_finished[core_pos]);
1518
1519 return result;
1520}
1521
1522test_result_t test_ffa_notifications_mp_sp_signals_up_sp(void)
1523{
1524 ffa_notification_bitmap_t to_bind = 0;
1525
1526 /* prepare info get variables. */
1527
1528 CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
1529
1530 /* Setting per-vCPU sender and receiver IDs. */
1531 per_vcpu_sender = SP_ID(2); /* MP SP */
1532 per_vcpu_receiver = SP_ID(3); /* UP SP */
1533
1534 schedule_receiver_interrupt_init();
1535
J-Alvesbe2daa62021-11-04 17:06:57 +00001536 /* Prepare notifications bitmap to have one bit platform core. */
1537 for (uint32_t i = 0; i < PLATFORM_CORE_COUNT; i++) {
1538 to_bind |= FFA_NOTIFICATION(i);
1539 }
1540
1541 /* Request receiver to bind a set of notifications to the sender. */
1542 if (!request_notification_bind(per_vcpu_receiver, per_vcpu_receiver,
1543 per_vcpu_sender, to_bind,
1544 FFA_NOTIFICATIONS_FLAG_PER_VCPU,
1545 CACTUS_SUCCESS, 0)) {
1546 return TEST_RESULT_FAIL;
1547 }
1548
1549 /*
1550 * Boot up system, and then request sender to signal notification from
1551 * every core into into receiver's only vCPU. Delayed SRI.
1552 */
1553 if (!notification_set(per_vcpu_receiver, per_vcpu_sender,
1554 FFA_NOTIFICATIONS_FLAG_DELAY_SRI |
1555 FFA_NOTIFICATIONS_FLAG_PER_VCPU |
1556 FFA_NOTIFICATIONS_FLAGS_VCPU_ID(0),
1557 FFA_NOTIFICATION(0))) {
1558 return TEST_RESULT_FAIL;
1559 }
1560
1561 if (spm_run_multi_core_test(
1562 (uintptr_t)notifications_set_per_vcpu_on_handler,
1563 per_vcpu_finished) != TEST_RESULT_SUCCESS) {
1564 return TEST_RESULT_FAIL;
1565 }
1566
1567 if (!check_schedule_receiver_interrupt_handled()) {
1568 return TEST_RESULT_FAIL;
1569 }
1570
1571 if (!notification_get_and_validate(per_vcpu_receiver, to_bind, 0, 0,
1572 FFA_NOTIFICATIONS_FLAG_BITMAP_SP, true)) {
1573 return TEST_RESULT_FAIL;
1574 }
1575
1576 /* Request unbind. */
1577 if (!request_notification_unbind(per_vcpu_receiver, per_vcpu_receiver,
1578 per_vcpu_sender, to_bind,
1579 CACTUS_SUCCESS, 0)) {
1580 return TEST_RESULT_FAIL;
1581 }
1582
1583 schedule_receiver_interrupt_deinit();
1584
J-Alvesbe2daa62021-11-04 17:06:57 +00001585 return TEST_RESULT_SUCCESS;
1586}