blob: fe0475197be622b76ece82ee1f91a12aeb95877b [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 /*
J-Alves4849c8c2021-10-27 18:49:54 +0100984 * Request to get notifications sent to the respective vCPU.
985 * Check also if NPI was handled by the receiver. It should have been
986 * pended at notifications set, in the respective vCPU.
987 */
J-Alves44ec4f72021-07-27 12:07:14 +0100988 if (!notification_get_and_validate(
989 per_vcpu_receiver, exp_from_sp, exp_from_vm, core_pos,
J-Alves4849c8c2021-10-27 18:49:54 +0100990 per_vcpu_flags_get, true)) {
J-Alves44ec4f72021-07-27 12:07:14 +0100991 goto out;
992 }
993
994 result = TEST_RESULT_SUCCESS;
995
996out:
Madhukar Pappireddy6681b7a2024-11-01 16:27:44 -0500997 INFO("Request get per-vCPU notification to %x, core: %u.\n",
998 per_vcpu_receiver, core_pos);
J-Alves44ec4f72021-07-27 12:07:14 +0100999 /* Tell the lead CPU that the calling CPU has completed the test. */
1000 tftf_send_event(&per_vcpu_finished[core_pos]);
1001
1002 return result;
1003}
1004
J-Alves4849c8c2021-10-27 18:49:54 +01001005static test_result_t base_npi_enable_per_cpu(bool enable)
1006{
1007 test_result_t result = TEST_RESULT_FAIL;
1008 uint32_t core_pos = get_current_core_id();
1009
1010 VERBOSE("Request SP %x to enable NPI in core %u\n",
1011 per_vcpu_receiver, core_pos);
1012
J-Alves4849c8c2021-10-27 18:49:54 +01001013 result = TEST_RESULT_SUCCESS;
1014
J-Alves4849c8c2021-10-27 18:49:54 +01001015 /* Tell the lead CPU that the calling CPU has completed the test. */
1016 tftf_send_event(&per_vcpu_finished[core_pos]);
1017
1018 return result;
1019}
1020
1021static test_result_t npi_enable_per_vcpu_on_handler(void)
1022{
1023 return base_npi_enable_per_cpu(true);
1024}
1025
1026static test_result_t npi_disable_per_vcpu_on_handler(void)
1027{
1028 return base_npi_enable_per_cpu(false);
1029}
J-Alves44ec4f72021-07-27 12:07:14 +01001030/**
1031 * Base function to test signaling of per-vCPU notifications.
1032 * Test whole flow between two FF-A endpoints: binding, getting notification
1033 * info, and getting pending notifications.
1034 * Each vCPU will receive a notification whose ID is the same as the core
1035 * position.
1036 */
1037static test_result_t base_test_per_vcpu_notifications(ffa_id_t sender,
1038 ffa_id_t receiver)
1039{
J-Alves44ec4f72021-07-27 12:07:14 +01001040 /*
1041 * Manually set variables to validate what should be the return of to
1042 * FFA_NOTIFICATION_INFO_GET.
1043 */
1044 uint16_t exp_ids[FFA_NOTIFICATIONS_INFO_GET_MAX_IDS] = {
1045 receiver, 0, 1, 2,
1046 receiver, 3, 4, 5,
1047 receiver, 6, 7, 0,
1048 0, 0, 0, 0,
1049 0, 0, 0, 0,
1050 };
1051 uint32_t exp_lists_count = 3;
1052 uint32_t exp_lists_sizes[FFA_NOTIFICATIONS_INFO_GET_MAX_IDS] = {
1053 3, 3, 2, 0, 0, 0, 0, 0, 0, 0,
1054 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1055 };
1056
1057 const bool exp_more_notif_pending = false;
1058 test_result_t result = TEST_RESULT_SUCCESS;
1059 uint64_t notifications_to_unbind = 0;
1060
J-Alves4849c8c2021-10-27 18:49:54 +01001061 CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
1062
J-Alves44ec4f72021-07-27 12:07:14 +01001063 per_vcpu_flags_get = IS_SP_ID(sender)
1064 ? FFA_NOTIFICATIONS_FLAG_BITMAP_SP
1065 : FFA_NOTIFICATIONS_FLAG_BITMAP_VM;
1066
J-Alves4849c8c2021-10-27 18:49:54 +01001067 /* Setting global variables to be accessed by the cpu_on handler. */
1068 per_vcpu_receiver = receiver;
1069 per_vcpu_sender = sender;
1070
Madhukar Pappireddy6681b7a2024-11-01 16:27:44 -05001071 INFO("Execute npi_enable_per_vcpu_on_handler\n");
J-Alves4849c8c2021-10-27 18:49:54 +01001072 /* Boot all cores and enable the NPI in all of them. */
1073 if (spm_run_multi_core_test(
1074 (uintptr_t)npi_enable_per_vcpu_on_handler,
1075 per_vcpu_finished) != TEST_RESULT_SUCCESS) {
1076 return TEST_RESULT_FAIL;
1077 }
1078
J-Alves44ec4f72021-07-27 12:07:14 +01001079 /*
1080 * Prepare notifications bitmap to request Cactus to bind them as
1081 * per-vCPU.
1082 */
1083 for (unsigned int i = 0; i < PLATFORM_CORE_COUNT; i++) {
1084 notifications_to_unbind |= FFA_NOTIFICATION(i);
1085
J-Alveseb378792024-06-19 13:17:44 +01001086 uint32_t flags = FFA_NOTIFICATIONS_FLAG_PER_VCPU |
J-Alves44ec4f72021-07-27 12:07:14 +01001087 FFA_NOTIFICATIONS_FLAGS_VCPU_ID((uint16_t)i);
1088
J-Alveseb378792024-06-19 13:17:44 +01001089 flags |= (IS_SP_ID(sender))
1090 ? FFA_NOTIFICATIONS_FLAG_DELAY_SRI
1091 : 0;
1092
J-Alves44ec4f72021-07-27 12:07:14 +01001093 if (!notification_bind_and_set(sender,
1094 receiver,
1095 FFA_NOTIFICATION(i),
1096 flags)) {
1097 return TEST_RESULT_FAIL;
1098 }
1099 }
1100
1101 /* Call FFA_NOTIFICATION_INFO_GET and validate return. */
1102 if (!notifications_info_get(exp_ids, exp_lists_count, exp_lists_sizes,
1103 FFA_NOTIFICATIONS_INFO_GET_MAX_IDS,
1104 exp_more_notif_pending)) {
1105 ERROR("Info Get Failed....\n");
1106 result = TEST_RESULT_FAIL;
1107 goto out;
1108 }
1109
1110 /*
1111 * Request SP to get notifications in core 0, as this is not iterated
1112 * at the CPU ON handler.
J-Alves4849c8c2021-10-27 18:49:54 +01001113 * Set `check_npi_handled` to true, as the receiver is supposed to be
1114 * preempted by the NPI.
J-Alves44ec4f72021-07-27 12:07:14 +01001115 */
1116 if (!notification_get_and_validate(
J-Alvesc08db422021-10-19 16:15:06 +01001117 receiver, IS_SP_ID(sender) ? FFA_NOTIFICATION(0) : 0,
1118 !IS_SP_ID(sender) ? FFA_NOTIFICATION(0) : 0, 0,
J-Alves4849c8c2021-10-27 18:49:54 +01001119 per_vcpu_flags_get, true)) {
J-Alves44ec4f72021-07-27 12:07:14 +01001120 result = TEST_RESULT_FAIL;
1121 }
1122
Madhukar Pappireddy6681b7a2024-11-01 16:27:44 -05001123 INFO("Execute request_notification_get_per_vcpu_on_handler\n");
J-Alves44ec4f72021-07-27 12:07:14 +01001124 /*
1125 * Bring up all the cores, and request the receiver to get notifications
1126 * in each one of them.
1127 */
1128 if (spm_run_multi_core_test(
1129 (uintptr_t)request_notification_get_per_vcpu_on_handler,
1130 per_vcpu_finished) != TEST_RESULT_SUCCESS) {
1131 result = TEST_RESULT_FAIL;
1132 }
1133
1134out:
Madhukar Pappireddy6681b7a2024-11-01 16:27:44 -05001135 INFO("UNbind message on CPU:%lx\n", read_mpidr_el1());
J-Alves44ec4f72021-07-27 12:07:14 +01001136 /* As a clean-up, unbind notifications. */
1137 if (!request_notification_unbind(receiver, receiver,
1138 sender,
1139 notifications_to_unbind,
1140 CACTUS_SUCCESS, 0)) {
1141 result = TEST_RESULT_FAIL;
1142 }
1143
Madhukar Pappireddy6681b7a2024-11-01 16:27:44 -05001144 INFO("Execute npi_disable_per_vcpu_on_handler\n");
J-Alves4849c8c2021-10-27 18:49:54 +01001145 /* Boot all cores and DISABLE the NPI in all of them. */
1146 if (spm_run_multi_core_test(
1147 (uintptr_t)npi_disable_per_vcpu_on_handler,
1148 per_vcpu_finished) != TEST_RESULT_SUCCESS) {
1149 return TEST_RESULT_FAIL;
1150 }
1151
J-Alves44ec4f72021-07-27 12:07:14 +01001152 return result;
1153}
1154
1155/**
1156 * Test to validate a VM can signal a per-vCPU notification to an SP.
1157 */
1158test_result_t test_ffa_notifications_vm_signals_sp_per_vcpu(void)
1159{
1160 return base_test_per_vcpu_notifications(0, SP_ID(1));
1161}
1162
1163/**
1164 * Test to validate an SP can signal a per-vCPU notification to an SP.
1165 */
1166test_result_t test_ffa_notifications_sp_signals_sp_per_vcpu(void)
1167{
1168 return base_test_per_vcpu_notifications(SP_ID(1), SP_ID(2));
1169}
J-Alvesb0cb5d02021-07-08 11:19:33 +01001170
1171static test_result_t notification_get_per_vcpu_on_handler(void)
1172{
J-Alves79c08f12021-10-27 15:15:16 +01001173 unsigned int core_pos = get_current_core_id();
J-Alvesb0cb5d02021-07-08 11:19:33 +01001174 test_result_t result = TEST_RESULT_SUCCESS;
1175
1176 VERBOSE("Getting per-vCPU notifications from %x, core: %u.\n",
1177 per_vcpu_receiver, core_pos);
1178
J-Alvesb0cb5d02021-07-08 11:19:33 +01001179 if (!notification_get_and_validate(per_vcpu_receiver,
1180 FFA_NOTIFICATION(core_pos), 0,
1181 core_pos,
J-Alvesc08db422021-10-19 16:15:06 +01001182 FFA_NOTIFICATIONS_FLAG_BITMAP_SP,
1183 false)) {
J-Alvesb0cb5d02021-07-08 11:19:33 +01001184 result = TEST_RESULT_FAIL;
J-Alvesb0cb5d02021-07-08 11:19:33 +01001185 }
1186
J-Alvesb0cb5d02021-07-08 11:19:33 +01001187 /* Tell the lead CPU that the calling CPU has completed the test. */
1188 tftf_send_event(&per_vcpu_finished[core_pos]);
1189
1190 return result;
1191}
1192
1193/**
1194 * Test whole flow from binding, to getting notifications' info, and getting
1195 * pending notifications, namely signaling of notifications from SP to a VM.
1196 * Each vCPU will receive a notification whose ID is the same as the core
1197 * position.
1198 */
1199test_result_t test_ffa_notifications_sp_signals_vm_per_vcpu(void)
1200{
1201 /* Making a VM the receiver, and an SP the sender */
J-Alvesd5d87152021-10-29 11:48:37 +01001202 per_vcpu_receiver = VM_ID(1);
J-Alvesb0cb5d02021-07-08 11:19:33 +01001203 per_vcpu_sender = SP_ID(2);
1204
1205 /**
1206 * Manually set variables to validate what should be the return of to
1207 * FFA_NOTIFICATION_INFO_GET.
1208 */
1209 uint16_t exp_ids[FFA_NOTIFICATIONS_INFO_GET_MAX_IDS] = {
1210 per_vcpu_receiver, 0, 1, 2,
1211 per_vcpu_receiver, 3, 4, 5,
1212 per_vcpu_receiver, 6, 7, 0,
1213 0, 0, 0, 0,
1214 0, 0, 0, 0,
1215 };
1216 uint32_t exp_lists_count = 3;
1217 uint32_t exp_lists_sizes[FFA_NOTIFICATIONS_INFO_GET_MAX_IDS] = {
1218 3, 3, 2, 0, 0, 0, 0, 0, 0, 0,
1219 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1220 };
1221
1222 const bool exp_more_notif_pending = false;
1223 test_result_t result = TEST_RESULT_SUCCESS;
1224 uint64_t notifications_to_unbind = 0;
Daniel Boulbyce386b12022-03-29 18:36:36 +01001225 struct ffa_value ret;
J-Alvesb0cb5d02021-07-08 11:19:33 +01001226
1227 CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
1228
1229 /* Create bitmap for receiver. */
1230 if (!notifications_bitmap_create(per_vcpu_receiver,
1231 PLATFORM_CORE_COUNT)) {
1232 return TEST_RESULT_FAIL;
1233 }
1234
1235 /* Bind notifications, and request Cactus SP to set them. */
1236 for (uint32_t i = 0U; i < PLATFORM_CORE_COUNT; i++) {
1237 notifications_to_unbind |= FFA_NOTIFICATION(i);
1238
1239 uint32_t flags = FFA_NOTIFICATIONS_FLAG_DELAY_SRI |
1240 FFA_NOTIFICATIONS_FLAG_PER_VCPU |
1241 FFA_NOTIFICATIONS_FLAGS_VCPU_ID((uint16_t)i);
1242
1243 if (!notification_bind_and_set(per_vcpu_sender,
1244 per_vcpu_receiver,
1245 FFA_NOTIFICATION(i),
1246 flags)) {
1247 return TEST_RESULT_FAIL;
1248 };
1249 }
1250
1251 /* Call FFA_NOTIFICATION_INFO_GET and validate return. */
1252 if (!notifications_info_get(exp_ids, exp_lists_count, exp_lists_sizes,
1253 FFA_NOTIFICATIONS_INFO_GET_MAX_IDS,
1254 exp_more_notif_pending)) {
1255 ERROR("Info Get Failed....\n");
1256 return TEST_RESULT_FAIL;
1257 }
1258
1259 /*
1260 * Get notifications in core 0, as it is not iterated at the CPU ON
1261 * handler.
1262 */
1263 if (!notification_get_and_validate(per_vcpu_receiver,
1264 FFA_NOTIFICATION(0), 0, 0,
J-Alvesc08db422021-10-19 16:15:06 +01001265 FFA_NOTIFICATIONS_FLAG_BITMAP_SP,
1266 false)) {
J-Alvesb0cb5d02021-07-08 11:19:33 +01001267 result = TEST_RESULT_FAIL;
1268 }
1269
1270 /* Bring up all the cores, and get notifications in each one of them. */
1271 if (spm_run_multi_core_test(
1272 (uintptr_t)notification_get_per_vcpu_on_handler,
1273 per_vcpu_finished) != TEST_RESULT_SUCCESS) {
1274 ERROR("Failed to get per-vCPU notifications\n");
1275 result = TEST_RESULT_FAIL;
1276 }
1277
1278 /* As a clean-up, unbind notifications. */
1279 ret = ffa_notification_unbind(per_vcpu_sender, per_vcpu_receiver,
1280 notifications_to_unbind);
1281 if (is_ffa_call_error(ret)) {
1282 result = TEST_RESULT_FAIL;
1283 }
1284
J-Alvesdf2deb32024-04-22 15:17:45 +01001285 if (!notifications_bitmap_destroy(per_vcpu_receiver)) {
1286 result = TEST_RESULT_FAIL;
1287 }
1288
J-Alvesb0cb5d02021-07-08 11:19:33 +01001289 return result;
1290}
J-Alves5fb14212021-09-21 13:04:48 +01001291
1292/**
1293 * Test to validate behavior in SWd if the SRI is not delayed. If the
1294 * notification setter handled a managed exit it is indicative the SRI was
1295 * sent immediately.
1296 */
1297test_result_t test_ffa_notifications_sp_signals_sp_immediate_sri(void)
1298{
1299 CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
1300 const ffa_id_t sender = SP_ID(1);
1301 const ffa_id_t receiver = SP_ID(2);
1302 uint32_t get_flags = FFA_NOTIFICATIONS_FLAG_BITMAP_SP;
Daniel Boulbyce386b12022-03-29 18:36:36 +01001303 struct ffa_value ret;
J-Alves5fb14212021-09-21 13:04:48 +01001304 test_result_t result = TEST_RESULT_SUCCESS;
1305
1306 /** Variables to validate calls to FFA_NOTIFICATION_INFO_GET. */
1307 uint16_t ids[FFA_NOTIFICATIONS_INFO_GET_MAX_IDS] = {0};
1308 uint32_t lists_count;
1309 uint32_t lists_sizes[FFA_NOTIFICATIONS_INFO_GET_MAX_IDS] = {0};
1310
1311 ids[0] = receiver;
1312 lists_count = 1;
1313
J-Alves5fb14212021-09-21 13:04:48 +01001314 schedule_receiver_interrupt_init();
1315
1316 /* Request receiver to bind a set of notifications to the sender. */
1317 if (!request_notification_bind(receiver, receiver, sender,
1318 g_notifications, 0, CACTUS_SUCCESS, 0)) {
1319 result = TEST_RESULT_FAIL;
1320 }
1321
1322 /*
1323 * Request sender to set notification, and expect the response is
1324 * MANAGED_EXIT_INTERRUPT_ID.
1325 */
1326 if (!request_notification_set(sender, receiver, sender, 0,
J-Alvesf0328472021-09-21 18:32:02 +01001327 g_notifications, 0,
1328 MANAGED_EXIT_INTERRUPT_ID, 0)) {
J-Alves5fb14212021-09-21 13:04:48 +01001329 ERROR("SRI not handled immediately!\n");
1330 result = TEST_RESULT_FAIL;
1331 } else {
1332 VERBOSE("SP %x did a managed exit.\n", sender);
1333 }
1334
1335 if (!check_schedule_receiver_interrupt_handled()) {
1336 result = TEST_RESULT_FAIL;
1337 }
1338
1339 /* Call FFA_NOTIFICATION_INFO_GET and validate return. */
1340 if (!notifications_info_get(ids, lists_count, lists_sizes,
1341 FFA_NOTIFICATIONS_INFO_GET_MAX_IDS,
1342 false)) {
1343 result = TEST_RESULT_FAIL;
1344 }
1345
1346 /* Validate notification get. */
J-Alvesc08db422021-10-19 16:15:06 +01001347 if (!request_notification_get(receiver, receiver, 0, get_flags, false, &ret) ||
J-Alves5fb14212021-09-21 13:04:48 +01001348 !is_notifications_get_as_expected(&ret, g_notifications, 0,
1349 receiver)) {
1350 result = TEST_RESULT_FAIL;
1351 }
1352
1353 /*
1354 * Resume setter Cactus in the handling of CACTUS_NOTIFICATIONS_SET_CMD.
1355 */
Madhukar Pappireddy92d2e812022-09-19 13:48:13 -05001356 ret = cactus_resume_after_managed_exit(HYP_ID, sender);
J-Alves5fb14212021-09-21 13:04:48 +01001357
1358 /* Expected result to CACTUS_NOTIFICATIONS_SET_CMD. */
1359 if (!is_expected_cactus_response(ret, CACTUS_SUCCESS, 0)) {
1360 result = TEST_RESULT_FAIL;
1361 }
1362
1363 /* Unbind for clean-up. */
1364 if (!request_notification_unbind(receiver, receiver, sender,
1365 g_notifications, CACTUS_SUCCESS, 0)) {
1366 result = TEST_RESULT_FAIL;
1367 }
1368
1369 schedule_receiver_interrupt_deinit();
1370
J-Alves5fb14212021-09-21 13:04:48 +01001371 return result;
1372}
J-Alvesf0328472021-09-21 18:32:02 +01001373
1374/**
1375 * Test to validate behavior in SWd if the SRI is delayed.
1376 */
1377test_result_t test_ffa_notifications_sp_signals_sp_delayed_sri(void)
1378{
1379 CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
1380 const ffa_id_t sender = SP_ID(3);
1381 const ffa_id_t receiver = SP_ID(2);
1382 const ffa_id_t echo_dest = SP_ID(1);
1383 uint32_t echo_dest_cmd_count = 0;
1384 uint32_t get_flags = FFA_NOTIFICATIONS_FLAG_BITMAP_SP;
Daniel Boulbyce386b12022-03-29 18:36:36 +01001385 struct ffa_value ret;
J-Alvesf0328472021-09-21 18:32:02 +01001386 test_result_t result = TEST_RESULT_SUCCESS;
1387
1388 /** Variables to validate calls to FFA_NOTIFICATION_INFO_GET. */
1389 uint16_t ids[FFA_NOTIFICATIONS_INFO_GET_MAX_IDS] = {0};
1390 uint32_t lists_count;
1391 uint32_t lists_sizes[FFA_NOTIFICATIONS_INFO_GET_MAX_IDS] = {0};
1392
1393 ids[0] = receiver;
1394 lists_count = 1;
1395
J-Alvesf0328472021-09-21 18:32:02 +01001396 schedule_receiver_interrupt_init();
1397
1398 /* Request receiver to bind a set of notifications to the sender. */
1399 if (!request_notification_bind(receiver, receiver, sender,
1400 g_notifications, 0, CACTUS_SUCCESS, 0)) {
1401 result = TEST_RESULT_FAIL;
1402 }
1403
1404 ret = cactus_get_req_count_send_cmd(HYP_ID, echo_dest);
1405
1406 if (cactus_get_response(ret) == CACTUS_SUCCESS) {
1407 /*
1408 * Save the command count from the echo_dest, to validate it
1409 * has been incremented after the request to set notifications.
1410 */
1411 echo_dest_cmd_count = cactus_get_req_count(ret);
1412 VERBOSE("Partition %x command count %u.\n", echo_dest,
1413 echo_dest_cmd_count);
1414 } else {
1415 VERBOSE("Failed to get cmds count from %u\n", echo_dest);
1416 result = TEST_RESULT_FAIL;
1417 }
1418
1419 /*
1420 * Request sender to set notification with Delay SRI flag, and specify
1421 * echo destination.
1422 */
1423 if (!request_notification_set(sender, receiver, sender,
1424 FFA_NOTIFICATIONS_FLAG_DELAY_SRI,
1425 g_notifications, echo_dest,
1426 CACTUS_SUCCESS, 0)) {
1427 VERBOSE("Failed to set notifications!\n");
1428 result = TEST_RESULT_FAIL;
1429 }
1430
1431 if (!check_schedule_receiver_interrupt_handled()) {
1432 result = TEST_RESULT_FAIL;
1433 }
1434
1435 /*
1436 * Get command count again from echo_dest, to validate that it has been
1437 * incremented by one. This should indicate the notification setter has
1438 * issued a request to echo_dest right after the notification set, thus
1439 * proving the SRI hasn't been sent right after FFA_NOTIFICATION_SET.
1440 */
1441 ret = cactus_get_req_count_send_cmd(HYP_ID, echo_dest);
1442 if (cactus_get_response(ret) == CACTUS_SUCCESS) {
1443 if (cactus_get_req_count(ret) == echo_dest_cmd_count + 1) {
1444 VERBOSE("SRI successfully delayed.\n");
1445 } else {
1446 VERBOSE("Failed to get cmds count from %u.\n",
1447 echo_dest);
1448 result = TEST_RESULT_FAIL;
1449 }
1450 } else {
1451 VERBOSE("Failed to get cmds count from %x\n", echo_dest);
1452 result = TEST_RESULT_FAIL;
1453 }
1454
1455 /* Call FFA_NOTIFICATION_INFO_GET and validate return. */
1456 if (!notifications_info_get(ids, lists_count, lists_sizes,
1457 FFA_NOTIFICATIONS_INFO_GET_MAX_IDS,
1458 false)) {
1459 result = TEST_RESULT_FAIL;
1460 }
1461
1462 /* Validate notification get. */
J-Alvesc08db422021-10-19 16:15:06 +01001463 if (!request_notification_get(receiver, receiver, 0, get_flags, false, &ret) ||
J-Alvesf0328472021-09-21 18:32:02 +01001464 !is_notifications_get_as_expected(&ret, g_notifications, 0,
1465 receiver)) {
1466 result = TEST_RESULT_FAIL;
1467 }
1468
1469 /* Unbind for clean-up. */
1470 if (!request_notification_unbind(receiver, receiver, sender,
1471 g_notifications, CACTUS_SUCCESS, 0)) {
1472 result = TEST_RESULT_FAIL;
1473 }
1474
1475 schedule_receiver_interrupt_deinit();
1476
J-Alvesf0328472021-09-21 18:32:02 +01001477 return result;
1478}
J-Alvesbe2daa62021-11-04 17:06:57 +00001479
1480test_result_t notifications_set_per_vcpu_on_handler(void)
1481{
1482 unsigned int core_pos = get_current_core_id();
1483 test_result_t result = TEST_RESULT_FAIL;
1484
J-Alvesbe2daa62021-11-04 17:06:57 +00001485 if (!notification_set(per_vcpu_receiver, per_vcpu_sender,
1486 FFA_NOTIFICATIONS_FLAG_DELAY_SRI |
1487 FFA_NOTIFICATIONS_FLAG_PER_VCPU |
1488 FFA_NOTIFICATIONS_FLAGS_VCPU_ID(0),
1489 FFA_NOTIFICATION(core_pos))) {
1490 goto out;
1491 }
1492
1493 result = TEST_RESULT_SUCCESS;
1494
1495out:
1496 /* Tell the lead CPU that the calling CPU has completed the test. */
1497 tftf_send_event(&per_vcpu_finished[core_pos]);
1498
1499 return result;
1500}
1501
1502test_result_t test_ffa_notifications_mp_sp_signals_up_sp(void)
1503{
1504 ffa_notification_bitmap_t to_bind = 0;
1505
1506 /* prepare info get variables. */
1507
1508 CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
1509
1510 /* Setting per-vCPU sender and receiver IDs. */
1511 per_vcpu_sender = SP_ID(2); /* MP SP */
1512 per_vcpu_receiver = SP_ID(3); /* UP SP */
1513
1514 schedule_receiver_interrupt_init();
1515
J-Alvesbe2daa62021-11-04 17:06:57 +00001516 /* Prepare notifications bitmap to have one bit platform core. */
1517 for (uint32_t i = 0; i < PLATFORM_CORE_COUNT; i++) {
1518 to_bind |= FFA_NOTIFICATION(i);
1519 }
1520
1521 /* Request receiver to bind a set of notifications to the sender. */
1522 if (!request_notification_bind(per_vcpu_receiver, per_vcpu_receiver,
1523 per_vcpu_sender, to_bind,
1524 FFA_NOTIFICATIONS_FLAG_PER_VCPU,
1525 CACTUS_SUCCESS, 0)) {
1526 return TEST_RESULT_FAIL;
1527 }
1528
1529 /*
1530 * Boot up system, and then request sender to signal notification from
1531 * every core into into receiver's only vCPU. Delayed SRI.
1532 */
1533 if (!notification_set(per_vcpu_receiver, per_vcpu_sender,
1534 FFA_NOTIFICATIONS_FLAG_DELAY_SRI |
1535 FFA_NOTIFICATIONS_FLAG_PER_VCPU |
1536 FFA_NOTIFICATIONS_FLAGS_VCPU_ID(0),
1537 FFA_NOTIFICATION(0))) {
1538 return TEST_RESULT_FAIL;
1539 }
1540
1541 if (spm_run_multi_core_test(
1542 (uintptr_t)notifications_set_per_vcpu_on_handler,
1543 per_vcpu_finished) != TEST_RESULT_SUCCESS) {
1544 return TEST_RESULT_FAIL;
1545 }
1546
1547 if (!check_schedule_receiver_interrupt_handled()) {
1548 return TEST_RESULT_FAIL;
1549 }
1550
1551 if (!notification_get_and_validate(per_vcpu_receiver, to_bind, 0, 0,
1552 FFA_NOTIFICATIONS_FLAG_BITMAP_SP, true)) {
1553 return TEST_RESULT_FAIL;
1554 }
1555
1556 /* Request unbind. */
1557 if (!request_notification_unbind(per_vcpu_receiver, per_vcpu_receiver,
1558 per_vcpu_sender, to_bind,
1559 CACTUS_SUCCESS, 0)) {
1560 return TEST_RESULT_FAIL;
1561 }
1562
1563 schedule_receiver_interrupt_deinit();
1564
J-Alvesbe2daa62021-11-04 17:06:57 +00001565 return TEST_RESULT_SUCCESS;
1566}