diff options
Diffstat (limited to 'smc_fuzz/src/randsmcmod.c')
-rw-r--r-- | smc_fuzz/src/randsmcmod.c | 230 |
1 files changed, 143 insertions, 87 deletions
diff --git a/smc_fuzz/src/randsmcmod.c b/smc_fuzz/src/randsmcmod.c index 2b8d01729..a86feb61e 100644 --- a/smc_fuzz/src/randsmcmod.c +++ b/smc_fuzz/src/randsmcmod.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Arm Limited. All rights reserved. + * Copyright (c) 2024, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,19 +9,20 @@ #include <drivers/arm/private_timer.h> #include <events.h> #include "fifo3d.h" +#include "nfifo.h" #include <libfdt.h> +#include <plat_topology.h> #include <power_management.h> -#include <sdei.h> #include <tftf_lib.h> -#include <timer.h> - -#include <plat_topology.h> -#include <platform.h> extern char _binary___dtb_start[]; +extern void runtestfunction(int funcid); struct memmod tmod __aligned(65536) __section("smcfuzz"); +static int cntndarray; +static struct rand_smc_node *ndarray; +static struct memmod *mmod; /* * switch to use either standard C malloc or custom SMC malloc @@ -119,13 +120,14 @@ struct rand_smc_node { int *biases; // Biases of the individual nodes int *biasarray; // Array of biases across all nodes char **snames; // String that is unique to the SMC call called in test + int *snameid; // ID that is unique to the SMC call called in test struct rand_smc_node *treenodes; // Selection of nodes that are farther down in the tree - // that reference further rand_smc_node objects + // that reference further rand_smc_node objects int *norcall; // Specifies whether a particular node is a leaf node or tree node - int entries; // Number of nodes in object - int biasent; // Number that gives the total number of entries in biasarray - // based on all biases of the nodes - char **nname; // Array of node names + int entries; // Number of nodes in object + int biasent; // Number that gives the total number of entries in biasarray + // based on all biases of the nodes + char **nname; // Array of node names }; @@ -156,6 +158,9 @@ struct rand_smc_node *createsmctree(int *casz, int cntndarray; struct rand_smc_node nrnode; struct rand_smc_node *tndarray; + struct nfifo nf; + + nfifoinit(&nf, mmod); f3d.col = 0; f3d.curr_col = 0; @@ -166,9 +171,6 @@ struct rand_smc_node *createsmctree(int *casz, fhdptr = (struct fdt_header *)_binary___dtb_start; - if (fdt_check_header((void *)fhdptr) != 0) { - printf("ERROR, not device tree compliant\n"); - } fhd = *fhdptr; cntndarray = 0; nrnode.entries = 0; @@ -244,6 +246,8 @@ struct rand_smc_node *createsmctree(int *casz, if (strcmp(cset, "functionname") == 0) { pullstringdt(&dtb, dtb_beg, 0, cset); push_3dfifo_fname(&f3d, cset); + pushnme(cset, &nf, mmod); + push_3dfifo_fid(&f3d, searchnme(cset, &nf, mmod)); leafnode = 1; if (bias_count == 0U) { bintnode = 1U; @@ -279,6 +283,7 @@ struct rand_smc_node *createsmctree(int *casz, for (unsigned int j = 0U; (int)j < cntndarray; j++) { tndarray[j].biases = GENMALLOC(ndarray[j].entries * sizeof(int)); tndarray[j].snames = GENMALLOC(ndarray[j].entries * sizeof(char *)); + tndarray[j].snameid = GENMALLOC(ndarray[j].entries * sizeof(int)); tndarray[j].norcall = GENMALLOC(ndarray[j].entries * sizeof(int)); tndarray[j].nname = GENMALLOC(ndarray[j].entries * sizeof(char *)); tndarray[j].treenodes = GENMALLOC(ndarray[j].entries * sizeof(struct rand_smc_node)); @@ -286,6 +291,7 @@ struct rand_smc_node *createsmctree(int *casz, for (unsigned int i = 0U; (int)i < ndarray[j].entries; i++) { tndarray[j].snames[i] = GENMALLOC(1 * sizeof(char[MAX_NAME_CHARS])); strlcpy(tndarray[j].snames[i], ndarray[j].snames[i], MAX_NAME_CHARS); + tndarray[j].snameid[i] = ndarray[j].snameid[i]; tndarray[j].nname[i] = GENMALLOC(1 * sizeof(char[MAX_NAME_CHARS])); strlcpy(tndarray[j].nname[i], ndarray[j].nname[i], MAX_NAME_CHARS); tndarray[j].biases[i] = ndarray[j].biases[i]; @@ -303,6 +309,7 @@ struct rand_smc_node *createsmctree(int *casz, } tndarray[cntndarray].biases = GENMALLOC(f3d.row[f3d.col + 1] * sizeof(int)); tndarray[cntndarray].snames = GENMALLOC(f3d.row[f3d.col + 1] * sizeof(char *)); + tndarray[cntndarray].snameid = GENMALLOC(f3d.row[f3d.col + 1] * sizeof(int)); tndarray[cntndarray].norcall = GENMALLOC(f3d.row[f3d.col + 1] * sizeof(int)); tndarray[cntndarray].nname = GENMALLOC(f3d.row[f3d.col + 1] * sizeof(char *)); tndarray[cntndarray].treenodes = GENMALLOC(f3d.row[f3d.col + 1] * sizeof(struct rand_smc_node)); @@ -313,9 +320,11 @@ struct rand_smc_node *createsmctree(int *casz, */ int cntbias = 0; int bias_count = 0; + for (unsigned int j = 0U; (int)j < f3d.row[f3d.col + 1]; j++) { tndarray[cntndarray].snames[j] = GENMALLOC(1 * sizeof(char[MAX_NAME_CHARS])); strlcpy(tndarray[cntndarray].snames[j], f3d.fnamefifo[f3d.col + 1][j], MAX_NAME_CHARS); + tndarray[cntndarray].snameid[j] = f3d.fidfifo[f3d.col + 1][j]; tndarray[cntndarray].nname[j] = GENMALLOC(1 * sizeof(char[MAX_NAME_CHARS])); strlcpy(tndarray[cntndarray].nname[j], f3d.nnfifo[f3d.col + 1][j], MAX_NAME_CHARS); tndarray[cntndarray].biases[j] = f3d.biasfifo[f3d.col + 1][j]; @@ -355,6 +364,7 @@ struct rand_smc_node *createsmctree(int *casz, GENFREE(ndarray[j].norcall); GENFREE(ndarray[j].biasarray); GENFREE(ndarray[j].snames); + GENFREE(ndarray[j].snameid); GENFREE(ndarray[j].nname); GENFREE(ndarray[j].treenodes); } @@ -377,6 +387,7 @@ struct rand_smc_node *createsmctree(int *casz, GENFREE(f3d.nnfifo[f3d.col + 1]); GENFREE(f3d.fnamefifo[f3d.col + 1]); GENFREE(f3d.biasfifo[f3d.col + 1]); + GENFREE(f3d.fidfifo[f3d.col + 1]); f3d.curr_col -= 1; } } @@ -393,86 +404,25 @@ struct rand_smc_node *createsmctree(int *casz, GENFREE(f3d.nnfifo[i]); GENFREE(f3d.fnamefifo[i]); GENFREE(f3d.biasfifo[i]); + GENFREE(f3d.fidfifo[i]); } GENFREE(f3d.nnfifo); GENFREE(f3d.fnamefifo); GENFREE(f3d.biasfifo); + GENFREE(f3d.fidfifo); GENFREE(f3d.row); dtdone = 1; } } - *casz = cntndarray; return ndarray; } /* - * Running SMC call from what function name is selected - */ -void runtestfunction(char *funcstr) -{ - if (strcmp(funcstr, "sdei_version") == 0) { - long long ret = sdei_version(); - if (ret != MAKE_SDEI_VERSION(1, 0, 0)) { - tftf_testcase_printf("Unexpected SDEI version: 0x%llx\n", - ret); - } - printf("running %s\n", funcstr); - } - if (strcmp(funcstr, "sdei_pe_unmask") == 0) { - long long ret = sdei_pe_unmask(); - if (ret < 0) { - tftf_testcase_printf("SDEI pe unmask failed: 0x%llx\n", - ret); - } - printf("running %s\n", funcstr); - } - if (strcmp(funcstr, "sdei_pe_mask") == 0) { - int64_t ret = sdei_pe_mask(); - if (ret < 0) { - tftf_testcase_printf("SDEI pe mask failed: 0x%llx\n", ret); - } - printf("running %s\n", funcstr); - } - if (strcmp(funcstr, "sdei_event_status") == 0) { - int64_t ret = sdei_event_status(0); - if (ret < 0) { - tftf_testcase_printf("SDEI event status failed: 0x%llx\n", - ret); - } - printf("running %s\n", funcstr); - } - if (strcmp(funcstr, "sdei_event_signal") == 0) { - int64_t ret = sdei_event_signal(0); - if (ret < 0) { - tftf_testcase_printf("SDEI event signal failed: 0x%llx\n", - ret); - } - printf("running %s\n", funcstr); - } - if (strcmp(funcstr, "sdei_private_reset") == 0) { - int64_t ret = sdei_private_reset(); - if (ret < 0) { - tftf_testcase_printf("SDEI private reset failed: 0x%llx\n", - ret); - } - printf("running %s\n", funcstr); - } - if (strcmp(funcstr, "sdei_shared_reset") == 0) { - int64_t ret = sdei_shared_reset(); - if (ret < 0) { - tftf_testcase_printf("SDEI shared reset failed: 0x%llx\n", - ret); - } - printf("running %s\n", funcstr); - } -} - -/* - * Top of SMC fuzzing module + * Function executes a single SMC fuzz test instance with a supplied seed. */ -test_result_t smc_fuzzing_top(void) +test_result_t init_smc_fuzzing(void) { /* * Setting up malloc block parameters @@ -493,24 +443,27 @@ test_result_t smc_fuzzing_top(void) tmod.checkadd = 1U; tmod.checknumentries = 0U; tmod.memerror = 0U; - struct memmod *mmod; mmod = &tmod; - int cntndarray; - struct rand_smc_node *tlnode; /* * Creating SMC bias tree */ - struct rand_smc_node *ndarray = createsmctree(&cntndarray, &tmod); + ndarray = createsmctree(&cntndarray, &tmod); if (tmod.memerror != 0) { return TEST_RESULT_FAIL; } + return TEST_RESULT_SUCCESS; +} + +test_result_t smc_fuzzing_instance(uint32_t seed) +{ + struct rand_smc_node *tlnode; /* - * Hard coded seed, will change in the near future for better strategy + * Initialize pseudo random number generator with supplied seed. */ - srand(89758389); + srand(seed); /* * Code to traverse the bias tree and select function based on the biaes within @@ -532,21 +485,27 @@ test_result_t smc_fuzzing_top(void) * another loop to continue the process of selection until an eventual leaf * node is found. */ - for (unsigned int i = 0U; i < 100U; i++) { + for (unsigned int i = 0U; i < SMC_FUZZ_CALLS_PER_INSTANCE; i++) { tlnode = &ndarray[cntndarray - 1]; int nd = 0; + while (nd == 0) { int nch = rand()%tlnode->biasent; int selent = tlnode->biasarray[nch]; + if (tlnode->norcall[selent] == 0) { - runtestfunction(tlnode->snames[selent]); + runtestfunction(tlnode->snameid[selent]); nd = 1; } else { tlnode = &tlnode->treenodes[selent]; } } } + return TEST_RESULT_SUCCESS; +} +test_result_t smc_fuzzing_deinit(void) +{ /* * End of test SMC selection and freeing of nodes */ @@ -560,6 +519,7 @@ test_result_t smc_fuzzing_top(void) GENFREE(ndarray[j].norcall); GENFREE(ndarray[j].biasarray); GENFREE(ndarray[j].snames); + GENFREE(ndarray[j].snameid); GENFREE(ndarray[j].nname); GENFREE(ndarray[j].treenodes); } @@ -568,3 +528,99 @@ test_result_t smc_fuzzing_top(void) return TEST_RESULT_SUCCESS; } + +/* + * Top of SMC fuzzing module + */ +test_result_t smc_fuzzer_execute(void) +{ + /* These SMC_FUZZ_x macros are supplied by the build system. */ + test_result_t results[SMC_FUZZ_INSTANCE_COUNT]; + uint32_t seeds[SMC_FUZZ_INSTANCE_COUNT] = {SMC_FUZZ_SEEDS}; + test_result_t result = TEST_RESULT_SUCCESS; + unsigned int i; + + /* Run each instance. */ + for (i = 0U; i < SMC_FUZZ_INSTANCE_COUNT; i++) { + printf("Starting SMC fuzz test with seed 0x%x\n", seeds[i]); + results[i] = smc_fuzzing_instance(seeds[i]); + } + + /* Report successes and failures. */ + printf("SMC Fuzz Test Results Summary\n"); + for (i = 0U; i < SMC_FUZZ_INSTANCE_COUNT; i++) { + /* Display instance number. */ + printf(" Instance #%d\n", i); + + /* Print test results. */ + printf(" Result: "); + if (results[i] == TEST_RESULT_SUCCESS) { + printf("SUCCESS\n"); + } else if (results[i] == TEST_RESULT_FAIL) { + printf("FAIL\n"); + /* If we got a failure, update the result value. */ + result = TEST_RESULT_FAIL; + } else if (results[i] == TEST_RESULT_SKIPPED) { + printf("SKIPPED\n"); + } + + /* Print seed used */ + printf(" Seed: 0x%x\n", seeds[i]); + } + + /* + * Print out the smc fuzzer parameters so this test can be replicated. + */ + printf("SMC fuzz build parameters to recreate this test:\n"); + printf(" SMC_FUZZ_INSTANCE_COUNT=%u\n", + SMC_FUZZ_INSTANCE_COUNT); + printf(" SMC_FUZZ_CALLS_PER_INSTANCE=%u\n", + SMC_FUZZ_CALLS_PER_INSTANCE); + printf(" SMC_FUZZ_SEEDS=0x%x", seeds[0]); + for (i = 1U; i < SMC_FUZZ_INSTANCE_COUNT; i++) { + printf(",0x%x", seeds[i]); + } + printf("\n"); + + return result; +} + +test_result_t smc_fuzzing_top(void) +{ + test_result_t result = TEST_RESULT_SUCCESS; + init_smc_fuzzing(); + +#ifdef MULTI_CPU_SMC_FUZZER + u_register_t lead_mpid, target_mpid; + int cpu_node; + int32_t aff_info __unused; + int64_t ret; + + lead_mpid = read_mpidr_el1() & MPID_MASK; + for_each_cpu(cpu_node) { + target_mpid = tftf_get_mpidr_from_node(cpu_node) & MPID_MASK; + if (lead_mpid == target_mpid) { + /* Run on this CPU */ + if (smc_fuzzer_execute() != TEST_RESULT_SUCCESS) + return TEST_RESULT_FAIL; + } else { + /* Power on other CPU to run through fuzzing instructions */ + ret = tftf_cpu_on(target_mpid, + (uintptr_t) smc_fuzzer_execute, 0); + if (ret != PSCI_E_SUCCESS) { + ERROR("CPU ON failed for 0x%llx\n", + (unsigned long long) target_mpid); + return TEST_RESULT_FAIL; + } + + } + } + + smc_fuzzing_deinit(); + return result; +#else + result = smc_fuzzer_execute(); + smc_fuzzing_deinit(); + return result; +#endif +} |