aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--docs/change-log.rst108
-rw-r--r--docs/porting-guide.rst14
-rw-r--r--docs/user-guide.rst2
-rw-r--r--include/common/test_helpers.h23
-rw-r--r--include/lib/aarch64/arch.h50
-rw-r--r--include/lib/aarch64/arch_features.h8
-rw-r--r--include/lib/aarch64/arch_helpers.h12
-rw-r--r--include/lib/extensions/pauth.h20
-rw-r--r--include/plat/common/platform.h3
-rw-r--r--lib/extensions/pauth/aarch64/pauth.c26
-rw-r--r--lib/extensions/pauth/aarch64/pauth_helpers.S53
-rw-r--r--lib/power_management/hotplug/hotplug.c13
-rw-r--r--lib/power_management/suspend/aarch64/asm_tftf_suspend.S38
-rw-r--r--lib/power_management/suspend/suspend_private.h12
-rw-r--r--plat/arm/fvp/platform.mk4
-rw-r--r--tftf/framework/framework.mk9
-rw-r--r--tftf/framework/main.c20
-rw-r--r--tftf/tests/extensions/mte/test_mte.c57
-rw-r--r--tftf/tests/extensions/pauth/test_pauth.c267
-rw-r--r--tftf/tests/extensions/ptrauth/test_ptrauth.c164
-rw-r--r--tftf/tests/misc_tests/test_pmu_leakage.c393
-rw-r--r--tftf/tests/runtime_services/standard_service/psci/api_tests/system_reset/test_system_reset.c32
-rw-r--r--tftf/tests/tests-cpu-extensions.mk3
-rw-r--r--tftf/tests/tests-cpu-extensions.xml2
-rw-r--r--tftf/tests/tests-extensive.xml2
-rw-r--r--tftf/tests/tests-manual.mk5
-rw-r--r--tftf/tests/tests-manual.xml4
-rw-r--r--tftf/tests/tests-pmu-leakage.mk9
-rw-r--r--tftf/tests/tests-pmu-leakage.xml16
-rw-r--r--tftf/tests/tests-reboot.mk1
-rw-r--r--tftf/tests/tests-reboot.xml4
-rw-r--r--tftf/tests/tests-standard.mk3
-rw-r--r--tftf/tests/tests-standard.xml4
34 files changed, 1160 insertions, 223 deletions
diff --git a/Makefile b/Makefile
index bd179b9f0..c20011903 100644
--- a/Makefile
+++ b/Makefile
@@ -224,7 +224,7 @@ TFTF_ASFLAGS += ${COMMON_ASFLAGS}
TFTF_LDFLAGS += ${COMMON_LDFLAGS}
ifeq (${ENABLE_PAUTH},1)
-TFTF_CFLAGS += -msign-return-address=non-leaf
+TFTF_CFLAGS += -mbranch-protection=pac-ret
endif
NS_BL1U_SOURCES += ${PLAT_SOURCES} ${LIBC_SRCS}
diff --git a/docs/change-log.rst b/docs/change-log.rst
index da749236f..29de0ed64 100644
--- a/docs/change-log.rst
+++ b/docs/change-log.rst
@@ -10,6 +10,114 @@ Firmware-A version for simplicity. At any point in time, TF-A Tests version
Tests are not guaranteed to be compatible. This also means that a version
upgrade on the TF-A-Tests side might not necessarily introduce any new feature.
+Trusted Firmware-A Tests - version 2.2
+======================================
+
+New features
+------------
+
+- A wide range of tests are made available in this release to help validate
+ the functionality of TF-A.
+
+- Various improvements to test framework and test suite.
+
+TFTF
+````
+
+- Enhancement to xlat table library synchronous to TF-A code base.
+
+- Enabled strict alignment checks (SCTLR.A & SCTLR.SA) in all images.
+
+- Support for a simple console driver. Currently it serves as a placeholder
+ with empty functions.
+
+- A topology helper API is added in the framework to get parent node info.
+
+- Support for FVP with clusters having upto 8 CPUs.
+
+- Enhanced linker script to separate code and RO data sections.
+
+- Relax SMC calls tests. The SMCCC specification recommends Trusted OSes to
+ mitigate the risk of leaking information by either preserving the register
+ state over the call, or returning a constant value, such as zero, in each
+ register. Tests only allowed the former behaviour and have been extended to
+ allow the latter as well.
+
+- Pointer Authentication enabled on warm boot path with individual APIAKey
+ generation for each CPU.
+
+- New tests:
+
+ - Basic unit tests for xlat table library v2.
+
+ - Tests for validating SVE support in TF-A.
+
+ - Stress tests for dynamic xlat table library.
+
+ - PSCI test to measure latencies when turning ON a cluster.
+
+ - Series of AArch64 tests that stress the secure world to leak sensitive
+ counter values.
+
+ - Test to validate PSCI SYSTEM_RESET call.
+
+ - Basic tests to validate Memory Tagging Extensions are being enabled and
+ ensuring no undesired leak of sensitive data occurs.
+
+- Enhanced tests:
+
+ - Improved tests for Pointer Authentication support. Checks are performed
+ to see if pointer authentication keys are accessible as well as validate
+ if secure keys are being leaked after a PSCI version call or TSP call.
+
+ - Improved AMU test to remove unexecuted code iterating over Group1 counters
+ and fix the conditional check of AMU Group0 counter value.
+
+Secure partitions
+`````````````````
+
+A new Secure Partition Quark is introduced in this release.
+
+Quark
+'''''''''
+
+The Quark test secure partition provided is a simple service which returns a
+magic number. Further, a simple test is added to test if Quark is functional.
+
+Issues resolved since last release
+----------------------------------
+
+- Bug fix in libc memchr implementation.
+
+- Bug fix in calculation of number of CPUs.
+
+- Streamlined SMC WORKAROUND_2 test and fixed a false fail on Cortex-A76 CPU.
+
+- Pointer Authentication support is now available for secondary CPUs and the
+ corresponding tests are stable in this release.
+
+Known issues and limitations
+----------------------------
+
+The sections below list the known issues and limitations of each test image
+provided in this repository. Unless and otherwise stated, issues and limitations
+stated in previous release continue to exist in this release.
+
+TFTF
+````
+
+Tests
+'''''
+
+- Multicore spurious interrupt test is observed to have unstable behavior. As a
+ temporary solution, this test is skipped for AArch64 Juno configurations.
+
+- Generating SVE instructions requires `O3` compilation optimization. Since the
+ current build structure does not allow compilation flag modification for
+ specific files, the function which tests support for SVE has been pre-compiled
+ and added as an assembly file.
+
+
Trusted Firmware-A Tests - version 2.1
======================================
diff --git a/docs/porting-guide.rst b/docs/porting-guide.rst
index 6a5abb727..9759c9865 100644
--- a/docs/porting-guide.rst
+++ b/docs/porting-guide.rst
@@ -361,20 +361,6 @@ each CPU is specified by the platform defined constant ``PLATFORM_STACK_SIZE``.
Common implementation of this function is provided in
``plat/common/aarch64/platform_mp_stack.S``.
-Function : plat_init_apiakey
-````````````````````````````
-
-::
-
- Argument : void
- Return : uint64_t *
-
-This function returns a pointer to an array with the values used to set the
-``APIAKey{Hi,Lo}_EL1`` registers.
-
-This function is only needed if ARMv8.3 pointer authentication is used by
-building with ``ENABLE_PAUTH=1``.
-
Function : tftf_platform_end()
``````````````````````````````
diff --git a/docs/user-guide.rst b/docs/user-guide.rst
index ef12c90fd..2e6f7bae5 100644
--- a/docs/user-guide.rst
+++ b/docs/user-guide.rst
@@ -401,7 +401,7 @@ TFTF build options
- ``ENABLE_PAUTH``: Boolean option to enable ARMv8.3 Pointer Authentication
(``ARMv8.3-PAuth``) support in the Trusted Firmware-A Test Framework itself.
If enabled, it is needed to use a compiler that supports the option
- ``-msign-return-address``. It defaults to 0.
+ ``-mbranch-protection`` (GCC 9 and later). It defaults to 0.
- ``NEW_TEST_SESSION``: Choose whether a new test session should be started
every time or whether the framework should determine whether a previous
diff --git a/include/common/test_helpers.h b/include/common/test_helpers.h
index 2cf6e83d2..77cf7fd7d 100644
--- a/include/common/test_helpers.h
+++ b/include/common/test_helpers.h
@@ -109,6 +109,15 @@ typedef test_result_t (*test_function_arg_t)(void *arg);
} \
} while (0)
+#define SKIP_TEST_IF_MTE_SUPPORT_LESS_THAN(n) \
+ do { \
+ if (get_armv8_5_mte_support() < (n)) { \
+ tftf_testcase_printf( \
+ "Memory Tagging Extension not supported\n"); \
+ return TEST_RESULT_SKIPPED; \
+ } \
+ } while (0)
+
#define SKIP_TEST_IF_MM_VERSION_LESS_THAN(major, minor) \
do { \
smc_args version_smc = { MM_VERSION_AARCH32 }; \
@@ -155,6 +164,20 @@ typedef test_result_t (*test_function_arg_t)(void *arg);
} \
} while (0)
+#define SKIP_TEST_IF_ARCH_DEBUG_VERSION_LESS_THAN(version) \
+ do { \
+ uint32_t debug_ver = read_id_aa64dfr0_el1() & \
+ (ID_AA64DFR0_DEBUG_MASK << ID_AA64DFR0_DEBUG_SHIFT); \
+ \
+ if ((debug_ver >> ID_AA64DFR0_DEBUG_SHIFT) < version) { \
+ tftf_testcase_printf("Debug version returned %d\n" \
+ "The required version is %d\n", \
+ debug_ver >> ID_AA64DFR0_DEBUG_SHIFT,\
+ version); \
+ return TEST_RESULT_SKIPPED; \
+ } \
+ } while (0)
+
/* Helper macro to verify if system suspend API is supported */
#define is_psci_sys_susp_supported() \
(tftf_get_psci_feature_info(SMC_PSCI_SYSTEM_SUSPEND) \
diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h
index c839d1a6e..1d5cc11dc 100644
--- a/include/lib/aarch64/arch.h
+++ b/include/lib/aarch64/arch.h
@@ -148,6 +148,15 @@
#define ID_AA64DFR0_PMS_LENGTH U(4)
#define ID_AA64DFR0_PMS_MASK ULL(0xf)
+/* ID_AA64DFR0_EL1.DEBUG definitions */
+#define ID_AA64DFR0_DEBUG_SHIFT U(0)
+#define ID_AA64DFR0_DEBUG_LENGTH U(4)
+#define ID_AA64DFR0_DEBUG_MASK ULL(0xf)
+#define ID_AA64DFR0_V8_DEBUG_ARCH_SUPPORTED U(6)
+#define ID_AA64DFR0_V8_DEBUG_ARCH_VHE_SUPPORTED U(7)
+#define ID_AA64DFR0_V8_2_DEBUG_ARCH_SUPPORTED U(8)
+#define ID_AA64DFR0_V8_4_DEBUG_ARCH_SUPPORTED U(9)
+
#define EL_IMPL_NONE ULL(0)
#define EL_IMPL_A64ONLY ULL(1)
#define EL_IMPL_A64_A32 ULL(2)
@@ -213,6 +222,13 @@
#define SSBS_UNAVAILABLE ULL(0) /* No architectural SSBS support */
+#define ID_AA64PFR1_EL1_MTE_SHIFT U(8)
+#define ID_AA64PFR1_EL1_MTE_MASK ULL(0xf)
+
+#define MTE_UNIMPLEMENTED ULL(0)
+#define MTE_IMPLEMENTED_EL0 ULL(1) /* MTE is only implemented at EL0 */
+#define MTE_IMPLEMENTED_ELX ULL(2) /* MTE is implemented at all ELs */
+
/* ID_PFR1_EL1 definitions */
#define ID_PFR1_VIRTEXT_SHIFT U(12)
#define ID_PFR1_VIRTEXT_MASK U(0xf)
@@ -269,6 +285,7 @@
/* SCR definitions */
#define SCR_RES1_BITS ((U(1) << 4) | (U(1) << 5))
+#define SCR_ATA_BIT (U(1) << 26)
#define SCR_FIEN_BIT (U(1) << 21)
#define SCR_API_BIT (U(1) << 17)
#define SCR_APK_BIT (U(1) << 16)
@@ -659,6 +676,31 @@
#define PMCR_EL0_DP_BIT (U(1) << 5)
#define PMCR_EL0_X_BIT (U(1) << 4)
#define PMCR_EL0_D_BIT (U(1) << 3)
+#define PMCR_EL0_E_BIT (U(1) << 0)
+
+/* PMCNTENSET_EL0 definitions */
+#define PMCNTENSET_EL0_C_BIT (U(1) << 31)
+#define PMCNTENSET_EL0_P_BIT(x) (U(1) << x)
+
+/* PMEVTYPER<n>_EL0 definitions */
+#define PMEVTYPER_EL0_P_BIT (U(1) << 31)
+#define PMEVTYPER_EL0_NSK_BIT (U(1) << 29)
+#define PMEVTYPER_EL0_NSH_BIT (U(1) << 27)
+#define PMEVTYPER_EL0_M_BIT (U(1) << 26)
+#define PMEVTYPER_EL0_MT_BIT (U(1) << 25)
+#define PMEVTYPER_EL0_SH_BIT (U(1) << 24)
+#define PMEVTYPER_EL0_EVTCOUNT_BITS U(0x000003FF)
+
+/* PMCCFILTR_EL0 definitions */
+#define PMCCFILTR_EL0_P_BIT (U(1) << 31)
+#define PMCCFILTR_EL0_NSK_BIT (U(1) << 29)
+#define PMCCFILTR_EL0_NSH_BIT (U(1) << 27)
+#define PMCCFILTR_EL0_M_BIT (U(1) << 26)
+#define PMCCFILTR_EL0_MT_BIT (U(1) << 25)
+#define PMCCFILTR_EL0_SH_BIT (U(1) << 24)
+
+/* PMU event counter ID definitions */
+#define PMU_EV_PC_WRITE_RETIRED U(0x000C)
/*******************************************************************************
* Definitions for system register interface to SVE
@@ -869,4 +911,12 @@
******************************************************************************/
#define SSBS S3_3_C4_C2_6
+/*******************************************************************************
+ * Armv8.5 - Memory Tagging Extension Registers
+ ******************************************************************************/
+#define TFSRE0_EL1 S3_0_C5_C6_1
+#define TFSR_EL1 S3_0_C5_C6_0
+#define RGSR_EL1 S3_0_C1_C0_5
+#define GCR_EL1 S3_0_C1_C0_6
+
#endif /* ARCH_H */
diff --git a/include/lib/aarch64/arch_features.h b/include/lib/aarch64/arch_features.h
index 5891c7a71..86c0763b5 100644
--- a/include/lib/aarch64/arch_features.h
+++ b/include/lib/aarch64/arch_features.h
@@ -51,7 +51,7 @@ static inline bool is_armv8_3_pauth_apa_api_present(void)
static inline bool is_armv8_3_pauth_gpa_gpi_present(void)
{
uint64_t mask = (ID_AA64ISAR1_GPI_MASK << ID_AA64ISAR1_GPI_SHIFT) |
- (ID_AA64ISAR1_GPA_MASK << ID_AA64ISAR1_GPA_SHIFT);
+ (ID_AA64ISAR1_GPA_MASK << ID_AA64ISAR1_GPA_SHIFT);
return (read_id_aa64isar1_el1() & mask) != 0U;
}
@@ -62,4 +62,10 @@ static inline bool is_armv8_4_ttst_present(void)
ID_AA64MMFR2_EL1_ST_MASK) == 1U;
}
+static inline unsigned int get_armv8_5_mte_support(void)
+{
+ return ((read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_MTE_SHIFT) &
+ ID_AA64PFR1_EL1_MTE_MASK);
+}
+
#endif /* ARCH_FEATURES_H */
diff --git a/include/lib/aarch64/arch_helpers.h b/include/lib/aarch64/arch_helpers.h
index 151e5be94..d16960af8 100644
--- a/include/lib/aarch64/arch_helpers.h
+++ b/include/lib/aarch64/arch_helpers.h
@@ -395,6 +395,12 @@ DEFINE_SYSREG_RW_FUNCS(mdcr_el2)
DEFINE_SYSREG_RW_FUNCS(mdcr_el3)
DEFINE_SYSREG_RW_FUNCS(hstr_el2)
DEFINE_SYSREG_RW_FUNCS(pmcr_el0)
+DEFINE_SYSREG_RW_FUNCS(pmcntenset_el0)
+DEFINE_SYSREG_READ_FUNC(pmccntr_el0)
+DEFINE_SYSREG_RW_FUNCS(pmccfiltr_el0)
+
+DEFINE_SYSREG_RW_FUNCS(pmevtyper0_el0)
+DEFINE_SYSREG_READ_FUNC(pmevcntr0_el0)
/* GICv3 System Registers */
@@ -463,6 +469,12 @@ DEFINE_RENAME_SYSREG_RW_FUNCS(apdbkeylo_el1, APDBKeyLo_EL1)
DEFINE_RENAME_SYSREG_RW_FUNCS(apgakeyhi_el1, APGAKeyHi_EL1)
DEFINE_RENAME_SYSREG_RW_FUNCS(apgakeylo_el1, APGAKeyLo_EL1)
+/* MTE registers */
+DEFINE_RENAME_SYSREG_RW_FUNCS(tfsre0_el1, TFSRE0_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(tfsr_el1, TFSR_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(rgsr_el1, RGSR_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(gcr_el1, GCR_EL1)
+
#define IS_IN_EL(x) \
(GET_EL(read_CurrentEl()) == MODE_EL##x)
diff --git a/include/lib/extensions/pauth.h b/include/lib/extensions/pauth.h
new file mode 100644
index 000000000..a4da00990
--- /dev/null
+++ b/include/lib/extensions/pauth.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PAUTH_H
+#define PAUTH_H
+
+#include <stdint.h>
+
+#ifdef __aarch64__
+/* Initialize 128-bit ARMv8.3-PAuth key */
+uint128_t init_apkey(void);
+
+/* Program APIAKey_EL1 key and enable ARMv8.3-PAuth */
+void pauth_init_enable(void);
+#endif /* __aarch64__ */
+
+#endif /* PAUTH_H */
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index b30c41ebd..f3536bab7 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -67,9 +67,6 @@ int plat_crash_console_flush(void);
/* Gets a handle for the initialised IO entity */
void plat_get_nvm_handle(uintptr_t *handle);
-/* Initialize and get a pointer to a uint64_t[2] array with a 128-key */
-uint64_t *plat_init_apiakey(void);
-
/*
* Returns the platform topology description array. The size of this
* array should be PLATFORM_NUM_AFFS - PLATFORM_CORE_COUNT + 1.
diff --git a/lib/extensions/pauth/aarch64/pauth.c b/lib/extensions/pauth/aarch64/pauth.c
new file mode 100644
index 000000000..03de468b4
--- /dev/null
+++ b/lib/extensions/pauth/aarch64/pauth.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <cdefs.h>
+#include <stdint.h>
+
+/*
+ * This is only a toy implementation to generate a seemingly random
+ * 128-bit key from sp, x30 and cntpct_el0 values.
+ */
+uint128_t init_apkey(void)
+{
+ uint64_t return_addr = (uint64_t)__builtin_return_address(0U);
+ uint64_t frame_addr = (uint64_t)__builtin_frame_address(0U);
+
+ uint64_t cntpct = read_cntpct_el0();
+
+ uint64_t key_lo = (return_addr << 13) ^ frame_addr ^ cntpct;
+ uint64_t key_hi = (frame_addr << 15) ^ return_addr ^ cntpct;
+
+ return ((uint128_t)(key_hi) << 64) | key_lo;
+}
diff --git a/lib/extensions/pauth/aarch64/pauth_helpers.S b/lib/extensions/pauth/aarch64/pauth_helpers.S
new file mode 100644
index 000000000..e15cac90f
--- /dev/null
+++ b/lib/extensions/pauth/aarch64/pauth_helpers.S
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+
+ .global pauth_init_enable
+
+/* -----------------------------------------------------------
+ * Program APIAKey_EL1 key and enable Pointer Authentication
+ * of instruction addresses in the current translation regime
+ * for the calling CPU.
+ * -----------------------------------------------------------
+ */
+func pauth_init_enable
+ stp x29, x30, [sp, #-16]!
+
+ /* Initialize platform key */
+ bl init_apkey
+
+ /*
+ * Program instruction key A used by
+ * the Trusted Firmware Test Framework
+ */
+ msr APIAKeyLo_EL1, x0
+ msr APIAKeyHi_EL1, x1
+
+ /* Detect Current Exception level */
+ mrs x0, CurrentEL
+ cmp x0, #(MODE_EL1 << MODE_EL_SHIFT)
+ b.eq enable_el1
+
+ /* Enable EL2 pointer authentication */
+ mrs x0, sctlr_el2
+ orr x0, x0, #SCTLR_EnIA_BIT
+ msr sctlr_el2, x0
+ b enable_exit
+
+ /* Enable EL1 pointer authentication */
+enable_el1:
+ mrs x0, sctlr_el1
+ orr x0, x0, #SCTLR_EnIA_BIT
+ msr sctlr_el1, x0
+
+enable_exit:
+ isb
+
+ ldp x29, x30, [sp], #16
+ ret
+endfunc pauth_init_enable
diff --git a/lib/power_management/hotplug/hotplug.c b/lib/power_management/hotplug/hotplug.c
index 37bfc06bf..76fa287b9 100644
--- a/lib/power_management/hotplug/hotplug.c
+++ b/lib/power_management/hotplug/hotplug.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,6 +11,7 @@
#include <drivers/arm/arm_gic.h>
#include <drivers/console.h>
#include <irq.h>
+#include <pauth.h>
#include <platform.h>
#include <platform_def.h>
#include <power_management.h>
@@ -288,6 +289,16 @@ void __dead2 tftf_warm_boot_main(void)
{
/* Initialise the CPU */
tftf_arch_setup();
+
+#if ENABLE_PAUTH
+ /*
+ * Program APIAKey_EL1 key and enable ARMv8.3-PAuth here as this
+ * function doesn't return, and RETAA instuction won't be executed,
+ * what would cause translation fault otherwise.
+ */
+ pauth_init_enable();
+#endif /* ENABLE_PAUTH */
+
arm_gic_setup_local();
/* Enable the SGI used by the timer management framework */
diff --git a/lib/power_management/suspend/aarch64/asm_tftf_suspend.S b/lib/power_management/suspend/aarch64/asm_tftf_suspend.S
index 692baded6..09950b5c0 100644
--- a/lib/power_management/suspend/aarch64/asm_tftf_suspend.S
+++ b/lib/power_management/suspend/aarch64/asm_tftf_suspend.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -54,6 +54,11 @@ func __tftf_suspend
endfunc __tftf_suspend
func __tftf_save_arch_context
+#if ENABLE_PAUTH
+ mrs x1, APIAKeyLo_EL1
+ mrs x2, APIAKeyHi_EL1
+ stp x1, x2, [x0, #SUSPEND_CTX_APIAKEY_OFFSET]
+#endif
JUMP_EL1_OR_EL2 x1, 1f, 2f, dead
1: mrs x1, mair_el1
mrs x2, cpacr_el1
@@ -61,9 +66,9 @@ func __tftf_save_arch_context
mrs x4, tcr_el1
mrs x5, vbar_el1
mrs x6, sctlr_el1
- stp x1, x2, [x0]
- stp x3, x4, [x0, #16]
- stp x5, x6, [x0, #32]
+ stp x1, x2, [x0, #SUSPEND_CTX_MAIR_OFFSET]
+ stp x3, x4, [x0, #SUSPEND_CTX_TTBR0_OFFSET]
+ stp x5, x6, [x0, #SUSPEND_CTX_VBAR_OFFSET]
ret
2: mrs x1, mair_el2
@@ -72,9 +77,9 @@ func __tftf_save_arch_context
mrs x4, tcr_el2
mrs x5, vbar_el2
mrs x6, sctlr_el2
- stp x1, x2, [x0]
- stp x3, x4, [x0, #16]
- stp x5, x6, [x0, #32]
+ stp x1, x2, [x0, #SUSPEND_CTX_MAIR_OFFSET]
+ stp x3, x4, [x0, #SUSPEND_CTX_TTBR0_OFFSET]
+ stp x5, x6, [x0, #SUSPEND_CTX_VBAR_OFFSET]
ret
endfunc __tftf_save_arch_context
@@ -86,9 +91,9 @@ func __tftf_cpu_resume_ep
JUMP_EL1_OR_EL2 x1, 1f, 2f, dead
1: /* Invalidate local tlb entries before turning on MMU */
tlbi vmalle1
- ldp x1, x2, [x0]
- ldp x3, x4, [x0, #16]
- ldp x5, x6, [x0, #32]
+ ldp x1, x2, [x0, #SUSPEND_CTX_MAIR_OFFSET]
+ ldp x3, x4, [x0, #SUSPEND_CTX_TTBR0_OFFSET]
+ ldp x5, x6, [x0, #SUSPEND_CTX_VBAR_OFFSET]
msr mair_el1, x1
msr cpacr_el1, x2
msr ttbr0_el1, x3
@@ -101,13 +106,13 @@ func __tftf_cpu_resume_ep
msr sctlr_el1, x6
/* Ensure the MMU enable takes effect immediately */
isb
- b restore_callee_regs
+ b restore_callee_regs
/* Invalidate local tlb entries before turning on MMU */
2: tlbi alle2
- ldp x1, x2, [x0]
- ldp x3, x4, [x0, #16]
- ldp x5, x6, [x0, #32]
+ ldp x1, x2, [x0, #SUSPEND_CTX_MAIR_OFFSET]
+ ldp x3, x4, [x0, #SUSPEND_CTX_TTBR0_OFFSET]
+ ldp x5, x6, [x0, #SUSPEND_CTX_VBAR_OFFSET]
msr mair_el2, x1
msr hcr_el2, x2
msr ttbr0_el2, x3
@@ -122,6 +127,11 @@ func __tftf_cpu_resume_ep
isb
restore_callee_regs:
+#if ENABLE_PAUTH
+ ldp x1, x2, [x0, #SUSPEND_CTX_APIAKEY_OFFSET]
+ msr APIAKeyLo_EL1, x1
+ msr APIAKeyHi_EL1, x2
+#endif
ldr x2, [x0, #SUSPEND_CTX_SP_OFFSET]
mov sp, x2
ldr w1, [x0, #SUSPEND_CTX_SAVE_SYSTEM_CTX_OFFSET]
diff --git a/lib/power_management/suspend/suspend_private.h b/lib/power_management/suspend/suspend_private.h
index b67bbab0b..bc2f3a600 100644
--- a/lib/power_management/suspend/suspend_private.h
+++ b/lib/power_management/suspend/suspend_private.h
@@ -9,11 +9,21 @@
/*
* Number of system registers we need to save/restore across a CPU suspend:
- * MAIR, CPACR_EL1/HCR_EL2, TTBR0, TCR, VBAR and SCTLR.
+ * MAIR, CPACR_EL1/HCR_EL2, TTBR0, TCR, VBAR, SCTLR,
+ * APIAKeyLo_EL1 and APIAKeyHi_EL1 (if enabled).
*/
+#if ENABLE_PAUTH
+#define NR_CTX_REGS 8
+#else
#define NR_CTX_REGS 6
+#endif
/* Offsets of the fields in the context structure. Needed by asm code. */
+#define SUSPEND_CTX_MAIR_OFFSET 0
+#define SUSPEND_CTX_TTBR0_OFFSET 16
+#define SUSPEND_CTX_VBAR_OFFSET 32
+#define SUSPEND_CTX_APIAKEY_OFFSET 48
+
#define SUSPEND_CTX_SP_OFFSET (8 * NR_CTX_REGS)
#define SUSPEND_CTX_SAVE_SYSTEM_CTX_OFFSET (SUSPEND_CTX_SP_OFFSET + 8)
diff --git a/plat/arm/fvp/platform.mk b/plat/arm/fvp/platform.mk
index 9fb84c276..c014d6de7 100644
--- a/plat/arm/fvp/platform.mk
+++ b/plat/arm/fvp/platform.mk
@@ -23,8 +23,4 @@ CACTUS_SOURCES += plat/arm/fvp/${ARCH}/plat_helpers.S
# Firmware update is implemented on FVP.
FIRMWARE_UPDATE := 1
-ifeq (${ARCH},aarch64)
-PLAT_SOURCES += plat/common/aarch64/pauth.c
-endif
-
include plat/arm/common/arm_common.mk
diff --git a/tftf/framework/framework.mk b/tftf/framework/framework.mk
index 00bb84aa9..34601c2d6 100644
--- a/tftf/framework/framework.mk
+++ b/tftf/framework/framework.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2018, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2019, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -73,6 +73,13 @@ FRAMEWORK_SOURCES += \
FRAMEWORK_SOURCES += ${COMPILER_RT_SRCS}
+ifeq (${ARCH},aarch64)
+# ARMv8.3 Pointer Authentication support files
+FRAMEWORK_SOURCES += \
+ lib/extensions/pauth/aarch64/pauth.c \
+ lib/extensions/pauth/aarch64/pauth_helpers.S
+endif
+
TFTF_LINKERFILE := tftf/framework/tftf.ld.S
diff --git a/tftf/framework/main.c b/tftf/framework/main.c
index e84e45070..a2e84b7ea 100644
--- a/tftf/framework/main.c
+++ b/tftf/framework/main.c
@@ -12,6 +12,7 @@
#include <irq.h>
#include <mmio.h>
#include <nvm.h>
+#include <pauth.h>
#include <plat_topology.h>
#include <platform.h>
#include <platform_def.h>
@@ -528,19 +529,12 @@ void __dead2 tftf_cold_boot_main(void)
#if ENABLE_PAUTH
assert(is_armv8_3_pauth_apa_api_present());
- uint64_t *apiakey = plat_init_apiakey();
-
- write_apiakeylo_el1(apiakey[0]);
- write_apiakeyhi_el1(apiakey[1]);
-
- if (IS_IN_EL2()) {
- write_sctlr_el2(read_sctlr_el2() | SCTLR_EnIA_BIT);
- } else {
- assert(IS_IN_EL1());
- write_sctlr_el1(read_sctlr_el1() | SCTLR_EnIA_BIT);
- }
-
- isb();
+ /*
+ * Program APIAKey_EL1 key and enable ARMv8.3-PAuth here as this
+ * function doesn't return, and RETAA instuction won't be executed,
+ * what would cause translation fault otherwise.
+ */
+ pauth_init_enable();
#endif /* ENABLE_PAUTH */
tftf_platform_setup();
diff --git a/tftf/tests/extensions/mte/test_mte.c b/tftf/tests/extensions/mte/test_mte.c
new file mode 100644
index 000000000..13da667d2
--- /dev/null
+++ b/tftf/tests/extensions/mte/test_mte.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <tftf.h>
+#include <tftf_lib.h>
+#include <tsp.h>
+#include <test_helpers.h>
+
+test_result_t test_mte_instructions(void)
+{
+ SKIP_TEST_IF_AARCH32();
+#ifdef AARCH64
+ SKIP_TEST_IF_MTE_SUPPORT_LESS_THAN(MTE_IMPLEMENTED_EL0);
+
+ /* irg */
+ __asm__ volatile (".inst 0xD29BD5A9");
+ __asm__ volatile (".inst 0x9ADF1129");
+ /* addg */
+ __asm__ volatile (".inst 0x91800129");
+ /* subg */
+ __asm__ volatile (".inst 0xD1800129");
+
+ return TEST_RESULT_SUCCESS;
+#endif /* AARCH64 */
+}
+
+test_result_t test_mte_leakage(void)
+{
+ SKIP_TEST_IF_AARCH32();
+#ifdef AARCH64
+ smc_args tsp_svc_params;
+ int gcr_el1;
+
+ SKIP_TEST_IF_MTE_SUPPORT_LESS_THAN(MTE_IMPLEMENTED_ELX);
+ SKIP_TEST_IF_TSP_NOT_PRESENT();
+
+ /* We only test gcr_el1 as writes to other MTE registers are ignored */
+ write_gcr_el1(0xdd);
+
+ /* Standard SMC to ADD two numbers */
+ tsp_svc_params.fid = TSP_STD_FID(TSP_ADD);
+ tsp_svc_params.arg1 = 4;
+ tsp_svc_params.arg2 = 6;
+ tftf_smc(&tsp_svc_params);
+
+ gcr_el1 = read_gcr_el1();
+ if (gcr_el1 != 0xdd) {
+ printf("gcr_el1 has changed to %d\n", gcr_el1);
+ return TEST_RESULT_FAIL;
+ }
+
+ return TEST_RESULT_SUCCESS;
+#endif /* AARCH64 */
+}
diff --git a/tftf/tests/extensions/pauth/test_pauth.c b/tftf/tests/extensions/pauth/test_pauth.c
new file mode 100644
index 000000000..30b78ef19
--- /dev/null
+++ b/tftf/tests/extensions/pauth/test_pauth.c
@@ -0,0 +1,267 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <pauth.h>
+#include <psci.h>
+#include <smccc.h>
+#include <test_helpers.h>
+#include <tftf_lib.h>
+#include <tftf.h>
+#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_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_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_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_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
+ * EL3 and crash.
+ */
+test_result_t test_pauth_reg_access(void)
+{
+ SKIP_TEST_IF_AARCH32();
+#ifdef __aarch64__
+ SKIP_TEST_IF_PAUTH_NOT_SUPPORTED();
+ read_pauth_keys();
+ return TEST_RESULT_SUCCESS;
+#endif /* __aarch64__ */
+}
+
+/*
+ * Makes a call to PSCI version, and checks that the EL3 pauth keys are not
+ * leaked when it returns
+ */
+test_result_t test_pauth_leakage(void)
+{
+ SKIP_TEST_IF_AARCH32();
+#ifdef __aarch64__
+ SKIP_TEST_IF_PAUTH_NOT_SUPPORTED();
+ set_store_pauth_keys();
+
+ tftf_get_psci_version();
+
+ read_pauth_keys();
+
+ return compare_pauth_keys();
+#endif /* __aarch64__ */
+}
+
+/* Test execution of ARMv8.3-PAuth instructions */
+test_result_t test_pauth_instructions(void)
+{
+ SKIP_TEST_IF_AARCH32();
+#ifdef __aarch64__
+ SKIP_TEST_IF_PAUTH_NOT_SUPPORTED();
+
+#if ARM_ARCH_AT_LEAST(8, 3)
+ /* Pointer authentication instructions */
+ __asm__ volatile (
+ "paciasp\n"
+ "autiasp\n"
+ "paciasp\n"
+ "xpaclri"
+ );
+ return TEST_RESULT_SUCCESS;
+#else
+ tftf_testcase_printf("Pointer Authentication instructions "
+ "are not supported on ARMv%u.%u\n",
+ ARM_ARCH_MAJOR, ARM_ARCH_MINOR);
+ return TEST_RESULT_SKIPPED;
+#endif /* ARM_ARCH_AT_LEAST(8, 3) */
+
+#endif /* __aarch64__ */
+}
+
+/*
+ * Makes a call to TSP ADD, and checks that the checks that the Secure World
+ * pauth keys are not leaked
+ */
+test_result_t test_pauth_leakage_tsp(void)
+{
+ SKIP_TEST_IF_AARCH32();
+#ifdef __aarch64__
+ smc_args tsp_svc_params;
+ smc_ret_values tsp_result = {0};
+
+ SKIP_TEST_IF_PAUTH_NOT_SUPPORTED();
+ SKIP_TEST_IF_TSP_NOT_PRESENT();
+
+ set_store_pauth_keys();
+
+ /* Standard SMC to ADD two numbers */
+ tsp_svc_params.fid = TSP_STD_FID(TSP_ADD);
+ tsp_svc_params.arg1 = 4;
+ tsp_svc_params.arg2 = 6;
+ tsp_result = tftf_smc(&tsp_svc_params);
+
+ /*
+ * Check the result of the addition-TSP_ADD will add
+ * the arguments to themselves and return
+ */
+ if (tsp_result.ret0 != 0 || tsp_result.ret1 != 8 ||
+ tsp_result.ret2 != 12) {
+ tftf_testcase_printf("TSP add returned wrong result: "
+ "got %d %d %d expected: 0 8 12\n",
+ (unsigned int)tsp_result.ret0,
+ (unsigned int)tsp_result.ret1,
+ (unsigned int)tsp_result.ret2);
+ return TEST_RESULT_FAIL;
+ }
+
+ read_pauth_keys();
+
+ return compare_pauth_keys();
+#endif /* __aarch64__ */
+}
diff --git a/tftf/tests/extensions/ptrauth/test_ptrauth.c b/tftf/tests/extensions/ptrauth/test_ptrauth.c
deleted file mode 100644
index 564c56d9f..000000000
--- a/tftf/tests/extensions/ptrauth/test_ptrauth.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <psci.h>
-#include <smccc.h>
-#include <test_helpers.h>
-#include <tftf_lib.h>
-#include <tftf.h>
-#include <tsp.h>
-#include <string.h>
-
-/* The length of the array used to hold the pauth keys */
-#define LENGTH_KEYS 10
-
-#ifndef AARCH32
-static void read_pauth_keys(uint64_t *pauth_keys, unsigned int len)
-{
- assert(len >= LENGTH_KEYS);
-
- memset(pauth_keys, 0, len * sizeof(uint64_t));
-
- if (is_armv8_3_pauth_apa_api_present()) {
- /* read instruction keys a and b (both 128 bit) */
- pauth_keys[0] = read_apiakeylo_el1();
- pauth_keys[1] = read_apiakeyhi_el1();
-
- pauth_keys[2] = read_apibkeylo_el1();
- pauth_keys[3] = read_apibkeyhi_el1();
-
- /* read data keys a and b (both 128 bit) */
- pauth_keys[4] = read_apdakeylo_el1();
- pauth_keys[5] = read_apdakeyhi_el1();
-
- pauth_keys[6] = read_apdbkeylo_el1();
- pauth_keys[7] = read_apdbkeyhi_el1();
- }
-
- if (is_armv8_3_pauth_gpa_gpi_present()) {
- /* read generic key */
- pauth_keys[8] = read_apgakeylo_el1();
- pauth_keys[9] = read_apgakeyhi_el1();
- }
-
-}
-#endif
-
-/*
- * 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.
- */
-test_result_t test_pauth_reg_access(void)
-{
- SKIP_TEST_IF_AARCH32();
-#ifndef AARCH32
- uint64_t pauth_keys[LENGTH_KEYS];
- SKIP_TEST_IF_PAUTH_NOT_SUPPORTED();
- read_pauth_keys(pauth_keys, LENGTH_KEYS);
- return TEST_RESULT_SUCCESS;
-#endif
-}
-
-/*
- * Makes a call to psci version, and checks that the EL3 pauth keys are not
- * leaked when it returns
- */
-#if (__GNUC__ > 7 || (__GNUC__ == 7 && __GNUC_MINOR__ > 0)) && AARCH64
-__attribute__((target("sign-return-address=all")))
-#endif
-test_result_t test_pauth_leakage(void)
-{
- SKIP_TEST_IF_AARCH32();
-#ifndef AARCH32
- uint64_t pauth_keys_before[LENGTH_KEYS];
- uint64_t pauth_keys_after[LENGTH_KEYS];
- SKIP_TEST_IF_PAUTH_NOT_SUPPORTED();
-
- read_pauth_keys(pauth_keys_before, LENGTH_KEYS);
-
- tftf_get_psci_version();
-
- read_pauth_keys(pauth_keys_after, LENGTH_KEYS);
-
- if (memcmp(pauth_keys_before, pauth_keys_after,
- LENGTH_KEYS * sizeof(uint64_t)) != 0)
- return TEST_RESULT_FAIL;
- return TEST_RESULT_SUCCESS;
-#endif
-}
-
-/* Uses the pauth instructions, this checks the enable PAUTH bit has been set */
-test_result_t test_pauth_instructions(void)
-{
- SKIP_TEST_IF_AARCH32();
-#ifndef AARCH32
- SKIP_TEST_IF_PAUTH_NOT_SUPPORTED();
- /*
- * Pointer authentication instructions (explicit encoding for compilers
- * that do not recognize these instructions)
- */
- /* paciasp */
- __asm__ volatile (".inst 0xD503233F");
- /* autiasp */
- __asm__ volatile (".inst 0xD50323BF");
- /* paciasp */
- __asm__ volatile (".inst 0xD503233F");
- /* xpaclri */
- __asm__ volatile (".inst 0xD50320FF");
- return TEST_RESULT_SUCCESS;
-#endif
-}
-
-/*
- * Makes a call to TSP ADD, and checks that the checks that the Secure World
- * pauth keys are not leaked
- */
-#if (__GNUC__ > 7 || (__GNUC__ == 7 && __GNUC_MINOR__ > 0)) && AARCH64
-__attribute__((target("sign-return-address=all")))
-#endif
-test_result_t test_pauth_leakage_tsp(void)
-{
- SKIP_TEST_IF_AARCH32();
-#ifndef AARCH32
- smc_args tsp_svc_params;
- smc_ret_values tsp_result = {0};
- uint64_t pauth_keys_before[LENGTH_KEYS];
- uint64_t pauth_keys_after[LENGTH_KEYS];
-
- SKIP_TEST_IF_PAUTH_NOT_SUPPORTED();
- SKIP_TEST_IF_TSP_NOT_PRESENT();
-
- read_pauth_keys(pauth_keys_before, LENGTH_KEYS);
-
- /* Standard SMC to ADD two numbers */
- tsp_svc_params.fid = TSP_STD_FID(TSP_ADD);
- tsp_svc_params.arg1 = 4;
- tsp_svc_params.arg2 = 6;
- tsp_result = tftf_smc(&tsp_svc_params);
-
- /*
- * Check the result of the addition-TSP_ADD will add
- * the arguments to themselves and return
- */
- if (tsp_result.ret0 != 0 || tsp_result.ret1 != 8 ||
- tsp_result.ret2 != 12) {
- tftf_testcase_printf("TSP add returned wrong result:"
- "got %d %d %d expected: 0 8 12\n",
- (unsigned int)tsp_result.ret0,
- (unsigned int)tsp_result.ret1,
- (unsigned int)tsp_result.ret2);
-
- return TEST_RESULT_FAIL;
- }
- read_pauth_keys(pauth_keys_after, LENGTH_KEYS);
-
- if (memcmp(pauth_keys_before, pauth_keys_after,
- LENGTH_KEYS * sizeof(uint64_t)) != 0)
- return TEST_RESULT_FAIL;
- return TEST_RESULT_SUCCESS;
-#endif
-}
diff --git a/tftf/tests/misc_tests/test_pmu_leakage.c b/tftf/tests/misc_tests/test_pmu_leakage.c
new file mode 100644
index 000000000..09f4d510a
--- /dev/null
+++ b/tftf/tests/misc_tests/test_pmu_leakage.c
@@ -0,0 +1,393 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * This file contains tests that try to leak information from the secure world
+ * to the non-secure world (EL2) by using the PMU counters.
+ *
+ * The tests assume that the PMU (PMUv3) is implemented on the target, since
+ * TF-A performs initialization of the PMU and guards against PMU counter
+ * leakage.
+ *
+ * The non-secure world can use system registers to configure the PMU such that
+ * it increments counters in the secure world. Depending on the implemented
+ * features, the secure world can prohibit counting via the following:
+ * -v8.2 Debug not implemented:
+ * |-- Prohibit general event counters and the cycle counter:
+ * MDCR_EL3.SPME == 0 && !ExternalSecureNoninvasiveDebugEnabled()
+ * Since ExternalSecureNoninvasiveDebugEnabled() is a hardware
+ * line, it is not available on FVP and will therefore cause the
+ * tests to fail.
+ * The only other way is to disable the PMCR_EL0.E bit. This will
+ * disable counting altogether, but since this fix is not desired
+ * in TF-A, the tests have to be skipped if v8.2 Debug is not
+ * implemented.
+ *
+ * -v8.2 Debug implemented:
+ * |-- Prohibit general event counters: MDCR_EL3.SPME == 0. This bit
+ * resets to 0, so by default general events should not be counted
+ * in the secure world.
+ * |-- Prohibit cycle counter: MDCR_EL3.SPME == 0 && PMCR_EL0.DP == 1.
+ * This counter is only affected by MDCR_EL3.SPME if the
+ * PMCR_EL0.DP bit is set.
+ *
+ * -v8.5 implemented:
+ * |-- Prohibit general event counters: as in v8.2 Debug.
+ * |-- Prohibit cycle counter: MDCR_EL3.SCCD == 1
+ */
+
+#include <drivers/arm/arm_gic.h>
+#include <irq.h>
+#include <platform.h>
+#include <power_management.h>
+#include <sgi.h>
+#include <string.h>
+#include <test_helpers.h>
+
+#ifdef AARCH64
+#define ITERATIONS_CNT 1000
+
+/*
+ * A maximum of +10% deviation in event counts is tolerated.
+ * This is useful for testing on real hardware where event counts are usually
+ * not the same between runs. The large iteration count should cause the
+ * average event count to converge to values very close to baseline when the
+ * secure world successfully prohibits PMU counters from incrementing.
+ */
+#define ALLOWED_DEVIATION 10
+
+/*
+ * An invalid SMC function number.
+ * Used to establish a base value for PMU counters on each test.
+ */
+#define INVALID_FN 0x666
+
+struct pmu_event_info {
+ unsigned long long min;
+ unsigned long long max;
+ unsigned long long avg;
+};
+
+static inline void configure_pmu_cntr0(const uint32_t event)
+{
+ /*
+ * Disabling the P bit tells the counter to increment at EL1.
+ * Setting the NSK bit to be different from the P bit further tells the
+ * counter NOT to increment at non-secure EL1. Combined with the P bit,
+ * the effect is to tell the counter to increment at secure EL1.
+ * Setting the M bit to be equal to the P bit tells the counter to
+ * increment at EL3.
+ * Disabling the NSH bit tells the counter NOT to increment at
+ * non-secure EL2.
+ * Setting the SH bit to be different to the NSH bit tells the counter
+ * to increment at secure EL2.
+ * The counter therefore is told to count only at secure EL1, secure EL2
+ * and EL3. This is to ensure maximum accuracy of the results, since we
+ * are only interested if the secure world is leaking PMU counters.
+ */
+ write_pmevtyper0_el0(
+ (read_pmevtyper0_el0() | PMEVTYPER_EL0_NSK_BIT |
+ PMEVTYPER_EL0_SH_BIT) &
+ ~(PMEVTYPER_EL0_P_BIT | PMEVTYPER_EL0_NSH_BIT |
+ PMEVTYPER_EL0_M_BIT));
+
+ /*
+ * Write to the EVTCOUNT bits to tell the counter which event to
+ * monitor.
+ */
+ write_pmevtyper0_el0(
+ (read_pmevtyper0_el0() & ~PMEVTYPER_EL0_EVTCOUNT_BITS) | event);
+
+ /* Setting the P[n] bit enables counter n */
+ write_pmcntenset_el0(
+ read_pmcntenset_el0() | PMCNTENSET_EL0_P_BIT(0));
+}
+
+static inline void configure_pmu_cycle_cntr(void)
+{
+ /*
+ * Disabling the P bit tells the counter to increment at EL1.
+ * Setting the NSK bit to be different from the P bit further tells the
+ * counter NOT to increment at non-secure EL1. Combined with the P bit,
+ * the effect is to tell the counter to increment at secure EL1.
+ * Setting the M bit to be equal to the P bit tells the counter to
+ * increment at EL3.
+ * Disabling the NSH bit tells the counter NOT to increment at
+ * non-secure EL2.
+ * Setting the SH bit to be different to the NSH bit tells the counter
+ * to increment at secure EL2.
+ * The counter therefore is told to count only at secure EL1, secure EL2
+ * and EL3. This is to ensure maximum accuracy of the results, since we
+ * are only interested if the secure world is leaking PMU counters.
+ */
+ write_pmccfiltr_el0(
+ (read_pmccfiltr_el0() | PMCCFILTR_EL0_NSK_BIT |
+ PMCCFILTR_EL0_SH_BIT) &
+ ~(PMCCFILTR_EL0_P_BIT | PMCCFILTR_EL0_NSH_BIT |
+ PMCCFILTR_EL0_M_BIT));
+
+ /* Setting the C bit enables the cycle counter in the PMU */
+ write_pmcntenset_el0(
+ read_pmcntenset_el0() | PMCNTENSET_EL0_C_BIT);
+
+ /*
+ * Disabling the DP bit makes the cycle counter increment where
+ * prohibited by MDCR_EL3.SPME. If higher execution levels don't save
+ * and restore PMCR_EL0, then PMU information will be leaked.
+ */
+ write_pmcr_el0(read_pmcr_el0() & ~PMCR_EL0_DP_BIT);
+}
+
+static inline void pmu_enable_counting(void)
+{
+ /*
+ * Setting the E bit gives [fine-grained] control to the PMCNTENSET_EL0
+ * register, which controls which counters can increment.
+ */
+ write_pmcr_el0(read_pmcr_el0() | PMCR_EL0_E_BIT);
+}
+
+static unsigned long long profile_invalid_smc(u_register_t (*read_cntr_f)(void))
+{
+ unsigned long long evt_cnt;
+ smc_args args = { INVALID_FN };
+
+ evt_cnt = (*read_cntr_f)();
+ tftf_smc(&args);
+ evt_cnt = (*read_cntr_f)() - evt_cnt;
+
+ return evt_cnt;
+}
+
+static unsigned long long profile_cpu_suspend(u_register_t (*read_cntr_f)(void))
+{
+ unsigned long long evt_cnt;
+ unsigned int power_state;
+ unsigned int stateid;
+
+ tftf_psci_make_composite_state_id(MPIDR_AFFLVL0,
+ PSTATE_TYPE_STANDBY, &stateid);
+ power_state = tftf_make_psci_pstate(MPIDR_AFFLVL0,
+ PSTATE_TYPE_STANDBY, stateid);
+
+ tftf_irq_enable(IRQ_NS_SGI_0, GIC_HIGHEST_NS_PRIORITY);
+
+ /*
+ * Mask IRQ to prevent the interrupt handler being invoked
+ * and clearing the interrupt. A pending interrupt will cause this
+ * CPU to wake-up from suspend.
+ */
+ disable_irq();
+
+ /* Configure an SGI to wake-up from suspend */
+ tftf_send_sgi(IRQ_NS_SGI_0,
+ platform_get_core_pos(read_mpidr_el1() & MPID_MASK));
+
+ evt_cnt = (*read_cntr_f)();
+ tftf_cpu_suspend(power_state);
+ evt_cnt = (*read_cntr_f)() - evt_cnt;
+
+ /* Unmask the IRQ to let the interrupt handler to execute */
+ enable_irq();
+ isb();
+
+ tftf_irq_disable(IRQ_NS_SGI_0);
+
+ return evt_cnt;
+}
+
+static unsigned long long profile_fast_smc_add(u_register_t (*read_cntr_f)(void))
+{
+ unsigned long long evt_cnt;
+ smc_args args = { TSP_FAST_FID(TSP_ADD), 4, 6 };
+
+ evt_cnt = (*read_cntr_f)();
+ tftf_smc(&args);
+ evt_cnt = (*read_cntr_f)() - evt_cnt;
+
+ return evt_cnt;
+}
+
+static void measure_event(u_register_t (*read_cntr_func)(void),
+ unsigned long long (*profile_func)(u_register_t (*read_cntr_f)(void)),
+ struct pmu_event_info *info)
+{
+ unsigned long long evt_cnt;
+ unsigned long long min_cnt;
+ unsigned long long max_cnt;
+ unsigned long long avg_cnt;
+ unsigned long long cnt_sum = 0;
+
+ min_cnt = UINT64_MAX;
+ max_cnt = 0;
+
+ for (unsigned int i = 0; i < ITERATIONS_CNT; ++i) {
+ evt_cnt = (*profile_func)(read_cntr_func);
+
+ min_cnt = MIN(min_cnt, evt_cnt);
+ max_cnt = MAX(max_cnt, evt_cnt);
+
+ cnt_sum += evt_cnt;
+
+ tftf_irq_disable(IRQ_NS_SGI_0);
+ }
+
+ avg_cnt = cnt_sum / ITERATIONS_CNT;
+
+ info->avg = avg_cnt;
+ info->min = min_cnt;
+ info->max = max_cnt;
+
+ tftf_testcase_printf(
+ "Average count: %llu (ranging from %llu to %llu)\n",
+ avg_cnt,
+ min_cnt,
+ max_cnt);
+}
+
+/*
+ * Checks that when requesting an SMC call after getting a baseline PMU event
+ * count the number of PMU events counted is either not greater than the
+ * baseline or it has increased by no more than ALLOWED_DEVIATION%. The first
+ * comparison is required because of underflow on unsigned types.
+ * This is used to determine if PMU timing information has been leaked from the
+ * secure world.
+ */
+static bool results_within_allowed_margin(unsigned long long baseline_cnt,
+ unsigned long long smc_cnt)
+{
+ return (smc_cnt <= baseline_cnt) ||
+ (smc_cnt - baseline_cnt <= baseline_cnt / ALLOWED_DEVIATION);
+}
+
+/*
+ * Measure the number of retired writes to the PC in the PSCI_SUSPEND SMC.
+ * This test only succeeds if no useful information about the PMU counters has
+ * been leaked.
+ */
+test_result_t smc_psci_suspend_pc_write_retired(void)
+{
+ struct pmu_event_info baseline, cpu_suspend;
+
+ SKIP_TEST_IF_ARCH_DEBUG_VERSION_LESS_THAN(
+ ID_AA64DFR0_V8_2_DEBUG_ARCH_SUPPORTED);
+
+ configure_pmu_cntr0(PMU_EV_PC_WRITE_RETIRED);
+ pmu_enable_counting();
+
+ tftf_testcase_printf("Getting baseline event count:\n");
+ measure_event(read_pmevcntr0_el0, profile_invalid_smc, &baseline);
+ tftf_testcase_printf("Profiling PSCI_SUSPEND_PC:\n");
+ measure_event(read_pmevcntr0_el0, profile_cpu_suspend, &cpu_suspend);
+
+ if (!results_within_allowed_margin(baseline.avg, cpu_suspend.avg))
+ return TEST_RESULT_FAIL;
+ return TEST_RESULT_SUCCESS;
+}
+
+/*
+ * Measure the CPU cycles count of the PSCI_SUSPEND SMC.
+ * This test only succeeds if no useful information about the PMU counters has
+ * been leaked.
+ */
+test_result_t smc_psci_suspend_cycles(void)
+{
+ struct pmu_event_info baseline, cpu_suspend;
+
+ SKIP_TEST_IF_ARCH_DEBUG_VERSION_LESS_THAN(
+ ID_AA64DFR0_V8_2_DEBUG_ARCH_SUPPORTED);
+
+ configure_pmu_cycle_cntr();
+ pmu_enable_counting();
+
+ tftf_testcase_printf("Getting baseline event count:\n");
+ measure_event(read_pmccntr_el0, profile_invalid_smc, &baseline);
+ tftf_testcase_printf("Profiling PSCI_SUSPEND_PC:\n");
+ measure_event(read_pmccntr_el0, profile_cpu_suspend, &cpu_suspend);
+
+ if (!results_within_allowed_margin(baseline.avg, cpu_suspend.avg))
+ return TEST_RESULT_FAIL;
+ return TEST_RESULT_SUCCESS;
+}
+
+/*
+ * Measure the number of retired writes to the PC in the fast add SMC.
+ * This test only succeeds if no useful information about the PMU counters has
+ * been leaked.
+ */
+test_result_t fast_smc_add_pc_write_retired(void)
+{
+ struct pmu_event_info baseline, fast_smc_add;
+
+ SKIP_TEST_IF_ARCH_DEBUG_VERSION_LESS_THAN(
+ ID_AA64DFR0_V8_2_DEBUG_ARCH_SUPPORTED);
+
+ SKIP_TEST_IF_TSP_NOT_PRESENT();
+
+ configure_pmu_cntr0(PMU_EV_PC_WRITE_RETIRED);
+ pmu_enable_counting();
+
+ tftf_testcase_printf("Getting baseline event count:\n");
+ measure_event(read_pmevcntr0_el0, profile_invalid_smc, &baseline);
+ tftf_testcase_printf("Profiling Fast Add SMC:\n");
+ measure_event(read_pmevcntr0_el0, profile_fast_smc_add, &fast_smc_add);
+
+ if (!results_within_allowed_margin(baseline.avg, fast_smc_add.avg))
+ return TEST_RESULT_FAIL;
+ return TEST_RESULT_SUCCESS;
+}
+
+/*
+ * Measure the CPU cycles count of the fast add SMC.
+ * This test only succeeds if no useful information about the PMU counters has
+ * been leaked.
+ */
+test_result_t fast_smc_add_cycles(void)
+{
+ struct pmu_event_info baseline, fast_smc_add;
+
+ SKIP_TEST_IF_ARCH_DEBUG_VERSION_LESS_THAN(
+ ID_AA64DFR0_V8_2_DEBUG_ARCH_SUPPORTED);
+
+ SKIP_TEST_IF_TSP_NOT_PRESENT();
+
+ configure_pmu_cycle_cntr();
+ pmu_enable_counting();
+
+ tftf_testcase_printf("Getting baseline event count:\n");
+ measure_event(read_pmccntr_el0, profile_invalid_smc, &baseline);
+ tftf_testcase_printf("Profiling Fast Add SMC:\n");
+ measure_event(read_pmccntr_el0, profile_fast_smc_add, &fast_smc_add);
+
+ if (!results_within_allowed_margin(baseline.avg, fast_smc_add.avg))
+ return TEST_RESULT_FAIL;
+ return TEST_RESULT_SUCCESS;
+}
+#else
+test_result_t smc_psci_suspend_pc_write_retired(void)
+{
+ INFO("%s skipped on AArch32\n", __func__);
+ return TEST_RESULT_SKIPPED;
+}
+
+test_result_t smc_psci_suspend_cycles(void)
+{
+ INFO("%s skipped on AArch32\n", __func__);
+ return TEST_RESULT_SKIPPED;
+}
+
+test_result_t fast_smc_add_pc_write_retired(void)
+{
+ INFO("%s skipped on AArch32\n", __func__);
+ return TEST_RESULT_SKIPPED;
+}
+
+test_result_t fast_smc_add_cycles(void)
+{
+ INFO("%s skipped on AArch32\n", __func__);
+ return TEST_RESULT_SKIPPED;
+}
+#endif
diff --git a/tftf/tests/runtime_services/standard_service/psci/api_tests/system_reset/test_system_reset.c b/tftf/tests/runtime_services/standard_service/psci/api_tests/system_reset/test_system_reset.c
new file mode 100644
index 000000000..41eb7af18
--- /dev/null
+++ b/tftf/tests/runtime_services/standard_service/psci/api_tests/system_reset/test_system_reset.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <psci.h>
+#include <smccc.h>
+#include <tftf_lib.h>
+
+/*
+ * @Test_Aim@ Validate the SYSTEM_RESET call.
+ * Test SUCCESS in case of system reset.
+ * Test FAIL in case of execution not terminated.
+ */
+test_result_t test_system_reset(void)
+{
+ smc_args args = { SMC_PSCI_SYSTEM_RESET };
+
+ if (tftf_is_rebooted() == 1) {
+ /* Successfully resumed from SYSTEM_RESET */
+ return TEST_RESULT_SUCCESS;
+ }
+
+ tftf_notify_reboot();
+ tftf_smc(&args);
+
+ /* The PSCI SYSTEM_RESET call is not supposed to return */
+ tftf_testcase_printf("System didn't reboot properly\n");
+
+ return TEST_RESULT_FAIL;
+}
diff --git a/tftf/tests/tests-cpu-extensions.mk b/tftf/tests/tests-cpu-extensions.mk
index daf9528ab..9102b351d 100644
--- a/tftf/tests/tests-cpu-extensions.mk
+++ b/tftf/tests/tests-cpu-extensions.mk
@@ -6,9 +6,10 @@
TESTS_SOURCES += $(addprefix tftf/tests/, \
extensions/amu/test_amu.c \
+ extensions/mte/test_mte.c \
extensions/sve/sve_operations.S \
extensions/sve/test_sve.c \
runtime_services/arm_arch_svc/smccc_arch_workaround_1.c \
runtime_services/arm_arch_svc/smccc_arch_workaround_2.c \
- extensions/ptrauth/test_ptrauth.c \
+ extensions/pauth/test_pauth.c \
)
diff --git a/tftf/tests/tests-cpu-extensions.xml b/tftf/tests/tests-cpu-extensions.xml
index e64143782..158cb04f6 100644
--- a/tftf/tests/tests-cpu-extensions.xml
+++ b/tftf/tests/tests-cpu-extensions.xml
@@ -16,6 +16,8 @@
<testcase name="Use Pointer Authentication Instructions" function="test_pauth_instructions" />
<testcase name="Check for Pointer Authentication key leakage from EL3" function="test_pauth_leakage" />
<testcase name="Check for Pointer Authentication key leakage from TSP" function="test_pauth_leakage_tsp" />
+ <testcase name="Use MTE Instructions" function="test_mte_instructions" />
+ <testcase name="Check for MTE register leakage" function="test_mte_leakage" />
</testsuite>
<testsuite name="ARM_ARCH_SVC" description="Arm Architecture Service tests">
diff --git a/tftf/tests/tests-extensive.xml b/tftf/tests/tests-extensive.xml
index 67d2346be..773c19e0f 100644
--- a/tftf/tests/tests-extensive.xml
+++ b/tftf/tests/tests-extensive.xml
@@ -22,6 +22,7 @@
<!ENTITY tests-cpu-extensions SYSTEM "tests-cpu-extensions.xml">
<!ENTITY tests-performance SYSTEM "tests-performance.xml">
<!ENTITY tests-smc SYSTEM "tests-smc.xml">
+ <!ENTITY tests-pmu-leakage SYSTEM "tests-pmu-leakage.xml">
]>
<testsuites>
@@ -39,5 +40,6 @@
&tests-cpu-extensions;
&tests-performance;
&tests-smc;
+ &tests-pmu-leakage;
</testsuites>
diff --git a/tftf/tests/tests-manual.mk b/tftf/tests/tests-manual.mk
index bd8132bb0..67e246090 100644
--- a/tftf/tests/tests-manual.mk
+++ b/tftf/tests/tests-manual.mk
@@ -1,11 +1,12 @@
#
-# Copyright (c) 2018, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2019, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
TESTS_SOURCES += \
$(addprefix tftf/tests/runtime_services/standard_service/psci/api_tests/, \
+ system_reset/test_system_reset.c \
mem_protect/test_mem_protect.c \
psci_stat/test_psci_stat.c \
reset2/reset2.c \
@@ -18,4 +19,4 @@ endif
ifeq (${NEW_TEST_SESSION},1)
$(error Manual tests require NEW_TEST_SESSION=0 to persist test results across reboots)
-endif \ No newline at end of file
+endif
diff --git a/tftf/tests/tests-manual.xml b/tftf/tests/tests-manual.xml
index 0fd6e552b..f718fabb8 100644
--- a/tftf/tests/tests-manual.xml
+++ b/tftf/tests/tests-manual.xml
@@ -9,6 +9,10 @@
<testsuites>
+ <testsuite name="System Reset Test" description="Validate SYSTEM_RESET PSCI call">
+ <testcase name="System Reset" function="test_system_reset" />
+ </testsuite>
+
<testsuite name="PSCI STAT" description="Test PSCI STAT support System level">
<testcase name="for stats after system reset" function="test_psci_stats_after_reset" />
<testcase name="for stats after system shutdown" function="test_psci_stats_after_shutdown" />
diff --git a/tftf/tests/tests-pmu-leakage.mk b/tftf/tests/tests-pmu-leakage.mk
new file mode 100644
index 000000000..2d46073fc
--- /dev/null
+++ b/tftf/tests/tests-pmu-leakage.mk
@@ -0,0 +1,9 @@
+#
+# Copyright (c) 2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+TESTS_SOURCES += $(addprefix tftf/tests/misc_tests/, \
+ test_pmu_leakage.c \
+ )
diff --git a/tftf/tests/tests-pmu-leakage.xml b/tftf/tests/tests-pmu-leakage.xml
new file mode 100644
index 000000000..932c21fc4
--- /dev/null
+++ b/tftf/tests/tests-pmu-leakage.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ Copyright (c) 2018, Arm Limited. All rights reserved.
+
+ SPDX-License-Identifier: BSD-3-Clause
+-->
+
+<testsuites>
+ <testsuite name="PMU Leakage" description="Increment PMU counters in the secure world">
+ <testcase name="Leak PMU PC_WRITE_RETIRED counter values from EL3 on PSCI suspend SMC" function="smc_psci_suspend_pc_write_retired" />
+ <testcase name="Leak PMU CYCLE counter values from EL3 on PSCI suspend SMC" function="smc_psci_suspend_cycles" />
+ <testcase name="Leak PMU PC_WRITE_RETIRED counter values from S_EL1 on fast SMC add" function="fast_smc_add_pc_write_retired" />
+ <testcase name="Leak PMU CYCLE counter values from S_EL1 on fast SMC add" function="fast_smc_add_cycles" />
+ </testsuite>
+</testsuites>
diff --git a/tftf/tests/tests-reboot.mk b/tftf/tests/tests-reboot.mk
index b0f573841..ad80973ff 100644
--- a/tftf/tests/tests-reboot.mk
+++ b/tftf/tests/tests-reboot.mk
@@ -6,6 +6,7 @@
TESTS_SOURCES += \
$(addprefix tftf/tests/runtime_services/standard_service/psci/api_tests/, \
+ system_reset/test_system_reset.c \
mem_protect/test_mem_protect.c \
psci_stat/test_psci_stat.c \
reset2/reset2.c \
diff --git a/tftf/tests/tests-reboot.xml b/tftf/tests/tests-reboot.xml
index fa4da1373..a0728723e 100644
--- a/tftf/tests/tests-reboot.xml
+++ b/tftf/tests/tests-reboot.xml
@@ -9,6 +9,10 @@
<testsuites>
+ <testsuite name="System Reset Test" description="Validate SYSTEM_RESET PSCI call">
+ <testcase name="System Reset" function="test_system_reset" />
+ </testsuite>
+
<testsuite name="PSCI STAT" description="Test PSCI STAT support System level">
<testcase name="for stats after system reset" function="test_psci_stats_after_reset" />
</testsuite>
diff --git a/tftf/tests/tests-standard.mk b/tftf/tests/tests-standard.mk
index f249a373c..9ef75bb94 100644
--- a/tftf/tests/tests-standard.mk
+++ b/tftf/tests/tests-standard.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2018, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2019, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -10,6 +10,7 @@ TESTS_MAKEFILE := $(addprefix tftf/tests/, \
tests-cpu-extensions.mk \
tests-el3-power-state.mk \
tests-performance.mk \
+ tests-pmu-leakage.mk \
tests-psci.mk \
tests-runtime-instrumentation.mk \
tests-sdei.mk \
diff --git a/tftf/tests/tests-standard.xml b/tftf/tests/tests-standard.xml
index a1323d555..fa5762173 100644
--- a/tftf/tests/tests-standard.xml
+++ b/tftf/tests/tests-standard.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright (c) 2018, Arm Limited. All rights reserved.
+ Copyright (c) 2018-2019, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-3-Clause
-->
@@ -20,6 +20,7 @@
<!ENTITY tests-cpu-extensions SYSTEM "tests-cpu-extensions.xml">
<!ENTITY tests-performance SYSTEM "tests-performance.xml">
<!ENTITY tests-smc SYSTEM "tests-smc.xml">
+ <!ENTITY tests-pmu-leakage SYSTEM "tests-pmu-leakage.xml">
]>
<testsuites>
@@ -35,5 +36,6 @@
&tests-cpu-extensions;
&tests-performance;
&tests-smc;
+ &tests-pmu-leakage;
</testsuites>