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/include/runtime_services/sdei.h b/include/runtime_services/sdei.h
index 0e0a249..43cb9df 100644
--- a/include/runtime_services/sdei.h
+++ b/include/runtime_services/sdei.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -92,6 +92,8 @@
int64_t sdei_event_context(uint32_t param);
int64_t sdei_event_complete(uint32_t flags);
int64_t sdei_event_complete_and_resume(uint64_t addr);
+int64_t sdei_features(uint32_t feature);
+int64_t sdei_event_get_info(int32_t event, uint32_t info);
#endif /* __ASSEMBLY__ */
#endif /* __SDEI_H__ */
diff --git a/lib/sdei/sdei.c b/lib/sdei/sdei.c
index 157ab6c..eb0e961 100644
--- a/lib/sdei/sdei.c
+++ b/lib/sdei/sdei.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -76,6 +76,7 @@
args.arg4 = flags;
args.arg5 = mpidr;
ret = tftf_smc(&args);
+
return ret.ret0;
}
@@ -219,3 +220,26 @@
ret = tftf_smc(&args);
return ret.ret0;
}
+
+int64_t sdei_features(uint32_t feature)
+{
+ smc_args args = { 0 };
+ smc_ret_values ret;
+
+ args.fid = SDEI_FEATURES;
+ args.arg1 = feature;
+ ret = tftf_smc(&args);
+ return ret.ret0;
+}
+
+int64_t sdei_event_get_info(int32_t event, uint32_t info)
+{
+ smc_args args = { 0 };
+ smc_ret_values ret;
+
+ args.fid = SDEI_EVENT_GET_INFO;
+ args.arg1 = event;
+ args.arg2 = info;
+ ret = tftf_smc(&args);
+ return ret.ret0;
+}
diff --git a/smc_fuzz/combined_smc_calls.txt b/smc_fuzz/combined_smc_calls.txt
new file mode 100644
index 0000000..63ca64b
--- /dev/null
+++ b/smc_fuzz/combined_smc_calls.txt
@@ -0,0 +1,83 @@
+#
+# Copyright (c) 2024 Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+smc: SDEI_EVENT_STATUS_CALL
+ arg1:bev
+ field:bev:[0,31] = 0
+smc: SDEI_INTERRUPT_BIND_CALL
+ arg1:interruptnum
+ field:inum:[0,31] = 1
+smc: SDEI_VERSION_CALL
+ arg1-arg17 = 0
+smc: SDEI_EVENT_REGISTER_CALL
+ arg1:eventnum
+ field:enum:[0,31] = 0
+ arg2:entryaddr
+ field:addr:[0,63] = 0
+ arg3:eparg
+ field:arg:[0,63] = 0
+ arg4:flags
+ field:routing:[0,0] = 0
+ field:relative:[1,1] = 0
+ field:reserved:[2,63] = 0
+ arg5:affinity
+ field:aff:[0,63] = 0
+smc: SDEI_EVENT_ENABLE_CALL
+ arg1:eventnum
+ field:enum:[0,31] = 0
+smc: SDEI_FEATURES_CALL
+ arg1:feature
+ field:feat:[0,31] = 0
+smc: SDEI_EVENT_DISABLE_CALL
+ arg1:eventnum
+ field:enum:[0,31] = 0
+smc: SDEI_EVENT_CONTEXT_CALL
+ arg1:paramid
+ field:param:[0,31] = 0
+smc: SDEI_EVENT_COMPLETE_CALL
+ arg1:status
+ field:stat:[0,31] = 0
+smc: SDEI_EVENT_COMPLETE_AND_RESUME_CALL
+ arg1:resumeaddr
+ field:addr:[0,63] = 0
+smc: SDEI_EVENT_UNREGISTER_CALL
+ arg1:event
+ field:enum:[0,31] = 0
+smc: SDEI_EVENT_GET_INFO_CALL
+ arg1:event
+ field:enum:[0,31] = 0
+ arg2:info
+ field:info:[0,31] = 0
+smc: SDEI_EVENT_ROUTING_SET_CALL
+ arg1:event
+ field:enum:[0,31] = 0
+ arg2:routingmode
+ field:routing:[0,0] = 0
+ field:constant:[1,63] = 0
+ arg3:affinity
+ field:aff:[0,63] = 0
+smc: SDEI_PE_MASK_CALL
+ arg1 = 0
+smc: SDEI_PE_UNMASK_CALL
+ arg1 = 0
+smc: SDEI_INTERRUPT_RELEASE_CALL
+ arg1:event
+ field:enum:[0,31] = 0
+smc: SDEI_EVENT_SIGNAL_CALL
+ arg1:event
+ field:enum:[0,31] = 0
+ arg2:targetpe
+ field:pe:[0,31] = 0
+smc: SDEI_PRIVATE_RESET_CALL
+ arg1 = 0
+smc: SDEI_SHARED_RESET_CALL
+ arg1 = 0
+smc: VEN_EL3_SVC_UUID_CALL
+ arg1=0
+smc: VEN_EL3_SVC_COUNT_CALL
+ arg1=0
+smc: VEN_EL3_SVC_VERSION_CALL
+ arg1=0
diff --git a/smc_fuzz/dts/auto.dts b/smc_fuzz/dts/auto.dts
new file mode 100644
index 0000000..3c2626c
--- /dev/null
+++ b/smc_fuzz/dts/auto.dts
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+/ {
+ candidates {
+ bias = <1>;
+ sdei_pe_unmask_funcid {
+ bias = <30>;
+ functionname = "sdei_pe_unmask_funcid";
+ };
+ sdei_version_funcid {
+ bias = <30>;
+ functionname = "sdei_version_funcid";
+ };
+ sdei_interrupt_bind_funcid {
+ bias = <30>;
+ functionname = "sdei_interrupt_bind_funcid";
+ };
+ sdei_event_enable_funcid {
+ bias = <30>;
+ functionname = "sdei_event_enable_funcid";
+ };
+ sdei_interrupt_release_funcid {
+ bias = <30>;
+ functionname = "sdei_interrupt_release_funcid";
+ };
+ sdei_features_funcid {
+ bias = <30>;
+ functionname = "sdei_features_funcid";
+ };
+ sdei_private_reset_funcid {
+ bias = <30>;
+ functionname = "sdei_private_reset_funcid";
+ };
+ sdei_event_disable_funcid {
+ bias = <30>;
+ functionname = "sdei_event_disable_funcid";
+ };
+ sdei_event_status_funcid {
+ bias = <30>;
+ functionname = "sdei_event_status_funcid";
+ };
+ sdei_shared_reset_funcid {
+ bias = <30>;
+ functionname = "sdei_shared_reset_funcid";
+ };
+ sdei_event_routing_set_funcid {
+ bias = <30>;
+ functionname = "sdei_event_routing_set_funcid";
+ };
+ sdei_event_unregister_funcid {
+ bias = <30>;
+ functionname = "sdei_event_unregister_funcid";
+ };
+ sdei_pe_mask_funcid {
+ bias = <30>;
+ functionname = "sdei_pe_mask_funcid";
+ };
+ };
+};
diff --git a/smc_fuzz/dts/sdei.dts b/smc_fuzz/dts/sdei.dts
index 8b55441..bf9acf1 100644
--- a/smc_fuzz/dts/sdei.dts
+++ b/smc_fuzz/dts/sdei.dts
@@ -42,6 +42,49 @@
bias = <30>;
functionname = "sdei_interrupt_bind_funcid";
};
+ sdei_event_register {
+ bias = <30>;
+ functionname = "sdei_event_register_funcid";
+ };
+ sdei_event_enable {
+ bias = <30>;
+ functionname = "sdei_event_enable_funcid";
+ };
+ sdei_features {
+ bias = <30>;
+ functionname = "sdei_features_funcid";
+ };
+ sdei_event_disable {
+ bias = <30>;
+ functionname = "sdei_event_disable_funcid";
+ };
+ sdei_event_context {
+ bias = <30>;
+ functionname = "sdei_event_context_funcid";
+ };
+ sdei_event_complete {
+ bias = <30>;
+ functionname = "sdei_event_complete_funcid";
+ };
+ sdei_event_complete_and_resume {
+ bias = <30>;
+ functionname = "sdei_event_complete_and_resume_funcid";
+ };
+ sdei_event_unregister {
+ bias = <30>;
+ functionname = "sdei_event_unregister_funcid";
+ };
+ sdei_event_get_info {
+ bias = <30>;
+ functionname = "sdei_event_get_info_funcid";
+ };
+ sdei_event_routing_set {
+ bias = <30>;
+ functionname = "sdei_event_routing_set_funcid";
+ };
+ sdei_interrupt_release {
+ bias = <30>;
+ functionname = "sdei_interrupt_release_funcid";
+ };
};
-
};
diff --git a/smc_fuzz/dts/sdei_coverage.dts b/smc_fuzz/dts/sdei_coverage.dts
new file mode 100644
index 0000000..2afbc50
--- /dev/null
+++ b/smc_fuzz/dts/sdei_coverage.dts
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+
+/ {
+
+ sdei {
+ bias = <30>;
+ sdei_version {
+ bias = <30>;
+ functionname = "sdei_version_funcid";
+ };
+ sdei_pe_unmask {
+ bias = <30>;
+ functionname = "sdei_pe_unmask_funcid";
+ };
+ sdei_pe_mask {
+ bias = <30>;
+ functionname = "sdei_pe_mask_funcid";
+ };
+ sdei_event_status {
+ bias = <30>;
+ functionname = "sdei_event_status_funcid";
+ };
+ sdei_event_signal {
+ bias = <30>;
+ functionname = "sdei_event_signal_funcid";
+ };
+ sdei_private_reset {
+ bias = <30>;
+ functionname = "sdei_private_reset_funcid";
+ };
+ sdei_shared_reset {
+ bias = <30>;
+ functionname = "sdei_shared_reset_funcid";
+ };
+ sdei_interrupt_bind {
+ bias = <100>;
+ functionname = "sdei_interrupt_bind_funcid";
+ };
+ // added
+ sdei_event_register {
+ bias = <30>;
+ functionname = "sdei_event_register_funcid";
+ };
+ sdei_event_enable {
+ bias = <30>;
+ functionname = "sdei_event_enable_funcid";
+ };
+ sdei_features {
+ bias = <30>;
+ functionname = "sdei_features_funcid";
+ };
+ sdei_event_disable {
+ bias = <30>;
+ functionname = "sdei_event_disable_funcid";
+ };
+ sdei_event_context {
+ bias = <30>;
+ functionname = "sdei_event_context_funcid";
+ };
+ sdei_event_complete {
+ bias = <30>;
+ functionname = "sdei_event_complete_funcid";
+ };
+ sdei_event_complete_and_resume {
+ bias = <30>;
+ functionname = "sdei_event_complete_and_resume_funcid";
+ };
+ sdei_event_unregister {
+ bias = <30>;
+ functionname = "sdei_event_unregister_funcid";
+ };
+ sdei_event_get_info {
+ bias = <30>;
+ functionname = "sdei_event_get_info_funcid";
+ };
+ sdei_event_routing_set {
+ bias = <30>;
+ functionname = "sdei_event_routing_set_funcid";
+ };
+ sdei_interrupt_release {
+ bias = <30>;
+ functionname = "sdei_interrupt_release_funcid";
+ };
+ sdei_routing_set_coverage {
+ bias = <30>;
+ functionname = "sdei_routing_set_coverage_funcid";
+ };
+ sdei_event_get_info_coverage {
+ bias = <30>;
+ functionname = "sdei_event_get_info_coverage_funcid";
+ };
+ };
+
+};
diff --git a/smc_fuzz/dts/test.dts b/smc_fuzz/dts/test.dts
new file mode 100644
index 0000000..2d2b3ec
--- /dev/null
+++ b/smc_fuzz/dts/test.dts
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+
+/ {
+ experiment {
+ bias = <1>;
+ interrupt {
+ bias = <30>;
+ functionname = "test_funcid";
+ };
+ interrupt_release {
+ bias = <0>;
+ functionname = "sdei_event_signal_funcid";
+ };
+ event {
+ bias = <0>;
+ functionname = "sdei_event_register_funcid";
+ };
+ };
+};
diff --git a/smc_fuzz/include/sdei.h b/smc_fuzz/include/sdei.h
new file mode 100644
index 0000000..63c9698
--- /dev/null
+++ b/smc_fuzz/include/sdei.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __SDEI_H__
+#define __SDEI_H__
+
+#define SDEI_VERSION 0xC4000020
+#define SDEI_EVENT_REGISTER 0xC4000021
+#define SDEI_EVENT_ENABLE 0xC4000022
+#define SDEI_EVENT_DISABLE 0xC4000023
+#define SDEI_EVENT_CONTEXT 0xC4000024
+#define SDEI_EVENT_COMPLETE 0xC4000025
+#define SDEI_EVENT_COMPLETE_AND_RESUME 0xC4000026
+
+#define SDEI_EVENT_UNREGISTER 0xC4000027
+#define SDEI_EVENT_STATUS 0xC4000028
+#define SDEI_EVENT_GET_INFO 0xC4000029
+#define SDEI_EVENT_ROUTING_SET 0xC400002A
+#define SDEI_PE_MASK 0xC400002B
+#define SDEI_PE_UNMASK 0xC400002C
+
+#define SDEI_INTERRUPT_BIND 0xC400002D
+#define SDEI_INTERRUPT_RELEASE 0xC400002E
+#define SDEI_EVENT_SIGNAL 0xC400002F
+#define SDEI_FEATURES 0xC4000030
+#define SDEI_PRIVATE_RESET 0xC4000031
+#define SDEI_SHARED_RESET 0xC4000032
+
+/* For debug */
+#define SDEI_SHOW_DEBUG 0xC400003F
+
+/* SDEI_EVENT_REGISTER flags */
+#define SDEI_REGF_RM_ANY 0
+#define SDEI_REGF_RM_PE 1
+
+/* SDEI_EVENT_COMPLETE status flags */
+#define SDEI_EV_HANDLED 0
+#define SDEI_EV_FAILED 1
+
+/* sde event status values in bit position */
+#define SDEI_STATF_REGISTERED 0
+#define SDEI_STATF_ENABLED 1
+#define SDEI_STATF_RUNNING 2
+
+#define SDEI_INFOF_TYPE 0
+#define SDEI_INFOF_SIGNALABLE 1
+#define SDEI_INFOF_ROUTING_MODE 2
+#define SDEI_INFOF_ROUTING_AFF 3
+
+#define SMC_EINVAL 2
+#define SMC_EDENY 3
+#define SMC_EPEND 5
+#define SMC_ENOMEM 10
+
+#define MAKE_SDEI_VERSION(_major, _minor, _vendor) \
+ (((uint64_t)(_major)) << 48 | \
+ ((uint64_t)(_minor)) << 32 | \
+ (_vendor))
+
+#ifndef __ASSEMBLY__
+#include <stdint.h>
+
+struct sdei_intr_ctx {
+ unsigned int priority;
+ unsigned int num;
+ unsigned int enabled;
+};
+
+typedef int sdei_handler_t(int ev, uint64_t arg);
+
+void sdei_trigger_event(void);
+void sdei_handler_done(void);
+
+int64_t sdei_version(void);
+int64_t sdei_interrupt_bind(int intr, struct sdei_intr_ctx *intr_ctx);
+int64_t sdei_interrupt_release(int intr, const struct sdei_intr_ctx *intr_ctx);
+int64_t sdei_event_register(int ev, sdei_handler_t *ep,
+ uint64_t ep_arg, int flags, uint64_t mpidr);
+int64_t sdei_event_unregister(int ev);
+int64_t sdei_event_enable(int ev);
+int64_t sdei_event_disable(int ev);
+int64_t sdei_pe_mask(void);
+int64_t sdei_pe_unmask(void);
+int64_t sdei_private_reset(void);
+int64_t sdei_shared_reset(void);
+int64_t sdei_event_signal(uint64_t mpidr);
+int64_t sdei_event_status(int32_t ev);
+int64_t sdei_event_routing_set(int32_t ev, uint64_t flags);
+int64_t sdei_event_context(uint32_t param);
+int64_t sdei_event_complete(uint32_t flags);
+int64_t sdei_event_complete_and_resume(uint64_t addr);
+// added
+int64_t sdei_features(uint32_t feature);
+#endif /* __ASSEMBLY__ */
+
+#endif /* __SDEI_H__ */
diff --git a/smc_fuzz/include/sdei_fuzz_helper.h b/smc_fuzz/include/sdei_fuzz_helper.h
index 72c179d..22c961d 100644
--- a/smc_fuzz/include/sdei_fuzz_helper.h
+++ b/smc_fuzz/include/sdei_fuzz_helper.h
@@ -36,6 +36,64 @@
#endif
-void tftf_test_sdei_noarg(int64_t (*sdei_func)(void), char *funcstr);
+#ifndef sdei_event_register_funcid
+#define sdei_event_register_funcid 0
+#endif
+#ifndef sdei_event_enable_funcid
+#define sdei_event_enable_funcid 0
+#endif
+#ifndef sdei_event_disable_funcid
+#define sdei_event_disable_funcid 0
+#endif
+#ifndef sdei_event_context_funcid
+#define sdei_event_context_funcid 0
+#endif
+#ifndef sdei_event_complete_funcid
+#define sdei_event_complete_funcid 0
+#endif
+#ifndef sdei_event_complete_and_resume_funcid
+#define sdei_event_complete_and_resume_funcid 0
+#endif
+#ifndef sdei_event_unregister_funcid
+#define sdei_event_unregister_funcid 0
+#endif
+#ifndef sdei_event_get_info_funcid
+#define sdei_event_get_info_funcid 0
+#endif
+#ifndef sdei_event_routing_set_funcid
+#define sdei_event_routing_set_funcid 0
+#endif
+#ifndef sdei_interrupt_bind_funcid
+#define sdei_interrupt_bind_funcid 0
+#endif
+#ifndef sdei_interrupt_release_funcid
+#define sdei_interrupt_release_funcid 0
+#endif
+#ifndef sdei_features_funcid
+#define sdei_features_funcid 0
+#endif
+#ifndef sdei_signal_hang_funcid
+#define sdei_signal_hang_funcid 0
+#endif
+#ifndef experiment_funcid
+#define experiment_funcid 0
+#endif
+#ifndef repeat_interrupt_bind_funcid
+#define repeat_interrupt_bind_funcid 0
+#endif
+#ifndef sdei_event_get_info_coverage_funcid
+#define sdei_event_get_info_coverage_funcid 0
+#endif
+#ifndef sdei_routing_set_coverage_funcid
+#define sdei_routing_set_coverage_funcid 0
+#endif
+#ifndef test_funcid
+#define test_funcid 0
+#endif
+
+
+int64_t tftf_test_sdei_noarg(int64_t (*sdei_func)(void), char *funcstr);
void tftf_test_sdei_singlearg(int64_t (*sdei_func)(uint64_t), char *funcstr);
-void run_sdei_fuzz(int funcid, struct memmod *mmod);
+void run_sdei_fuzz(int funcid, struct memmod *mmod, bool inrange, int cntid);
+char *return_str(int64_t ret);
+void print_ret(char *funcstr, int64_t ret);
diff --git a/smc_fuzz/smc_calls.txt b/smc_fuzz/smc_calls.txt
new file mode 100644
index 0000000..263ad76
--- /dev/null
+++ b/smc_fuzz/smc_calls.txt
@@ -0,0 +1,77 @@
+#
+# Copyright (c) 2024 Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+smc: SDEI_EVENT_STATUS_CALL
+ arg1:bev
+ field:bev:[0,31] = 0
+smc: SDEI_INTERRUPT_BIND_CALL
+ arg1:interruptnum
+ field:inum:[0,31] = 1
+smc: SDEI_VERSION_CALL
+ arg1-arg17 = 0
+smc: SDEI_EVENT_REGISTER_CALL
+ arg1:eventnum
+ field:enum:[0,31] = 0
+ arg2:entryaddr
+ field:addr:[0,63] = 0
+ arg3:eparg
+ field:arg:[0,63] = 0
+ arg4:flags
+ field:routing:[0,0] = 0
+ field:relative:[1,1] = 0
+ field:reserved:[2,63] = 0
+ arg5:affinity
+ field:aff:[0,63] = 0
+smc: SDEI_EVENT_ENABLE_CALL
+ arg1:eventnum
+ field:enum:[0,31] = 0
+smc: SDEI_FEATURES_CALL
+ arg1:feature
+ field:feat:[0,31] = 0
+smc: SDEI_EVENT_DISABLE_CALL
+ arg1:eventnum
+ field:enum:[0,31] = 0
+smc: SDEI_EVENT_CONTEXT_CALL
+ arg1:paramid
+ field:param:[0,31] = 0
+smc: SDEI_EVENT_COMPLETE_CALL
+ arg1:status
+ field:stat:[0,31] = 0
+smc: SDEI_EVENT_COMPLETE_AND_RESUME_CALL
+ arg1:resumeaddr
+ field:addr:[0,63] = 0
+smc: SDEI_EVENT_UNREGISTER_CALL
+ arg1:event
+ field:enum:[0,31] = 0
+smc: SDEI_EVENT_GET_INFO_CALL
+ arg1:event
+ field:enum:[0,31] = 0
+ arg2:info
+ field:info:[0,31] = 0
+smc: SDEI_EVENT_ROUTING_SET_CALL
+ arg1:event
+ field:enum:[0,31] = 0
+ arg4:routingmode
+ field:routing:[0,0] = 0
+ field:constant:[1,63] = 0
+ arg5:affinity
+ field:aff:[0,63] = 0
+smc: SDEI_PE_MASK_CALL
+ arg1 = 0
+smc: SDEI_PE_UNMASK_CALL
+ arg1 = 0
+smc: SDEI_INTERRUPT_RELEASE_CALL
+ arg1:event
+ field:enum:[0,31] = 0
+smc: SDEI_EVENT_SIGNAL_CALL
+ arg1:event
+ field:enum:[0,31] = 0
+ arg2:targetpe
+ field:pe:[0,31] = 0
+smc: SDEI_PRIVATE_RESET_CALL
+ arg1 = 0
+smc: SDEI_SHARED_RESET_CALL
+ arg1 = 0
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);
+ }
}
}
diff --git a/tftf/tests/tests-smcfuzzing.mk b/tftf/tests/tests-smcfuzzing.mk
index a10ea50..05ea46b 100644
--- a/tftf/tests/tests-smcfuzzing.mk
+++ b/tftf/tests/tests-smcfuzzing.mk
@@ -11,6 +11,13 @@
SMC_FUZZ_INSTANCE_COUNT ?= 1
SMC_FUZZ_SEEDS ?= $(shell python -c "from random import randint; seeds = [randint(0, 4294967295) for i in range($(SMC_FUZZ_INSTANCE_COUNT))];print(\",\".join(str(x) for x in seeds));")
SMC_FUZZ_CALLS_PER_INSTANCE ?= 100
+# ADDED: which fuzz call to start with per instance
+SMC_FUZZ_CALL_START ?= 0
+SMC_FUZZ_CALL_END ?= $(SMC_FUZZ_CALLS_PER_INSTANCE)
+# ADDED: define whether events should specifically be constrained
+EXCLUDE_FUNCID ?= 0
+CONSTRAIN_EVENTS ?= 1
+INTR_ASSERT ?= 0
# Validate SMC fuzzer parameters
@@ -30,6 +37,25 @@
$(error Number of seeds does not match SMC_FUZZ_INSTANCE_COUNT!)
endif
+# Start must be nonnegative and less than calls per instance
+ifeq ($(shell test $(SMC_FUZZ_CALL_START) -lt 0; echo $$?),0)
+$(error SMC_FUZZ_CALL_START must be nonnegative!)
+endif
+
+ifeq ($(shell test $(SMC_FUZZ_CALL_START) -gt $(shell expr $(SMC_FUZZ_CALLS_PER_INSTANCE) - 1); echo $$?),0)
+$(error SMC_FUZZ_CALL_START must be less than SMC_FUZZ_CALLS_PER_INSTANCE!)
+endif
+
+# End must be greater than start and less than or equal to calls per instance
+ifneq ($(shell test $(SMC_FUZZ_CALL_START) -lt $(SMC_FUZZ_CALL_END); echo $$?),0)
+$(error SMC_FUZZ_CALL_END must be greater than SMC_FUZZ_CALL_START!)
+endif
+
+ifeq ($(shell test $(SMC_FUZZ_CALL_END) -gt $(SMC_FUZZ_CALLS_PER_INSTANCE); echo $$?),0)
+$(error SMC_FUZZ_CALL_END must not be greater than SMC_FUZZ_CALLS_PER_INSTANCE!)
+endif
+
+
# Add definitions to TFTF_DEFINES so they can be used in the code
$(eval $(call add_define,TFTF_DEFINES,SMC_FUZZ_SEEDS))
$(eval $(call add_define,TFTF_DEFINES,SMC_FUZZ_INSTANCE_COUNT))
@@ -41,6 +67,17 @@
$(eval $(call add_define,TFTF_DEFINES,MULTI_CPU_SMC_FUZZER))
endif
$(eval $(call add_define,TFTF_DEFINES,SMC_FUZZ_SANITY_LEVEL))
+$(eval $(call add_define,TFTF_DEFINES,SMC_FUZZ_CALL_START))
+$(eval $(call add_define,TFTF_DEFINES,SMC_FUZZ_CALL_END))
+$(eval $(call add_define,TFTF_DEFINES,CONSTRAIN_EVENTS))
+$(eval $(call add_define,TFTF_DEFINES,EXCLUDE_FUNCID))
+$(eval $(call add_define,TFTF_DEFINES,INTR_ASSERT))
+
+TESTS_SOURCES += \
+ $(addprefix tftf/tests/runtime_services/standard_service/sdei/system_tests/, \
+ sdei_entrypoint.S \
+ test_sdei.c \
+ )
TESTS_SOURCES += \
$(addprefix smc_fuzz/src/, \