blob: 6f271058e543d507dc3e8ecde1f83d9e9152add4 [file] [log] [blame]
Mark Dykese7810b52020-06-03 15:46:55 -05001/*
mardyk0182389fb2023-09-25 16:34:56 -05002 * Copyright (c) 2023, Arm Limited. All rights reserved.
Mark Dykese7810b52020-06-03 15:46:55 -05003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <arch_helpers.h>
8#include <debug.h>
9#include <drivers/arm/private_timer.h>
10#include <events.h>
11#include "fifo3d.h"
12#include <libfdt.h>
13
mardyk01c14e4ad2023-10-11 16:50:19 -050014#include <plat_topology.h>
15#include <power_management.h>
Mark Dykese7810b52020-06-03 15:46:55 -050016#include <tftf_lib.h>
Mark Dykese7810b52020-06-03 15:46:55 -050017
18extern char _binary___dtb_start[];
mardyk0182389fb2023-09-25 16:34:56 -050019extern void runtestfunction(char *funcstr);
Mark Dykese7810b52020-06-03 15:46:55 -050020
21struct memmod tmod __aligned(65536) __section("smcfuzz");
mardyk01c14e4ad2023-10-11 16:50:19 -050022static int cntndarray;
23static struct rand_smc_node *ndarray;
24static struct memmod *mmod;
Mark Dykese7810b52020-06-03 15:46:55 -050025
26/*
27 * switch to use either standard C malloc or custom SMC malloc
28 */
29
30#define FIRST_NODE_DEVTREE_OFFSET (8)
31
32#ifdef SMC_FUZZ_TMALLOC
33#define GENMALLOC(x) malloc((x))
34#define GENFREE(x) free((x))
35#else
36#define GENMALLOC(x) smcmalloc((x), mmod)
37#define GENFREE(x) smcfree((x), mmod)
38#endif
39
40/*
41 * Device tree parameter struct
42 */
43
44struct fdt_header_sf {
45 unsigned int magic;
46 unsigned int totalsize;
47 unsigned int off_dt_struct;
48 unsigned int off_dt_strings;
49 unsigned int off_mem_rsvmap;
50 unsigned int version;
51 unsigned int last_comp_version;
52 unsigned int boot_cpuid_phys;
53 unsigned int size_dt_strings;
54 unsigned int size_dt_struct;
55};
56
57/*
58 * Structure to read the fields of the device tree
59 */
60struct propval {
61 unsigned int len;
62 unsigned int nameoff;
63};
64
65/*
66 * Converting from big endian to little endian to read values
67 * of device tree
68 */
69unsigned int lendconv(unsigned int val)
70{
71 unsigned int res;
72
73 res = val << 24;
74 res |= ((val << 8) & 0xFF0000U);
75 res |= ((val >> 8) & 0xFF00U);
76 res |= ((val >> 24) & 0xFFU);
77 return res;
78}
79
80/*
81 * Function to read strings from device tree
82 */
83void pullstringdt(void **dtb,
84 void *dtb_beg,
85 unsigned int offset,
86 char *cset)
87{
88 int fistr;
89 int cntchr;
90 char rval;
91
92 if (offset != 0U) {
93 *dtb = dtb_beg + offset;
94 }
95 fistr = 0;
96
97 cntchr = 0;
98 while (fistr == 0) {
99 rval = *((char *)*dtb);
100 *dtb += sizeof(char);
101 cset[cntchr] = rval;
102 if (cset[cntchr] == 0) {
103 fistr = 1;
104 }
105 cntchr++;
106 }
107
108 if ((cntchr % 4) != 0) {
109 for (unsigned int i = 0U; (int)i < (4 - (cntchr % 4)); i++) {
110 *dtb += sizeof(char);
111 }
112 }
113}
114
115/*
116 * Structure for Node information extracted from device tree
117 */
118struct rand_smc_node {
119 int *biases; // Biases of the individual nodes
120 int *biasarray; // Array of biases across all nodes
121 char **snames; // String that is unique to the SMC call called in test
122 struct rand_smc_node *treenodes; // Selection of nodes that are farther down in the tree
123 // that reference further rand_smc_node objects
124 int *norcall; // Specifies whether a particular node is a leaf node or tree node
125 int entries; // Number of nodes in object
126 int biasent; // Number that gives the total number of entries in biasarray
127 // based on all biases of the nodes
128 char **nname; // Array of node names
129};
130
131
132/*
133 * Create bias tree from given device tree description
134 */
135
136struct rand_smc_node *createsmctree(int *casz,
137 struct memmod *mmod)
138{
139 void *dtb;
140 void *dtb_pn;
141 void *dtb_beg;
142 struct fdt_header fhd;
143 unsigned int rval;
144 struct propval pv;
145 char cset[MAX_NAME_CHARS];
146 char nodename[MAX_NAME_CHARS];
147 int dtdone;
148 struct fifo3d f3d;
149 int leafnode = 0;
150 unsigned int fnode = 0U;
151 unsigned int bias_count = 0U;
152 unsigned int bintnode = 0U;
153 unsigned int treenodetrack = 0U;
154 struct fdt_header *fhdptr;
155 struct rand_smc_node *ndarray = NULL;
156 int cntndarray;
157 struct rand_smc_node nrnode;
158 struct rand_smc_node *tndarray;
159
160 f3d.col = 0;
161 f3d.curr_col = 0;
162
163 /*
164 * Read device tree header and check for valid type
165 */
166
167 fhdptr = (struct fdt_header *)_binary___dtb_start;
168
169 if (fdt_check_header((void *)fhdptr) != 0) {
170 printf("ERROR, not device tree compliant\n");
171 }
172 fhd = *fhdptr;
173 cntndarray = 0;
174 nrnode.entries = 0;
175
176 /*
177 * Create pointers to device tree data
178 */
179 dtb = _binary___dtb_start;
180 dtb_pn = _binary___dtb_start;
181
182 dtb_beg = dtb;
183 fhd = *((struct fdt_header *)dtb);
184 dtb += (fdt32_to_cpu(fhd.off_dt_struct) + FIRST_NODE_DEVTREE_OFFSET);
185 dtdone = 0;
186
187 /*
188 * Reading device tree file
189 */
190 while (dtdone == 0) {
191 rval = *((unsigned int *)dtb);
192 dtb += sizeof(unsigned int);
193
194 /*
195 * Reading node name from device tree and pushing it into the raw data
196 * Table of possible values reading from device tree binary file:
197 * 1 New node found within current tree, possible leaf or tree variant
198 * 2 Node termination of current hiearchy.
199 * Could indicate end of tree or preparation for another branch
200 * 3 Leaf node indication where a bias with a function name should be
201 * found for the current node
202 * 9 End of device tree file and we end the read of the bias tree
203 */
204 if (fdt32_to_cpu(rval) == 1) {
205 pullstringdt(&dtb, dtb_beg, 0U, cset);
206 push_3dfifo_col(&f3d, cset, mmod);
207 strlcpy(nodename, cset, MAX_NAME_CHARS);
208
209 /*
210 * Error checking to make sure that bias is specified
211 */
212 if (fnode == 0U) {
213 fnode = 1U;
214 } else {
215 if (!((fnode == 1U) && (bias_count == 1U))) {
216 printf("ERROR: Did not find bias or multiple bias ");
217 printf("designations before %s %u %u\n",
218 cset, fnode, bias_count);
219 }
220 bias_count = 0U;
221 }
222 }
223
224 /*
225 * Reading node parameters of bias and function name
226 */
227 if (fdt32_to_cpu(rval) == 3) {
228 pv = *((struct propval *)dtb);
229 dtb += sizeof(struct propval);
230 pullstringdt(&dtb_pn, dtb_beg,
231 (fdt32_to_cpu(fhd.off_dt_strings) +
232 fdt32_to_cpu(pv.nameoff)), cset);
233 if (strcmp(cset, "bias") == 0) {
234 rval = *((unsigned int *)dtb);
235 dtb += sizeof(unsigned int);
236 push_3dfifo_bias(&f3d, fdt32_to_cpu(rval));
237 bias_count++;
238 if (bintnode == 1U) {
239 fnode = 0U;
240 bintnode = 0U;
241 bias_count = 0U;
242 }
243 }
244 if (strcmp(cset, "functionname") == 0) {
245 pullstringdt(&dtb, dtb_beg, 0, cset);
246 push_3dfifo_fname(&f3d, cset);
247 leafnode = 1;
248 if (bias_count == 0U) {
249 bintnode = 1U;
250 fnode = 1U;
251 } else {
252 bias_count = 0U;
253 fnode = 0U;
254 }
255 }
256 }
257
258 /*
259 * Node termination and evaluate whether the bias tree requires addition.
260 * The non tree nodes are added.
261 */
262 if (fdt32_to_cpu(rval) == 2) {
263 if ((fnode > 0U) || (bias_count > 0U)) {
264 printf("ERROR: early node termination... ");
265 printf("no bias or functionname field for leaf node, near %s %u\n",
266 nodename, fnode);
267 }
268 f3d.col--;
269 if (leafnode == 1) {
270 leafnode = 0;
271 } else {
272 /*
273 * Create bias tree in memory from raw data
274 */
275 tndarray =
276 GENMALLOC((cntndarray + 1) *
277 sizeof(struct rand_smc_node));
278 unsigned int treenodetrackmal = 0;
279 for (unsigned int j = 0U; (int)j < cntndarray; j++) {
280 tndarray[j].biases = GENMALLOC(ndarray[j].entries * sizeof(int));
281 tndarray[j].snames = GENMALLOC(ndarray[j].entries * sizeof(char *));
282 tndarray[j].norcall = GENMALLOC(ndarray[j].entries * sizeof(int));
283 tndarray[j].nname = GENMALLOC(ndarray[j].entries * sizeof(char *));
284 tndarray[j].treenodes = GENMALLOC(ndarray[j].entries * sizeof(struct rand_smc_node));
285 tndarray[j].entries = ndarray[j].entries;
286 for (unsigned int i = 0U; (int)i < ndarray[j].entries; i++) {
287 tndarray[j].snames[i] = GENMALLOC(1 * sizeof(char[MAX_NAME_CHARS]));
288 strlcpy(tndarray[j].snames[i], ndarray[j].snames[i], MAX_NAME_CHARS);
289 tndarray[j].nname[i] = GENMALLOC(1 * sizeof(char[MAX_NAME_CHARS]));
290 strlcpy(tndarray[j].nname[i], ndarray[j].nname[i], MAX_NAME_CHARS);
291 tndarray[j].biases[i] = ndarray[j].biases[i];
292 tndarray[j].norcall[i] = ndarray[j].norcall[i];
293 if (tndarray[j].norcall[i] == 1) {
294 tndarray[j].treenodes[i] = tndarray[treenodetrackmal];
295 treenodetrackmal++;
296 }
297 }
298 tndarray[j].biasent = ndarray[j].biasent;
299 tndarray[j].biasarray = GENMALLOC((tndarray[j].biasent) * sizeof(int));
300 for (unsigned int i = 0U; (int)i < ndarray[j].biasent; i++) {
301 tndarray[j].biasarray[i] = ndarray[j].biasarray[i];
302 }
303 }
304 tndarray[cntndarray].biases = GENMALLOC(f3d.row[f3d.col + 1] * sizeof(int));
305 tndarray[cntndarray].snames = GENMALLOC(f3d.row[f3d.col + 1] * sizeof(char *));
306 tndarray[cntndarray].norcall = GENMALLOC(f3d.row[f3d.col + 1] * sizeof(int));
307 tndarray[cntndarray].nname = GENMALLOC(f3d.row[f3d.col + 1] * sizeof(char *));
308 tndarray[cntndarray].treenodes = GENMALLOC(f3d.row[f3d.col + 1] * sizeof(struct rand_smc_node));
309 tndarray[cntndarray].entries = f3d.row[f3d.col + 1];
310
311 /*
312 * Populate bias tree with former values in tree
313 */
314 int cntbias = 0;
315 int bias_count = 0;
316 for (unsigned int j = 0U; (int)j < f3d.row[f3d.col + 1]; j++) {
317 tndarray[cntndarray].snames[j] = GENMALLOC(1 * sizeof(char[MAX_NAME_CHARS]));
318 strlcpy(tndarray[cntndarray].snames[j], f3d.fnamefifo[f3d.col + 1][j], MAX_NAME_CHARS);
319 tndarray[cntndarray].nname[j] = GENMALLOC(1 * sizeof(char[MAX_NAME_CHARS]));
320 strlcpy(tndarray[cntndarray].nname[j], f3d.nnfifo[f3d.col + 1][j], MAX_NAME_CHARS);
321 tndarray[cntndarray].biases[j] = f3d.biasfifo[f3d.col + 1][j];
322 cntbias += tndarray[cntndarray].biases[j];
323 if (strcmp(tndarray[cntndarray].snames[j], "none") != 0) {
324 strlcpy(tndarray[cntndarray].snames[j], f3d.fnamefifo[f3d.col + 1][j], MAX_NAME_CHARS);
325 tndarray[cntndarray].norcall[j] = 0;
326 tndarray[cntndarray].treenodes[j] = nrnode;
327 } else {
328 tndarray[cntndarray].norcall[j] = 1;
329 tndarray[cntndarray].treenodes[j] = tndarray[treenodetrack];
330 treenodetrack++;
331 }
332 }
333
334 tndarray[cntndarray].biasent = cntbias;
335 tndarray[cntndarray].biasarray = GENMALLOC((tndarray[cntndarray].biasent) * sizeof(int));
336 for (unsigned int j = 0U; j < tndarray[cntndarray].entries; j++) {
337 for (unsigned int i = 0U; i < tndarray[cntndarray].biases[j]; i++) {
338 tndarray[cntndarray].biasarray[bias_count] = j;
339 bias_count++;
340 }
341 }
342
343 /*
344 * Free memory of old bias tree
345 */
346 if (cntndarray > 0) {
347 for (unsigned int j = 0U; (int)j < cntndarray; j++) {
348 for (unsigned int i = 0U;
349 (int)i < ndarray[j].entries;
350 i++) {
351 GENFREE(ndarray[j].snames[i]);
352 GENFREE(ndarray[j].nname[i]);
353 }
354 GENFREE(ndarray[j].biases);
355 GENFREE(ndarray[j].norcall);
356 GENFREE(ndarray[j].biasarray);
357 GENFREE(ndarray[j].snames);
358 GENFREE(ndarray[j].nname);
359 GENFREE(ndarray[j].treenodes);
360 }
361 GENFREE(ndarray);
362 }
363
364 /*
365 * Move pointers to new bias tree to current tree
366 */
367 ndarray = tndarray;
368 cntndarray++;
369
370 /*
371 * Free raw data
372 */
373 for (unsigned int j = 0U; (int)j < f3d.row[f3d.col + 1]; j++) {
374 GENFREE(f3d.nnfifo[f3d.col + 1][j]);
375 GENFREE(f3d.fnamefifo[f3d.col + 1][j]);
376 }
377 GENFREE(f3d.nnfifo[f3d.col + 1]);
378 GENFREE(f3d.fnamefifo[f3d.col + 1]);
379 GENFREE(f3d.biasfifo[f3d.col + 1]);
380 f3d.curr_col -= 1;
381 }
382 }
383
384 /*
385 * Ending device tree file and freeing raw data
386 */
387 if (fdt32_to_cpu(rval) == 9) {
388 for (unsigned int i = 0U; (int)i < f3d.col; i++) {
389 for (unsigned int j = 0U; (int)j < f3d.row[i]; j++) {
390 GENFREE(f3d.nnfifo[i][j]);
391 GENFREE(f3d.fnamefifo[i][j]);
392 }
393 GENFREE(f3d.nnfifo[i]);
394 GENFREE(f3d.fnamefifo[i]);
395 GENFREE(f3d.biasfifo[i]);
396 }
397 GENFREE(f3d.nnfifo);
398 GENFREE(f3d.fnamefifo);
399 GENFREE(f3d.biasfifo);
400 GENFREE(f3d.row);
401 dtdone = 1;
402 }
403 }
404
405
406 *casz = cntndarray;
407 return ndarray;
408}
409
410/*
johpow01d5c79cc2021-06-23 16:10:22 -0500411 * Function executes a single SMC fuzz test instance with a supplied seed.
Mark Dykese7810b52020-06-03 15:46:55 -0500412 */
mardyk01c14e4ad2023-10-11 16:50:19 -0500413test_result_t init_smc_fuzzing(void)
Mark Dykese7810b52020-06-03 15:46:55 -0500414{
415 /*
416 * Setting up malloc block parameters
417 */
418 tmod.memptr = (void *)tmod.memory;
419 tmod.memptrend = (void *)tmod.memory;
420 tmod.maxmemblk = ((TOTALMEMORYSIZE / BLKSPACEDIV) / sizeof(struct memblk));
421 tmod.nmemblk = 1;
422 tmod.memptr->address = 0U;
423 tmod.memptr->size = TOTALMEMORYSIZE - (TOTALMEMORYSIZE / BLKSPACEDIV);
424 tmod.memptr->valid = 1;
425 tmod.mallocdeladd[0] = 0U;
426 tmod.precblock[0] = (void *)tmod.memory;
427 tmod.trailblock[0] = NULL;
428 tmod.cntdeladd = 0U;
429 tmod.ptrmemblkqueue = 0U;
430 tmod.mallocdeladd_queue_cnt = 0U;
431 tmod.checkadd = 1U;
432 tmod.checknumentries = 0U;
433 tmod.memerror = 0U;
Mark Dykese7810b52020-06-03 15:46:55 -0500434 mmod = &tmod;
Mark Dykese7810b52020-06-03 15:46:55 -0500435
436 /*
437 * Creating SMC bias tree
438 */
mardyk01c14e4ad2023-10-11 16:50:19 -0500439 ndarray = createsmctree(&cntndarray, &tmod);
Mark Dykese7810b52020-06-03 15:46:55 -0500440
441 if (tmod.memerror != 0) {
442 return TEST_RESULT_FAIL;
443 }
444
mardyk01c14e4ad2023-10-11 16:50:19 -0500445 return TEST_RESULT_SUCCESS;
446}
447
448/*
449 * Declaration of single fuzzing instance(seed based)
450 */
451test_result_t smc_fuzzing_instance(uint32_t seed)
452{
453 struct rand_smc_node *tlnode;
Mark Dykese7810b52020-06-03 15:46:55 -0500454 /*
johpow01d5c79cc2021-06-23 16:10:22 -0500455 * Initialize pseudo random number generator with supplied seed.
Mark Dykese7810b52020-06-03 15:46:55 -0500456 */
johpow01d5c79cc2021-06-23 16:10:22 -0500457 srand(seed);
Mark Dykese7810b52020-06-03 15:46:55 -0500458
459 /*
460 * Code to traverse the bias tree and select function based on the biaes within
461 *
462 * The algorithm starts with the first node to pull up the biasarray. The
463 * array is specified as a series of values that reflect the bias of the nodes
464 * in question. So for instance if there are three nodes with a bias of 2,5,7
465 * the biasarray would have the following constituency:
466 *
467 * 0,0,1,1,1,1,1,2,2,2,2,2,2,2.
468 *
469 * Mapping 0 as node 1, 1 as node 2, and 2 as node 3.
470 * The biasent variable contains the count of the size of the biasarray which
471 * provides the input for random selection. This is subsequently applied as an
472 * index to the biasarray. The selection pulls up the node and then is checked
473 * for whether it is a leaf or tree node using the norcall variable.
474 * If it is a leaf then the bias tree traversal ends with an SMC call.
475 * If it is a tree node then the process begins again with
476 * another loop to continue the process of selection until an eventual leaf
477 * node is found.
478 */
johpow01d5c79cc2021-06-23 16:10:22 -0500479 for (unsigned int i = 0U; i < SMC_FUZZ_CALLS_PER_INSTANCE; i++) {
Mark Dykese7810b52020-06-03 15:46:55 -0500480 tlnode = &ndarray[cntndarray - 1];
481 int nd = 0;
482 while (nd == 0) {
483 int nch = rand()%tlnode->biasent;
484 int selent = tlnode->biasarray[nch];
485 if (tlnode->norcall[selent] == 0) {
486 runtestfunction(tlnode->snames[selent]);
487 nd = 1;
488 } else {
489 tlnode = &tlnode->treenodes[selent];
490 }
491 }
492 }
mardyk01c14e4ad2023-10-11 16:50:19 -0500493 return TEST_RESULT_SUCCESS;
494}
Mark Dykese7810b52020-06-03 15:46:55 -0500495
mardyk01c14e4ad2023-10-11 16:50:19 -0500496/*
497 * free memory after fuzzing is complete
498 */
499test_result_t smc_fuzzing_deinit(void)
500{
Mark Dykese7810b52020-06-03 15:46:55 -0500501 /*
502 * End of test SMC selection and freeing of nodes
503 */
504 if (cntndarray > 0) {
505 for (unsigned int j = 0U; j < cntndarray; j++) {
506 for (unsigned int i = 0U; i < ndarray[j].entries; i++) {
507 GENFREE(ndarray[j].snames[i]);
508 GENFREE(ndarray[j].nname[i]);
509 }
510 GENFREE(ndarray[j].biases);
511 GENFREE(ndarray[j].norcall);
512 GENFREE(ndarray[j].biasarray);
513 GENFREE(ndarray[j].snames);
514 GENFREE(ndarray[j].nname);
515 GENFREE(ndarray[j].treenodes);
516 }
517 GENFREE(ndarray);
518 }
519
520 return TEST_RESULT_SUCCESS;
521}
johpow01d5c79cc2021-06-23 16:10:22 -0500522
523/*
mardyk01c14e4ad2023-10-11 16:50:19 -0500524 * Execute fuzzing module
johpow01d5c79cc2021-06-23 16:10:22 -0500525 */
mardyk01c14e4ad2023-10-11 16:50:19 -0500526test_result_t smc_fuzzer_execute(void)
johpow01d5c79cc2021-06-23 16:10:22 -0500527{
528 /* These SMC_FUZZ_x macros are supplied by the build system. */
529 test_result_t results[SMC_FUZZ_INSTANCE_COUNT];
530 uint32_t seeds[SMC_FUZZ_INSTANCE_COUNT] = {SMC_FUZZ_SEEDS};
531 test_result_t result = TEST_RESULT_SUCCESS;
532 unsigned int i;
533
534 /* Run each instance. */
535 for (i = 0U; i < SMC_FUZZ_INSTANCE_COUNT; i++) {
536 printf("Starting SMC fuzz test with seed 0x%x\n", seeds[i]);
537 results[i] = smc_fuzzing_instance(seeds[i]);
538 }
539
540 /* Report successes and failures. */
541 printf("SMC Fuzz Test Results Summary\n");
542 for (i = 0U; i < SMC_FUZZ_INSTANCE_COUNT; i++) {
543 /* Display instance number. */
544 printf(" Instance #%d\n", i);
545
546 /* Print test results. */
547 printf(" Result: ");
548 if (results[i] == TEST_RESULT_SUCCESS) {
549 printf("SUCCESS\n");
550 } else if (results[i] == TEST_RESULT_FAIL) {
551 printf("FAIL\n");
552 /* If we got a failure, update the result value. */
553 result = TEST_RESULT_FAIL;
554 } else if (results[i] == TEST_RESULT_SKIPPED) {
555 printf("SKIPPED\n");
556 }
557
558 /* Print seed used */
559 printf(" Seed: 0x%x\n", seeds[i]);
560 }
561
562 /*
563 * Print out the smc fuzzer parameters so this test can be replicated.
564 */
565 printf("SMC fuzz build parameters to recreate this test:\n");
566 printf(" SMC_FUZZ_INSTANCE_COUNT=%u\n",
567 SMC_FUZZ_INSTANCE_COUNT);
568 printf(" SMC_FUZZ_CALLS_PER_INSTANCE=%u\n",
569 SMC_FUZZ_CALLS_PER_INSTANCE);
570 printf(" SMC_FUZZ_SEEDS=0x%x", seeds[0]);
571 for (i = 1U; i < SMC_FUZZ_INSTANCE_COUNT; i++) {
572 printf(",0x%x", seeds[i]);
573 }
574 printf("\n");
575
576 return result;
577}
mardyk01c14e4ad2023-10-11 16:50:19 -0500578
579/*
580 * Top level of fuzzing module
581 */
582test_result_t smc_fuzzing_top(void)
583{
584 test_result_t result = TEST_RESULT_SUCCESS;
585 init_smc_fuzzing();
586#ifdef MULTI_CPU_SMC_FUZZER
587 u_register_t lead_mpid, target_mpid;
588 int cpu_node;
589 int32_t aff_info __unused;
590 int64_t ret;
591
592 lead_mpid = read_mpidr_el1() & MPID_MASK;
593 for_each_cpu(cpu_node) {
594 target_mpid = tftf_get_mpidr_from_node(cpu_node) & MPID_MASK;
595 if (lead_mpid == target_mpid) {
596 /* Run on this CPU */
597 if (smc_fuzzer_execute() != TEST_RESULT_SUCCESS)
598 return TEST_RESULT_FAIL;
599 } else {
600 /* Power on other CPU to run through fuzzing instructions */
601 ret = tftf_cpu_on(target_mpid,
602 (uintptr_t) smc_fuzzer_execute, 0);
603 if (ret != PSCI_E_SUCCESS) {
604 ERROR("CPU ON failed for 0x%llx\n",
605 (unsigned long long) target_mpid);
606 return TEST_RESULT_FAIL;
607 }
608
609 }
610 }
611
612 smc_fuzzing_deinit();
613 return result;
614#else
615 result = smc_fuzzer_execute();
616 smc_fuzzing_deinit();
617 return result;
618#endif
619}