xref: /optee_os/core/pta/tests/misc.c (revision 9f2dc7a17efdd58b8afa6c45edcc5bb99c766bfa)
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 <asan.h>
7 #include <asan_test.h>
8 #include <assert.h>
9 #include <config.h>
10 #include <kernel/dt_driver.h>
11 #include <kernel/linker.h>
12 #include <kernel/panic.h>
13 #include <malloc.h>
14 #include <mm/core_memprot.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 static int self_test_asan(void)
666 {
667 	uint32_t vfp_state = UINT32_C(0);
668 	int ret = 0;
669 	struct asan_test_ctx ctx = {0};
670 
671 	asan_test_init(&ctx);
672 	/*
673 	 * We need enable access to floating-point registers, in other
674 	 * way sync exception during setjmp/longjmp will occur.
675 	 */
676 	vfp_state = thread_kernel_enable_vfp();
677 
678 	if (asan_call_test(&ctx, asan_test_global_stat, "(s) glob overflow") ||
679 	    asan_call_test(&ctx, asan_test_global, "glob overflow") ||
680 	    asan_call_test(&ctx, asan_test_global_ro, "glob ro overflow") ||
681 #ifndef CFG_DYN_CONFIG
682 	    asan_call_test(&ctx, asan_test_stack, "stack overflow") ||
683 #endif
684 	    asan_call_test(&ctx, asan_test_malloc, "malloc") ||
685 	    asan_call_test(&ctx, asan_test_malloc2, "malloc2") ||
686 	    asan_call_test(&ctx, asan_test_use_after_free, "use_after_free") ||
687 	    asan_call_test(&ctx, asan_test_memcpy_dst, "memcpy_dst") ||
688 	    asan_call_test(&ctx, asan_test_memcpy_src, "memcpy_src") ||
689 	    asan_call_test(&ctx, asan_test_memset, "memset")) {
690 		ret = -1;
691 	}
692 
693 	thread_kernel_disable_vfp(vfp_state);
694 	asan_test_deinit(&ctx);
695 	return ret;
696 }
697 #else
698 static int self_test_asan(void)
699 {
700 	return 0;
701 }
702 #endif
703 
704 /* exported entry points for some basic test */
705 TEE_Result core_self_tests(uint32_t nParamTypes __unused,
706 		TEE_Param pParams[TEE_NUM_PARAMS] __unused)
707 {
708 	if (self_test_mul_signed_overflow() || self_test_add_overflow() ||
709 	    self_test_sub_overflow() || self_test_mul_unsigned_overflow() ||
710 	    self_test_division() || self_test_malloc() ||
711 	    self_test_nex_malloc() || self_test_va2pa() ||
712 	    self_test_asan()) {
713 		EMSG("some self_test_xxx failed! you should enable local LOG");
714 		return TEE_ERROR_GENERIC;
715 	}
716 	return TEE_SUCCESS;
717 }
718 
719 /* Exported entrypoint for dt_driver tests */
720 TEE_Result core_dt_driver_tests(uint32_t nParamTypes __unused,
721 				TEE_Param pParams[TEE_NUM_PARAMS] __unused)
722 {
723 	if (IS_ENABLED(CFG_DT_DRIVER_EMBEDDED_TEST)) {
724 		if (dt_driver_test_status())
725 			return TEE_ERROR_GENERIC;
726 	} else {
727 		IMSG("dt_driver tests are not embedded");
728 	}
729 
730 	return TEE_SUCCESS;
731 }
732