1 // SPDX-License-Identifier: BSD-3-Clause
2 /*
3  * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
4  */
5 #include <fcntl.h>
6 #include <ffa.h>
7 #include <stdio.h>
8 #include <string.h>
9 #include <sys/ioctl.h>
10 #include <unistd.h>
11 #include "include/uapi/linux/arm_ffa_user.h"
12 #include "xtest_helpers.h"
13 #include "xtest_test.h"
14 
15 #define FFA_DRIVER_FS_PATH	"/sys/kernel/debug/arm_ffa_user"
16 #define SPMC_TEST_OK 0xaa
17 #define INCORRECT_ENDPOINT_ID 0xffff
18 #define NORMAL_WORLD_ENDPOINT_ID	0
19 
20 /* Get the 32 least significant bits of a handle.*/
21 #define MEM_SHARE_HANDLE_LOW(x) ((x) & 0xffffffff)
22 /* Get the 32 most significant bits of a handle.*/
23 #define MEM_SHARE_HANDLE_HIGH(x) (((x) >> 32) & 0xffffffff)
24 
25 #define MEM_SHARE_HANDLE_LOW_INDEX	1
26 #define MEM_SHARE_HANDLE_HIGH_INDEX	2
27 #define MEM_SHARE_HANDLE_ENDPOINT_INDEX	3
28 
29 enum sp_tests {
30 	EP_TEST_SP,
31 	EP_TEST_SP_COMMUNICATION,
32 	EP_TEST_SP_INCREASE,
33 	EP_TRY_R_ACCESS,
34 	EP_TRY_W_ACCESS,
35 	EP_RETRIEVE,
36 	EP_RELINQUISH,
37 	EP_SP_MEM_SHARING,
38 	EP_SP_MEM_SHARING_MULTI,
39 	EP_SP_MEM_SHARING_EXC,
40 	EP_SP_MEM_INCORRECT_ACCESS,
41 	EP_SP_NOP
42 };
43 
44 static int ffa_fd = -1;
45 
46 static const char test_endpoint1_uuid[] =
47 	"5c9edbc3-7b3a-4367-9f83-7c191ae86a37";
48 static const char test_endpoint2_uuid[] =
49 	"7817164c-c40c-4d1a-867a-9bb2278cf41a";
50 static const char test_endpoint3_uuid[] =
51 	"23eb0100-e32a-4497-9052-2f11e584afa6";
52 
53 static struct ffa_ioctl_ep_desc test_endpoint1 = {
54 	.uuid_ptr = (uint64_t)test_endpoint1_uuid,
55 };
56 
57 static struct ffa_ioctl_ep_desc test_endpoint2 = {
58 	.uuid_ptr = (uint64_t)test_endpoint2_uuid,
59 };
60 
61 static struct ffa_ioctl_ep_desc test_endpoint3 = {
62 	.uuid_ptr = (uint64_t)test_endpoint3_uuid,
63 };
64 
close_debugfs(void)65 static void close_debugfs(void)
66 {
67 	int err = 0;
68 
69 	if (ffa_fd >= 0) {
70 		err = close(ffa_fd);
71 		if (err < 0)
72 			Do_ADBG_Log("Error: Could not close the FF-A driver");
73 	}
74 	ffa_fd = -1;
75 }
76 
init_sp_xtest(ADBG_Case_t * c)77 static bool init_sp_xtest(ADBG_Case_t *c)
78 {
79 	if (ffa_fd < 0) {
80 		ffa_fd = open(FFA_DRIVER_FS_PATH, O_RDWR);
81 		if (ffa_fd < 0) {
82 			Do_ADBG_Log("Error: Could not open the FF-A driver");
83 			return false;
84 		}
85 	}
86 	return true;
87 }
88 
start_sp_test(uint16_t endpoint,enum sp_tests test,struct ffa_ioctl_msg_args * args)89 static int start_sp_test(uint16_t endpoint, enum sp_tests test,
90 			 struct ffa_ioctl_msg_args *args)
91 {
92 	args->dst_id = endpoint;
93 	args->args[0] = test;
94 	return ioctl(ffa_fd, FFA_IOC_MSG_SEND, args);
95 }
96 
get_endpoint_id(uint64_t endp)97 static uint16_t get_endpoint_id(uint64_t endp)
98 {
99 	struct ffa_ioctl_ep_desc sid = { .uuid_ptr = endp };
100 
101 	/* Get ID of destination SP based on UUID */
102 	if(ioctl(ffa_fd, FFA_IOC_GET_PART_ID, &sid))
103 		return INCORRECT_ENDPOINT_ID;
104 
105 	return sid.id;
106 }
107 
xtest_ffa_spmc_test_1001(ADBG_Case_t * c)108 static void xtest_ffa_spmc_test_1001(ADBG_Case_t *c)
109 {
110 	struct ffa_ioctl_msg_args args = { 0 };
111 	uint16_t endpoint1_id = 0;
112 	uint16_t endpoint2_id = 0;
113 	int rc = 0;
114 
115 	Do_ADBG_BeginSubCase(c, "SP1 comms check");
116 	if (!init_sp_xtest(c)) {
117 		Do_ADBG_Log("Failed to initialise test, skipping SP test");
118 		goto out;
119 	}
120 
121 	endpoint1_id = get_endpoint_id(test_endpoint1.uuid_ptr);
122 	if (endpoint1_id == INCORRECT_ENDPOINT_ID) {
123 		Do_ADBG_Log("Could not contact xtest_1 sp, skipping SP test");
124 		Do_ADBG_Log("Add xtest_1 sp to the image to enable tests");
125 		goto out;
126 	}
127 
128 	memset(&args, 0, sizeof(args));
129 	rc = start_sp_test(endpoint1_id, EP_TEST_SP, &args);
130 	if (!ADBG_EXPECT_COMPARE_SIGNED(c, rc, ==, 0))
131 		goto out;
132 
133 	if (!ADBG_EXPECT_COMPARE_UNSIGNED(c, args.args[0], ==, SPMC_TEST_OK))
134 		goto out;
135 	Do_ADBG_EndSubCase(c, "SP1 comms check");
136 
137 	Do_ADBG_BeginSubCase(c, "Sp2 comms check");
138 	endpoint2_id = get_endpoint_id(test_endpoint2.uuid_ptr);
139 	if (endpoint2_id == INCORRECT_ENDPOINT_ID) {
140 		Do_ADBG_Log("Could not contact xtest_2 sp, skipping SP test");
141 		Do_ADBG_Log("Add xtest_2 sp to the image to enable tests");
142 		goto out;
143 	}
144 
145 	memset(&args, 0, sizeof(args));
146 	rc = start_sp_test(endpoint2_id, EP_TEST_SP, &args);
147 	if (!ADBG_EXPECT_COMPARE_SIGNED(c, rc, ==, 0))
148 		goto out;
149 
150 	if (!ADBG_EXPECT_COMPARE_UNSIGNED(c, args.args[0], ==, SPMC_TEST_OK))
151 		goto out;
152 	Do_ADBG_EndSubCase(c, "Sp2 comms check");
153 
154 	/* Test SP to SP messaging. */
155 	Do_ADBG_BeginSubCase(c, "SP to SP messaging check");
156 	memset(&args, 0, sizeof(args));
157 	args.args[1] = endpoint2_id;
158 
159 	rc = start_sp_test(endpoint1_id, EP_TEST_SP_COMMUNICATION, &args);
160 	ADBG_EXPECT_COMPARE_SIGNED(c, rc, ==, 0);
161 	ADBG_EXPECT_COMPARE_UNSIGNED(c, args.args[0], ==, SPMC_TEST_OK);
162 
163 	memset(&args, 0, sizeof(args));
164 	args.args[1] = endpoint1_id;
165 
166 	rc = start_sp_test(endpoint2_id, EP_TEST_SP_COMMUNICATION, &args);
167 	ADBG_EXPECT_COMPARE_SIGNED(c, rc, ==, 0);
168 	ADBG_EXPECT_COMPARE_UNSIGNED(c, args.args[0], ==, SPMC_TEST_OK);
169 
170 out:
171 	Do_ADBG_EndSubCase(c, NULL);
172 	close_debugfs();
173 }
174 
175 ADBG_CASE_DEFINE(ffa_spmc, 1001, xtest_ffa_spmc_test_1001,
176 		 "Test FF-A communication");
177 
check_alive(ADBG_Case_t * c,uint16_t endpoint)178 static void check_alive(ADBG_Case_t *c, uint16_t endpoint)
179 {
180 	struct ffa_ioctl_msg_args args = {};
181 	int rc = 0;
182 
183 	args.dst_id = endpoint;
184 	rc = start_sp_test(endpoint, EP_SP_NOP, &args);
185 	ADBG_EXPECT_COMPARE_SIGNED(c, rc, ==, 0);
186 	ADBG_EXPECT_COMPARE_UNSIGNED(c, args.args[0], ==, SPMC_TEST_OK);
187 }
188 
share_mem(uint16_t endpoint,uint64_t * handle)189 static int share_mem(uint16_t endpoint, uint64_t *handle)
190 {
191 	int status = false;
192 	struct ffa_ioctl_shm_desc shm_desc = { .dst_id = endpoint,
193 					      .size = 0x1000 };
194 
195 	status = ioctl(ffa_fd, FFA_IOC_SHM_INIT, &shm_desc);
196 
197 	if (!status)
198 		*handle = shm_desc.handle;
199 
200 	return status;
201 }
202 
set_up_mem(struct ffa_ioctl_ep_desc * endp,struct ffa_ioctl_msg_args * args,uint64_t * handle,ADBG_Case_t * c)203 static int set_up_mem(struct ffa_ioctl_ep_desc *endp,
204 		      struct ffa_ioctl_msg_args *args,
205 		      uint64_t *handle, ADBG_Case_t *c)
206 {
207 	uint16_t endpoint = 0;
208 	int rc = 0;
209 
210 	endpoint = get_endpoint_id(endp->uuid_ptr);
211 	*handle = 0;
212 	/* Share memory with SP*/
213 	rc = share_mem(endpoint, handle);
214 	ADBG_EXPECT_COMPARE_SIGNED(c, rc, ==, 0);
215 
216 	if (!ADBG_EXPECT_TRUE(c, handle != NULL))
217 	     return TEEC_ERROR_GENERIC;
218 
219 	/* SP will retrieve the memory region. */
220 	memset(args, 0, sizeof(*args));
221 	args->dst_id = endpoint;
222 	args->args[MEM_SHARE_HANDLE_LOW_INDEX] = MEM_SHARE_HANDLE_LOW(*handle);
223 	args->args[MEM_SHARE_HANDLE_HIGH_INDEX] = MEM_SHARE_HANDLE_HIGH(*handle);
224 	args->args[MEM_SHARE_HANDLE_ENDPOINT_INDEX] = NORMAL_WORLD_ENDPOINT_ID;
225 
226 	rc = start_sp_test(endpoint, EP_RETRIEVE, args);
227 	ADBG_EXPECT_COMPARE_SIGNED(c, rc, ==, 0);
228 	ADBG_EXPECT_COMPARE_UNSIGNED(c, args->args[0], ==, SPMC_TEST_OK);
229 
230 	return TEEC_SUCCESS;
231 }
232 
xtest_ffa_spmc_test_1002(ADBG_Case_t * c)233 static void xtest_ffa_spmc_test_1002(ADBG_Case_t *c)
234 {
235 	struct ffa_ioctl_msg_args args = { 0 };
236 	uint64_t handle = 0;
237 	uint16_t endpoint1_id = 0;
238 	int rc = 0;
239 	struct ffa_ioctl_shm_desc shm_desc = { 0 };
240 
241 	if (!init_sp_xtest(c)) {
242 		Do_ADBG_Log("Failed to initialise test, skipping SP test");
243 		goto out;
244 	}
245 
246 	endpoint1_id = get_endpoint_id(test_endpoint1.uuid_ptr);
247 	if (endpoint1_id == INCORRECT_ENDPOINT_ID) {
248 		Do_ADBG_Log("Could not contact xtest_1 sp, skipping SP test");
249 		Do_ADBG_Log("Add xtest_1 sp to the image to enable tests");
250 		goto out;
251 	}
252 
253 	memset(&args, 0, sizeof(args));
254 	rc = start_sp_test(endpoint1_id, EP_TEST_SP, &args);
255 	ADBG_EXPECT_COMPARE_SIGNED(c, rc, ==, 0);
256 	if (!ADBG_EXPECT_COMPARE_UNSIGNED(c, args.args[0], ==, SPMC_TEST_OK))
257 	     goto out;
258 
259 	/* Set up memory and have the SP retrieve it. */
260 	Do_ADBG_BeginSubCase(c, "Test memory set-up");
261 	memset(&args, 0, sizeof(args));
262 	if (set_up_mem(&test_endpoint1, &args, &handle, c)) {
263 		Do_ADBG_EndSubCase(c, "Test memory set-up");
264 		goto out;
265 	}
266 	Do_ADBG_EndSubCase(c, "Test memory set-up");
267 
268 	/* Retrieve it again. */
269 	Do_ADBG_BeginSubCase(c, "Test retrieve memory second time");
270 	memset(&args, 0, sizeof(args));
271 	args.dst_id = endpoint1_id;
272 	args.args[MEM_SHARE_HANDLE_LOW_INDEX] = MEM_SHARE_HANDLE_LOW(handle);
273 	args.args[MEM_SHARE_HANDLE_HIGH_INDEX] = MEM_SHARE_HANDLE_HIGH(handle);
274 	args.args[MEM_SHARE_HANDLE_ENDPOINT_INDEX] = NORMAL_WORLD_ENDPOINT_ID;
275 	rc = start_sp_test(endpoint1_id, EP_RETRIEVE, &args);
276 	ADBG_EXPECT_COMPARE_SIGNED(c, rc, ==, 0);
277 	Do_ADBG_EndSubCase(c, "Test retrieve memory second time");
278 
279 	/*Access it. */
280 	Do_ADBG_BeginSubCase(c, "Test accessing memory");
281 	memset(&args, 0, sizeof(args));
282 	rc = start_sp_test(endpoint1_id, EP_TRY_R_ACCESS, &args);
283 	ADBG_EXPECT_COMPARE_SIGNED(c, rc, ==, 0);
284 	ADBG_EXPECT_COMPARE_UNSIGNED(c, args.args[0], ==, SPMC_TEST_OK);
285 	Do_ADBG_EndSubCase(c, "Test accessing memory");
286 
287 	/*RELINQUISH the memory area.*/
288 	Do_ADBG_BeginSubCase(c, "Test relinquish memory");
289 	memset(&args, 0, sizeof(args));
290 	args.args[MEM_SHARE_HANDLE_LOW_INDEX] = MEM_SHARE_HANDLE_LOW(handle);
291 	args.args[MEM_SHARE_HANDLE_HIGH_INDEX] = MEM_SHARE_HANDLE_HIGH(handle);
292 	rc = start_sp_test(endpoint1_id, EP_RELINQUISH, &args);
293 	ADBG_EXPECT_COMPARE_SIGNED(c, rc, ==, 0);
294 	ADBG_EXPECT_COMPARE_UNSIGNED(c, args.args[0], ==, SPMC_TEST_OK);
295 	check_alive(c, endpoint1_id);
296 	Do_ADBG_EndSubCase(c, "Test relinquish memory");
297 
298 	/* Try to reclaim the mem with the SP still having access to it. */
299 	Do_ADBG_BeginSubCase(c, "Test incorrect reclaim");
300 	shm_desc.handle = handle;
301 	shm_desc.dst_id = endpoint1_id;
302 	rc = ioctl(ffa_fd, FFA_IOC_SHM_DEINIT, &shm_desc);
303 	ADBG_EXPECT_COMPARE_SIGNED(c, rc, <, 0);
304 	Do_ADBG_EndSubCase(c, "Test incorrect reclaim");
305 
306 	/*RELINQUISH the memory area.*/
307 	Do_ADBG_BeginSubCase(c, "Test relinquish memory second time");
308 	memset(&args, 0, sizeof(args));
309 	args.args[MEM_SHARE_HANDLE_LOW_INDEX] = MEM_SHARE_HANDLE_LOW(handle);
310 	args.args[MEM_SHARE_HANDLE_HIGH_INDEX] = MEM_SHARE_HANDLE_HIGH(handle);
311 	rc = start_sp_test(endpoint1_id, EP_RELINQUISH, &args);
312 	ADBG_EXPECT_COMPARE_SIGNED(c, rc, ==, 0);
313 	ADBG_EXPECT_COMPARE_UNSIGNED(c, args.args[0], ==, SPMC_TEST_OK);
314 	check_alive(c, endpoint1_id);
315 	Do_ADBG_EndSubCase(c, "Test relinquish memory second time");
316 
317 	/* Try to reclaim again this time it should work. */
318 	Do_ADBG_BeginSubCase(c, "Test correct reclaim");
319 	shm_desc.handle = handle;
320 	shm_desc.dst_id = endpoint1_id;
321 	rc = ioctl(ffa_fd, FFA_IOC_SHM_DEINIT, &shm_desc);
322 	ADBG_EXPECT_COMPARE_SIGNED(c, rc, >=, 0);
323 	check_alive(c, endpoint1_id);
324 	Do_ADBG_EndSubCase(c, "Test correct reclaim");
325 
326 	/* SP will try to retrieve invalid memory region. */
327 	Do_ADBG_BeginSubCase(c, "Test retrieve invalid memory region");
328 	memset(&args, 0, sizeof(args));
329 	args.args[MEM_SHARE_HANDLE_LOW_INDEX] = MEM_SHARE_HANDLE_LOW(handle);
330 	args.args[MEM_SHARE_HANDLE_HIGH_INDEX] = MEM_SHARE_HANDLE_HIGH(handle);
331 	args.args[MEM_SHARE_HANDLE_ENDPOINT_INDEX] = NORMAL_WORLD_ENDPOINT_ID;
332 	rc = start_sp_test(endpoint1_id, EP_RETRIEVE, &args);
333 	ADBG_EXPECT_COMPARE_SIGNED(c, rc, ==, 0);
334 	ADBG_EXPECT_COMPARE_UNSIGNED(c, args.args[0], !=, SPMC_TEST_OK);
335 	check_alive(c, endpoint1_id);
336 
337 	Do_ADBG_EndSubCase(c, "Test retrieve invalid memory region");
338 out:
339 	close_debugfs();
340 }
341 
342 ADBG_CASE_DEFINE(ffa_spmc, 1002, xtest_ffa_spmc_test_1002,
343 		 "Test FF-A memory: share memory from Normal World to SP");
344 
xtest_ffa_spmc_test_1003(ADBG_Case_t * c)345 static void xtest_ffa_spmc_test_1003(ADBG_Case_t *c)
346 {
347 	struct ffa_ioctl_msg_args args = { 0 };
348 	uint16_t endpoint1 = 0;
349 	uint16_t endpoint2 = 0;
350 	int rc = 0;
351 
352 	if (!init_sp_xtest(c)) {
353 		Do_ADBG_Log("Failed to initialise test, skipping SP test");
354 		goto out;
355 	}
356 
357 	endpoint1 = get_endpoint_id(test_endpoint1.uuid_ptr);
358 	if (endpoint1 == INCORRECT_ENDPOINT_ID) {
359 		Do_ADBG_Log("Could not contact xtest_1 sp, skipping SP test");
360 		Do_ADBG_Log("Add xtest_1 sp to the image to enable tests");
361 		goto out;
362 	}
363 
364 	/* Test SP to SP memory sharing. */
365 	endpoint2 = get_endpoint_id(test_endpoint2.uuid_ptr);
366 	if (endpoint2 == INCORRECT_ENDPOINT_ID) {
367 		Do_ADBG_Log("Could not contact xtest_2 sp, skipping SP test");
368 		Do_ADBG_Log("Add xtest_2 sp to the image to enable tests");
369 		goto out;
370 	}
371 
372 	memset(&args, 0, sizeof(args));
373 	args.args[1] = endpoint2;
374 	rc = start_sp_test(endpoint1, EP_SP_MEM_SHARING, &args);
375 	ADBG_EXPECT_COMPARE_SIGNED(c, rc, ==, 0);
376 	ADBG_EXPECT_COMPARE_UNSIGNED(c, args.args[0], ==, SPMC_TEST_OK);
377 
378 out:
379 	close_debugfs();
380 }
381 
382 ADBG_CASE_DEFINE(ffa_spmc, 1003, xtest_ffa_spmc_test_1003,
383 		 "Test FF-A memory: SP to SP");
384 
xtest_ffa_spmc_test_1004(ADBG_Case_t * c)385 static void xtest_ffa_spmc_test_1004(ADBG_Case_t *c)
386 {
387 	struct ffa_ioctl_msg_args args = { 0 };
388 	uint16_t endpoint1 = 0;
389 	uint16_t endpoint2 = 0;
390 	int rc = 0;
391 
392 	if (!init_sp_xtest(c)) {
393 		Do_ADBG_Log("Failed to initialise test, skipping SP test");
394 		goto out;
395 	}
396 
397 	endpoint1 = get_endpoint_id(test_endpoint1.uuid_ptr);
398 	if (endpoint1 == INCORRECT_ENDPOINT_ID) {
399 		Do_ADBG_Log("Could not contact xtest_1 sp, skipping SP test");
400 		Do_ADBG_Log("Add xtest_1 sp to the image to enable tests");
401 		goto out;
402 	}
403 
404 	/* Test SP to SP memory sharing. */
405 	endpoint2 = get_endpoint_id(test_endpoint2.uuid_ptr);
406 	if (endpoint2 == INCORRECT_ENDPOINT_ID) {
407 		Do_ADBG_Log("Could not contact xtest_2 sp, skipping SP test");
408 		Do_ADBG_Log("Add xtest_2 sp to the image to enable tests");
409 		goto out;
410 	}
411 
412 	Do_ADBG_BeginSubCase(c, "Test sharing with exc access");
413 	memset(&args, 0, sizeof(args));
414 	args.args[1] = endpoint2;
415 	rc = start_sp_test(endpoint1, EP_SP_MEM_SHARING_EXC, &args);
416 	ADBG_EXPECT_COMPARE_SIGNED(c, rc, ==, 0);
417 	ADBG_EXPECT_COMPARE_UNSIGNED(c, args.args[0], ==, SPMC_TEST_OK);
418 	Do_ADBG_EndSubCase(c, "Test sharing with exc access");
419 
420 	Do_ADBG_BeginSubCase(c, "Test sharing with incorrect access");
421 	memset(&args, 0, sizeof(args));
422 	args.args[1] = endpoint2;
423 	rc = start_sp_test(endpoint1, EP_SP_MEM_INCORRECT_ACCESS, &args);
424 	ADBG_EXPECT_COMPARE_SIGNED(c, rc, ==, 0);
425 	ADBG_EXPECT_COMPARE_UNSIGNED(c, args.args[0], ==, SPMC_TEST_OK);
426 	Do_ADBG_EndSubCase(c, "Test sharing with incorrect access");
427 
428 out:
429 	close_debugfs();
430 }
431 
432 ADBG_CASE_DEFINE(ffa_spmc, 1004, xtest_ffa_spmc_test_1004,
433 		 "Test FF-A memory: Access and flags");
434 
xtest_ffa_spmc_test_1005(ADBG_Case_t * c)435 static void xtest_ffa_spmc_test_1005(ADBG_Case_t *c)
436 {
437 	struct ffa_ioctl_msg_args args = { 0 };
438 	uint16_t endpoint1 = 0;
439 	uint16_t endpoint2 = 0;
440 	uint16_t endpoint3 = 0;
441 	int rc = 0;
442 
443 	if (!init_sp_xtest(c)) {
444 		Do_ADBG_Log("Failed to initialise test, skipping SP test");
445 		goto out;
446 	}
447 
448 	endpoint1 = get_endpoint_id(test_endpoint1.uuid_ptr);
449 	if (endpoint1 == INCORRECT_ENDPOINT_ID) {
450 		Do_ADBG_Log("Could not contact xtest_1 sp, skipping SP test");
451 		Do_ADBG_Log("Add xtest_1 sp to the image to enable tests");
452 		goto out;
453 	}
454 
455 	endpoint2 = get_endpoint_id(test_endpoint2.uuid_ptr);
456 	if (endpoint2 == INCORRECT_ENDPOINT_ID) {
457 		Do_ADBG_Log("Could not contact xtest_2 sp, skipping SP test");
458 		Do_ADBG_Log("Add xtest_2 sp to the image to enable tests");
459 		goto out;
460 	}
461 
462 	endpoint3 = get_endpoint_id(test_endpoint3.uuid_ptr);
463 	if (endpoint3 == INCORRECT_ENDPOINT_ID) {
464 		Do_ADBG_Log("Could not contact xtest_3 sp, skipping SP test");
465 		Do_ADBG_Log("Add xtest_3 sp to the image to enable tests");
466 		goto out;
467 	}
468 
469 	memset(&args, 0, sizeof(args));
470 	args.args[1] = endpoint2;
471 	args.args[2] = endpoint3;
472 	rc = start_sp_test(endpoint1, EP_SP_MEM_SHARING_MULTI,&args);
473 	ADBG_EXPECT_COMPARE_SIGNED(c, rc, ==, 0);
474 	ADBG_EXPECT_COMPARE_UNSIGNED(c, args.args[0], ==, SPMC_TEST_OK);
475 
476 out:
477 	close_debugfs();
478 }
479 
480 ADBG_CASE_DEFINE(regression, 1005, xtest_ffa_spmc_test_1005,
481 		 "Test FF-A memory: multiple receiver");
482