aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bl31/bl31.mk4
-rw-r--r--include/lib/cpus/aarch64/cpu_macros.S25
-rw-r--r--include/lib/cpus/workaround_cve_2017_5715.h12
-rw-r--r--lib/cpus/aarch64/cortex_a57.S4
-rw-r--r--lib/cpus/aarch64/cortex_a72.S4
-rw-r--r--lib/cpus/aarch64/cortex_a73.S3
-rw-r--r--lib/cpus/aarch64/cortex_a75.S3
-rw-r--r--lib/cpus/aarch64/cpu_helpers.S37
-rw-r--r--services/arm_arch_svc/arm_arch_svc_setup.c13
9 files changed, 88 insertions, 17 deletions
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index 886d3016ff..0e47ddf681 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -61,8 +61,8 @@ BL31_SOURCES += lib/extensions/sve/sve.c
endif
ifeq (${WORKAROUND_CVE_2017_5715},1)
-BL31_SOURCES += lib/cpus/aarch64/workaround_cve_2017_5715_mmu.S \
- lib/cpus/aarch64/workaround_cve_2017_5715_bpiall.S
+BL31_SOURCES += lib/cpus/aarch64/workaround_cve_2017_5715_bpiall.S \
+ lib/cpus/aarch64/workaround_cve_2017_5715_mmu.S
endif
BL31_LINKERFILE := bl31/bl31.ld.S
diff --git a/include/lib/cpus/aarch64/cpu_macros.S b/include/lib/cpus/aarch64/cpu_macros.S
index 6c3a5b992f..8f0a74f0a3 100644
--- a/include/lib/cpus/aarch64/cpu_macros.S
+++ b/include/lib/cpus/aarch64/cpu_macros.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -46,6 +46,8 @@ CPU_MIDR: /* cpu_ops midr */
CPU_RESET_FUNC: /* cpu_ops reset_func */
.space 8
#endif
+CPU_EXTRA1_FUNC:
+ .space 8
#ifdef IMAGE_BL31 /* The power down core and cluster is needed only in BL31 */
CPU_PWR_DWN_OPS: /* cpu_ops power down functions */
.space (8 * CPU_MAX_PWR_DWN_OPS)
@@ -113,6 +115,10 @@ CPU_OPS_SIZE = .
* _resetfunc:
* Reset function for the CPU. If there's no CPU reset function,
* specify CPU_NO_RESET_FUNC
+ * _extra1:
+ * This is a placeholder for future per CPU operations. Currently,
+ * some CPUs use this entry to set a test function to determine if
+ * the workaround for CVE-2017-5715 needs to be applied or not.
* _power_down_ops:
* Comma-separated list of functions to perform power-down
* operatios on the CPU. At least one, and up to
@@ -122,8 +128,8 @@ CPU_OPS_SIZE = .
* CPU_MAX_PWR_DWN_OPS functions, the last specified one will be
* used to handle power down at subsequent levels
*/
- .macro declare_cpu_ops _name:req, _midr:req, _resetfunc:req, \
- _power_down_ops:vararg
+ .macro declare_cpu_ops_base _name:req, _midr:req, _resetfunc:req, \
+ _extra1:req, _power_down_ops:vararg
.section cpu_ops, "a"
.align 3
.type cpu_ops_\_name, %object
@@ -131,6 +137,7 @@ CPU_OPS_SIZE = .
#if defined(IMAGE_AT_EL3)
.quad \_resetfunc
#endif
+ .quad \_extra1
#ifdef IMAGE_BL31
1:
/* Insert list of functions */
@@ -187,6 +194,18 @@ CPU_OPS_SIZE = .
#endif
.endm
+ .macro declare_cpu_ops _name:req, _midr:req, _resetfunc:req, \
+ _power_down_ops:vararg
+ declare_cpu_ops_base \_name, \_midr, \_resetfunc, 0, \
+ \_power_down_ops
+ .endm
+
+ .macro declare_cpu_ops_workaround_cve_2017_5715 _name:req, _midr:req, \
+ _resetfunc:req, _extra1:req, _power_down_ops:vararg
+ declare_cpu_ops_base \_name, \_midr, \_resetfunc, \
+ \_extra1, \_power_down_ops
+ .endm
+
#if REPORT_ERRATA
/*
* Print status of a CPU errata
diff --git a/include/lib/cpus/workaround_cve_2017_5715.h b/include/lib/cpus/workaround_cve_2017_5715.h
new file mode 100644
index 0000000000..e837a673ac
--- /dev/null
+++ b/include/lib/cpus/workaround_cve_2017_5715.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __WORKAROUND_CVE_2017_5715_H__
+#define __WORKAROUND_CVE_2017_5715_H__
+
+int check_workaround_cve_2017_5715(void);
+
+#endif /* __WORKAROUND_CVE_2017_5715_H__ */
diff --git a/lib/cpus/aarch64/cortex_a57.S b/lib/cpus/aarch64/cortex_a57.S
index c82ebfc951..4d072e11c6 100644
--- a/lib/cpus/aarch64/cortex_a57.S
+++ b/lib/cpus/aarch64/cortex_a57.S
@@ -555,8 +555,8 @@ func cortex_a57_cpu_reg_dump
ret
endfunc cortex_a57_cpu_reg_dump
-
-declare_cpu_ops cortex_a57, CORTEX_A57_MIDR, \
+declare_cpu_ops_workaround_cve_2017_5715 cortex_a57, CORTEX_A57_MIDR, \
cortex_a57_reset_func, \
+ check_errata_cve_2017_5715, \
cortex_a57_core_pwr_dwn, \
cortex_a57_cluster_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_a72.S b/lib/cpus/aarch64/cortex_a72.S
index 199820ccd3..29fa77b901 100644
--- a/lib/cpus/aarch64/cortex_a72.S
+++ b/lib/cpus/aarch64/cortex_a72.S
@@ -292,8 +292,8 @@ func cortex_a72_cpu_reg_dump
ret
endfunc cortex_a72_cpu_reg_dump
-
-declare_cpu_ops cortex_a72, CORTEX_A72_MIDR, \
+declare_cpu_ops_workaround_cve_2017_5715 cortex_a72, CORTEX_A72_MIDR, \
cortex_a72_reset_func, \
+ check_errata_cve_2017_5715, \
cortex_a72_core_pwr_dwn, \
cortex_a72_cluster_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_a73.S b/lib/cpus/aarch64/cortex_a73.S
index 63d16f9db1..0a961ea333 100644
--- a/lib/cpus/aarch64/cortex_a73.S
+++ b/lib/cpus/aarch64/cortex_a73.S
@@ -170,7 +170,8 @@ func cortex_a73_cpu_reg_dump
ret
endfunc cortex_a73_cpu_reg_dump
-declare_cpu_ops cortex_a73, CORTEX_A73_MIDR, \
+declare_cpu_ops_workaround_cve_2017_5715 cortex_a73, CORTEX_A73_MIDR, \
cortex_a73_reset_func, \
+ check_errata_cve_2017_5715, \
cortex_a73_core_pwr_dwn, \
cortex_a73_cluster_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_a75.S b/lib/cpus/aarch64/cortex_a75.S
index d102795167..288f5afedb 100644
--- a/lib/cpus/aarch64/cortex_a75.S
+++ b/lib/cpus/aarch64/cortex_a75.S
@@ -113,6 +113,7 @@ func cortex_a75_cpu_reg_dump
ret
endfunc cortex_a75_cpu_reg_dump
-declare_cpu_ops cortex_a75, CORTEX_A75_MIDR, \
+declare_cpu_ops_workaround_cve_2017_5715 cortex_a75, CORTEX_A75_MIDR, \
cortex_a75_reset_func, \
+ check_errata_cve_2017_5715, \
cortex_a75_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cpu_helpers.S b/lib/cpus/aarch64/cpu_helpers.S
index ae1c3c2525..5a9226d832 100644
--- a/lib/cpus/aarch64/cpu_helpers.S
+++ b/lib/cpus/aarch64/cpu_helpers.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,9 +7,7 @@
#include <arch.h>
#include <asm_macros.S>
#include <assert_macros.S>
-#if defined(IMAGE_BL31) || (defined(IMAGE_BL2) && BL2_AT_EL3)
#include <cpu_data.h>
-#endif
#include <cpu_macros.S>
#include <debug.h>
#include <errata_report.h>
@@ -281,3 +279,36 @@ func print_errata_status
br x1
endfunc print_errata_status
#endif
+
+/*
+ * int check_workaround_cve_2017_5715(void);
+ *
+ * This function returns:
+ * - ERRATA_APPLIES when firmware mitigation is required.
+ * - ERRATA_NOT_APPLIES when firmware mitigation is _not_ required.
+ * - ERRATA_MISSING when firmware mitigation would be required but
+ * is not compiled in.
+ *
+ * NOTE: Must be called only after cpu_ops have been initialized
+ * in per-CPU data.
+ */
+ .globl check_workaround_cve_2017_5715
+func check_workaround_cve_2017_5715
+ mrs x0, tpidr_el3
+#if ENABLE_ASSERTIONS
+ cmp x0, #0
+ ASM_ASSERT(ne)
+#endif
+ ldr x0, [x0, #CPU_DATA_CPU_OPS_PTR]
+ ldr x0, [x0, #CPU_EXTRA1_FUNC]
+ /*
+ * If the reserved function pointer is NULL, this CPU
+ * is unaffected by CVE-2017-5715 so bail out.
+ */
+ cmp x0, #0
+ beq 1f
+ br x0
+1:
+ mov x0, #ERRATA_NOT_APPLIES
+ ret
+endfunc check_workaround_cve_2017_5715
diff --git a/services/arm_arch_svc/arm_arch_svc_setup.c b/services/arm_arch_svc/arm_arch_svc_setup.c
index a809c429a0..f75a737e9f 100644
--- a/services/arm_arch_svc/arm_arch_svc_setup.c
+++ b/services/arm_arch_svc/arm_arch_svc_setup.c
@@ -6,9 +6,11 @@
#include <arm_arch_svc.h>
#include <debug.h>
+#include <errata_report.h>
#include <runtime_svc.h>
#include <smcc.h>
#include <smcc_helpers.h>
+#include <workaround_cve_2017_5715.h>
static int32_t smccc_version(void)
{
@@ -17,14 +19,19 @@ static int32_t smccc_version(void)
static int32_t smccc_arch_features(u_register_t arg)
{
+ int ret;
+
switch (arg) {
case SMCCC_VERSION:
case SMCCC_ARCH_FEATURES:
return SMC_OK;
-#if WORKAROUND_CVE_2017_5715
case SMCCC_ARCH_WORKAROUND_1:
- return SMC_OK;
-#endif
+ ret = check_workaround_cve_2017_5715();
+ if (ret == ERRATA_APPLIES)
+ return 0;
+ else if (ret == ERRATA_NOT_APPLIES)
+ return 1;
+ return -1; /* ERRATA_MISSING */
default:
return SMC_UNK;
}