fix(security): workaround for CVE-2022-23960 for A76AE, A78AE, A78C

Implements the loop workaround for Cortex-A76AE, Cortex-A78AE and
Cortex-A78C.

Signed-off-by: Bipin Ravi <bipin.ravi@arm.com>
Signed-off-by: Madhukar Pappireddy <madhukar.pappireddy@arm.com>
Change-Id: I5c838f5b9d595ed3c461a7452bd465bd54acc548
diff --git a/include/lib/cpus/aarch64/cortex_a76ae.h b/include/lib/cpus/aarch64/cortex_a76ae.h
index 9e34efb..0d30f70 100644
--- a/include/lib/cpus/aarch64/cortex_a76ae.h
+++ b/include/lib/cpus/aarch64/cortex_a76ae.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,6 +12,9 @@
 /* Cortex-A76AE MIDR for revision 0 */
 #define CORTEX_A76AE_MIDR		U(0x410FD0E0)
 
+/* Cortex-A76 loop count for CVE-2022-23960 mitigation */
+#define CORTEX_A76AE_BHB_LOOP_COUNT	U(24)
+
 /*******************************************************************************
  * CPU Extended Control register specific definitions.
  ******************************************************************************/
diff --git a/include/lib/cpus/aarch64/cortex_a78_ae.h b/include/lib/cpus/aarch64/cortex_a78_ae.h
index 0c8adcf..90b6d6f 100644
--- a/include/lib/cpus/aarch64/cortex_a78_ae.h
+++ b/include/lib/cpus/aarch64/cortex_a78_ae.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+ * Copyright (c) 2019-2022, ARM Limited. All rights reserved.
  * Copyright (c) 2021, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -10,7 +10,10 @@
 
 #include <cortex_a78.h>
 
-#define CORTEX_A78_AE_MIDR U(0x410FD420)
+#define CORTEX_A78_AE_MIDR 				U(0x410FD420)
+
+/* Cortex-A78AE loop count for CVE-2022-23960 mitigation */
+#define CORTEX_A78_AE_BHB_LOOP_COUNT			U(32)
 
 /*******************************************************************************
  * CPU Extended Control register specific definitions.
diff --git a/include/lib/cpus/aarch64/cortex_a78c.h b/include/lib/cpus/aarch64/cortex_a78c.h
index adb13bc..b1945ed 100644
--- a/include/lib/cpus/aarch64/cortex_a78c.h
+++ b/include/lib/cpus/aarch64/cortex_a78c.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,6 +10,9 @@
 
 #define CORTEX_A78C_MIDR			        U(0x410FD4B1)
 
+/* Cortex-A76 loop count for CVE-2022-23960 mitigation */
+#define CORTEX_A78C_BHB_LOOP_COUNT			U(32)
+
 /*******************************************************************************
  * CPU Extended Control register specific definitions.
  ******************************************************************************/
diff --git a/lib/cpus/aarch64/cortex_a76ae.S b/lib/cpus/aarch64/cortex_a76ae.S
index 888f98b..5c19548 100644
--- a/lib/cpus/aarch64/cortex_a76ae.S
+++ b/lib/cpus/aarch64/cortex_a76ae.S
@@ -1,12 +1,15 @@
 /*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <arch.h>
 #include <asm_macros.S>
+#include <common/bl_common.h>
 #include <cortex_a76ae.h>
 #include <cpu_macros.S>
+#include "wa_cve_2022_23960_bhb_vector.S"
 
 /* Hardware handled coherency */
 #if HW_ASSISTED_COHERENCY == 0
@@ -18,14 +21,46 @@
 #error "Cortex-A76AE supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
 #endif
 
-	/* ---------------------------------------------
+#if WORKAROUND_CVE_2022_23960
+	wa_cve_2022_23960_bhb_vector_table CORTEX_A76AE_BHB_LOOP_COUNT, cortex_a76ae
+#endif /* WORKAROUND_CVE_2022_23960 */
+
+func check_errata_cve_2022_23960
+#if WORKAROUND_CVE_2022_23960
+	mov	x0, #ERRATA_APPLIES
+#else
+	mov	x0, #ERRATA_MISSING
+#endif /* WORKAROUND_CVE_2022_23960 */
+	ret
+endfunc check_errata_cve_2022_23960
+
+	/* --------------------------------------------
+	 * The CPU Ops reset function for Cortex-A76AE.
+	 * Shall clobber: x0-x19
+	 * --------------------------------------------
+	 */
+func cortex_a76ae_reset_func
+#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
+	/*
+	 * The Cortex-A76ae generic vectors are overridden to apply errata
+	 * mitigation on exception entry from lower ELs.
+	 */
+	adr	x0, wa_cve_vbar_cortex_a76ae
+	msr	vbar_el3, x0
+	isb
+#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
+
+	ret
+endfunc cortex_a76ae_reset_func
+
+	/* ----------------------------------------------------
 	 * HW will do the cache maintenance while powering down
-	 * ---------------------------------------------
+	 * ----------------------------------------------------
 	 */
 func cortex_a76ae_core_pwr_dwn
-	/* ---------------------------------------------
+	/* ---------------------------------------------------
 	 * Enable CPU power down bit in power control register
-	 * ---------------------------------------------
+	 * ---------------------------------------------------
 	 */
 	mrs	x0, CORTEX_A76AE_CPUPWRCTLR_EL1
 	orr	x0, x0, #CORTEX_A76AE_CORE_PWRDN_EN_MASK
@@ -39,6 +74,18 @@
  * Errata printing function for Cortex-A76AE. Must follow AAPCS.
  */
 func cortex_a76ae_errata_report
+	stp	x8, x30, [sp, #-16]!
+
+	bl	cpu_get_rev_var
+	mov	x8, x0
+
+	/*
+	 * Report all errata. The revision-variant information is passed to
+	 * checking functions of each errata.
+	 */
+	report_errata WORKAROUND_CVE_2022_23960, cortex_a76ae, cve_2022_23960
+
+	ldp	x8, x30, [sp], #16
 	ret
 endfunc cortex_a76ae_errata_report
 #endif	/* REPORT_ERRATA */
@@ -62,5 +109,5 @@
 	ret
 endfunc cortex_a76ae_cpu_reg_dump
 
-declare_cpu_ops cortex_a76ae, CORTEX_A76AE_MIDR, CPU_NO_RESET_FUNC, \
+declare_cpu_ops cortex_a76ae, CORTEX_A76AE_MIDR, cortex_a76ae_reset_func, \
 	cortex_a76ae_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_a78_ae.S b/lib/cpus/aarch64/cortex_a78_ae.S
index 421c174..bf872df 100644
--- a/lib/cpus/aarch64/cortex_a78_ae.S
+++ b/lib/cpus/aarch64/cortex_a78_ae.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+ * Copyright (c) 2019-2022, ARM Limited. All rights reserved.
  * Copyright (c) 2021, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -11,12 +11,17 @@
 #include <cortex_a78_ae.h>
 #include <cpu_macros.S>
 #include <plat_macros.S>
+#include "wa_cve_2022_23960_bhb_vector.S"
 
 /* Hardware handled coherency */
 #if HW_ASSISTED_COHERENCY == 0
 #error "cortex_a78_ae must be compiled with HW_ASSISTED_COHERENCY enabled"
 #endif
 
+#if WORKAROUND_CVE_2022_23960
+	wa_cve_2022_23960_bhb_vector_table CORTEX_A78_AE_BHB_LOOP_COUNT, cortex_a78_ae
+#endif /* WORKAROUND_CVE_2022_23960 */
+
 /* --------------------------------------------------
  * Errata Workaround for A78 AE Erratum 1941500.
  * This applies to revisions r0p0 and r0p1 of A78 AE.
@@ -99,6 +104,15 @@
 	b	cpu_rev_var_range
 endfunc check_errata_1951502
 
+func check_errata_cve_2022_23960
+#if WORKAROUND_CVE_2022_23960
+	mov	x0, #ERRATA_APPLIES
+#else
+	mov	x0, #ERRATA_MISSING
+#endif
+	ret
+endfunc check_errata_cve_2022_23960
+
 	/* -------------------------------------------------
 	 * The CPU Ops reset function for Cortex-A78-AE
 	 * -------------------------------------------------
@@ -138,8 +152,16 @@
 	msr	CPUAMCNTENSET1_EL0, x0
 #endif
 
-	isb
+#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
+	/*
+	 * The Cortex-A78AE generic vectors are overridden to apply errata
+	 * mitigation on exception entry from lower ELs.
+	 */
+	adr	x0, wa_cve_vbar_cortex_a78_ae
+	msr	vbar_el3, x0
+#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
 
+	isb
 	ret	x19
 endfunc cortex_a78_ae_reset_func
 
@@ -175,6 +197,7 @@
 	 */
 	report_errata ERRATA_A78_AE_1941500, cortex_a78_ae, 1941500
 	report_errata ERRATA_A78_AE_1951502, cortex_a78_ae, 1951502
+	report_errata WORKAROUND_CVE_2022_23960, cortex_a78_ae, cve_2022_23960
 
 	ldp	x8, x30, [sp], #16
 	ret
diff --git a/lib/cpus/aarch64/cortex_a78c.S b/lib/cpus/aarch64/cortex_a78c.S
index 1b170fe..0712109 100644
--- a/lib/cpus/aarch64/cortex_a78c.S
+++ b/lib/cpus/aarch64/cortex_a78c.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,12 +10,43 @@
 #include <cortex_a78c.h>
 #include <cpu_macros.S>
 #include <plat_macros.S>
+#include "wa_cve_2022_23960_bhb_vector.S"
 
 /* Hardware handled coherency */
 #if HW_ASSISTED_COHERENCY == 0
 #error "cortex_a78c must be compiled with HW_ASSISTED_COHERENCY enabled"
 #endif
 
+#if WORKAROUND_CVE_2022_23960
+	wa_cve_2022_23960_bhb_vector_table CORTEX_A78C_BHB_LOOP_COUNT, cortex_a78c
+#endif /* WORKAROUND_CVE_2022_23960 */
+
+func check_errata_cve_2022_23960
+#if WORKAROUND_CVE_2022_23960
+	mov	x0, #ERRATA_APPLIES
+#else
+	mov	x0, #ERRATA_MISSING
+#endif
+	ret
+endfunc check_errata_cve_2022_23960
+
+	/* -------------------------------------------------
+	 * The CPU Ops reset function for Cortex-A78C
+	 * -------------------------------------------------
+	 */
+func cortex_a78c_reset_func
+#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
+	/*
+	 * The Cortex-A78c generic vectors are overridden to apply errata
+	 * mitigation on exception entry from lower ELs.
+	 */
+	adr	x0, wa_cve_vbar_cortex_a78c
+	msr	vbar_el3, x0
+#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
+	isb
+	ret
+endfunc cortex_a78c_reset_func
+
 	/* ----------------------------------------------------
 	 * HW will do the cache maintenance while powering down
 	 * ----------------------------------------------------
@@ -37,6 +68,18 @@
  * Errata printing function for Cortex A78C. Must follow AAPCS.
  */
 func cortex_a78c_errata_report
+	stp	x8, x30, [sp, #-16]!
+
+	bl	cpu_get_rev_var
+	mov	x8, x0
+
+	/*
+	 * Report all errata. The revision-variant information is passed to
+	 * checking functions of each errata.
+	 */
+	report_errata WORKAROUND_CVE_2022_23960, cortex_a78c, cve_2022_23960
+
+	ldp	x8, x30, [sp], #16
         ret
 endfunc cortex_a78c_errata_report
 #endif
@@ -61,5 +104,5 @@
 endfunc cortex_a78c_cpu_reg_dump
 
 declare_cpu_ops cortex_a78c, CORTEX_A78C_MIDR, \
-	CPU_NO_RESET_FUNC, \
+	cortex_a78c_reset_func, \
 	cortex_a78c_core_pwr_dwn