Introduce test to access pointer authentication register
EL3 runtime firmware currently enables unconditional access to pointer
authentication registers from lower EL [1]. The test performs a read
access on a pointer authentication system register to ensure that the
access is permitted from a lower EL, and doesn't result in a trap to
EL3.
[1] https://github.com/ARM-software/arm-trusted-firmware/commit/3ff4aaaca44b75504aec5ab5b72cd587a6fcd432
Change-Id: I893604ebcd9e5df830d97cce405c2a7518c0b23c
Signed-off-by: Jeenu Viswambharan <jeenu.viswambharan@arm.com>
diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h
index 215730d..2da0630 100644
--- a/include/lib/aarch64/arch.h
+++ b/include/lib/aarch64/arch.h
@@ -159,6 +159,25 @@
#define ID_AA64MMFR0_EL1_PARANGE_SHIFT U(0)
#define ID_AA64MMFR0_EL1_PARANGE_MASK ULL(0xf)
+/* ID_AA64ISAR1_EL1 definitions */
+#define ID_AA64ISAR1_GPI_SHIFT U(28)
+#define ID_AA64ISAR1_GPI_WIDTH U(4)
+#define ID_AA64ISAR1_GPA_SHIFT U(24)
+#define ID_AA64ISAR1_GPA_WIDTH U(4)
+#define ID_AA64ISAR1_API_SHIFT U(8)
+#define ID_AA64ISAR1_API_WIDTH U(4)
+#define ID_AA64ISAR1_APA_SHIFT U(4)
+#define ID_AA64ISAR1_APA_WIDTH U(4)
+
+#define ID_AA64ISAR1_GPI_MASK \
+ (((ULL(1) << ID_AA64ISAR1_GPI_WIDTH) - ULL(1)) << ID_AA64ISAR1_GPI_SHIFT)
+#define ID_AA64ISAR1_GPA_MASK \
+ (((ULL(1) << ID_AA64ISAR1_GPA_WIDTH) - ULL(1)) << ID_AA64ISAR1_GPA_SHIFT)
+#define ID_AA64ISAR1_API_MASK \
+ (((ULL(1) << ID_AA64ISAR1_API_WIDTH) - ULL(1)) << ID_AA64ISAR1_API_SHIFT)
+#define ID_AA64ISAR1_APA_MASK \
+ (((ULL(1) << ID_AA64ISAR1_APA_WIDTH) - ULL(1)) << ID_AA64ISAR1_APA_SHIFT)
+
#define PARANGE_0000 U(32)
#define PARANGE_0001 U(36)
#define PARANGE_0010 U(40)
@@ -618,4 +637,9 @@
#define ERXPFGCTL_UEU_BIT (1 << 2)
#define ERXPFGCTL_CDEN_BIT (1 << 31)
+/*******************************************************************************
+ * Armv8.3 Pointer Authentication Registers
+ *******************************************************************************/
+#define APGAKeyLo_EL1 S3_0_C2_C3_0
+
#endif /* __ARCH_H__ */
diff --git a/include/lib/aarch64/arch_helpers.h b/include/lib/aarch64/arch_helpers.h
index c313d60..0bd52de 100644
--- a/include/lib/aarch64/arch_helpers.h
+++ b/include/lib/aarch64/arch_helpers.h
@@ -128,6 +128,7 @@
******************************************************************************/
DEFINE_SYSREG_READ_FUNC(id_pfr1_el1)
+DEFINE_SYSREG_READ_FUNC(id_aa64isar1_el1)
DEFINE_SYSREG_READ_FUNC(id_aa64pfr0_el1)
DEFINE_SYSREG_READ_FUNC(CurrentEl)
DEFINE_SYSREG_READ_FUNC(ctr_el0)
@@ -323,6 +324,9 @@
DEFINE_RENAME_SYSREG_RW_FUNCS(amcntenclr1_el0, AMCNTENCLR1_EL0)
DEFINE_RENAME_SYSREG_RW_FUNCS(amcntenset1_el0, AMCNTENSET1_EL0)
+/* Armv8.3 Pointer Authentication Registers */
+DEFINE_RENAME_SYSREG_RW_FUNCS(apgakeylo_el1, APGAKeyLo_EL1)
+
#define IS_IN_EL(x) \
(GET_EL(read_CurrentEl()) == MODE_EL##x)
diff --git a/tftf/tests/extensions/ptrauth/test_ptrauth_access.c b/tftf/tests/extensions/ptrauth/test_ptrauth_access.c
new file mode 100644
index 0000000..21efc18
--- /dev/null
+++ b/tftf/tests/extensions/ptrauth/test_ptrauth_access.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <arch_helpers.h>
+#include <stdbool.h>
+#include <tftf_lib.h>
+
+#ifndef AARCH32
+
+/*
+ * This function asserts that pointer authentication registers are accessible
+ * from lower ELs. If not permitted from EL3, the access will cause a crash.
+ */
+test_result_t test_ptrauth_access(void)
+{
+ bool has_ptrauth = false;
+ uint64_t id_aa64isar1 = read_id_aa64isar1_el1();
+
+ has_ptrauth = has_ptrauth || ((id_aa64isar1 & ID_AA64ISAR1_GPI_MASK) != 0U);
+ has_ptrauth = has_ptrauth || ((id_aa64isar1 & ID_AA64ISAR1_GPA_MASK) != 0U);
+ has_ptrauth = has_ptrauth || ((id_aa64isar1 & ID_AA64ISAR1_API_MASK) != 0U);
+ has_ptrauth = has_ptrauth || ((id_aa64isar1 & ID_AA64ISAR1_APA_MASK) != 0U);
+
+ if (!has_ptrauth) {
+ tftf_testcase_printf("Pointer authentication not supported.\n");
+ return TEST_RESULT_SKIPPED;
+ }
+
+ (void) read_apgakeylo_el1();
+
+ return TEST_RESULT_SUCCESS;
+}
+
+#else
+
+test_result_t test_ptrauth_access(void)
+{
+ tftf_testcase_printf("Not supported on AArch32.\n");
+ return TEST_RESULT_SKIPPED;
+}
+
+#endif
diff --git a/tftf/tests/tests-ptrauth.mk b/tftf/tests/tests-ptrauth.mk
new file mode 100644
index 0000000..4e50d3a
--- /dev/null
+++ b/tftf/tests/tests-ptrauth.mk
@@ -0,0 +1,7 @@
+#
+# Copyright (c) 2018, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+TESTS_SOURCES += tftf/tests/extensions/ptrauth/test_ptrauth_access.c
diff --git a/tftf/tests/tests-ptrauth.xml b/tftf/tests/tests-ptrauth.xml
new file mode 100644
index 0000000..a9179cf
--- /dev/null
+++ b/tftf/tests/tests-ptrauth.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ Copyright (c) 2018, Arm Limited. All rights reserved.
+
+ SPDX-License-Identifier: BSD-3-Clause
+-->
+
+<testsuites>
+ <testsuite name="PtrAuth" description="Pointer Authentication">
+ <testcase name="Simple register access" function="test_ptrauth_access" />
+ </testsuite>
+</testsuites>