Merge changes from topic "xlnx_versal_intro"
* changes:
docs(maintainers): add maintainers for AMD-Xilinx
docs(versal): add versal documentation
feat(versal): add platform specific testcase
feat(versal): introduce platform support
diff --git a/Makefile b/Makefile
index 34ed34f..0a1ae9e 100644
--- a/Makefile
+++ b/Makefile
@@ -106,6 +106,11 @@
@echo "Building ${PLAT}"
@echo "Selected set of tests: ${TESTS}"
+# Set flags for Realm Payload Tests
+ifeq (${ENABLE_REALM_PAYLOAD_TESTS},1)
+BRANCH_PROTECTION := 2
+endif
+
# Include test images makefiles.
include tftf/framework/framework.mk
include tftf/tests/tests.mk
@@ -148,6 +153,8 @@
$(eval $(call assert_boolean,FWU_BL_TEST))
$(eval $(call assert_boolean,NEW_TEST_SESSION))
$(eval $(call assert_boolean,USE_NVM))
+$(eval $(call assert_numeric,BRANCH_PROTECTION))
+$(eval $(call assert_boolean,ENABLE_REALM_PAYLOAD_TESTS))
################################################################################
# Process build options
@@ -537,8 +544,6 @@
--redefine-sym _binary___build_$(PLAT)_$(BUILD_TYPE)_smcf_dtb_end=_binary___dtb_end
endif
-$(eval $(call MAKE_IMG,tftf))
-
ifeq ($(FIRMWARE_UPDATE), 1)
$(eval $(call MAKE_IMG,ns_bl1u))
$(eval $(call MAKE_IMG,ns_bl2u))
@@ -548,11 +553,25 @@
$(eval $(call MAKE_IMG,cactus_mm))
$(eval $(call MAKE_IMG,cactus))
$(eval $(call MAKE_IMG,ivy))
+endif
+
+ifeq (${ENABLE_REALM_PAYLOAD_TESTS},1)
$(eval $(call MAKE_IMG,realm))
endif
+.PHONY : tftf
+ $(eval $(call MAKE_IMG,tftf))
+
+ifeq (${ENABLE_REALM_PAYLOAD_TESTS},1)
+tftf: realm
+ @echo " PACK REALM PAYLOAD"
+ $(shell dd if=$(BUILD_PLAT)/realm.bin of=$(BUILD_PLAT)/tftf.bin obs=1 \
+ seek=$(TFTF_MAX_IMAGE_SIZE))
+endif
+
ifeq (${ARCH}-${PLAT},aarch64-fvp)
.PHONY : pack_realm
+$(eval $(call MAKE_IMG,realm))
pack_realm: realm tftf
@echo " PACK REALM PAYLOAD"
$(shell dd if=$(BUILD_PLAT)/realm.bin of=$(BUILD_PLAT)/tftf.bin obs=1 \
@@ -595,7 +614,7 @@
.SILENT: help
help:
echo "usage: ${MAKE} PLAT=<${PLATFORMS}> \
-<all|tftf|ns_bl1u|ns_bl2u|cactus|ivy|realm|pack_realm|el3_payload|distclean|clean|checkcodebase|checkpatch|help_tests>"
+<all|tftf|ns_bl1u|ns_bl2u|cactus|ivy|el3_payload|distclean|clean|checkcodebase|checkpatch|help_tests>"
echo ""
echo "PLAT is used to specify which platform you wish to build."
echo "If no platform is specified, PLAT defaults to: ${DEFAULT_PLAT}"
@@ -606,8 +625,6 @@
echo " tftf Build the TFTF image"
echo " ns_bl1u Build the NS_BL1U image"
echo " ns_bl2u Build the NS_BL2U image"
- echo " realm Build the Realm image (Test R-EL1 payload)."
- echo " pack_realm Pack the realm image to tftf.bin."
echo " cactus Build the Cactus image (FF-A S-EL1 test payload)."
echo " cactus_mm Build the Cactus-MM image (SPM-MM S-EL0 test payload)."
echo " ivy Build the Ivy image (FF-A S-EL0 test payload)."
diff --git a/branch_protection.mk b/branch_protection.mk
index c16cdad..86f197f 100644
--- a/branch_protection.mk
+++ b/branch_protection.mk
@@ -10,9 +10,6 @@
# poised to handle dependencies, as all build variables would have a default
# value by then.
-# Select the branch protection features to use.
-BRANCH_PROTECTION := 0
-
# Flag to enable Branch Target Identification in the TFTF.
# Internal flag not meant for direct setting.
# Use BRANCH_PROTECTION to enable BTI.
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index a891380..8e62380 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -107,6 +107,9 @@
- ``V``: Verbose build. If assigned anything other than 0, the build commands
are printed. Default is 0.
+- ``ENABLE_REALM_PAYLOAD_TESTS``: This option builds and packs Realm payload tests for
+ RME enabled stack. Default is 0.
+
Arm FVP Platform Specific Build Options
---------------------------------------
@@ -152,7 +155,7 @@
- ``TFTF_MAX_IMAGE_SIZE``: The option needs to be either set by the user or
by the platform makefile to specify the maximum size of TFTF binary. This
is needed so that the Realm payload binary can be appended to TFTF binary
- via ``make pack_realm`` build command.
+ via ``make ENABLE_REALM_PAYLOAD_TESTS=1 tftf`` build command.
FWU-specific Build Options
--------------------------
diff --git a/docs/getting_started/build.rst b/docs/getting_started/build.rst
index 034a99e..70b7edc 100644
--- a/docs/getting_started/build.rst
+++ b/docs/getting_started/build.rst
@@ -111,14 +111,10 @@
::
- make PLAT=<platform> realm
+ make PLAT=<platform> ENABLE_REALM_PAYLOAD_TESTS=1 tftf
-The generated ``realm.bin`` needs to be packaged as part of ``tftf.bin`` to
-be used as a single BL33 image and can be done using the following command:
-
-::
-
- make PLAT=<platform> pack_realm
+The generated ``realm.bin`` is packaged as part of ``tftf.bin``
+to be used as a single BL33 image.
Please refer to the `TF-A RME documentation`_ for build and run instructions.
diff --git a/fwu/ns_bl2u/ns_bl2u.mk b/fwu/ns_bl2u/ns_bl2u.mk
index 0864313..7225d01 100644
--- a/fwu/ns_bl2u/ns_bl2u.mk
+++ b/fwu/ns_bl2u/ns_bl2u.mk
@@ -16,6 +16,7 @@
-Iinclude/common/${ARCH} \
-Iinclude/lib \
-Iinclude/lib/${ARCH} \
+ -Iinclude/lib/extensions \
-Iinclude/lib/utils \
-Iinclude/lib/xlat_tables \
-Iinclude/plat/common \
diff --git a/include/common/test_helpers.h b/include/common/test_helpers.h
index 5af4d19..4972d6a 100644
--- a/include/common/test_helpers.h
+++ b/include/common/test_helpers.h
@@ -8,13 +8,9 @@
#define TEST_HELPERS_H__
#include <arch_features.h>
-#include <ffa_helpers.h>
-#include <ffa_svc.h>
-#include <events.h>
#include <plat_topology.h>
#include <psci.h>
#include <sme.h>
-#include <spm_common.h>
#include <tftf_lib.h>
#include <trusted_os.h>
#include <tsp.h>
@@ -182,33 +178,6 @@
version & MM_VERSION_MINOR_MASK); \
} while (0)
-#define SKIP_TEST_IF_FFA_VERSION_LESS_THAN(major, minor) \
- do { \
- struct ffa_value ret = ffa_version( \
- MAKE_FFA_VERSION(major, minor)); \
- uint32_t version = ret.fid; \
- \
- if (version == FFA_ERROR_NOT_SUPPORTED) { \
- tftf_testcase_printf("FFA_VERSION not supported.\n"); \
- return TEST_RESULT_SKIPPED; \
- } \
- \
- if ((version & FFA_VERSION_BIT31_MASK) != 0U) { \
- tftf_testcase_printf("FFA_VERSION bad response: %x\n", \
- version); \
- return TEST_RESULT_FAIL; \
- } \
- \
- if (version < MAKE_FFA_VERSION(major, minor)) { \
- tftf_testcase_printf("FFA_VERSION returned %u.%u\n" \
- "The required version is %u.%u\n", \
- version >> FFA_VERSION_MAJOR_SHIFT, \
- version & FFA_VERSION_MINOR_MASK, \
- major, minor); \
- return TEST_RESULT_SKIPPED; \
- } \
- } while (0)
-
#define SKIP_TEST_IF_ARCH_DEBUG_VERSION_LESS_THAN(version) \
do { \
uint32_t debug_ver = arch_get_debug_version(); \
@@ -222,41 +191,6 @@
} \
} while (0)
-#define SKIP_TEST_IF_FFA_ENDPOINT_NOT_DEPLOYED(mb, ffa_uuid) \
- do { \
- struct ffa_value sc_ret = ffa_partition_info_get(ffa_uuid); \
- ffa_rx_release(); \
- if (ffa_func_id(sc_ret) == FFA_ERROR && \
- ffa_error_code(sc_ret) == FFA_ERROR_INVALID_PARAMETER) { \
- tftf_testcase_printf("FFA endpoint not deployed!\n"); \
- return TEST_RESULT_SKIPPED; \
- } else if (ffa_func_id(sc_ret) != FFA_SUCCESS_SMC32) { \
- ERROR("ffa_partition_info_get failed!\n"); \
- return TEST_RESULT_FAIL; \
- } \
- } while (0)
-
-#define GET_TFTF_MAILBOX(mb) \
- do { \
- if (!get_tftf_mailbox(&mb)) { \
- ERROR("Mailbox RXTX buffers not configured!\n"); \
- return TEST_RESULT_FAIL; \
- } \
- } while (false);
-
-#define CHECK_SPMC_TESTING_SETUP(ffa_major, ffa_minor, expected_uuids) \
- do { \
- SKIP_TEST_IF_AARCH32(); \
- const size_t expected_uuids_size = \
- sizeof(expected_uuids) / sizeof(struct ffa_uuid); \
- test_result_t ret = check_spmc_testing_set_up( \
- ffa_major, ffa_minor, expected_uuids, \
- expected_uuids_size); \
- if (ret != TEST_RESULT_SUCCESS) { \
- return ret; \
- } \
- } while (false);
-
#define SKIP_TEST_IF_TRBE_NOT_SUPPORTED() \
do { \
if (!get_armv9_0_trbe_support()) { \
@@ -436,47 +370,6 @@
test_function_arg_t test);
/*
- * Helper function to reset TFTF global mailbox for SPM related tests.
- * It calls the FFA_RXTX_UNMAP interface, for the SPMC to drop the current
- * address.
- */
-bool reset_tftf_mailbox(void);
-
-/*
- * Helper function to get TFTF global mailbox for SPM related tests.
- * Allocates RX/TX buffer pair and calls FFA_RXTX_MAP interface, for the SPMC
- * to map them into its own S1 translation.
- * If this function is called, and the buffers had been priorly mapped, it
- * sets 'mb' with the respective addresses.
- */
-bool get_tftf_mailbox(struct mailbox_buffers *mb);
-
-test_result_t check_spmc_testing_set_up(uint32_t ffa_version_major,
- uint32_t ffa_version_minor, const struct ffa_uuid *ffa_uuids,
- size_t ffa_uuids_size);
-
-/**
- * Turn on all cpus to execute a test in all.
- * - 'cpu_on_handler' should have the code containing the test.
- * - 'cpu_booted' is used for notifying which cores the test has been executed.
- * This should be used in the test executed by cpu_on_handler at the end of
- * processing to make sure it complies with this function's implementation.
- */
-test_result_t spm_run_multi_core_test(uintptr_t cpu_on_handler,
- event_t *cpu_booted);
-
-/**
- * Call FFA_RUN in the designated SP to make it reach the message loop.
- * Used within CPU_ON handlers, to bring up the SP in the current core.
- */
-bool spm_core_sp_init(ffa_id_t sp_id);
-
-/**
- * Initializes the Mailbox for other SPM related tests that need to use
- * RXTX buffers.
- */
-bool mailbox_init(struct mailbox_buffers mb);
-/*
* Utility function to wait for all CPUs other than the caller to be
* OFF.
*/
diff --git a/include/lib/extensions/pauth.h b/include/lib/extensions/pauth.h
index d072f5c..c8d577f 100644
--- a/include/lib/extensions/pauth.h
+++ b/include/lib/extensions/pauth.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,6 +7,7 @@
#ifndef PAUTH_H
#define PAUTH_H
+#include <stdbool.h>
#include <stdint.h>
#ifdef __aarch64__
@@ -18,6 +19,22 @@
/* Disable ARMv8.3-PAuth */
void pauth_disable(void);
+
+/*
+ * Fill Pauth Keys and template with random values if keys werenot initialized earlier,
+ * Else Copy PAuth key registers to template.
+ */
+void pauth_test_lib_fill_regs_and_template(void);
+
+/* Read and Compare PAuth registers with provided template values. */
+bool pauth_test_lib_compare_template(void);
+
+/* Read and Store PAuth registers in template. */
+void pauth_test_lib_read_keys(void);
+
+/* Test PAuth instructions. */
+void pauth_test_lib_test_intrs(void);
+
#endif /* __aarch64__ */
#endif /* PAUTH_H */
diff --git a/include/runtime_services/host_realm_managment/host_shared_data.h b/include/runtime_services/host_realm_managment/host_shared_data.h
index 98ab287..821a62f 100644
--- a/include/runtime_services/host_realm_managment/host_shared_data.h
+++ b/include/runtime_services/host_realm_managment/host_shared_data.h
@@ -55,7 +55,10 @@
REALM_SVE_ID_REGISTERS,
REALM_SVE_PROBE_VL,
REALM_SVE_OPS,
- REALM_SVE_FILL_REGS
+ REALM_SVE_FILL_REGS,
+ REALM_PAUTH_SET_CMD,
+ REALM_PAUTH_CHECK_CMD,
+ REALM_PAUTH_FAULT
};
/*
diff --git a/include/runtime_services/spm_test_helpers.h b/include/runtime_services/spm_test_helpers.h
new file mode 100644
index 0000000..fede4ad
--- /dev/null
+++ b/include/runtime_services/spm_test_helpers.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2018-2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SPM_TEST_HELPERS_H__
+#define SPM_TEST_HELPERS_H__
+
+#include <events.h>
+#include <ffa_helpers.h>
+#include <ffa_svc.h>
+#include <spm_common.h>
+
+#define SKIP_TEST_IF_FFA_VERSION_LESS_THAN(major, minor) \
+ do { \
+ struct ffa_value ret = ffa_version( \
+ MAKE_FFA_VERSION(major, minor)); \
+ uint32_t version = ret.fid; \
+ \
+ if (version == FFA_ERROR_NOT_SUPPORTED) { \
+ tftf_testcase_printf("FFA_VERSION not supported.\n"); \
+ return TEST_RESULT_SKIPPED; \
+ } \
+ \
+ if ((version & FFA_VERSION_BIT31_MASK) != 0U) { \
+ tftf_testcase_printf("FFA_VERSION bad response: %x\n", \
+ version); \
+ return TEST_RESULT_FAIL; \
+ } \
+ \
+ if (version < MAKE_FFA_VERSION(major, minor)) { \
+ tftf_testcase_printf("FFA_VERSION returned %u.%u\n" \
+ "The required version is %u.%u\n", \
+ version >> FFA_VERSION_MAJOR_SHIFT, \
+ version & FFA_VERSION_MINOR_MASK, \
+ major, minor); \
+ return TEST_RESULT_SKIPPED; \
+ } \
+ } while (0)
+
+#define SKIP_TEST_IF_FFA_ENDPOINT_NOT_DEPLOYED(mb, ffa_uuid) \
+ do { \
+ struct ffa_value sc_ret = ffa_partition_info_get(ffa_uuid); \
+ ffa_rx_release(); \
+ if (ffa_func_id(sc_ret) == FFA_ERROR && \
+ ffa_error_code(sc_ret) == FFA_ERROR_INVALID_PARAMETER) { \
+ tftf_testcase_printf("FFA endpoint not deployed!\n"); \
+ return TEST_RESULT_SKIPPED; \
+ } else if (ffa_func_id(sc_ret) != FFA_SUCCESS_SMC32) { \
+ ERROR("ffa_partition_info_get failed!\n"); \
+ return TEST_RESULT_FAIL; \
+ } \
+ } while (0)
+
+#define GET_TFTF_MAILBOX(mb) \
+ do { \
+ if (!get_tftf_mailbox(&mb)) { \
+ ERROR("Mailbox RXTX buffers not configured!\n"); \
+ return TEST_RESULT_FAIL; \
+ } \
+ } while (false);
+
+#define CHECK_SPMC_TESTING_SETUP(ffa_major, ffa_minor, expected_uuids) \
+ do { \
+ SKIP_TEST_IF_AARCH32(); \
+ const size_t expected_uuids_size = \
+ sizeof(expected_uuids) / sizeof(struct ffa_uuid); \
+ test_result_t ret = check_spmc_testing_set_up( \
+ ffa_major, ffa_minor, expected_uuids, \
+ expected_uuids_size); \
+ if (ret != TEST_RESULT_SUCCESS) { \
+ return ret; \
+ } \
+ } while (false);
+
+/*
+ * Helper function to reset TFTF global mailbox for SPM related tests.
+ * It calls the FFA_RXTX_UNMAP interface, for the SPMC to drop the current
+ * address.
+ */
+bool reset_tftf_mailbox(void);
+
+/*
+ * Helper function to get TFTF global mailbox for SPM related tests.
+ * Allocates RX/TX buffer pair and calls FFA_RXTX_MAP interface, for the SPMC
+ * to map them into its own S1 translation.
+ * If this function is called, and the buffers had been priorly mapped, it
+ * sets 'mb' with the respective addresses.
+ */
+bool get_tftf_mailbox(struct mailbox_buffers *mb);
+
+test_result_t check_spmc_testing_set_up(uint32_t ffa_version_major,
+ uint32_t ffa_version_minor, const struct ffa_uuid *ffa_uuids,
+ size_t ffa_uuids_size);
+
+/**
+ * Turn on all cpus to execute a test in all.
+ * - 'cpu_on_handler' should have the code containing the test.
+ * - 'cpu_booted' is used for notifying which cores the test has been executed.
+ * This should be used in the test executed by cpu_on_handler at the end of
+ * processing to make sure it complies with this function's implementation.
+ */
+test_result_t spm_run_multi_core_test(uintptr_t cpu_on_handler,
+ event_t *cpu_booted);
+
+/**
+ * Call FFA_RUN in the designated SP to make it reach the message loop.
+ * Used within CPU_ON handlers, to bring up the SP in the current core.
+ */
+bool spm_core_sp_init(ffa_id_t sp_id);
+
+/**
+ * Initializes the Mailbox for other SPM related tests that need to use
+ * RXTX buffers.
+ */
+bool mailbox_init(struct mailbox_buffers mb);
+
+#endif /* __SPM_TEST_HELPERS_H__ */
diff --git a/lib/extensions/pauth/aarch64/pauth.c b/lib/extensions/pauth/aarch64/pauth.c
index 03de468..90e16d5 100644
--- a/lib/extensions/pauth/aarch64/pauth.c
+++ b/lib/extensions/pauth/aarch64/pauth.c
@@ -6,7 +6,18 @@
#include <arch_helpers.h>
#include <cdefs.h>
+#include <stdbool.h>
#include <stdint.h>
+#include <debug.h>
+#include <pauth.h>
+
+/* Number of ARMv8.3-PAuth keys */
+#define NUM_KEYS 5U
+
+static const char * const key_name[] = {"IA", "IB", "DA", "DB", "GA"};
+
+static uint128_t pauth_keys_before[NUM_KEYS];
+static uint128_t pauth_keys_after[NUM_KEYS];
/*
* This is only a toy implementation to generate a seemingly random
@@ -24,3 +35,151 @@
return ((uint128_t)(key_hi) << 64) | key_lo;
}
+
+/* Check if ARMv8.3-PAuth key is enabled */
+static bool is_pauth_key_enabled(uint64_t key_bit)
+{
+ unsigned int el = (unsigned int)GET_EL(read_CurrentEl());
+
+ if (el == 1U) {
+ return ((read_sctlr_el1() & key_bit) != 0U);
+ } else if (el == 2U) {
+ return ((read_sctlr_el2() & key_bit) != 0U);
+ }
+ return false;
+}
+
+bool pauth_test_lib_compare_template(void)
+{
+ bool result = true;
+
+ pauth_test_lib_read_keys();
+ for (unsigned int i = 0U; i < NUM_KEYS; ++i) {
+ if (pauth_keys_before[i] != pauth_keys_after[i]) {
+ ERROR("AP%sKey_EL1 read 0x%llx:%llx "
+ "expected 0x%llx:%llx\n", key_name[i],
+ (uint64_t)(pauth_keys_after[i] >> 64U),
+ (uint64_t)(pauth_keys_after[i]),
+ (uint64_t)(pauth_keys_before[i] >> 64U),
+ (uint64_t)(pauth_keys_before[i]));
+
+ result = false;
+ }
+ }
+ return result;
+}
+
+/*
+ * Program or read ARMv8.3-PAuth keys (if already enabled)
+ * and store them in <pauth_keys_before> buffer
+ */
+void pauth_test_lib_fill_regs_and_template(void)
+{
+ uint128_t plat_key;
+
+ (void)memset(pauth_keys_before, 0, NUM_KEYS * sizeof(uint128_t));
+
+ if (is_pauth_key_enabled(SCTLR_EnIA_BIT)) {
+ /* Read APIAKey_EL1 */
+ plat_key = read_apiakeylo_el1() |
+ ((uint128_t)(read_apiakeyhi_el1()) << 64U);
+ INFO("EnIA is set\n");
+ } else {
+ /* Program APIAKey_EL1 */
+ plat_key = init_apkey();
+ write_apiakeylo_el1((uint64_t)plat_key);
+ write_apiakeyhi_el1((uint64_t)(plat_key >> 64U));
+ }
+ pauth_keys_before[0] = plat_key;
+
+ if (is_pauth_key_enabled(SCTLR_EnIB_BIT)) {
+ /* Read APIBKey_EL1 */
+ plat_key = read_apibkeylo_el1() |
+ ((uint128_t)(read_apibkeyhi_el1()) << 64U);
+ INFO("EnIB is set\n");
+ } else {
+ /* Program APIBKey_EL1 */
+ plat_key = init_apkey();
+ write_apibkeylo_el1((uint64_t)plat_key);
+ write_apibkeyhi_el1((uint64_t)(plat_key >> 64U));
+ }
+ pauth_keys_before[1] = plat_key;
+
+ if (is_pauth_key_enabled(SCTLR_EnDA_BIT)) {
+ /* Read APDAKey_EL1 */
+ plat_key = read_apdakeylo_el1() |
+ ((uint128_t)(read_apdakeyhi_el1()) << 64U);
+ INFO("EnDA is set\n");
+ } else {
+ /* Program APDAKey_EL1 */
+ plat_key = init_apkey();
+ write_apdakeylo_el1((uint64_t)plat_key);
+ write_apdakeyhi_el1((uint64_t)(plat_key >> 64U));
+ }
+ pauth_keys_before[2] = plat_key;
+
+ if (is_pauth_key_enabled(SCTLR_EnDB_BIT)) {
+ /* Read APDBKey_EL1 */
+ plat_key = read_apdbkeylo_el1() |
+ ((uint128_t)(read_apdbkeyhi_el1()) << 64U);
+ INFO("EnDB is set\n");
+ } else {
+ /* Program APDBKey_EL1 */
+ plat_key = init_apkey();
+ write_apdbkeylo_el1((uint64_t)plat_key);
+ write_apdbkeyhi_el1((uint64_t)(plat_key >> 64U));
+ }
+ pauth_keys_before[3] = plat_key;
+
+ pauth_keys_before[4] = read_apgakeylo_el1() |
+ ((uint128_t)(read_apgakeyhi_el1()) << 64U);
+ if (pauth_keys_before[4] == 0ULL) {
+ /* Program APGAKey_EL1 */
+ plat_key = init_apkey();
+ write_apgakeylo_el1((uint64_t)plat_key);
+ write_apgakeyhi_el1((uint64_t)(plat_key >> 64U));
+ pauth_keys_before[4] = plat_key;
+ }
+
+ isb();
+}
+
+/*
+ * Read ARMv8.3-PAuth keys and store them in
+ * <pauth_keys_after> buffer
+ */
+void pauth_test_lib_read_keys(void)
+{
+ (void)memset(pauth_keys_after, 0, NUM_KEYS * sizeof(uint128_t));
+
+ /* Read APIAKey_EL1 */
+ pauth_keys_after[0] = read_apiakeylo_el1() |
+ ((uint128_t)(read_apiakeyhi_el1()) << 64U);
+
+ /* Read APIBKey_EL1 */
+ pauth_keys_after[1] = read_apibkeylo_el1() |
+ ((uint128_t)(read_apibkeyhi_el1()) << 64U);
+
+ /* Read APDAKey_EL1 */
+ pauth_keys_after[2] = read_apdakeylo_el1() |
+ ((uint128_t)(read_apdakeyhi_el1()) << 64U);
+
+ /* Read APDBKey_EL1 */
+ pauth_keys_after[3] = read_apdbkeylo_el1() |
+ ((uint128_t)(read_apdbkeyhi_el1()) << 64U);
+
+ /* Read APGAKey_EL1 */
+ pauth_keys_after[4] = read_apgakeylo_el1() |
+ ((uint128_t)(read_apgakeyhi_el1()) << 64U);
+}
+
+/* Test execution of ARMv8.3-PAuth instructions */
+void pauth_test_lib_test_intrs(void)
+{
+ /* Pointer authentication instructions */
+ __asm__ volatile (
+ "paciasp\n"
+ "autiasp\n"
+ "paciasp\n"
+ "xpaclri");
+}
diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk
index 5cd8bc6..e12f8e2 100644
--- a/make_helpers/build_macros.mk
+++ b/make_helpers/build_macros.mk
@@ -18,6 +18,22 @@
$(and $(patsubst 0,,$(value $(1))),$(patsubst 1,,$(value $(1))),$(error $(1) must be boolean))
endef
+0-9 := 0 1 2 3 4 5 6 7 8 9
+
+# Function to verify that a given option $(1) contains a numeric value
+define assert_numeric
+$(if $($(1)),,$(error $(1) must not be empty))
+$(eval __numeric := $($(1)))
+$(foreach d,$(0-9),$(eval __numeric := $(subst $(d),,$(__numeric))))
+$(if $(__numeric),$(error $(1) must be numeric))
+endef
+
+# Convenience function for verifying options have numeric values
+# $(eval $(call assert_numerics,FOO BOO)) will assert FOO and BOO contain numeric values
+define assert_numerics
+ $(foreach num,$1,$(eval $(call assert_numeric,$(num))))
+endef
+
# CREATE_SEQ is a recursive function to create sequence of numbers from 1 to
# $(2) and assign the sequence to $(1)
define CREATE_SEQ
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index 2e18d67..3605d01 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -45,3 +45,9 @@
# Build verbosity
V := 0
+
+# Select the branch protection features to use
+BRANCH_PROTECTION := 0
+
+# Build RME stack
+ENABLE_REALM_PAYLOAD_TESTS := 0
diff --git a/realm/aarch64/realm_entrypoint.S b/realm/aarch64/realm_entrypoint.S
index 28a37de..e0638f0 100644
--- a/realm/aarch64/realm_entrypoint.S
+++ b/realm/aarch64/realm_entrypoint.S
@@ -49,9 +49,14 @@
mov x1, REALM_MAX_LOAD_IMG_SIZE
add x1, x1, x0
bl fixup_gdt_reloc
+#if ENABLE_PAUTH
+ bl pauth_init_enable
+#endif
+loop:
/* And jump to the C entrypoint. */
- b realm_payload_main
+ bl realm_payload_main
+ b loop
endfunc realm_entrypoint
/* Initialize architectural state. */
diff --git a/realm/include/realm_tests.h b/realm/include/realm_tests.h
index 61d4493..4bd260c 100644
--- a/realm/include/realm_tests.h
+++ b/realm/include/realm_tests.h
@@ -12,6 +12,9 @@
bool test_pmuv3_event_works_realm(void);
bool test_pmuv3_rmm_preserves(void);
bool test_pmuv3_overflow_interrupt(void);
+bool test_realm_pauth_set_cmd(void);
+bool test_realm_pauth_check_cmd(void);
+bool test_realm_pauth_fault(void);
bool test_realm_sve_rdvl(void);
bool test_realm_sve_read_id_registers(void);
bool test_realm_sve_probe_vl(void);
diff --git a/realm/realm.mk b/realm/realm.mk
index 047dff8..77499d0 100644
--- a/realm/realm.mk
+++ b/realm/realm.mk
@@ -28,6 +28,7 @@
aarch64/realm_exceptions.S \
realm_debug.c \
realm_interrupt.c \
+ realm_pauth.c \
realm_payload_main.c \
realm_pmuv3.c \
realm_rsi.c \
@@ -52,6 +53,12 @@
REALM_LINKERFILE:= realm/realm.ld.S
+# ARMv8.3 Pointer Authentication support files
+REALM_SOURCES += lib/extensions/pauth/aarch64/pauth.c \
+ lib/extensions/pauth/aarch64/pauth_helpers.S
+
+REALM_INCLUDES += -Iinclude/lib/extensions
+
REALM_DEFINES:=
$(eval $(call add_define,REALM_DEFINES,ARM_ARCH_MAJOR))
$(eval $(call add_define,REALM_DEFINES,ARM_ARCH_MINOR))
diff --git a/realm/realm_pauth.c b/realm/realm_pauth.c
new file mode 100644
index 0000000..0a5a022
--- /dev/null
+++ b/realm/realm_pauth.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <stdio.h>
+#include <arch_features.h>
+#include <debug.h>
+#include <pauth.h>
+#include <realm_rsi.h>
+#include <sync.h>
+
+static volatile bool set_cmd_done;
+
+static bool exception_handler(void)
+{
+ u_register_t lr = read_elr_el1();
+
+ /* Disable PAuth to avoid further PAuth faults. */
+ pauth_disable();
+
+ /* Check for PAuth exception. */
+ /* Note- PAuth decode instruction clobbers PAC Fields[63:56] in case of error. */
+ if (lr & (0xFFULL << 56U)) {
+ rsi_exit_to_host(HOST_CALL_EXIT_SUCCESS_CMD);
+ }
+
+ rsi_exit_to_host(HOST_CALL_EXIT_FAILED_CMD);
+
+ /* Does not return. */
+ return false;
+}
+
+void dummy_func(void)
+{
+ realm_printf("Realm: shouldn't reach here.\n");
+ rsi_exit_to_host(HOST_CALL_EXIT_FAILED_CMD);
+}
+
+bool test_realm_pauth_fault(void)
+{
+ u_register_t ptr = (u_register_t)dummy_func;
+
+ if (!is_armv8_3_pauth_present()) {
+ return false;
+ }
+
+ register_custom_sync_exception_handler(exception_handler);
+ realm_printf("Realm: overwrite LR to generate fault.\n");
+ __asm__("mov x17, x30; "
+ "mov x30, %0; " /* overwite LR. */
+ "isb; "
+ "autiasp; "
+ "ret; " /* fault on return. */
+ :
+ : "r"(ptr));
+
+ /* Does not return. */
+ return false;
+}
+
+/*
+ * TF-A is expected to allow access to key registers from lower EL's,
+ * reading the keys excercises this, on failure this will trap to
+ * EL3 and crash.
+ */
+bool test_realm_pauth_set_cmd(void)
+{
+ if (!is_armv8_3_pauth_present()) {
+ return false;
+ }
+ pauth_test_lib_test_intrs();
+ pauth_test_lib_fill_regs_and_template();
+ set_cmd_done = true;
+ return true;
+}
+
+bool test_realm_pauth_check_cmd(void)
+{
+ if (!is_armv8_3_pauth_present() || !set_cmd_done) {
+ return false;
+ }
+ return pauth_test_lib_compare_template();
+}
diff --git a/realm/realm_payload_main.c b/realm/realm_payload_main.c
index d99037a..e867546 100644
--- a/realm/realm_payload_main.c
+++ b/realm/realm_payload_main.c
@@ -7,10 +7,12 @@
#include <stdio.h>
+#include <arch_features.h>
#include <debug.h>
#include <fpu.h>
#include <host_realm_helper.h>
#include <host_shared_data.h>
+#include <pauth.h>
#include "realm_def.h"
#include <realm_rsi.h>
#include <realm_tests.h>
@@ -62,7 +64,6 @@
bool test_succeed = false;
realm_set_shared_structure((host_shared_data_t *)rsi_get_ns_buffer());
-
if (realm_get_shared_structure() != NULL) {
uint8_t cmd = realm_shared_data_get_realm_cmd();
@@ -71,6 +72,15 @@
realm_sleep_cmd();
test_succeed = true;
break;
+ case REALM_PAUTH_SET_CMD:
+ test_succeed = test_realm_pauth_set_cmd();
+ break;
+ case REALM_PAUTH_CHECK_CMD:
+ test_succeed = test_realm_pauth_check_cmd();
+ break;
+ case REALM_PAUTH_FAULT:
+ test_succeed = test_realm_pauth_fault();
+ break;
case REALM_GET_RSI_VERSION:
realm_get_rsi_version();
test_succeed = true;
diff --git a/tftf/tests/aarch32_tests_to_skip.txt b/tftf/tests/aarch32_tests_to_skip.txt
index e31202d..83e4028 100644
--- a/tftf/tests/aarch32_tests_to_skip.txt
+++ b/tftf/tests/aarch32_tests_to_skip.txt
@@ -6,5 +6,14 @@
Realm payload at EL1
SIMD,SVE Registers context
Invalid memory access with RME extension
+FF-A Setup and Discovery
+SP exceptions
+FF-A Direct messaging
+FF-A Group0 interrupts
+FF-A Power management
+FF-A Memory Sharing
+SIMD,SVE Registers context
+FF-A Interrupt
+SMMUv3 tests
+FF-A Notifications
RMI and SPM tests
-SP exceptions
\ No newline at end of file
diff --git a/tftf/tests/common/test_helpers.c b/tftf/tests/common/test_helpers.c
index 90773ae..6a0b08b 100644
--- a/tftf/tests/common/test_helpers.c
+++ b/tftf/tests/common/test_helpers.c
@@ -7,15 +7,11 @@
#include <stdlib.h>
#include <arch_helpers.h>
-#include <cactus_test_cmds.h>
#include <plat_topology.h>
#include <platform.h>
-#include <power_management.h>
#include <test_helpers.h>
#include <tftf_lib.h>
-static struct mailbox_buffers test_mb = {.send = NULL, .recv = NULL};
-
int is_sys_suspend_state_ready(void)
{
int aff_info;
@@ -134,120 +130,6 @@
return test_ret;
}
-bool reset_tftf_mailbox(void)
-{
- if (is_ffa_call_error(ffa_rxtx_unmap())) {
- return false;
- }
-
- test_mb.send = NULL;
- test_mb.recv = NULL;
-
- return true;
-}
-
-bool get_tftf_mailbox(struct mailbox_buffers *mb)
-{
- struct ffa_value ret;
-
- if (test_mb.recv == NULL || test_mb.send == NULL) {
- CONFIGURE_AND_MAP_MAILBOX(test_mb, PAGE_SIZE, ret);
- if (is_ffa_call_error(ret)) {
- return false;
- }
- }
-
- *mb = test_mb;
-
- return true;
-}
-
-test_result_t check_spmc_testing_set_up(
- uint32_t ffa_version_major, uint32_t ffa_version_minor,
- const struct ffa_uuid *ffa_uuids, size_t ffa_uuids_size)
-{
- struct mailbox_buffers mb;
-
- if (ffa_uuids == NULL) {
- ERROR("Invalid parameter ffa_uuids!\n");
- return TEST_RESULT_FAIL;
- }
-
- SKIP_TEST_IF_FFA_VERSION_LESS_THAN(ffa_version_major,
- ffa_version_minor);
-
- /**********************************************************************
- * If OP-TEE is SPMC skip the current test.
- **********************************************************************/
- if (check_spmc_execution_level()) {
- VERBOSE("OPTEE as SPMC at S-EL1. Skipping test!\n");
- return TEST_RESULT_SKIPPED;
- }
-
- GET_TFTF_MAILBOX(mb);
-
- for (unsigned int i = 0U; i < ffa_uuids_size; i++)
- SKIP_TEST_IF_FFA_ENDPOINT_NOT_DEPLOYED(*mb, ffa_uuids[i]);
-
- return TEST_RESULT_SUCCESS;
-}
-
-test_result_t spm_run_multi_core_test(uintptr_t cpu_on_handler,
- event_t *cpu_done)
-{
- unsigned int lead_mpid = read_mpidr_el1() & MPID_MASK;
- unsigned int core_pos, cpu_node, mpidr;
- int32_t ret;
-
- VERBOSE("Powering on all cpus.\n");
-
- for (unsigned int i = 0U; i < PLATFORM_CORE_COUNT; i++) {
- tftf_init_event(&cpu_done[i]);
- }
-
- /* Power on each secondary CPU one after the other. */
- for_each_cpu(cpu_node) {
- mpidr = tftf_get_mpidr_from_node(cpu_node);
- if (mpidr == lead_mpid) {
- continue;
- }
-
- ret = tftf_cpu_on(mpidr, cpu_on_handler, 0U);
- if (ret != 0) {
- ERROR("tftf_cpu_on mpidr 0x%x returns %d\n",
- mpidr, ret);
- }
-
- /* Wait for the secondary CPU to be ready. */
- core_pos = platform_get_core_pos(mpidr);
- tftf_wait_for_event(&cpu_done[core_pos]);
- }
-
- VERBOSE("Done exiting.\n");
-
- return TEST_RESULT_SUCCESS;
-}
-
-bool spm_core_sp_init(ffa_id_t sp_id)
-{
- /*
- * Secure Partitions secondary ECs need one round of ffa_run to reach
- * the message loop.
- */
- if (sp_id != SP_ID(1)) {
- uint32_t core_pos = get_current_core_id();
- struct ffa_value ret = ffa_run(sp_id, core_pos);
-
- if (ffa_func_id(ret) != FFA_MSG_WAIT) {
- ERROR("Failed to run SP%x on core %u\n",
- sp_id, core_pos);
- return false;
- }
- }
-
- return true;
-}
-
/*
* Utility function to wait for all CPUs other than the caller to be
* OFF.
diff --git a/tftf/tests/extensions/pauth/test_pauth.c b/tftf/tests/extensions/pauth/test_pauth.c
index b7434a8..b29e5d0 100644
--- a/tftf/tests/extensions/pauth/test_pauth.c
+++ b/tftf/tests/extensions/pauth/test_pauth.c
@@ -13,157 +13,6 @@
#include <tsp.h>
#include <string.h>
-#ifdef __aarch64__
-
-/* Number of ARMv8.3-PAuth keys */
-#define NUM_KEYS 5
-
-static const char * const key_name[] = {"IA", "IB", "DA", "DB", "GA"};
-
-static uint128_t pauth_keys_before[NUM_KEYS];
-static uint128_t pauth_keys_after[NUM_KEYS];
-
-/* Check if ARMv8.3-PAuth key is enabled */
-static bool is_pauth_key_enabled(uint64_t key_bit)
-{
- return (IS_IN_EL2() ?
- ((read_sctlr_el2() & key_bit) != 0U) :
- ((read_sctlr_el1() & key_bit) != 0U));
-}
-
-static test_result_t compare_pauth_keys(void)
-{
- test_result_t result = TEST_RESULT_SUCCESS;
-
- for (unsigned int i = 0; i < NUM_KEYS; ++i) {
- if (pauth_keys_before[i] != pauth_keys_after[i]) {
- ERROR("AP%sKey_EL1 read 0x%llx:%llx "
- "expected 0x%llx:%llx\n", key_name[i],
- (uint64_t)(pauth_keys_after[i] >> 64),
- (uint64_t)(pauth_keys_after[i]),
- (uint64_t)(pauth_keys_before[i] >> 64),
- (uint64_t)(pauth_keys_before[i]));
-
- result = TEST_RESULT_FAIL;
- }
- }
- return result;
-}
-
-/*
- * Program or read ARMv8.3-PAuth keys (if already enabled)
- * and store them in <pauth_keys_before> buffer
- */
-static void set_store_pauth_keys(void)
-{
- uint128_t plat_key;
-
- memset(pauth_keys_before, 0, NUM_KEYS * sizeof(uint128_t));
-
- if (is_armv8_3_pauth_apa_api_apa3_present()) {
- if (is_pauth_key_enabled(SCTLR_EnIA_BIT)) {
- /* Read APIAKey_EL1 */
- plat_key = read_apiakeylo_el1() |
- ((uint128_t)(read_apiakeyhi_el1()) << 64);
- INFO("EnIA is set\n");
- } else {
- /* Program APIAKey_EL1 */
- plat_key = init_apkey();
- write_apiakeylo_el1((uint64_t)plat_key);
- write_apiakeyhi_el1((uint64_t)(plat_key >> 64));
- }
- pauth_keys_before[0] = plat_key;
-
- if (is_pauth_key_enabled(SCTLR_EnIB_BIT)) {
- /* Read APIBKey_EL1 */
- plat_key = read_apibkeylo_el1() |
- ((uint128_t)(read_apibkeyhi_el1()) << 64);
- INFO("EnIB is set\n");
- } else {
- /* Program APIBKey_EL1 */
- plat_key = init_apkey();
- write_apibkeylo_el1((uint64_t)plat_key);
- write_apibkeyhi_el1((uint64_t)(plat_key >> 64));
- }
- pauth_keys_before[1] = plat_key;
-
- if (is_pauth_key_enabled(SCTLR_EnDA_BIT)) {
- /* Read APDAKey_EL1 */
- plat_key = read_apdakeylo_el1() |
- ((uint128_t)(read_apdakeyhi_el1()) << 64);
- INFO("EnDA is set\n");
- } else {
- /* Program APDAKey_EL1 */
- plat_key = init_apkey();
- write_apdakeylo_el1((uint64_t)plat_key);
- write_apdakeyhi_el1((uint64_t)(plat_key >> 64));
- }
- pauth_keys_before[2] = plat_key;
-
- if (is_pauth_key_enabled(SCTLR_EnDB_BIT)) {
- /* Read APDBKey_EL1 */
- plat_key = read_apdbkeylo_el1() |
- ((uint128_t)(read_apdbkeyhi_el1()) << 64);
- INFO("EnDB is set\n");
- } else {
- /* Program APDBKey_EL1 */
- plat_key = init_apkey();
- write_apdbkeylo_el1((uint64_t)plat_key);
- write_apdbkeyhi_el1((uint64_t)(plat_key >> 64));
- }
- pauth_keys_before[3] = plat_key;
- }
-
- /*
- * It is safe to assume that Generic Pointer authentication code key
- * APGAKey_EL1 can be re-programmed, as this key is not set in
- * TF-A Test suite and PACGA instruction is not used.
- */
- if (is_armv8_3_pauth_gpa_gpi_gpa3_present()) {
- /* Program APGAKey_EL1 */
- plat_key = init_apkey();
- write_apgakeylo_el1((uint64_t)plat_key);
- write_apgakeyhi_el1((uint64_t)(plat_key >> 64));
- pauth_keys_before[4] = plat_key;
- }
-
- isb();
-}
-
-/*
- * Read ARMv8.3-PAuth keys and store them in
- * <pauth_keys_after> buffer
- */
-static void read_pauth_keys(void)
-{
- memset(pauth_keys_after, 0, NUM_KEYS * sizeof(uint128_t));
-
- if (is_armv8_3_pauth_apa_api_apa3_present()) {
- /* Read APIAKey_EL1 */
- pauth_keys_after[0] = read_apiakeylo_el1() |
- ((uint128_t)(read_apiakeyhi_el1()) << 64);
-
- /* Read APIBKey_EL1 */
- pauth_keys_after[1] = read_apibkeylo_el1() |
- ((uint128_t)(read_apibkeyhi_el1()) << 64);
-
- /* Read APDAKey_EL1 */
- pauth_keys_after[2] = read_apdakeylo_el1() |
- ((uint128_t)(read_apdakeyhi_el1()) << 64);
-
- /* Read APDBKey_EL1 */
- pauth_keys_after[3] = read_apdbkeylo_el1() |
- ((uint128_t)(read_apdbkeyhi_el1()) << 64);
- }
-
- if (is_armv8_3_pauth_gpa_gpi_gpa3_present()) {
- /* Read APGAKey_EL1 */
- pauth_keys_after[4] = read_apgakeylo_el1() |
- ((uint128_t)(read_apgakeyhi_el1()) << 64);
- }
-}
-#endif /* __aarch64__ */
-
/*
* TF-A is expected to allow access to key registers from lower EL's,
* reading the keys excercises this, on failure this will trap to
@@ -174,7 +23,7 @@
SKIP_TEST_IF_AARCH32();
#ifdef __aarch64__
SKIP_TEST_IF_PAUTH_NOT_SUPPORTED();
- read_pauth_keys();
+ pauth_test_lib_read_keys();
return TEST_RESULT_SUCCESS;
#endif /* __aarch64__ */
}
@@ -188,13 +37,11 @@
SKIP_TEST_IF_AARCH32();
#ifdef __aarch64__
SKIP_TEST_IF_PAUTH_NOT_SUPPORTED();
- set_store_pauth_keys();
+ pauth_test_lib_read_keys();
tftf_get_psci_version();
- read_pauth_keys();
-
- return compare_pauth_keys();
+ return pauth_test_lib_compare_template();
#endif /* __aarch64__ */
}
@@ -220,7 +67,6 @@
ARM_ARCH_MAJOR, ARM_ARCH_MINOR);
return TEST_RESULT_SKIPPED;
#endif /* ARM_ARCH_AT_LEAST(8, 3) */
-
#endif /* __aarch64__ */
}
@@ -238,7 +84,7 @@
SKIP_TEST_IF_PAUTH_NOT_SUPPORTED();
SKIP_TEST_IF_TSP_NOT_PRESENT();
- set_store_pauth_keys();
+ pauth_test_lib_fill_regs_and_template();
/* Standard SMC to ADD two numbers */
tsp_svc_params.fid = TSP_STD_FID(TSP_ADD);
@@ -260,8 +106,6 @@
return TEST_RESULT_FAIL;
}
- read_pauth_keys();
-
- return compare_pauth_keys();
+ return pauth_test_lib_compare_template();
#endif /* __aarch64__ */
}
diff --git a/tftf/tests/extensions/sve/test_sve.c b/tftf/tests/extensions/sve/test_sve.c
index 68ab775..bdd76e1 100644
--- a/tftf/tests/extensions/sve/test_sve.c
+++ b/tftf/tests/extensions/sve/test_sve.c
@@ -10,6 +10,7 @@
#include <stdlib.h>
#include <test_helpers.h>
#include <tftf_lib.h>
+#include <lib/extensions/sve.h>
#include "./test_sve.h"
diff --git a/tftf/tests/misc_tests/test_invalid_access.c b/tftf/tests/misc_tests/test_invalid_access.c
index 7325ace..5c173c5 100644
--- a/tftf/tests/misc_tests/test_invalid_access.c
+++ b/tftf/tests/misc_tests/test_invalid_access.c
@@ -11,6 +11,7 @@
#include <arch_features.h>
#include <debug.h>
#ifdef __aarch64__
+#include <spm_test_helpers.h>
#include <sync.h>
#endif
#include <host_realm_helper.h>
diff --git a/tftf/tests/runtime_services/host_realm_managment/rmi_spm_tests.c b/tftf/tests/runtime_services/host_realm_managment/rmi_spm_tests.c
index 7d2fe7f..d7a8157 100644
--- a/tftf/tests/runtime_services/host_realm_managment/rmi_spm_tests.c
+++ b/tftf/tests/runtime_services/host_realm_managment/rmi_spm_tests.c
@@ -17,6 +17,7 @@
#include <plat_topology.h>
#include <platform.h>
#include "rmi_spm_tests.h"
+#include <spm_test_helpers.h>
#include <smccc.h>
#include <test_helpers.h>
diff --git a/tftf/tests/runtime_services/realm_payload/host_realm_payload_tests.c b/tftf/tests/runtime_services/realm_payload/host_realm_payload_tests.c
index ae62336..43747b1 100644
--- a/tftf/tests/runtime_services/realm_payload/host_realm_payload_tests.c
+++ b/tftf/tests/runtime_services/realm_payload/host_realm_payload_tests.c
@@ -12,6 +12,7 @@
#include <irq.h>
#include <drivers/arm/arm_gic.h>
#include <drivers/arm/gic_v3.h>
+#include <pauth.h>
#include <test_helpers.h>
#include <host_realm_helper.h>
@@ -57,6 +58,97 @@
return host_cmp_result();
}
+
+/*
+ * @Test_Aim@ Test PAuth in realm
+ */
+test_result_t host_realm_enable_pauth(void)
+{
+#if ENABLE_PAUTH == 0
+ return TEST_RESULT_SKIPPED;
+#else
+ bool ret1, ret2;
+
+ SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
+
+ pauth_test_lib_fill_regs_and_template();
+ if (!host_create_realm_payload((u_register_t)REALM_IMAGE_BASE,
+ (u_register_t)PAGE_POOL_BASE,
+ (u_register_t)(PAGE_POOL_MAX_SIZE +
+ NS_REALM_SHARED_MEM_SIZE),
+ (u_register_t)PAGE_POOL_MAX_SIZE,
+ 0UL)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ if (!host_create_shared_mem(NS_REALM_SHARED_MEM_BASE,
+ NS_REALM_SHARED_MEM_SIZE)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ ret1 = host_enter_realm_execute(REALM_PAUTH_SET_CMD, NULL, RMI_EXIT_HOST_CALL);
+
+ if (ret1) {
+ /* Re-enter Realm to compare PAuth registers. */
+ ret1 = host_enter_realm_execute(REALM_PAUTH_CHECK_CMD, NULL, RMI_EXIT_HOST_CALL);
+ }
+
+ ret2 = host_destroy_realm();
+
+ if (!ret1) {
+ ERROR("%s(): enter=%d destroy=%d\n",
+ __func__, ret1, ret2);
+ return TEST_RESULT_FAIL;
+ }
+
+ /* Check if PAuth keys are preserved. */
+ if (!pauth_test_lib_compare_template()) {
+ ERROR("%s(): NS PAuth keys not preserved\n",
+ __func__);
+ return TEST_RESULT_FAIL;
+ }
+
+ return host_cmp_result();
+#endif
+}
+
+/*
+ * @Test_Aim@ Test PAuth fault in Realm
+ */
+test_result_t host_realm_pauth_fault(void)
+{
+#if ENABLE_PAUTH == 0
+ return TEST_RESULT_SKIPPED;
+#else
+ bool ret1, ret2;
+
+ SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
+ if (!host_create_realm_payload((u_register_t)REALM_IMAGE_BASE,
+ (u_register_t)PAGE_POOL_BASE,
+ (u_register_t)(PAGE_POOL_MAX_SIZE +
+ NS_REALM_SHARED_MEM_SIZE),
+ (u_register_t)PAGE_POOL_MAX_SIZE,
+ 0UL)) {
+ return TEST_RESULT_FAIL;
+ }
+ if (!host_create_shared_mem(NS_REALM_SHARED_MEM_BASE,
+ NS_REALM_SHARED_MEM_SIZE)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ ret1 = host_enter_realm_execute(REALM_PAUTH_FAULT, NULL, RMI_EXIT_HOST_CALL);
+ ret2 = host_destroy_realm();
+
+ if (!ret1) {
+ ERROR("%s(): enter=%d destroy=%d\n",
+ __func__, ret1, ret2);
+ return TEST_RESULT_FAIL;
+ }
+
+ return host_cmp_result();
+#endif
+}
+
/*
* This function is called on REC exit due to IRQ.
* By checking Realm PMU state in RecExit object this finction
diff --git a/tftf/tests/runtime_services/realm_payload/host_realm_spm.c b/tftf/tests/runtime_services/realm_payload/host_realm_spm.c
index 7cc4ec3..895a6dd 100644
--- a/tftf/tests/runtime_services/realm_payload/host_realm_spm.c
+++ b/tftf/tests/runtime_services/realm_payload/host_realm_spm.c
@@ -13,6 +13,7 @@
#include <host_realm_helper.h>
#include <host_realm_mem_layout.h>
#include <host_shared_data.h>
+#include <spm_test_helpers.h>
#include <test_helpers.h>
#define REALM_TIME_SLEEP 300U
diff --git a/tftf/tests/runtime_services/secure_service/spm_test_helpers.c b/tftf/tests/runtime_services/secure_service/spm_test_helpers.c
new file mode 100644
index 0000000..054e774
--- /dev/null
+++ b/tftf/tests/runtime_services/secure_service/spm_test_helpers.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdlib.h>
+
+#include <power_management.h>
+#include <spm_test_helpers.h>
+#include <test_helpers.h>
+#include <tftf_lib.h>
+
+static struct mailbox_buffers test_mb = {.send = NULL, .recv = NULL};
+
+bool reset_tftf_mailbox(void)
+{
+ if (is_ffa_call_error(ffa_rxtx_unmap())) {
+ return false;
+ }
+
+ test_mb.send = NULL;
+ test_mb.recv = NULL;
+
+ return true;
+}
+
+bool get_tftf_mailbox(struct mailbox_buffers *mb)
+{
+ struct ffa_value ret;
+
+ if (test_mb.recv == NULL || test_mb.send == NULL) {
+ CONFIGURE_AND_MAP_MAILBOX(test_mb, PAGE_SIZE, ret);
+ if (is_ffa_call_error(ret)) {
+ return false;
+ }
+ }
+
+ *mb = test_mb;
+
+ return true;
+}
+
+test_result_t check_spmc_testing_set_up(
+ uint32_t ffa_version_major, uint32_t ffa_version_minor,
+ const struct ffa_uuid *ffa_uuids, size_t ffa_uuids_size)
+{
+ struct mailbox_buffers mb;
+
+ if (ffa_uuids == NULL) {
+ ERROR("Invalid parameter ffa_uuids!\n");
+ return TEST_RESULT_FAIL;
+ }
+
+ SKIP_TEST_IF_FFA_VERSION_LESS_THAN(ffa_version_major,
+ ffa_version_minor);
+
+ /**********************************************************************
+ * If OP-TEE is SPMC skip the current test.
+ **********************************************************************/
+ if (check_spmc_execution_level()) {
+ VERBOSE("OPTEE as SPMC at S-EL1. Skipping test!\n");
+ return TEST_RESULT_SKIPPED;
+ }
+
+ GET_TFTF_MAILBOX(mb);
+
+ for (unsigned int i = 0U; i < ffa_uuids_size; i++)
+ SKIP_TEST_IF_FFA_ENDPOINT_NOT_DEPLOYED(*mb, ffa_uuids[i]);
+
+ return TEST_RESULT_SUCCESS;
+}
+
+test_result_t spm_run_multi_core_test(uintptr_t cpu_on_handler,
+ event_t *cpu_done)
+{
+ unsigned int lead_mpid = read_mpidr_el1() & MPID_MASK;
+ unsigned int core_pos, cpu_node, mpidr;
+ int32_t ret;
+
+ VERBOSE("Powering on all cpus.\n");
+
+ for (unsigned int i = 0U; i < PLATFORM_CORE_COUNT; i++) {
+ tftf_init_event(&cpu_done[i]);
+ }
+
+ /* Power on each secondary CPU one after the other. */
+ for_each_cpu(cpu_node) {
+ mpidr = tftf_get_mpidr_from_node(cpu_node);
+ if (mpidr == lead_mpid) {
+ continue;
+ }
+
+ ret = tftf_cpu_on(mpidr, cpu_on_handler, 0U);
+ if (ret != 0) {
+ ERROR("tftf_cpu_on mpidr 0x%x returns %d\n",
+ mpidr, ret);
+ }
+
+ /* Wait for the secondary CPU to be ready. */
+ core_pos = platform_get_core_pos(mpidr);
+ tftf_wait_for_event(&cpu_done[core_pos]);
+ }
+
+ VERBOSE("Done exiting.\n");
+
+ return TEST_RESULT_SUCCESS;
+}
+
+bool spm_core_sp_init(ffa_id_t sp_id)
+{
+ /*
+ * Secure Partitions secondary ECs need one round of ffa_run to reach
+ * the message loop.
+ */
+ if (sp_id != SP_ID(1)) {
+ uint32_t core_pos = get_current_core_id();
+ struct ffa_value ret = ffa_run(sp_id, core_pos);
+
+ if (ffa_func_id(ret) != FFA_MSG_WAIT) {
+ ERROR("Failed to run SP%x on core %u\n",
+ sp_id, core_pos);
+ return false;
+ }
+ }
+
+ return true;
+}
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_direct_messaging.c b/tftf/tests/runtime_services/secure_service/test_ffa_direct_messaging.c
index 5e52f12..1f8e81c 100644
--- a/tftf/tests/runtime_services/secure_service/test_ffa_direct_messaging.c
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_direct_messaging.c
@@ -14,6 +14,7 @@
#include <lib/events.h>
#include <lib/power_management.h>
#include <platform.h>
+#include <spm_test_helpers.h>
#include <test_helpers.h>
#define ECHO_VAL1 U(0xa0a0a0a0)
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_exceptions.c b/tftf/tests/runtime_services/secure_service/test_ffa_exceptions.c
index 870a00a..6fd77d2 100644
--- a/tftf/tests/runtime_services/secure_service/test_ffa_exceptions.c
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_exceptions.c
@@ -14,6 +14,7 @@
#include <platform.h>
#include <smccc.h>
#include <spm_common.h>
+#include <spm_test_helpers.h>
#include <test_helpers.h>
#define SENDER HYP_ID
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_group0_interrupts.c b/tftf/tests/runtime_services/secure_service/test_ffa_group0_interrupts.c
index 9359edf..c6c7194 100644
--- a/tftf/tests/runtime_services/secure_service/test_ffa_group0_interrupts.c
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_group0_interrupts.c
@@ -7,6 +7,7 @@
#include <cactus_test_cmds.h>
#include <ffa_endpoints.h>
#include <platform.h>
+#include <spm_test_helpers.h>
#include <test_helpers.h>
#define SP_SLEEP_TIME 200U
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_interrupts.c b/tftf/tests/runtime_services/secure_service/test_ffa_interrupts.c
index 01fa2ee..454ea05 100644
--- a/tftf/tests/runtime_services/secure_service/test_ffa_interrupts.c
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_interrupts.c
@@ -7,6 +7,7 @@
#include <cactus_test_cmds.h>
#include <ffa_endpoints.h>
#include <ffa_helpers.h>
+#include <spm_test_helpers.h>
#include <test_helpers.h>
#include <timer.h>
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_memory_sharing.c b/tftf/tests/runtime_services/secure_service/test_ffa_memory_sharing.c
index 9418b57..83c94c1 100644
--- a/tftf/tests/runtime_services/secure_service/test_ffa_memory_sharing.c
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_memory_sharing.c
@@ -8,9 +8,10 @@
#include <cactus_test_cmds.h>
#include <ffa_endpoints.h>
+#include <spm_common.h>
+#include <spm_test_helpers.h>
#include <test_helpers.h>
#include <tftf_lib.h>
-#include <spm_common.h>
#include <xlat_tables_defs.h>
#define MAILBOX_SIZE PAGE_SIZE
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_notifications.c b/tftf/tests/runtime_services/secure_service/test_ffa_notifications.c
index ea264b4..9ca337a 100644
--- a/tftf/tests/runtime_services/secure_service/test_ffa_notifications.c
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_notifications.c
@@ -14,6 +14,7 @@
#include <ffa_svc.h>
#include <platform.h>
#include <spm_common.h>
+#include <spm_test_helpers.h>
#include <test_helpers.h>
/**
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_secure_interrupts.c b/tftf/tests/runtime_services/secure_service/test_ffa_secure_interrupts.c
index 5977717..336faf9 100644
--- a/tftf/tests/runtime_services/secure_service/test_ffa_secure_interrupts.c
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_secure_interrupts.c
@@ -7,6 +7,7 @@
#include <cactus_test_cmds.h>
#include <ffa_endpoints.h>
#include <ffa_helpers.h>
+#include <spm_test_helpers.h>
#include <test_helpers.h>
#include <timer.h>
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_setup_and_discovery.c b/tftf/tests/runtime_services/secure_service/test_ffa_setup_and_discovery.c
index 613bdc4..4b0df1c 100644
--- a/tftf/tests/runtime_services/secure_service/test_ffa_setup_and_discovery.c
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_setup_and_discovery.c
@@ -10,6 +10,7 @@
#include <ffa_helpers.h>
#include <ffa_svc.h>
#include <spm_common.h>
+#include <spm_test_helpers.h>
#include <test_helpers.h>
#include <tftf_lib.h>
#include <xlat_tables_defs.h>
@@ -185,7 +186,7 @@
test_result_t test_ffa_version_bigger(void)
{
return test_ffa_version(MAKE_FFA_VERSION(FFA_VERSION_MAJOR + 1, 0),
- SPM_VERSION);
+ FFA_ERROR_NOT_SUPPORTED);
}
/*
@@ -193,7 +194,8 @@
*/
test_result_t test_ffa_version_smaller(void)
{
- return test_ffa_version(MAKE_FFA_VERSION(0, 9), SPM_VERSION);
+ return test_ffa_version(MAKE_FFA_VERSION(0, 9),
+ FFA_ERROR_NOT_SUPPORTED);
}
/******************************************************************************
diff --git a/tftf/tests/runtime_services/secure_service/test_spm_cpu_features.c b/tftf/tests/runtime_services/secure_service/test_spm_cpu_features.c
index 8f090a2..efd6c8a 100644
--- a/tftf/tests/runtime_services/secure_service/test_spm_cpu_features.c
+++ b/tftf/tests/runtime_services/secure_service/test_spm_cpu_features.c
@@ -8,6 +8,7 @@
#include <ffa_endpoints.h>
#include <ffa_helpers.h>
#include <fpu.h>
+#include <spm_test_helpers.h>
#include <test_helpers.h>
#include <lib/extensions/sve.h>
diff --git a/tftf/tests/runtime_services/secure_service/test_spm_smmu.c b/tftf/tests/runtime_services/secure_service/test_spm_smmu.c
index 0f0a5d9..238feae 100644
--- a/tftf/tests/runtime_services/secure_service/test_spm_smmu.c
+++ b/tftf/tests/runtime_services/secure_service/test_spm_smmu.c
@@ -8,6 +8,7 @@
#include <debug.h>
#include <ffa_endpoints.h>
#include <smccc.h>
+#include <spm_test_helpers.h>
#include <test_helpers.h>
static const struct ffa_uuid expected_sp_uuids[] = { {PRIMARY_UUID} };
diff --git a/tftf/tests/tests-realm-payload.mk b/tftf/tests/tests-realm-payload.mk
index 0e0d148..ee8ebc0 100644
--- a/tftf/tests/tests-realm-payload.mk
+++ b/tftf/tests/tests-realm-payload.mk
@@ -29,6 +29,7 @@
${ARCH}/ffa_arch_helpers.S \
ffa_helpers.c \
spm_common.c \
+ spm_test_helpers.c \
)
TESTS_SOURCES += \
diff --git a/tftf/tests/tests-realm-payload.xml b/tftf/tests/tests-realm-payload.xml
index 6569357..8498472 100644
--- a/tftf/tests/tests-realm-payload.xml
+++ b/tftf/tests/tests-realm-payload.xml
@@ -51,5 +51,9 @@
function="host_sve_realm_check_vectors_operations" />
<testcase name="Check if RMM does not leak Realm SVE vector registers"
function="host_sve_realm_check_vectors_leaked" />
+ <testcase name="Check if PAuth keys are preserved in RL/SE/NS"
+ function="host_realm_enable_pauth" />
+ <testcase name="Generate PAuth Fault by overwriting LR"
+ function="host_realm_pauth_fault" />
</testsuite>
</testsuites>
diff --git a/tftf/tests/tests-spm.mk b/tftf/tests/tests-spm.mk
index c0a7eb0..13f3f86 100644
--- a/tftf/tests/tests-spm.mk
+++ b/tftf/tests/tests-spm.mk
@@ -12,6 +12,7 @@
${ARCH}/ffa_arch_helpers.S \
ffa_helpers.c \
spm_common.c \
+ spm_test_helpers.c \
test_ffa_direct_messaging.c \
test_ffa_interrupts.c \
test_ffa_secure_interrupts.c \
diff --git a/tftf/tests/tests-standard.mk b/tftf/tests/tests-standard.mk
index 2ff0882..46157ce 100644
--- a/tftf/tests/tests-standard.mk
+++ b/tftf/tests/tests-standard.mk
@@ -16,7 +16,6 @@
tests-sdei.mk \
tests-single-fault.mk \
tests-smc.mk \
- tests-spm.mk \
tests-template.mk \
tests-tftf-validation.mk \
tests-trng.mk \
@@ -24,12 +23,13 @@
tests-tsp.mk \
tests-uncontainable.mk \
tests-debugfs.mk \
- tests-rmi-spm.mk \
)
ifeq (${ARCH},aarch64)
TESTS_MAKEFILE += $(addprefix tftf/tests/, \
+ tests-spm.mk \
tests-realm-payload.mk \
+ tests-rmi-spm.mk \
)
endif