aboutsummaryrefslogtreecommitdiff
path: root/smc_fuzz/src/randsmcmod.c
diff options
context:
space:
mode:
Diffstat (limited to 'smc_fuzz/src/randsmcmod.c')
-rw-r--r--smc_fuzz/src/randsmcmod.c230
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
+}