feat: introduce UNDEF injection test
Test to verify UNDEF injection support in TF-A by trapping FGT register
access from tftf into EL3.
To trap FGT register access to EL3, run the test on model with FEAT_FGT
present but the traps from EL3 are not enabled (ENABLE_FEAT_FGT = 0).
Signed-off-by: Manish Pandey <manish.pandey2@arm.com>
Change-Id: Ic58ef797c64aad6d17ea33d9fc34e14b4e1a7055
diff --git a/tftf/tests/misc_tests/test_undef_injection.c b/tftf/tests/misc_tests/test_undef_injection.c
new file mode 100644
index 0000000..2d925a2
--- /dev/null
+++ b/tftf/tests/misc_tests/test_undef_injection.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <arm_arch_svc.h>
+#include <assert.h>
+#include <debug.h>
+#include <smccc.h>
+#include <sync.h>
+#include <tftf_lib.h>
+#include <platform_def.h>
+
+static volatile bool undef_injection_triggered;
+
+static bool undef_injection_handler(void)
+{
+ uint64_t esr_el2 = read_esr_el2();
+ if (EC_BITS(esr_el2) == EC_UNKNOWN) {
+ VERBOSE("UNDEF injection from EL3\n");
+ undef_injection_triggered = true;
+ return true;
+ }
+
+ return false;
+}
+
+/*
+ * Test to verify UNDEF injection support in TF-A
+ *
+ * This test tries to access FGT EL2 registers which traps to EL3 and then
+ * the error is injected back from EL3 to TFTF to ensure that injection
+ * logic in TF-A is working, it also ensures that EL3 is still functional
+ * after UNDEF injection.
+ *
+ * To trap FGT register access to EL3, we run this test on a model with
+ * FEAT_FGT present but the traps from EL3 are not disabled by setting
+ * ENABLE_FEAT_FGT = 0
+ */
+test_result_t test_undef_injection(void)
+{
+ undef_injection_triggered = false;
+
+ register_custom_sync_exception_handler(undef_injection_handler);
+
+ /* Try to access a register which traps to EL3 */
+ read_hfgitr_el2();
+
+ unregister_custom_sync_exception_handler();
+
+ /* Ensure that EL3 still functional */
+ smc_args args;
+ smc_ret_values smc_ret;
+ memset(&args, 0, sizeof(args));
+ args.fid = SMCCC_VERSION;
+ smc_ret = tftf_smc(&args);
+
+ tftf_testcase_printf("SMCCC Version = %d.%d\n",
+ (int)((smc_ret.ret0 >> SMCCC_VERSION_MAJOR_SHIFT) & SMCCC_VERSION_MAJOR_MASK),
+ (int)((smc_ret.ret0 >> SMCCC_VERSION_MINOR_SHIFT) & SMCCC_VERSION_MINOR_MASK));
+
+ if (undef_injection_triggered == false) {
+ return TEST_RESULT_FAIL;
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
diff --git a/tftf/tests/tests-undef-injection.mk b/tftf/tests/tests-undef-injection.mk
new file mode 100644
index 0000000..e13df17
--- /dev/null
+++ b/tftf/tests/tests-undef-injection.mk
@@ -0,0 +1,7 @@
+#
+# Copyright (c) 2023, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+TESTS_SOURCES += tftf/tests/misc_tests/test_undef_injection.c
diff --git a/tftf/tests/tests-undef-injection.xml b/tftf/tests/tests-undef-injection.xml
new file mode 100644
index 0000000..0d43cdf
--- /dev/null
+++ b/tftf/tests/tests-undef-injection.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ Copyright (c) 2023, Arm Limited. All rights reserved.
+
+ SPDX-License-Identifier: BSD-3-Clause
+-->
+
+<testsuites>
+ <testsuite name="UNDEF Injection" description="UNDEF injection from EL3 to lower EL">
+ <testcase name="UNDEF Injection to lower EL"
+ function="test_undef_injection" />
+ </testsuite>
+</testsuites>