test(fuzz) adding fuzzing for all SDEI calls
added constraints for all calls
added fuzzer feature to start at arbitrary call number
added fuzzer features for function exclusion, fuzzer starting/ending call
worked on additional fuzzing for event_register
Change-Id: I9814b8387ea9e0fb00b53adbdbe0f8429845924e
Signed-off-by: Alex Liang <alex.liang2@arm.com>
diff --git a/smc_fuzz/src/randsmcmod.c b/smc_fuzz/src/randsmcmod.c
index 1cbf44a..e1725f0 100644
--- a/smc_fuzz/src/randsmcmod.c
+++ b/smc_fuzz/src/randsmcmod.c
@@ -462,6 +462,7 @@
test_result_t smc_fuzzing_instance(uint32_t seed)
{
struct rand_smc_node *tlnode;
+
/*
* Initialize pseudo random number generator with supplied seed.
*/
diff --git a/smc_fuzz/src/runtestfunction_helpers.c b/smc_fuzz/src/runtestfunction_helpers.c
index 50bf395..95dd30a 100644
--- a/smc_fuzz/src/runtestfunction_helpers.c
+++ b/smc_fuzz/src/runtestfunction_helpers.c
@@ -8,11 +8,19 @@
#include "smcmalloc.h"
#include <tsp_fuzz_helper.h>
+int cntid = 0;
+
/*
* Invoke the SMC call based on the function name specified.
*/
void runtestfunction(int funcid, struct memmod *mmod)
{
- run_sdei_fuzz(funcid, mmod);
+
+ bool inrange = (cntid >= SMC_FUZZ_CALL_START) && (cntid < SMC_FUZZ_CALL_END);
+ inrange = inrange && (funcid != EXCLUDE_FUNCID);
+
+ run_sdei_fuzz(funcid, mmod, inrange, cntid);
run_tsp_fuzz(funcid);
+
+ cntid++;
}
diff --git a/smc_fuzz/src/sdei_fuzz_helper.c b/smc_fuzz/src/sdei_fuzz_helper.c
index cbba482..591db0b 100644
--- a/smc_fuzz/src/sdei_fuzz_helper.c
+++ b/smc_fuzz/src/sdei_fuzz_helper.c
@@ -4,26 +4,94 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
#include <arg_struct_def.h>
#include "constraint.h"
#include <fuzz_names.h>
#include <sdei_fuzz_helper.h>
-#define INTERRUPT_BIND_INT_LOWVAL 170
-#define INTERRUPT_BIND_INT_HIGHVAL 200
-
int stbev = 0;
+#define MIN_PPI_ID U(16)
+#define MAX_PPI_ID U(31)
+#define MIN_SPI_ID U(32)
+#define MAX_SPI_ID U(255)
+#define EV_COOKIE 0xDEADBEEF
+#define PPI_RANGE ((uint64_t[2]) {MIN_PPI_ID, MAX_PPI_ID})
+#define SPI_RANGE ((uint64_t[2]) {MIN_SPI_ID, MAX_SPI_ID})
+#define BIND_SLOTS_MASK 0xffffU
+#define FEATURES_SHARED_SLOTS_SHIFT 16U
+#define FEATURES_PRIVATE_SLOTS_SHIFT 0U
+
+extern sdei_handler_t sdei_entrypoint;
+extern sdei_handler_t sdei_entrypoint_resume;
+
+#define HANDLER_SVALUE ((uint64_t[1]) { (uint64_t)(uintptr_t)sdei_entrypoint_resume })
+#define PE_SVALUE ((uint64_t[1]) { read_mpidr_el1() })
+#define ZERO_EVENT_SVALUE ((uint64_t[1]) { 0 })
+#define EV_COOKIE_SVALUE ((uint64_t[1]) { 0xDEADBEEF })
+#define VENDOR_EVENTS_RANGE ((uint64_t[2]) { 0x40000000, 0x40FFFFFF })
+#define STD_EVENTS_RANGE ((uint64_t[2]) { 0x00000001, 0x00FFFFFF })
+#define ANY_ROUTING ((uint64_t[1]) { SDEI_REGF_RM_ANY })
+#define PE_ROUTING ((uint64_t[1]) { SDEI_REGF_RM_PE })
+#define ROUTING_MODES ((uint64_t[2]) { SDEI_REGF_RM_ANY, SDEI_REGF_RM_PE })
+#define OUT_OF_RESOURCE_ERR -10
+#define MAX_BIND_SLOTS (1 << 16)
+
+#define register_handler() setconstraint(FUZZER_CONSTRAINT_SVALUE, HANDLER_SVALUE, 1, \
+SDEI_EVENT_REGISTER_CALL_ARG2_ADDR, mmod, FUZZER_CONSTRAINT_ACCMODE)
+
+char *return_str(int64_t return_val)
+{
+ switch (return_val) {
+ case -1:
+ return "NOT_SUPPORTED";
+ case -2:
+ return "INVALID_PARAMETERS";
+ case -3:
+ return "DENIED";
+ case -5:
+ return "PENDING";
+ case -10:
+ return "OUT_OF_RESOURCE";
+ default:
+ return "UNKNOWN ERROR CODE";
+ }
+}
+
+void print_return(char *funcstr, int64_t ret)
+{
+ if (ret < 0) {
+ printf("%s failed: 0x%llx. %s\n", funcstr, ret, return_str(ret));
+ } else {
+ printf("%s successful return: %llx\n", funcstr, ret);
+ }
+}
+
+void set_event_constraints(int sdei_arg_name, struct memmod *mmod)
+{
+ setconstraint(FUZZER_CONSTRAINT_SVALUE, ZERO_EVENT_SVALUE, 1, sdei_arg_name, mmod, FUZZER_CONSTRAINT_ACCMODE);
+ setconstraint(FUZZER_CONSTRAINT_SVALUE, STD_EVENTS_RANGE, 2, sdei_arg_name, mmod, FUZZER_CONSTRAINT_ACCMODE);
+ setconstraint(FUZZER_CONSTRAINT_SVALUE, VENDOR_EVENTS_RANGE, 2, sdei_arg_name, mmod, FUZZER_CONSTRAINT_ACCMODE);
+}
+
/*
* SDEI function that has no arguments
*/
-void tftf_test_sdei_noarg(int64_t (*sdei_func)(void), char *funcstr)
+int64_t tftf_test_sdei_noarg(int64_t (*sdei_func)(void), char *funcstr)
{
int64_t ret = (*sdei_func)();
if (ret < 0) {
tftf_testcase_printf("%s failed: 0x%llx\n", funcstr, ret);
}
+
+ printf("%s return: %llx\n", funcstr, ret);
+
+ return ret;
}
/*
@@ -42,53 +110,678 @@
}
}
+uint64_t *bound_shared_inums;
+uint64_t *bound_private_inums;
+uint64_t *bound_shared_evnums;
+uint64_t *bound_private_evnums;
+int64_t private_slots_count;
+int64_t shared_slots_count;
+static int64_t private_slots_len;
+static int64_t shared_slots_len;
+
+
+void bound_event_constraints(int fieldname, struct memmod *mmod)
+{
+ setconstraint(FUZZER_CONSTRAINT_VECTOR, bound_shared_evnums, shared_slots_len, fieldname, mmod, FUZZER_CONSTRAINT_ACCMODE);
+ setconstraint(FUZZER_CONSTRAINT_VECTOR, bound_private_evnums, private_slots_len, fieldname, mmod, FUZZER_CONSTRAINT_ACCMODE);
+}
+
+void release_shared_slots(struct memmod *mmod, int slots, bool release)
+{
+
+ if ((slots < 0) || (slots > shared_slots_len)) {
+ return;
+ }
+
+ struct inputparameters inp;
+ int64_t ret;
+ struct sdei_intr_ctx intr_ctx;
+
+ if (release) {
+ for (int k = 0; k < slots; k++) {
+ uint64_t release_enum[1] = {bound_shared_evnums[shared_slots_len - 1 - k]};
+
+
+ setconstraint(FUZZER_CONSTRAINT_SVALUE, release_enum, 1, SDEI_EVENT_UNREGISTER_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
+ inp = generate_args(SDEI_EVENT_UNREGISTER_CALL, SMC_FUZZ_SANITY_LEVEL);
+ ret = sdei_event_unregister(inp.x1);
+ print_return("unregister", ret);
+
+
+ setconstraint(FUZZER_CONSTRAINT_SVALUE, release_enum, 1, SDEI_INTERRUPT_RELEASE_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
+ inp = generate_args(SDEI_INTERRUPT_RELEASE_CALL, SANITY_LEVEL_3);
+ ret = sdei_interrupt_release(inp.x1, &intr_ctx);
+ print_return("release", ret);
+ }
+ }
+
+ for (int i = shared_slots_len; i > 0; i--) {
+ bound_shared_inums[i] = bound_shared_inums[i-slots];
+ }
+ for (int i = 0; i < slots; i++) {
+ bound_shared_inums[i] = 0;
+ }
+
+ for (int i = shared_slots_len; i > 0; i--) {
+ bound_shared_evnums[i] = bound_shared_evnums[i-slots];
+ }
+ for (int i = 0; i < slots; i++) {
+ bound_shared_evnums[i] = 0;
+ }
+ shared_slots_count = (shared_slots_count + slots < shared_slots_len ? shared_slots_count + slots : shared_slots_len);
+}
+
+void release_private_slots(struct memmod *mmod, int slots, bool release)
+{
+ if ((slots < 0) || (slots > private_slots_len)) {
+ return;
+ }
+
+ struct inputparameters inp;
+ int64_t ret;
+ struct sdei_intr_ctx intr_ctx;
+
+ if (release) {
+ for (int k = 0; k < slots; k++) {
+ uint64_t release_enum[1] = {bound_private_evnums[private_slots_len-1-k]};
+
+ setconstraint(FUZZER_CONSTRAINT_SVALUE, release_enum, 1, SDEI_EVENT_UNREGISTER_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
+ inp = generate_args(SDEI_EVENT_UNREGISTER_CALL, SMC_FUZZ_SANITY_LEVEL);
+ ret = sdei_event_unregister(inp.x1);
+ print_return("unregister", ret);
+
+ setconstraint(FUZZER_CONSTRAINT_SVALUE, release_enum, 1, SDEI_INTERRUPT_RELEASE_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
+ inp = generate_args(SDEI_INTERRUPT_RELEASE_CALL, SANITY_LEVEL_3);
+ ret = sdei_interrupt_release(inp.x1, &intr_ctx);
+ print_return("release", ret);
+ }
+ }
+
+ for (int i = private_slots_len; i > 0; i--) {
+ bound_private_inums[i] = bound_private_inums[i-slots];
+ }
+ for (int i = 0; i < slots; i++) {
+ bound_private_inums[i] = 0;
+ }
+
+ for (int i = private_slots_len; i > 0; i--) {
+ bound_private_evnums[i] = bound_private_evnums[i-slots];
+ }
+ for (int i = 0; i < slots; i++) {
+ bound_private_evnums[i] = 0;
+ }
+
+ private_slots_count = (private_slots_count + slots < private_slots_len ? private_slots_count + slots : private_slots_len);
+}
+
+void initalize_interrupt_slots(struct memmod *mmod)
+{
+ uint64_t bind_slots[1] = {0};
+
+ setconstraint(FUZZER_CONSTRAINT_SVALUE, bind_slots, 1, SDEI_FEATURES_CALL_ARG1_FEAT, mmod, FUZZER_CONSTRAINT_ACCMODE);
+ struct inputparameters inp = generate_args(SDEI_FEATURES_CALL, SMC_FUZZ_SANITY_LEVEL);
+ int64_t slots = sdei_features(inp.x1);
+
+ shared_slots_count = slots & 0xffffU;
+ private_slots_count = (slots >> 16U) & 0xfffU;
+ shared_slots_len = shared_slots_count;
+ private_slots_len = private_slots_count;
+ static uint64_t tmp[MAX_BIND_SLOTS];
+ static uint64_t tmp1[MAX_BIND_SLOTS];
+ static uint64_t tmp2[MAX_BIND_SLOTS];
+ static uint64_t tmp3[MAX_BIND_SLOTS];
+
+ bound_shared_inums = tmp;
+ bound_shared_evnums = tmp1;
+
+ bound_private_inums = tmp2;
+ bound_private_evnums = tmp3;
+ for (int i = 0; i < shared_slots_count; i++) {
+ bound_shared_inums[i] = 0;
+ bound_shared_evnums[i] = 0;
+ }
+ for (int i = 0; i < private_slots_count; i++) {
+ bound_private_inums[i] = 0;
+ bound_private_evnums[i] = 0;
+ }
+}
+
+void release_full_slots(struct inputparameters inp, struct memmod *mmod)
+{
+ if ((!shared_slots_count)) {
+ if (inp.x1 >= MIN_SPI_ID && inp.x1 <= MAX_SPI_ID) {
+ release_shared_slots(mmod, 1, true);
+ }
+ }
+
+ if ((!private_slots_count)) {
+ if (inp.x1 >= MIN_PPI_ID && inp.x1 <= MAX_PPI_ID) {
+ release_private_slots(mmod, 1, true);
+ }
+ }
+}
+
/*
* SDEI function called from fuzzer
*/
-void run_sdei_fuzz(int funcid, struct memmod *mmod)
+void run_sdei_fuzz(int funcid, struct memmod *mmod, bool inrange, int cntid)
{
- if (funcid == sdei_version_funcid) {
- long long ret = sdei_version();
+ #ifdef SMC_FUZZER_DEBUG
+ if (inrange) {
+ printf("%d\n", cntid);
+ }
+ #endif
- if (ret != MAKE_SDEI_VERSION(1, 0, 0)) {
- tftf_testcase_printf("Unexpected SDEI version: 0x%llx\n",
- ret);
+ if (cntid == 0 && CONSTRAIN_EVENTS) {
+ initalize_interrupt_slots(mmod);
+ }
+
+ #ifdef SMC_FUZZER_DEBUG
+ if (CONSTRAIN_EVENTS) {
+ printf("Bound priv inums: %llu, %llu, %llu\n", bound_private_inums[0], bound_private_inums[1], bound_private_inums[2]);
+ printf("Bound priv evnums: %llu, %llu, %llu\n", bound_private_evnums[0], bound_private_evnums[1], bound_private_evnums[2]);
+ printf("Bound shared inums: %llu, %llu, %llu\n", bound_shared_inums[0], bound_shared_inums[1], bound_shared_inums[2]);
+ printf("Bound shared evnums: %llu, %llu, %llu\n", bound_shared_evnums[0], bound_shared_evnums[1], bound_shared_evnums[2]);
+ printf("Shared slots left: %lld\n", shared_slots_count);
+ printf("Private slots left: %lld\n\n", private_slots_count);
+ }
+ #endif
+ if (funcid == sdei_version_funcid) {
+ long long ret;
+
+ if (inrange) {
+ ret = sdei_version();
+
+ if (ret != MAKE_SDEI_VERSION(1, 0, 0)) {
+ tftf_testcase_printf("Unexpected SDEI version: 0x%llx\n", ret);
+ }
}
} else if (funcid == sdei_pe_unmask_funcid) {
- tftf_test_sdei_noarg(sdei_pe_unmask, "sdei_pe_unmuask");
+ if (inrange) {
+ tftf_test_sdei_noarg(sdei_pe_unmask, "sdei_pe_unmask");
+ }
} else if (funcid == sdei_pe_mask_funcid) {
- tftf_test_sdei_noarg(sdei_pe_mask, "sdei_pe_mask");
+ if (inrange) {
+ tftf_test_sdei_noarg(sdei_pe_mask, "sdei_pe_mask");
+ }
} else if (funcid == sdei_interrupt_bind_funcid) {
struct sdei_intr_ctx intr_ctx;
- uint64_t inputbind[2] = {INTERRUPT_BIND_INT_LOWVAL, INTERRUPT_BIND_INT_HIGHVAL};
- setconstraint(FUZZER_CONSTRAINT_RANGE, inputbind, 2,
- SDEI_INTERRUPT_BIND_CALL_ARG1_INUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
+ setconstraint(FUZZER_CONSTRAINT_RANGE, SPI_RANGE, 2,
+ SDEI_INTERRUPT_BIND_CALL_ARG1_INUM, mmod, FUZZER_CONSTRAINT_ACCMODE);
- struct inputparameters inp = generate_args(SDEI_INTERRUPT_BIND_CALL, SMC_FUZZ_SANITY_LEVEL);
+ if (INTR_ASSERT) {
+ setconstraint(FUZZER_CONSTRAINT_RANGE, PPI_RANGE, 2,
+ SDEI_INTERRUPT_BIND_CALL_ARG1_INUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
+ }
- stbev = sdei_interrupt_bind(inp.x1, &intr_ctx);
+ struct inputparameters inp = generate_args(SDEI_INTERRUPT_BIND_CALL, SANITY_LEVEL_3);
+ release_full_slots(inp, mmod);
+
+ if (inrange) {
+ stbev = sdei_interrupt_bind(inp.x1, &intr_ctx);
+ if (stbev < 0) {
+ tftf_testcase_printf("sdei_interrupt_bind failed: 0x%llx %d\n", inp.x1, stbev);
+ } else if (CONSTRAIN_EVENTS) {
+ bool duplicate = false;
+
+ if (inp.x1 >= MIN_SPI_ID && inp.x1 <= MAX_SPI_ID) {
+
+ for (int i = 0; i < shared_slots_len; i++) {
+ if (bound_shared_inums[i] == inp.x1) {
+ duplicate = true;
+ }
+ }
+ if (!duplicate) {
+ shared_slots_count--;
+ bound_shared_inums[shared_slots_count] = inp.x1;
+ bound_shared_evnums[shared_slots_count] = stbev;
+ }
+
+ } else if (inp.x1 >= MIN_PPI_ID && inp.x1 <= MAX_PPI_ID) {
+ for (int i = 0; i < private_slots_len; i++) {
+ if (bound_private_inums[i] == inp.x1) {
+ duplicate = true;
+ }
+ }
+ if (!duplicate) {
+ private_slots_count--;
+ bound_private_inums[private_slots_count] = inp.x1;
+ bound_private_evnums[private_slots_count] = stbev;
+ }
+ }
+ }
+
+ #ifdef SMC_FUZZER_DEBUG
+ printf("stbev is %d and interrupt number is %lld\n", stbev, inp.x1);
+ #endif
+ }
} else if (funcid == sdei_event_status_funcid) {
- int64_t ret = sdei_event_status(stbev);
+ struct inputparameters inp;
- if (ret < 0) {
- tftf_testcase_printf("sdei_event_status failed: 0x%llx %d\n", ret, stbev);
+ if (CONSTRAIN_EVENTS) {
+ bound_event_constraints(SDEI_EVENT_STATUS_CALL_ARG1_BEV, mmod);
+ set_event_constraints(SDEI_EVENT_STATUS_CALL_ARG1_BEV, mmod);
+ }
+ inp = generate_args(SDEI_EVENT_STATUS_CALL, SMC_FUZZ_SANITY_LEVEL);
+ int64_t ret;
+
+ if (inrange) {
+ ret = sdei_event_status(inp.x1);
+ if (ret < 0) {
+
+ tftf_testcase_printf("sdei_event_status failed: 0x%llx %d\n", ret, stbev);
+ } else {
+
+ }
}
- tftf_test_sdei_singlearg((int64_t (*)(uint64_t))sdei_event_status,
- "sdei_event_status");
} else if (funcid == sdei_event_signal_funcid) {
- int64_t ret = sdei_event_signal(read_mpidr_el1());
- if (ret < 0) {
- tftf_testcase_printf("sdei_event_status failed: 0x%llx\n", ret);
+ setconstraint(FUZZER_CONSTRAINT_SVALUE, PE_SVALUE, 1,
+ SDEI_EVENT_SIGNAL_CALL_ARG2_PE, mmod, FUZZER_CONSTRAINT_ACCMODE);
+ struct inputparameters inp = generate_args(SDEI_EVENT_SIGNAL_CALL, SMC_FUZZ_SANITY_LEVEL);
+ int64_t ret;
+
+ if (inrange) {
+ ret = sdei_event_signal(inp.x2);
+ if (ret < 0) {
+ tftf_testcase_printf("sdei_event_signal failed: %lld\n", ret);
+ }
+ }
+ } else if (funcid == sdei_private_reset_funcid) {
+ if (inrange) {
+ tftf_test_sdei_noarg(sdei_private_reset, "sdei_private_reset");
+ }
+ } else if (funcid == sdei_shared_reset_funcid) {
+ int64_t ret = -1;
+
+ if (inrange) {
+ ret = tftf_test_sdei_noarg(sdei_shared_reset, "sdei_shared_reset");
+ }
+ if (ret == 0) {
+ release_shared_slots(mmod, private_slots_len, false);
+ release_private_slots(mmod, shared_slots_len, false);
}
- tftf_test_sdei_singlearg(sdei_event_signal, "sdei_event_signal");
- } else if (funcid == sdei_private_reset_funcid) {
- tftf_test_sdei_noarg(sdei_private_reset, "sdei_private_reset");
- } else if (funcid == sdei_shared_reset_funcid) {
- tftf_test_sdei_noarg(sdei_shared_reset, "sdei_shared_reset");
+ } else if (funcid == sdei_event_register_funcid) {
+
+ if (CONSTRAIN_EVENTS) {
+ set_event_constraints(SDEI_EVENT_REGISTER_CALL_ARG1_ENUM, mmod);
+ bound_event_constraints(SDEI_EVENT_REGISTER_CALL_ARG1_ENUM, mmod);
+ }
+
+ register_handler();
+
+ uint64_t routing_modes[2] = {SDEI_REGF_RM_ANY, SDEI_REGF_RM_PE};
+
+ setconstraint(FUZZER_CONSTRAINT_RANGE, routing_modes, 2, SDEI_EVENT_REGISTER_CALL_ARG4_ROUTING, mmod, FUZZER_CONSTRAINT_ACCMODE);
+ setconstraint(FUZZER_CONSTRAINT_SVALUE, EV_COOKIE_SVALUE, 1, SDEI_EVENT_REGISTER_CALL_ARG3_ARG, mmod, FUZZER_CONSTRAINT_EXCMODE);
+ setconstraint(FUZZER_CONSTRAINT_SVALUE, PE_SVALUE, 1, SDEI_EVENT_REGISTER_CALL_ARG5_AFF, mmod, FUZZER_CONSTRAINT_ACCMODE);
+
+ struct inputparameters inp = generate_args(SDEI_EVENT_REGISTER_CALL, SMC_FUZZ_SANITY_LEVEL);
+
+ int64_t ret;
+
+ if (inrange) {
+ ret = sdei_event_register(inp.x1, (int (*)(int, uint64_t))(uintptr_t)inp.x2, inp.x3, inp.x4, inp.x5);
+ if (ret < 0) {
+ tftf_testcase_printf("sdei_event_register failed: 0x%llx\n", ret);
+ }
+ }
+
+
+ } else if (funcid == sdei_event_enable_funcid) {
+ struct inputparameters inp;
+
+
+ if (CONSTRAIN_EVENTS) {
+ set_event_constraints(SDEI_EVENT_ENABLE_CALL_ARG1_ENUM, mmod);
+ bound_event_constraints(SDEI_EVENT_ENABLE_CALL_ARG1_ENUM, mmod);
+ }
+
+ inp = generate_args(SDEI_EVENT_ENABLE_CALL, SMC_FUZZ_SANITY_LEVEL);
+ int64_t ret;
+
+ if (inrange) {
+ ret = sdei_event_enable(inp.x1);
+ if (ret < 0) {
+ tftf_testcase_printf("sdei_event_enable failed: 0x%llx\n", ret);
+ }
+ }
+
+ } else if (funcid == sdei_event_disable_funcid) {
+ struct inputparameters inp;
+
+ if (CONSTRAIN_EVENTS) {
+ set_event_constraints(SDEI_EVENT_DISABLE_CALL_ARG1_ENUM, mmod);
+ bound_event_constraints(SDEI_EVENT_DISABLE_CALL_ARG1_ENUM, mmod);
+ }
+
+ inp = generate_args(SDEI_EVENT_DISABLE_CALL, SMC_FUZZ_SANITY_LEVEL);
+
+ int64_t ret;
+
+ if (inrange) {
+ ret = sdei_event_disable(inp.x1);
+ if (ret < 0) {
+ tftf_testcase_printf("sdei_event_disable failed: 0x%llx\n", ret);
+ }
+ }
+
+ } else if (funcid == sdei_features_funcid) {
+ uint64_t feature_values[2] = {0, 1};
+
+ setconstraint(FUZZER_CONSTRAINT_RANGE, feature_values, 2, SDEI_FEATURES_CALL_ARG1_FEAT, mmod, FUZZER_CONSTRAINT_ACCMODE);
+ struct inputparameters inp = generate_args(SDEI_FEATURES_CALL, SANITY_LEVEL_3);
+
+ int64_t ret;
+
+ if (inrange) {
+ ret = sdei_features(inp.x1);
+ if (ret < 0) {
+ tftf_testcase_printf("sdei_features failed: 0x%llx\n", ret);
+ } else if ((ret >> 32) == 0) {
+ #ifdef SMC_FUZZER_DEBUG
+ printf("SUCCESS: sdei_features expected [63:32]\n");
+ printf("private event slots: %llx\n", (ret & 0xffffU));
+ printf("shared event slots: %llx\n", ((ret >> 16U) & 0xfffU));
+ #endif
+ }
+ }
+ } else if (funcid == sdei_event_unregister_funcid) {
+ struct inputparameters inp;
+
+ if (CONSTRAIN_EVENTS) {
+ set_event_constraints(SDEI_EVENT_UNREGISTER_CALL_ARG1_ENUM, mmod);
+ bound_event_constraints(SDEI_EVENT_UNREGISTER_CALL_ARG1_ENUM, mmod);
+ }
+
+ inp = generate_args(SDEI_EVENT_UNREGISTER_CALL, SMC_FUZZ_SANITY_LEVEL);
+
+ int64_t ret;
+
+ if (inrange) {
+ ret = sdei_event_unregister(inp.x1);
+
+ if (ret < 0) {
+ tftf_testcase_printf("sdei_event_unregister failed: 0x%llx\n", ret);
+ }
+ }
+
+ } else if (funcid == sdei_event_context_funcid) {
+
+ uint64_t register_range[2] = {0, 17};
+
+ setconstraint(FUZZER_CONSTRAINT_RANGE, register_range, 2, SDEI_EVENT_CONTEXT_CALL_ARG1_PARAM, mmod, FUZZER_CONSTRAINT_ACCMODE);
+ struct inputparameters inp = generate_args(SDEI_EVENT_CONTEXT_CALL, SMC_FUZZ_SANITY_LEVEL);
+
+ int64_t ret;
+
+ if (inrange) {
+ ret = sdei_event_context(inp.x1);
+ if (ret < 0) {
+ tftf_testcase_printf("sdei_event_context failed: 0x%llx\n", ret);
+ }
+ }
+
+ } else if (funcid == sdei_event_complete_funcid) {
+
+ uint64_t status_codes[2] = {0, 1};
+
+ setconstraint(FUZZER_CONSTRAINT_RANGE, status_codes, 2, SDEI_EVENT_COMPLETE_CALL_ARG1_STAT, mmod, FUZZER_CONSTRAINT_ACCMODE);
+
+ struct inputparameters inp = generate_args(SDEI_EVENT_COMPLETE_CALL, SMC_FUZZ_SANITY_LEVEL);
+
+ int64_t ret;
+
+ if (inrange) {
+ ret = sdei_event_complete(inp.x1);
+ if (ret < 0) {
+ tftf_testcase_printf("sdei_event_complete failed: 0x%llx\n", ret);
+ }
+ }
+
+ } else if (funcid == sdei_event_complete_and_resume_funcid) {
+ struct inputparameters inp = generate_args(SDEI_EVENT_COMPLETE_AND_RESUME_CALL, SMC_FUZZ_SANITY_LEVEL);
+
+ int64_t ret;
+
+ if (inrange) {
+ ret = sdei_event_complete_and_resume(inp.x1);
+ if (ret < 0) {
+ tftf_testcase_printf("sdei_event_complete_and_resume failed: 0x%llx\n", ret);
+ }
+ }
+
+ } else if (funcid == sdei_event_get_info_funcid) {
+ struct inputparameters inp;
+ uint64_t info_values[2] = {0, 4};
+
+ setconstraint(FUZZER_CONSTRAINT_RANGE, info_values, 2, SDEI_EVENT_GET_INFO_CALL_ARG2_INFO, mmod, FUZZER_CONSTRAINT_ACCMODE);
+
+
+ if (CONSTRAIN_EVENTS) {
+ set_event_constraints(SDEI_EVENT_GET_INFO_CALL_ARG1_ENUM, mmod);
+ bound_event_constraints(SDEI_EVENT_GET_INFO_CALL_ARG1_ENUM, mmod);
+ }
+
+ inp = generate_args(SDEI_EVENT_GET_INFO_CALL, SMC_FUZZ_SANITY_LEVEL);
+
+ int64_t ret;
+
+ if (inrange) {
+ ret = sdei_event_get_info(inp.x1, inp.x2);
+ if (ret < 0) {
+ tftf_testcase_printf("sdei_event_get_info failed: 0x%llx\n", ret);
+ }
+ }
+ } else if (funcid == sdei_event_routing_set_funcid) {
+ uint64_t routing_modes[2] = {SDEI_REGF_RM_ANY, SDEI_REGF_RM_PE};
+
+ setconstraint(FUZZER_CONSTRAINT_RANGE, routing_modes, 2, SDEI_EVENT_ROUTING_SET_CALL_ARG4_ROUTING, mmod, FUZZER_CONSTRAINT_ACCMODE);
+ setconstraint(FUZZER_CONSTRAINT_SVALUE, PE_SVALUE, 1, SDEI_EVENT_ROUTING_SET_CALL_ARG5_AFF, mmod, FUZZER_CONSTRAINT_ACCMODE);
+ struct inputparameters inp;
+
+ if (CONSTRAIN_EVENTS) {
+ set_event_constraints(SDEI_EVENT_ROUTING_SET_CALL_ARG1_ENUM, mmod);
+ bound_event_constraints(SDEI_EVENT_ROUTING_SET_CALL_ARG1_ENUM, mmod);
+ }
+
+ inp = generate_args(SDEI_EVENT_ROUTING_SET_CALL, SMC_FUZZ_SANITY_LEVEL);
+
+ int64_t ret;
+
+ if (inrange) {
+ ret = sdei_event_routing_set(inp.x1, inp.x2);
+ if (ret < 0) {
+ tftf_testcase_printf("sdei_event_routing_set failed: 0x%llx\n", ret);
+ }
+ }
+
+ } else if (funcid == sdei_interrupt_release_funcid) {
+ struct sdei_intr_ctx intr_ctx;
+
+ setconstraint(FUZZER_CONSTRAINT_RANGE, PPI_RANGE, 2,
+ SDEI_INTERRUPT_RELEASE_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_ACCMODE);
+ setconstraint(FUZZER_CONSTRAINT_RANGE, SPI_RANGE, 2,
+ SDEI_INTERRUPT_RELEASE_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_ACCMODE);
+
+ struct inputparameters inp = generate_args(SDEI_INTERRUPT_RELEASE_CALL, SMC_FUZZ_SANITY_LEVEL);
+
+ int64_t ret;
+
+ if (inrange) {
+ ret = sdei_interrupt_release(inp.x1, &intr_ctx);
+ if (ret < 0) {
+
+ tftf_testcase_printf("sdei_interrupt_release failed: 0x%llx\n", ret);
+ } else {
+ if (inp.x1 >= MIN_SPI_ID && inp.x1 <= MAX_SPI_ID) {
+ release_shared_slots(mmod, 1, false);
+ } else if (inp.x1 >= MIN_PPI_ID && inp.x1 <= MAX_PPI_ID) {
+ release_private_slots(mmod, 1, false);
+ }
+ }
+ }
+
+ } else if (funcid == sdei_routing_set_coverage_funcid) {
+ int64_t ret;
+ struct inputparameters inp;
+
+ uint64_t bind_slots[1] = {0};
+
+ setconstraint(FUZZER_CONSTRAINT_SVALUE, bind_slots, 1, SDEI_FEATURES_CALL_ARG1_FEAT, mmod, FUZZER_CONSTRAINT_ACCMODE);
+ inp = generate_args(SDEI_FEATURES_CALL, SMC_FUZZ_SANITY_LEVEL);
+ int64_t slots = sdei_features(inp.x1);
+
+ print_return("features", slots);
+
+ // bind shared interrupt to create shared event
+ struct sdei_intr_ctx intr_ctx;
+ uint64_t inum_range[2] = { MIN_SPI_ID, U(255) };
+
+ setconstraint(FUZZER_CONSTRAINT_RANGE, inum_range, 2, SDEI_INTERRUPT_BIND_CALL_ARG1_INUM, mmod, FUZZER_CONSTRAINT_ACCMODE);
+ inp = generate_args(SDEI_INTERRUPT_BIND_CALL, SANITY_LEVEL_3);
+
+ release_full_slots(inp, mmod);
+
+
+ ret = sdei_interrupt_bind(inp.x1, &intr_ctx);
+ if (ret < 0) {
+ return;
+ }
+
+ // register shared event
+ uint64_t evnum[1] = {ret};
+
+ setconstraint(FUZZER_CONSTRAINT_SVALUE, evnum, 1, SDEI_EVENT_REGISTER_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
+ setconstraint(FUZZER_CONSTRAINT_SVALUE, HANDLER_SVALUE, 1, SDEI_EVENT_REGISTER_CALL_ARG2_ADDR, mmod, FUZZER_CONSTRAINT_ACCMODE);
+ setconstraint(FUZZER_CONSTRAINT_SVALUE, PE_SVALUE, 1, SDEI_EVENT_REGISTER_CALL_ARG5_AFF, mmod, FUZZER_CONSTRAINT_ACCMODE);
+ setconstraint(FUZZER_CONSTRAINT_SVALUE, ANY_ROUTING, 1, SDEI_EVENT_REGISTER_CALL_ARG4_ROUTING, mmod, FUZZER_CONSTRAINT_ACCMODE);
+ inp = generate_args(SDEI_EVENT_REGISTER_CALL, SMC_FUZZ_SANITY_LEVEL);
+ ret = sdei_event_register(inp.x1, (int (*)(int, uint64_t))(uintptr_t)inp.x2, inp.x3, inp.x4, inp.x5);
+ print_return("register", ret);
+
+ uint64_t signal_info[1] = {0};
+
+ setconstraint(FUZZER_CONSTRAINT_SVALUE, evnum, 1, SDEI_EVENT_GET_INFO_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
+ setconstraint(FUZZER_CONSTRAINT_SVALUE, signal_info, 1, SDEI_EVENT_GET_INFO_CALL_ARG2_INFO, mmod, FUZZER_CONSTRAINT_ACCMODE);
+ inp = generate_args(SDEI_EVENT_GET_INFO_CALL, SMC_FUZZ_SANITY_LEVEL);
+ ret = sdei_event_get_info(inp.x1, inp.x2);
+ print_return("get_info", ret);
+
+
+ setconstraint(FUZZER_CONSTRAINT_SVALUE, evnum, 1, SDEI_EVENT_ROUTING_SET_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
+ setconstraint(FUZZER_CONSTRAINT_SVALUE, ANY_ROUTING, 1, SDEI_EVENT_ROUTING_SET_CALL_ARG4_ROUTING, mmod, FUZZER_CONSTRAINT_ACCMODE);
+ setconstraint(FUZZER_CONSTRAINT_SVALUE, PE_SVALUE, 1, SDEI_EVENT_ROUTING_SET_CALL_ARG5_AFF, mmod, FUZZER_CONSTRAINT_ACCMODE);
+ inp = generate_args(SDEI_EVENT_ROUTING_SET_CALL, SMC_FUZZ_SANITY_LEVEL);
+ ret = sdei_event_routing_set(inp.x1, inp.x2);
+ print_return("routing_set", ret);
+
+ // unregister
+ setconstraint(FUZZER_CONSTRAINT_SVALUE, evnum, 1, SDEI_EVENT_UNREGISTER_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
+ inp = generate_args(SDEI_EVENT_UNREGISTER_CALL, SMC_FUZZ_SANITY_LEVEL);
+ ret = sdei_event_unregister(inp.x1);
+ print_return("unregister", ret);
+
+ // release
+ setconstraint(FUZZER_CONSTRAINT_SVALUE, evnum, 1, SDEI_INTERRUPT_RELEASE_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
+ inp = generate_args(SDEI_INTERRUPT_RELEASE_CALL, SMC_FUZZ_SANITY_LEVEL);
+ sdei_interrupt_release(inp.x1, &intr_ctx);
+ print_return("release", ret);
+
+ if (inp.x1 >= MIN_SPI_ID && inp.x1 <= MAX_SPI_ID) {
+ release_shared_slots(mmod, 1, false);
+ } else if (inp.x1 >= MIN_PPI_ID && inp.x1 <= MAX_PPI_ID) {
+ release_private_slots(mmod, 1, false);
+ }
+
+ } else if (funcid == sdei_event_get_info_coverage_funcid) {
+ int64_t ret;
+ struct inputparameters inp;
+ uint64_t info[1];
+
+ // bind shared interrupt to create shared event
+ struct sdei_intr_ctx intr_ctx;
+ uint64_t inum_range[2] = { MIN_SPI_ID, U(255)};
+
+ setconstraint(FUZZER_CONSTRAINT_RANGE, inum_range, 2, SDEI_INTERRUPT_BIND_CALL_ARG1_INUM, mmod, FUZZER_CONSTRAINT_ACCMODE);
+ inp = generate_args(SDEI_INTERRUPT_BIND_CALL, SANITY_LEVEL_3);
+
+ release_full_slots(inp, mmod);
+
+ ret = sdei_interrupt_bind(inp.x1, &intr_ctx);
+
+ if (ret < 0) {
+ return;
+ }
+
+ uint64_t evnum[1] = {ret};
+
+ // event type
+ info[0] = 0;
+ setconstraint(FUZZER_CONSTRAINT_SVALUE, info, 1, SDEI_EVENT_GET_INFO_CALL_ARG2_INFO, mmod, FUZZER_CONSTRAINT_EXCMODE);
+ setconstraint(FUZZER_CONSTRAINT_SVALUE, evnum, 1, SDEI_EVENT_GET_INFO_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
+ inp = generate_args(SDEI_EVENT_GET_INFO_CALL, SMC_FUZZ_SANITY_LEVEL);
+ ret = sdei_event_get_info(inp.x1, inp.x2);
+ print_return("get info", ret);
+
+ // event signalable
+ info[0] = 1;
+ setconstraint(FUZZER_CONSTRAINT_SVALUE, info, 1, SDEI_EVENT_GET_INFO_CALL_ARG2_INFO, mmod, FUZZER_CONSTRAINT_EXCMODE);
+ inp = generate_args(SDEI_EVENT_GET_INFO_CALL, SMC_FUZZ_SANITY_LEVEL);
+ ret = sdei_event_get_info(inp.x1, inp.x2);
+ print_return("get info", ret);
+
+ // event priority
+ printf("priority\n");
+ info[0] = 2;
+ setconstraint(FUZZER_CONSTRAINT_SVALUE, info, 1, SDEI_EVENT_GET_INFO_CALL_ARG2_INFO, mmod, FUZZER_CONSTRAINT_EXCMODE);
+ inp = generate_args(SDEI_EVENT_GET_INFO_CALL, SMC_FUZZ_SANITY_LEVEL);
+ ret = sdei_event_get_info(inp.x1, inp.x2);
+ print_return("get info", ret);
+
+ // register event
+ setconstraint(FUZZER_CONSTRAINT_SVALUE, evnum, 1, SDEI_EVENT_REGISTER_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
+ setconstraint(FUZZER_CONSTRAINT_SVALUE, HANDLER_SVALUE, 1, SDEI_EVENT_REGISTER_CALL_ARG2_ADDR, mmod, FUZZER_CONSTRAINT_ACCMODE);
+ setconstraint(FUZZER_CONSTRAINT_SVALUE, PE_SVALUE, 1, SDEI_EVENT_REGISTER_CALL_ARG5_AFF, mmod, FUZZER_CONSTRAINT_ACCMODE);
+ setconstraint(FUZZER_CONSTRAINT_SVALUE, PE_ROUTING, 1, SDEI_EVENT_REGISTER_CALL_ARG4_ROUTING, mmod, FUZZER_CONSTRAINT_ACCMODE);
+ inp = generate_args(SDEI_EVENT_REGISTER_CALL, SMC_FUZZ_SANITY_LEVEL);
+ ret = sdei_event_register(inp.x1, (int (*)(int, uint64_t))(uintptr_t)inp.x2, inp.x3, inp.x4, inp.x5);
+ print_return("register", ret);
+
+ // event routing mode
+ info[0] = 3;
+ setconstraint(FUZZER_CONSTRAINT_SVALUE, info, 1, SDEI_EVENT_GET_INFO_CALL_ARG2_INFO, mmod, FUZZER_CONSTRAINT_EXCMODE);
+ inp = generate_args(SDEI_EVENT_GET_INFO_CALL, SMC_FUZZ_SANITY_LEVEL);
+ ret = sdei_event_get_info(inp.x1, inp.x2);
+ print_return("get info", ret);
+
+ // event affinity
+ info[0] = 4;
+ setconstraint(FUZZER_CONSTRAINT_SVALUE, info, 1, SDEI_EVENT_GET_INFO_CALL_ARG2_INFO, mmod, FUZZER_CONSTRAINT_EXCMODE);
+ inp = generate_args(SDEI_EVENT_GET_INFO_CALL, SMC_FUZZ_SANITY_LEVEL);
+ ret = sdei_event_get_info(inp.x1, inp.x2);
+ print_return("get info", ret);
+
+ // unregister
+ setconstraint(FUZZER_CONSTRAINT_SVALUE, evnum, 1, SDEI_EVENT_UNREGISTER_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
+ inp = generate_args(SDEI_EVENT_UNREGISTER_CALL, SMC_FUZZ_SANITY_LEVEL);
+ ret = sdei_event_unregister(inp.x1);
+ print_return("unregister", ret);
+
+ // release
+ setconstraint(FUZZER_CONSTRAINT_SVALUE, evnum, 1, SDEI_INTERRUPT_RELEASE_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
+ inp = generate_args(SDEI_INTERRUPT_RELEASE_CALL, SMC_FUZZ_SANITY_LEVEL);
+ ret = sdei_interrupt_release(inp.x1, &intr_ctx);
+ print_return("release", ret);
+
+ if (inp.x1 >= MIN_SPI_ID && inp.x1 <= MAX_SPI_ID) {
+ release_shared_slots(mmod, 1, false);
+ } else if (inp.x1 >= MIN_PPI_ID && inp.x1 <= MAX_PPI_ID) {
+ release_private_slots(mmod, 1, false);
+ }
}
}