xref: /optee_os/core/pta/tests/misc.c (revision 7749dda24cf2b1f0a04d1de529cde03b6ca79867)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2014, STMicroelectronics International N.V.
4  * Copyright (c) 2025, Linaro Limited.
5  */
6 #include <assert.h>
7 #include <config.h>
8 #include <kernel/asan.h>
9 #include <kernel/dt_driver.h>
10 #include <kernel/linker.h>
11 #include <kernel/panic.h>
12 #include <malloc.h>
13 #include <mm/core_memprot.h>
14 #include <setjmp.h>
15 #include <stdbool.h>
16 #include <trace.h>
17 #include <util.h>
18 
19 #include "misc.h"
20 
21 /*
22  * Enable expect LOG macro to enable/disable self tests traces.
23  *
24  * #define LOG     DMSG_RAW
25  * #define LOG(...)
26  */
27 #define LOG(...)
28 
29 static int self_test_add_overflow(void)
30 {
31 	uint32_t r_u32;
32 	int32_t r_s32;
33 	uintmax_t r_um;
34 	intmax_t r_sm;
35 
36 	if (ADD_OVERFLOW(8U, 0U, &r_s32))
37 		return -1;
38 	if (r_s32 != 8)
39 		return -1;
40 	if (ADD_OVERFLOW(32U, 30U, &r_u32))
41 		return -1;
42 	if (r_u32 != 62)
43 		return -1;
44 	if (!ADD_OVERFLOW(UINT32_MAX, UINT32_MAX, &r_u32))
45 		return -1;
46 	if (!ADD_OVERFLOW(UINT32_MAX / 2 + 1, UINT32_MAX / 2 + 1, &r_u32))
47 		return -1;
48 	if (ADD_OVERFLOW(UINT32_MAX / 2, UINT32_MAX / 2 + 1, &r_u32))
49 		return -1;
50 	if (r_u32 != UINT32_MAX)
51 		return -1;
52 
53 	if (ADD_OVERFLOW((uint32_t)30, (int32_t)-31, &r_s32))
54 		return -1;
55 	if (r_s32 != -1)
56 		return -1;
57 	if (ADD_OVERFLOW((int32_t)30, (int32_t)-31, &r_s32))
58 		return -1;
59 	if (r_s32 != -1)
60 		return -1;
61 	if (ADD_OVERFLOW((int32_t)-31, (uint32_t)30, &r_s32))
62 		return -1;
63 	if (r_s32 != -1)
64 		return -1;
65 
66 	if (ADD_OVERFLOW(INT32_MIN + 1, -1, &r_s32))
67 		return -1;
68 	if (r_s32 != INT32_MIN)
69 		return -1;
70 	if (!ADD_OVERFLOW(INT32_MIN, -1, &r_s32))
71 		return -1;
72 	if (!ADD_OVERFLOW(INT32_MIN + 1, -2, &r_s32))
73 		return -1;
74 	if (!ADD_OVERFLOW(INT32_MAX, INT32_MAX, &r_s32))
75 		return -1;
76 	if (ADD_OVERFLOW(INT32_MAX, INT32_MAX, &r_u32))
77 		return -1;
78 	if (!ADD_OVERFLOW(INTMAX_MAX, INTMAX_MAX, &r_sm))
79 		return -1;
80 	if (ADD_OVERFLOW(INTMAX_MAX, INTMAX_MAX, &r_um))
81 		return -1;
82 	if (!ADD_OVERFLOW(INT32_MAX / 2 + 1, INT32_MAX / 2 + 1, &r_s32))
83 		return -1;
84 	if (ADD_OVERFLOW(INT32_MAX / 2, INT32_MAX / 2 + 1, &r_s32))
85 		return -1;
86 	if (r_s32 != INT32_MAX)
87 		return -1;
88 
89 	return 0;
90 }
91 
92 static int self_test_sub_overflow(void)
93 {
94 	uint32_t r_u32;
95 	int32_t r_s32;
96 	intmax_t r_sm;
97 
98 	if (SUB_OVERFLOW(8U, 1U, &r_s32))
99 		return -1;
100 	if (r_s32 != 7)
101 		return -1;
102 	if (SUB_OVERFLOW(32U, 30U, &r_u32))
103 		return -1;
104 	if (r_u32 != 2)
105 		return -1;
106 	if (!SUB_OVERFLOW(30U, 31U, &r_u32))
107 		return -1;
108 
109 	if (SUB_OVERFLOW(30, 31, &r_s32))
110 		return -1;
111 	if (r_s32 != -1)
112 		return -1;
113 	if (SUB_OVERFLOW(-1, INT32_MAX, &r_s32))
114 		return -1;
115 	if (r_s32 != INT32_MIN)
116 		return -1;
117 	if (!SUB_OVERFLOW(-2, INT32_MAX, &r_s32))
118 		return -1;
119 
120 	if (SUB_OVERFLOW((uint32_t)30, (int32_t)-31, &r_s32))
121 		return -1;
122 	if (r_s32 != 61)
123 		return -1;
124 	if (SUB_OVERFLOW((int32_t)30, (int32_t)-31, &r_s32))
125 		return -1;
126 	if (r_s32 != 61)
127 		return -1;
128 	if (SUB_OVERFLOW((int32_t)-31, (uint32_t)30, &r_s32))
129 		return -1;
130 	if (r_s32 != -61)
131 		return -1;
132 	if (SUB_OVERFLOW((int32_t)-31, (int32_t)-30, &r_s32))
133 		return -1;
134 	if (r_s32 != -1)
135 		return -1;
136 
137 	if (SUB_OVERFLOW((int32_t)31, -(INTMAX_MIN + 1), &r_sm))
138 		return -1;
139 	if (r_sm != (INTMAX_MIN + 32))
140 		return -1;
141 
142 	return 0;
143 }
144 
145 static int self_test_mul_unsigned_overflow(void)
146 {
147 	const size_t um_half_shift = sizeof(uintmax_t) * 8 / 2;
148 	const uintmax_t um_half_mask = UINTMAX_MAX >> um_half_shift;
149 	uint32_t r_u32;
150 	uintmax_t r_um;
151 
152 	if (MUL_OVERFLOW(32, 30, &r_u32))
153 		return -1;
154 	if (r_u32 != 960)
155 		return -1;
156 	if (MUL_OVERFLOW(-32, -30, &r_u32))
157 		return -1;
158 	if (r_u32 != 960)
159 		return -1;
160 
161 	if (MUL_OVERFLOW(UINTMAX_MAX, 1, &r_um))
162 		return -1;
163 	if (r_um != UINTMAX_MAX)
164 		return -1;
165 	if (MUL_OVERFLOW(UINTMAX_MAX / 4, 4, &r_um))
166 		return -1;
167 	if (r_um != (UINTMAX_MAX - 3))
168 		return -1;
169 	if (!MUL_OVERFLOW(UINTMAX_MAX / 4 + 1, 4, &r_um))
170 		return -1;
171 	if (!MUL_OVERFLOW(UINTMAX_MAX, UINTMAX_MAX, &r_um))
172 		return -1;
173 	if (!MUL_OVERFLOW(um_half_mask << um_half_shift,
174 			  um_half_mask << um_half_shift, &r_um))
175 		return -1;
176 
177 	return 0;
178 }
179 
180 static int self_test_mul_signed_overflow(void)
181 {
182 	intmax_t r;
183 
184 	if (MUL_OVERFLOW(32, -30, &r))
185 		return -1;
186 	if (r != -960)
187 		return -1;
188 	if (MUL_OVERFLOW(-32, 30, &r))
189 		return -1;
190 	if (r != -960)
191 		return -1;
192 	if (MUL_OVERFLOW(32, 30, &r))
193 		return -1;
194 	if (r != 960)
195 		return -1;
196 
197 	if (MUL_OVERFLOW(INTMAX_MAX, 1, &r))
198 		return -1;
199 	if (r != INTMAX_MAX)
200 		return -1;
201 	if (MUL_OVERFLOW(INTMAX_MAX / 4, 4, &r))
202 		return -1;
203 	if (r != (INTMAX_MAX - 3))
204 		return -1;
205 	if (!MUL_OVERFLOW(INTMAX_MAX / 4 + 1, 4, &r))
206 		return -1;
207 	if (!MUL_OVERFLOW(INTMAX_MAX, INTMAX_MAX, &r))
208 		return -1;
209 	if (MUL_OVERFLOW(INTMAX_MIN + 1, 1, &r))
210 		return -1;
211 	if (r != INTMAX_MIN + 1)
212 		return -1;
213 	if (MUL_OVERFLOW(1, INTMAX_MIN + 1, &r))
214 		return -1;
215 	if (r != INTMAX_MIN + 1)
216 		return -1;
217 	if (MUL_OVERFLOW(0, INTMAX_MIN, &r))
218 		return -1;
219 	if (r != 0)
220 		return -1;
221 	if (MUL_OVERFLOW(1, INTMAX_MIN, &r))
222 		return -1;
223 	if (r != INTMAX_MIN)
224 		return -1;
225 
226 	return 0;
227 }
228 
229 /* test division support. resulting trace shall be manually checked */
230 static int self_test_division(void)
231 {
232 	signed a, b, c, d;
233 	bool r;
234 	int ret = 0;
235 
236 	LOG("");
237 	LOG("division tests (division and modulo):");
238 	/* get some unpredicted values to prevent compilation optimizations: */
239 	/* => use the stack address */
240 
241 	LOG("- test with unsigned small integers:");
242 	a = (signed)((unsigned)(vaddr_t)&a & 0xFFFFF);
243 	b = (signed)((unsigned)(vaddr_t)&b & 0x00FFF) + 1;
244 	c = a / b;
245 	d = a % b;
246 	r = ((b * c + d) == a);
247 	if (!r)
248 		ret = -1;
249 	LOG("  0x%08x / 0x%08x = %u / %u = %u = 0x%x)",
250 	    (unsigned)a, (unsigned)b, (unsigned)a, (unsigned)b, (unsigned)c,
251 	    (unsigned)c);
252 	LOG("  0x%08x %% 0x%08x = %u %% %u = %u = 0x%x)", (unsigned)a,
253 	    (unsigned)b, (unsigned)a, (unsigned)b, (unsigned)d, (unsigned)d);
254 	LOG("  check results => %s", r ? "ok" : "FAILED !!!");
255 	LOG("");
256 
257 	LOG("- test with signed small integers, negative numerator:");
258 	a = (signed)(vaddr_t)&a;
259 	b = (signed)((unsigned)(vaddr_t)&b & 0x00FFF) - 1;
260 	c = a / b;
261 	d = a % b;
262 	r = ((b * c + d) == a);
263 	if (!r)
264 		ret = -1;
265 	LOG("  0x%08x / 0x%08x = %d / %d = %d = 0x%x)",
266 	    (unsigned)a, (unsigned)b, (signed)a, (signed)b, (signed)c,
267 	    (unsigned)c);
268 	LOG("  0x%08x %% 0x%08x = %d %% %d = %d = 0x%x)", (unsigned)a,
269 	    (unsigned)b, (signed)a, (signed)b, (signed)d, (unsigned)d);
270 	LOG("  check results => %s", r ? "ok" : "FAILED !!!");
271 	LOG("");
272 
273 	LOG("- test with signed small integers, negative denominator:");
274 	a = (signed)((unsigned)(vaddr_t)&a & 0xFFFFF);
275 	b = -(signed)((unsigned)(vaddr_t)&b & 0x00FFF) + 1;
276 	c = a / b;
277 	d = a % b;
278 
279 	LOG("- test with unsigned integers, big numerator (> 0x80000000):");
280 	a = (signed)(vaddr_t)&a;
281 	b = (signed)((unsigned)(vaddr_t)&b & 0x00FFF) + 1;
282 	c = (signed)((unsigned)a / (unsigned)b);
283 	d = (signed)((unsigned)a % (unsigned)b);
284 	r = (((unsigned)b * (unsigned)c + (unsigned)d) == (unsigned)a);
285 	if (!r)
286 		ret = -1;
287 	LOG("  0x%08x / 0x%08x = %u / %u = %u = 0x%x)",
288 	    (unsigned)a, (unsigned)b, (unsigned)a, (unsigned)b, (unsigned)c,
289 	    (unsigned)c);
290 	LOG("  0x%08x %% 0x%08x = %u %% %u = %u = 0x%x)", (unsigned)a,
291 	    (unsigned)b, (unsigned)a, (unsigned)b, (unsigned)d, (unsigned)d);
292 	LOG("  check results => %s", r ? "ok" : "FAILED !!!");
293 	LOG("");
294 
295 	LOG("- test with unsigned integers, big num. & denom. (> 0x80000000):");
296 	a = (signed)(vaddr_t)&a;
297 	b = (signed)((unsigned)(vaddr_t)&a - 1);
298 	c = (signed)((unsigned)a / (unsigned)b);
299 	d = (signed)((unsigned)a % (unsigned)b);
300 	r = (((unsigned)b * (unsigned)c + (unsigned)d) == (unsigned)a);
301 	if (!r)
302 		ret = -1;
303 	LOG("  0x%08x / 0x%08x = %u / %u = %u = 0x%x)",
304 	    (unsigned)a, (unsigned)b, (unsigned)a, (unsigned)b, (unsigned)c,
305 	    (unsigned)c);
306 	LOG("  0x%08x %% 0x%08x = %u %% %u = %u = 0x%x)", (unsigned)a,
307 	    (unsigned)b, (unsigned)a, (unsigned)b, (unsigned)d, (unsigned)d);
308 	LOG("  check results => %s", r ? "ok" : "FAILED !!!");
309 	LOG("");
310 
311 	return ret;
312 }
313 
314 /* test malloc support. resulting trace shall be manually checked */
315 static int self_test_malloc(void)
316 {
317 	char *p1 = NULL, *p2 = NULL;
318 	int *p3 = NULL, *p4 = NULL;
319 	bool r;
320 	int ret = 0;
321 
322 	LOG("malloc tests:");
323 	LOG("  p1=%p  p2=%p  p3=%p  p4=%p",
324 	    (void *)p1, (void *)p2, (void *)p3, (void *)p4);
325 	/* test malloc */
326 	p1 = malloc(1024);
327 	LOG("- p1 = malloc(1024)");
328 	p2 = malloc(1024);
329 	LOG("- p2 = malloc(1024)");
330 	LOG("  p1=%p  p2=%p  p3=%p  p4=%p",
331 	    (void *)p1, (void *)p2, (void *)p3, (void *)p4);
332 	r = (p1 && p2 && malloc_buffer_is_within_alloced(p1, 1024) &&
333 		!malloc_buffer_is_within_alloced(p1 + 25, 1000) &&
334 		!malloc_buffer_is_within_alloced(p1 - 25, 500) &&
335 		malloc_buffer_overlaps_heap(p1 - 25, 500));
336 	if (!r)
337 		ret = -1;
338 	LOG("  => test %s", r ? "ok" : "FAILED");
339 	LOG("");
340 
341 	/* test realloc */
342 	p3 = realloc(p1, 3 * 1024);
343 	if (p3)
344 		p1 = NULL;
345 	LOG("- p3 = realloc(p1, 3*1024)");
346 	LOG("- free p2");
347 	free(p2);
348 	p2 = malloc(1024);
349 	LOG("- p2 = malloc(1024)");
350 	LOG("  p1=%p  p2=%p  p3=%p  p4=%p",
351 	    (void *)p1, (void *)p2, (void *)p3, (void *)p4);
352 	r = (p2 && p3);
353 	if (!r)
354 		ret = -1;
355 	LOG("  => test %s", r ? "ok" : "FAILED");
356 	LOG("");
357 	LOG("- free p1, p2, p3");
358 	free(p1);
359 	free(p2);
360 	free(p3);
361 	p1 = NULL;
362 	p2 = NULL;
363 	p3 = NULL;
364 
365 	/* test calloc */
366 	p3 = calloc(4, 1024);
367 	p4 = calloc(0x100, 1024 * 1024);
368 	LOG("- p3 = calloc(4, 1024)");
369 	LOG("- p4 = calloc(0x100, 1024*1024)   too big: should fail!");
370 	LOG("  p1=%p  p2=%p  p3=%p  p4=%p",
371 	    (void *)p1, (void *)p2, (void *)p3, (void *)p4);
372 	r = (p3 && !p4);
373 	if (!r)
374 		ret = -1;
375 	LOG("  => test %s", r ? "ok" : "FAILED");
376 	LOG("");
377 	LOG("- free p3, p4");
378 	free(p3);
379 	free(p4);
380 	p3 = NULL;
381 	p4 = NULL;
382 
383 	/* test memalign */
384 	p3 = memalign(0x1000, 1024);
385 	LOG("- p3 = memalign(%d, 1024)", 0x1000);
386 	p1 = malloc(1024);
387 	LOG("- p1 = malloc(1024)");
388 	p4 = memalign(0x100, 512);
389 	LOG("- p4 = memalign(%d, 512)", 0x100);
390 	LOG("  p1=%p  p2=%p  p3=%p  p4=%p",
391 	    (void *)p1, (void *)p2, (void *)p3, (void *)p4);
392 	r = (p1 && p3 && p4 &&
393 	    !((vaddr_t)p3 % 0x1000) && !((vaddr_t)p4 % 0x100));
394 	if (!r)
395 		ret = -1;
396 	LOG("  => test %s", r ? "ok" : "FAILED");
397 	LOG("");
398 	LOG("- free p1, p3, p4");
399 	free(p1);
400 	free(p3);
401 	free(p4);
402 	p1 = NULL;
403 	p3 = NULL;
404 	p4 = NULL;
405 
406 	/* test memalign with invalid alignments */
407 	p3 = memalign(100, 1024);
408 	LOG("- p3 = memalign(%d, 1024)", 100);
409 	p4 = memalign(0, 1024);
410 	LOG("- p4 = memalign(%d, 1024)", 0);
411 	LOG("  p1=%p  p2=%p  p3=%p  p4=%p",
412 	    (void *)p1, (void *)p2, (void *)p3, (void *)p4);
413 	r = (!p3 && !p4);
414 	if (!r)
415 		ret = -1;
416 	LOG("  => test %s", r ? "ok" : "FAILED");
417 	LOG("");
418 	LOG("- free p3, p4");
419 	free(p3);
420 	free(p4);
421 	p3 = NULL;
422 	p4 = NULL;
423 
424 	/* test free(NULL) */
425 	LOG("- free NULL");
426 	free(NULL);
427 	LOG("");
428 	LOG("malloc test done");
429 
430 	return ret;
431 }
432 
433 #ifdef CFG_NS_VIRTUALIZATION
434 /* test nex_malloc support. resulting trace shall be manually checked */
435 static int self_test_nex_malloc(void)
436 {
437 	char *p1 = NULL, *p2 = NULL;
438 	int *p3 = NULL, *p4 = NULL;
439 	bool r;
440 	int ret = 0;
441 
442 	LOG("nex_malloc tests:");
443 	LOG("  p1=%p  p2=%p  p3=%p  p4=%p",
444 	    (void *)p1, (void *)p2, (void *)p3, (void *)p4);
445 	/* test malloc */
446 	p1 = nex_malloc(1024);
447 	LOG("- p1 = nex_malloc(1024)");
448 	p2 = nex_malloc(1024);
449 	LOG("- p2 = nex_malloc(1024)");
450 	LOG("  p1=%p  p2=%p  p3=%p  p4=%p",
451 	    (void *)p1, (void *)p2, (void *)p3, (void *)p4);
452 	r = (p1 && p2 && nex_malloc_buffer_is_within_alloced(p1, 1024) &&
453 		!nex_malloc_buffer_is_within_alloced(p1 + 25, 1000) &&
454 		!nex_malloc_buffer_is_within_alloced(p1 - 25, 500) &&
455 		nex_malloc_buffer_overlaps_heap(p1 - 25, 500));
456 	if (!r)
457 		ret = -1;
458 	LOG("  => test %s", r ? "ok" : "FAILED");
459 	LOG("");
460 
461 	/* test realloc */
462 	p3 = nex_realloc(p1, 3 * 1024);
463 	if (p3)
464 		p1 = NULL;
465 	LOG("- p3 = nex_realloc(p1, 3*1024)");
466 	LOG("- nex_free p2");
467 	nex_free(p2);
468 	p2 = nex_malloc(1024);
469 	LOG("- p2 = nex_malloc(1024)");
470 	LOG("  p1=%p  p2=%p  p3=%p  p4=%p",
471 	    (void *)p1, (void *)p2, (void *)p3, (void *)p4);
472 	r = (p2 && p3);
473 	if (!r)
474 		ret = -1;
475 	LOG("  => test %s", r ? "ok" : "FAILED");
476 	LOG("");
477 	LOG("- nex_free p1, p2, p3");
478 	nex_free(p1);
479 	nex_free(p2);
480 	nex_free(p3);
481 	p1 = NULL;
482 	p2 = NULL;
483 	p3 = NULL;
484 
485 	/* test calloc */
486 	p3 = nex_calloc(4, 1024);
487 	p4 = nex_calloc(0x100, 1024 * 1024);
488 	LOG("- p3 = nex_calloc(4, 1024)");
489 	LOG("- p4 = nex_calloc(0x100, 1024*1024)   too big: should fail!");
490 	LOG("  p1=%p  p2=%p  p3=%p  p4=%p",
491 	    (void *)p1, (void *)p2, (void *)p3, (void *)p4);
492 	r = (p3 && !p4);
493 	if (!r)
494 		ret = -1;
495 	LOG("  => test %s", r ? "ok" : "FAILED");
496 	LOG("");
497 	LOG("- nex_free p3, p4");
498 	nex_free(p3);
499 	nex_free(p4);
500 	p3 = NULL;
501 	p4 = NULL;
502 
503 	/* test memalign */
504 	p3 = nex_memalign(0x1000, 1024);
505 	LOG("- p3 = nex_memalign(%d, 1024)", 0x1000);
506 	p1 = nex_malloc(1024);
507 	LOG("- p1 = nex_malloc(1024)");
508 	p4 = nex_memalign(0x100, 512);
509 	LOG("- p4 = nex_memalign(%d, 512)", 0x100);
510 	LOG("  p1=%p  p2=%p  p3=%p  p4=%p",
511 	    (void *)p1, (void *)p2, (void *)p3, (void *)p4);
512 	r = (p1 && p3 && p4 &&
513 	    !((vaddr_t)p3 % 0x1000) && !((vaddr_t)p4 % 0x100));
514 	if (!r)
515 		ret = -1;
516 	LOG("  => test %s", r ? "ok" : "FAILED");
517 	LOG("");
518 	LOG("- nex_free p1, p3, p4");
519 	nex_free(p1);
520 	nex_free(p3);
521 	nex_free(p4);
522 	p1 = NULL;
523 	p3 = NULL;
524 	p4 = NULL;
525 
526 	/* test memalign with invalid alignments */
527 	p3 = nex_memalign(100, 1024);
528 	LOG("- p3 = nex_memalign(%d, 1024)", 100);
529 	p4 = nex_memalign(0, 1024);
530 	LOG("- p4 = nex_memalign(%d, 1024)", 0);
531 	LOG("  p1=%p  p2=%p  p3=%p  p4=%p",
532 	    (void *)p1, (void *)p2, (void *)p3, (void *)p4);
533 	r = (!p3 && !p4);
534 	if (!r)
535 		ret = -1;
536 	LOG("  => test %s", r ? "ok" : "FAILED");
537 	LOG("");
538 	LOG("- nex_free p3, p4");
539 	nex_free(p3);
540 	nex_free(p4);
541 	p3 = NULL;
542 	p4 = NULL;
543 
544 	/* test free(NULL) */
545 	LOG("- nex_free NULL");
546 	nex_free(NULL);
547 	LOG("");
548 	LOG("nex_malloc test done");
549 
550 	return ret;
551 }
552 #else  /* CFG_NS_VIRTUALIZATION */
553 static int self_test_nex_malloc(void)
554 {
555 	return 0;
556 }
557 #endif
558 
559 static int check_virt_to_phys(vaddr_t va, paddr_t exp_pa,
560 			      enum teecore_memtypes m)
561 {
562 	paddr_t pa = 0;
563 	void *v = NULL;
564 
565 	pa = virt_to_phys((void *)va);
566 	LOG("virt_to_phys(%#"PRIxVA") => %#"PRIxPA" (expect %#"PRIxPA")",
567 	    va, pa, exp_pa);
568 	if (pa != exp_pa)
569 		goto fail;
570 
571 	if (!exp_pa)
572 		return 0;
573 
574 	v = phys_to_virt(pa, m, 1);
575 	LOG("phys_to_virt(%#"PRIxPA") => %p (expect %#"PRIxVA")",
576 	    pa, v, va);
577 	if ((vaddr_t)v != va)
578 		goto fail;
579 	return 0;
580 
581 fail:
582 	LOG("Fail");
583 	return -1;
584 }
585 
586 static int check_phys_to_virt(paddr_t pa, void *exp_va,
587 			      enum teecore_memtypes m)
588 {
589 	paddr_t new_pa = 0;
590 	void *v = NULL;
591 
592 	v = phys_to_virt(pa, m, 1);
593 	LOG("phys_to_virt(%#"PRIxPA") => %p (expect %p)",
594 	    pa, v, exp_va);
595 	if (v != exp_va)
596 		goto fail;
597 
598 	if (!exp_va)
599 		return 0;
600 
601 	new_pa = virt_to_phys(v);
602 	LOG("virt_to_phys(%p) => %#"PRIxPA" (expect %#"PRIxPA")",
603 	    v, new_pa, pa);
604 	if (new_pa != pa)
605 		goto fail;
606 	return 0;
607 
608 fail:
609 	LOG("Fail");
610 	return -1;
611 }
612 
613 static int self_test_va2pa(void)
614 {
615 	void *ptr = self_test_va2pa;
616 	int ret = 0;
617 
618 	if (IS_ENABLED(CFG_DYN_CONFIG) && VCORE_FREE_SZ) {
619 		vaddr_t va_base = VCORE_FREE_PA;
620 		paddr_t pa_base = 0;
621 
622 		pa_base = virt_to_phys((void *)va_base);
623 		if (!pa_base) {
624 			LOG("virt_to_phys(%#"PRIxVA") => 0 Fail!", va_base);
625 			return -1;
626 		}
627 
628 		/*
629 		 * boot_mem_release_unused() and
630 		 * boot_mem_release_tmp_alloc() has been called during
631 		 * boot.
632 		 *
633 		 * First pages of VCORE_FREE are expected to be allocated
634 		 * with boot_mem_alloc() while the end of VCORE_FREE should
635 		 * have been freed by the two mentioned release functions.
636 		 */
637 		if (check_virt_to_phys(va_base, pa_base, MEM_AREA_TEE_RAM))
638 			ret = -1;
639 		if (check_virt_to_phys(va_base + 16, pa_base + 16,
640 				       MEM_AREA_TEE_RAM))
641 			ret = -1;
642 		if (check_virt_to_phys(va_base + VCORE_FREE_SZ -
643 				       SMALL_PAGE_SIZE, 0, MEM_AREA_TEE_RAM))
644 			ret = -1;
645 		if (check_virt_to_phys(va_base + VCORE_FREE_SZ - 16, 0,
646 				       MEM_AREA_TEE_RAM))
647 			ret = -1;
648 	}
649 
650 	if (!IS_ENABLED(CFG_WITH_PAGER) &&
651 	    check_phys_to_virt(virt_to_phys(ptr), ptr, MEM_AREA_TEE_RAM))
652 		ret = -1;
653 	if (check_phys_to_virt(virt_to_phys(ptr), NULL, MEM_AREA_IO_SEC))
654 		ret = -1;
655 	if (check_virt_to_phys(0, 0, MEM_AREA_TEE_RAM))
656 		ret = -1;
657 	if (check_phys_to_virt(0, NULL, MEM_AREA_TEE_RAM))
658 		ret = -1;
659 
660 	return ret;
661 }
662 
663 #ifdef CFG_CORE_SANITIZE_KADDRESS
664 
665 #define ASAN_TEST_SUCCESS 1
666 #define ASAN_TEST_BUF_SIZE 15
667 
668 static char asan_test_sgbuf[ASAN_TEST_BUF_SIZE];
669 char asan_test_gbuf[ASAN_TEST_BUF_SIZE];
670 
671 static jmp_buf asan_test_jmp;
672 
673 struct asan_test_ctx {
674 	char *pmalloc1;
675 	char *pmalloc2[3];
676 	char write_value;
677 	void (*write_func)(char *buf, size_t pos, char value);
678 	void *(*memcpy_func)(void *__restrict dst,
679 			     const void *__restrict src, size_t size);
680 	void *(*memset_func)(void *buf, int val, size_t size);
681 };
682 
683 static void asan_out_of_bounds_write(char *buf, size_t pos,
684 				     char value)
685 {
686 	buf[pos] = value;
687 }
688 
689 static void *asan_out_of_bounds_memcpy(void *__restrict dst,
690 				       const void *__restrict src,
691 				       size_t size)
692 {
693 	return memcpy(dst, src, size);
694 }
695 
696 static void *asan_out_of_bounds_memset(void *buf, int val, size_t size)
697 {
698 	return memset(buf, val, size);
699 }
700 
701 static void asan_panic_test(void)
702 {
703 	longjmp(asan_test_jmp, ASAN_TEST_SUCCESS);
704 }
705 
706 static void asan_test_cleanup(struct asan_test_ctx *ctx)
707 {
708 	unsigned int i = 0;
709 
710 	free(ctx->pmalloc1);
711 
712 	for (; i < ARRAY_SIZE(ctx->pmalloc2); i++)
713 		free(ctx->pmalloc2[i]);
714 }
715 
716 static int asan_call_test(struct asan_test_ctx *ctx,
717 			  void (*test)(struct asan_test_ctx *ctx),
718 			  const char __maybe_unused *desc)
719 {
720 	int ret = 0;
721 
722 	ret = setjmp(asan_test_jmp);
723 	if (ret == 0) {
724 		test(ctx);
725 		ret = -1;
726 	} else if (ret == ASAN_TEST_SUCCESS) {
727 		ret = 0;
728 	} else {
729 		panic("Unexpected setjmp return");
730 	}
731 	LOG("  => [asan] test %s: %s", desc, !ret ? "ok" : "FAILED");
732 	return ret;
733 }
734 
735 #ifndef CFG_DYN_CONFIG
736 static void asan_stack(struct asan_test_ctx *ctx)
737 {
738 	char buf[ASAN_TEST_BUF_SIZE] = {0};
739 
740 	ctx->write_func(buf, ASAN_TEST_BUF_SIZE, ctx->write_value);
741 }
742 #endif
743 
744 static void asan_global_stat(struct asan_test_ctx *ctx)
745 {
746 	ctx->write_func(asan_test_sgbuf, ASAN_TEST_BUF_SIZE,
747 			ctx->write_value);
748 }
749 
750 static void asan_global(struct asan_test_ctx *ctx)
751 {
752 	ctx->write_func(asan_test_gbuf, ASAN_TEST_BUF_SIZE,
753 			ctx->write_value);
754 }
755 
756 static void asan_malloc(struct asan_test_ctx *ctx)
757 {
758 	ctx->pmalloc1 = malloc(ASAN_TEST_BUF_SIZE);
759 
760 	if (ctx->pmalloc1)
761 		ctx->write_func(ctx->pmalloc1, ASAN_TEST_BUF_SIZE,
762 				ctx->write_value);
763 }
764 
765 static void asan_malloc2(struct asan_test_ctx *ctx)
766 {
767 	unsigned int i = 0;
768 	char *p = NULL;
769 	size_t aligned_size = ROUNDUP(ASAN_TEST_BUF_SIZE, 8);
770 
771 	for (; i < ARRAY_SIZE(ctx->pmalloc2); i++) {
772 		ctx->pmalloc2[i] = malloc(aligned_size);
773 		if (!ctx->pmalloc2[i])
774 			return;
775 	}
776 	p = ctx->pmalloc2[1];
777 	ctx->write_func(p, aligned_size, ctx->write_value);
778 }
779 
780 static void asan_use_after_free(struct asan_test_ctx *ctx)
781 {
782 	char *a = malloc(ASAN_TEST_BUF_SIZE);
783 
784 	if (a) {
785 		free(a);
786 		ctx->write_func(a, 0, ctx->write_value);
787 	}
788 }
789 
790 static void asan_memcpy_dst(struct asan_test_ctx *ctx)
791 {
792 	static char b[ASAN_TEST_BUF_SIZE + 1];
793 	static char a[ASAN_TEST_BUF_SIZE];
794 
795 	ctx->memcpy_func(a, b, sizeof(b));
796 }
797 
798 static void asan_memcpy_src(struct asan_test_ctx *ctx)
799 {
800 	static char b[ASAN_TEST_BUF_SIZE];
801 	static char a[ASAN_TEST_BUF_SIZE + 1];
802 
803 	ctx->memcpy_func(a, b, sizeof(a));
804 }
805 
806 static void asan_memset(struct asan_test_ctx *ctx)
807 {
808 	static char b[ASAN_TEST_BUF_SIZE];
809 
810 	ctx->memset_func(b, ctx->write_value, ASAN_TEST_BUF_SIZE + 1);
811 }
812 
813 static int self_test_asan(void)
814 {
815 	uint32_t vfp_state = UINT32_C(0);
816 	int ret = 0;
817 	struct asan_test_ctx ctx = {0};
818 
819 	ctx.write_value = 0xab;
820 	ctx.write_func = asan_out_of_bounds_write;
821 	ctx.memcpy_func = asan_out_of_bounds_memcpy;
822 	ctx.memset_func = asan_out_of_bounds_memset;
823 
824 	asan_set_panic_cb(asan_panic_test);
825 	/*
826 	 * We need enable access to floating-point registers, in other
827 	 * way sync exception during setjmp/longjmp will occur.
828 	 */
829 	vfp_state = thread_kernel_enable_vfp();
830 
831 	if (asan_call_test(&ctx, asan_global_stat, "(s) glob overflow") ||
832 	    asan_call_test(&ctx, asan_global, "glob overflow") ||
833 #ifndef CFG_DYN_CONFIG
834 	    asan_call_test(&ctx, asan_stack, "stack overflow") ||
835 #endif
836 	    asan_call_test(&ctx, asan_malloc, "malloc") ||
837 	    asan_call_test(&ctx, asan_malloc2, "malloc2") ||
838 	    asan_call_test(&ctx, asan_use_after_free, "use_after_free") ||
839 	    asan_call_test(&ctx, asan_memcpy_dst, "memcpy_dst") ||
840 	    asan_call_test(&ctx, asan_memcpy_src, "memcpy_src") ||
841 	    asan_call_test(&ctx, asan_memset, "memset")) {
842 		ret = -1;
843 	}
844 
845 	thread_kernel_disable_vfp(vfp_state);
846 	asan_test_cleanup(&ctx);
847 	asan_set_panic_cb(asan_panic);
848 	return ret;
849 }
850 #else
851 static int self_test_asan(void)
852 {
853 	return 0;
854 }
855 #endif
856 
857 /* exported entry points for some basic test */
858 TEE_Result core_self_tests(uint32_t nParamTypes __unused,
859 		TEE_Param pParams[TEE_NUM_PARAMS] __unused)
860 {
861 	if (self_test_mul_signed_overflow() || self_test_add_overflow() ||
862 	    self_test_sub_overflow() || self_test_mul_unsigned_overflow() ||
863 	    self_test_division() || self_test_malloc() ||
864 	    self_test_nex_malloc() || self_test_va2pa() ||
865 	    self_test_asan()) {
866 		EMSG("some self_test_xxx failed! you should enable local LOG");
867 		return TEE_ERROR_GENERIC;
868 	}
869 	return TEE_SUCCESS;
870 }
871 
872 /* Exported entrypoint for dt_driver tests */
873 TEE_Result core_dt_driver_tests(uint32_t nParamTypes __unused,
874 				TEE_Param pParams[TEE_NUM_PARAMS] __unused)
875 {
876 	if (IS_ENABLED(CFG_DT_DRIVER_EMBEDDED_TEST)) {
877 		if (dt_driver_test_status())
878 			return TEE_ERROR_GENERIC;
879 	} else {
880 		IMSG("dt_driver tests are not embedded");
881 	}
882 
883 	return TEE_SUCCESS;
884 }
885