Merge changes from topic "for-lts-v2.8.30" into lts-v2.8

* changes:
  fix(cpus): workaround for Neoverse-V3 erratum 3701767
  fix(cpus): workaround for Neoverse-N2 erratum 3701773
  fix(cpus): workaround for Cortex-X4 erratum 3701758
  fix(cpus): workaround for Cortex-X3 erratum 3701769
  fix(cpus): workaround for Cortex-X2 erratum 3701772
  fix(cpus): workaround for Cortex-A720 erratum 3699561
  fix(cpus): workaround for Cortex-A715 erratum 3699560
  fix(cpus): workaround for Cortex-A710 erratum 3701772
  fix(cpus): workaround for accessing ICH_VMCR_EL2
  fix(cm): update gic el2 sysregs save/restore mechanism
  refactor(cm): move remaining EL2 save/restore into C
  refactor(errata-abi): move EXTRACT_PARTNUM to arch.h
  chore(cpus): fix incorrect header macro
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index 2f09b21..be45238 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -578,6 +578,12 @@
    CPU, this affects all configurations. This needs to be enabled for revisions
    r0p0 and r0p1. It has been fixed in r0p2.
 
+For Neoverse V3, the following errata build flags are defined :
+
+- ``ERRATA_V3_3701767``: This applies errata 3701767 workaround to Neoverse-V3
+  CPU. This needs to be enabled for revisions r0p0, r0p1, r0p2 of the CPU and
+  is still open.
+
 For Cortex-A710, the following errata build flags are defined :
 
 -  ``ERRATA_A710_1987031``: This applies errata 1987031 workaround to
@@ -653,6 +659,10 @@
    CPU. This needs to be enabled for revisions r0p0, r1p0, r2p0 and r2p1 of the
    CPU and is still open.
 
+- ``ERRATA_A710_3701772``: This applies errata 3701772 workaround to Cortex-A710
+  CPU. This needs to be enabled for revisions r0p0, r1p0, r2p0, r2p1 of the
+  CPU and is still open.
+
 For Neoverse N2, the following errata build flags are defined :
 
 -  ``ERRATA_N2_2002655``: This applies errata 2002655 workaround to Neoverse-N2
@@ -724,6 +734,10 @@
    CPU. This needs to be enabled for revisions r0p0, r0p1 and r0p2. It is fixed
    in r0p3.
 
+-  ``ERRATA_N2_3701773``: This applies errata 3701773 workaround to Neoverse-N2
+   CPU. This needs to be enabled for revisions r0p0, r0p1, r0p2, r0p3 and is
+   still open.
+
 For Cortex-X2, the following errata build flags are defined :
 
 -  ``ERRATA_X2_2002765``: This applies errata 2002765 workaround to Cortex-X2
@@ -778,6 +792,10 @@
    CPU. This needs to be enabled for revisions r0p0, r1p0, r2p0 and r2p1 of the
    CPU and it is still open.
 
+-  ``ERRATA_X2_3701772``: This applies errata 3701772 workaround to Cortex-X2
+   CPU. This needs to be enabled for revisions r0p0, r1p0, r2p0 and r2p1 of the
+   CPU and it is still open.
+
 For Cortex-X3, the following errata build flags are defined :
 
 - ``ERRATA_X3_2070301``: This applies errata 2070301 workaround to the Cortex-X3
@@ -821,6 +839,10 @@
   CPU. This needs to be enabled only for revisions r0p0, r1p0 and r1p1 of the
   CPU. It is fixed in r1p2.
 
+- ``ERRATA_X3_3701769``: This applies errata 3701769 workaround to Cortex-X3
+  CPU. This needs to be enabled only for revisions r0p0, r1p0, r1p1 and r1p2
+  of the CPU and it is still open.
+
 For Cortex-X4, the following errata build flags are defined :
 
 - ``ERRATA_X4_2701112``: This applies erratum 2701112 workaround to Cortex-X4
@@ -854,6 +876,10 @@
 - ``ERRATA_X4_3076789``: This applies errata 3076789 workaround to Cortex-X4
   CPU. This needs to be enabled for revisions r0p0 and r0p1. It is fixed in r0p2.
 
+- ``ERRATA_X4_3701758``: This applies errata 3701758 workaround to Cortex-X4
+  CPU. This needs to be enabled for revisions r0p0, r0p1, r0p2 and r0p3.
+  It is still open.
+
 For Cortex-A510, the following errata build flags are defined :
 
 -  ``ERRATA_A510_1922240``: This applies errata 1922240 workaround to
@@ -952,6 +978,10 @@
    Cortex-A715 CPU. This needs to be enabled for revisions r0p0, r1p0
    and r1p1. It is fixed in r1p2.
 
+-  ``ERRATA_A715_3699560``: This applies errata 3699560 workaround to
+   Cortex-A715 CPU. This needs to be enabled for revisions r0p0, r1p0,
+   r1p2, r1p3. It is still open.
+
 For Cortex-A720, the following errata build flags are defined :
 
 -  ``ERRATA_A720_2792132``: This applies errata 2792132 workaround to
@@ -970,6 +1000,10 @@
    Cortex-A720 CPU. This needs to be enabled for revisions r0p0 and r0p1.
    It is fixed in r0p2.
 
+-  ``ERRATA_A720_3699561``: This applies errata 3699561 workaround to
+   Cortex-A720 CPU. This needs to be enabled for revisions r0p0, r0p1
+   and r0p2. It is still open.
+
 DSU Errata Workarounds
 ----------------------
 
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index 67028bc..8f6afc2 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -24,6 +24,9 @@
 #define MIDR_PN_MASK		U(0xfff)
 #define MIDR_PN_SHIFT		U(0x4)
 
+/* Extracts the CPU part number from MIDR for checking CPU match */
+#define EXTRACT_PARTNUM(x)     ((x >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
+
 /*******************************************************************************
  * MPIDR macros
  ******************************************************************************/
diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h
index 50a5ad4..2979435 100644
--- a/include/arch/aarch64/arch_helpers.h
+++ b/include/arch/aarch64/arch_helpers.h
@@ -470,6 +470,13 @@
 DEFINE_SYSREG_RW_FUNCS(vpidr_el2)
 DEFINE_SYSREG_RW_FUNCS(vmpidr_el2)
 
+DEFINE_SYSREG_RW_FUNCS(hacr_el2)
+DEFINE_SYSREG_RW_FUNCS(hpfar_el2)
+DEFINE_SYSREG_RW_FUNCS(tpidr_el2)
+DEFINE_SYSREG_RW_FUNCS(dbgvcr32_el2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(ich_hcr_el2, ICH_HCR_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(ich_vmcr_el2, ICH_VMCR_EL2)
+
 DEFINE_SYSREG_READ_FUNC(isr_el1)
 
 DEFINE_SYSREG_RW_FUNCS(mdcr_el2)
@@ -544,6 +551,7 @@
 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_RENAME_SYSREG_RW_FUNCS(tfsr_el2, TFSR_EL2)
 
 /* Armv8.5 FEAT_RNG Registers */
 DEFINE_SYSREG_READ_FUNC(rndr)
diff --git a/include/lib/cpus/aarch64/cortex_a710.h b/include/lib/cpus/aarch64/cortex_a710.h
index 9df8d47..650193c 100644
--- a/include/lib/cpus/aarch64/cortex_a710.h
+++ b/include/lib/cpus/aarch64/cortex_a710.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -67,4 +67,8 @@
 #define CORTEX_A710_CPUPOR_EL3					S3_6_C15_C8_2
 #define CORTEX_A710_CPUPMR_EL3					S3_6_C15_C8_3
 
+#ifndef __ASSEMBLER__
+long check_erratum_cortex_a710_3701772(long cpu_rev);
+#endif /* __ASSEMBLER__ */
+
 #endif /* CORTEX_A710_H */
diff --git a/include/lib/cpus/aarch64/cortex_a715.h b/include/lib/cpus/aarch64/cortex_a715.h
index c7f50db..e9bd886 100644
--- a/include/lib/cpus/aarch64/cortex_a715.h
+++ b/include/lib/cpus/aarch64/cortex_a715.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -38,4 +38,8 @@
 #define CORTEX_A715_CPUPWRCTLR_EL1				S3_0_C15_C2_7
 #define CORTEX_A715_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
 
+#ifndef __ASSEMBLER__
+long check_erratum_cortex_a715_3699560(long cpu_rev);
+#endif /* __ASSEMBLER__ */
+
 #endif /* CORTEX_A715_H */
diff --git a/include/lib/cpus/aarch64/cortex_a720.h b/include/lib/cpus/aarch64/cortex_a720.h
index 129c1ee..670438f 100644
--- a/include/lib/cpus/aarch64/cortex_a720.h
+++ b/include/lib/cpus/aarch64/cortex_a720.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -38,4 +38,8 @@
 #define CORTEX_A720_CPUPWRCTLR_EL1				S3_0_C15_C2_7
 #define CORTEX_A720_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
 
+#ifndef __ASSEMBLER__
+long check_erratum_cortex_a720_3699561(long cpu_rev);
+#endif /* __ASSEMBLER__ */
+
 #endif /* CORTEX_A720_H */
diff --git a/include/lib/cpus/aarch64/cortex_x2.h b/include/lib/cpus/aarch64/cortex_x2.h
index 0f97b1e..9ec5177 100644
--- a/include/lib/cpus/aarch64/cortex_x2.h
+++ b/include/lib/cpus/aarch64/cortex_x2.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -64,4 +64,8 @@
 #define CORTEX_X2_IMP_CPUPOR_EL3				S3_6_C15_C8_2
 #define CORTEX_X2_IMP_CPUPMR_EL3				S3_6_C15_C8_3
 
+#ifndef __ASSEMBLER__
+long check_erratum_cortex_x2_3701772(long cpu_rev);
+#endif /* __ASSEMBLER__ */
+
 #endif /* CORTEX_X2_H */
diff --git a/include/lib/cpus/aarch64/cortex_x3.h b/include/lib/cpus/aarch64/cortex_x3.h
index c5f820c..8834db1 100644
--- a/include/lib/cpus/aarch64/cortex_x3.h
+++ b/include/lib/cpus/aarch64/cortex_x3.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -63,4 +63,8 @@
 #define CORTEX_X3_CPUACTLR3_EL1			S3_0_C15_C1_2
 #define CORTEX_X3_CPUACTLR3_EL1_BIT_47		(ULL(1) << 47)
 
+#ifndef __ASSEMBLER__
+long check_erratum_cortex_x3_3701769(long cpu_rev);
+#endif /* __ASSEMBLER__ */
+
 #endif /* CORTEX_X3_H */
diff --git a/include/lib/cpus/aarch64/cortex_x4.h b/include/lib/cpus/aarch64/cortex_x4.h
index 116f9a0..8ef830a 100644
--- a/include/lib/cpus/aarch64/cortex_x4.h
+++ b/include/lib/cpus/aarch64/cortex_x4.h
@@ -50,6 +50,8 @@
        return 0;
 }
 #endif /* ERRATA_X4_2726228 */
+
+long check_erratum_cortex_x4_3701758(long cpu_rev);
 #endif /* __ASSEMBLER__ */
 
 #endif /* CORTEX_X4_H */
diff --git a/include/lib/cpus/aarch64/neoverse_n2.h b/include/lib/cpus/aarch64/neoverse_n2.h
index b379fab..f5837d4 100644
--- a/include/lib/cpus/aarch64/neoverse_n2.h
+++ b/include/lib/cpus/aarch64/neoverse_n2.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -69,4 +69,8 @@
 #define CPUECTLR2_EL1_TXREQ_LSB				U(0)
 #define CPUECTLR2_EL1_TXREQ_WIDTH			U(3)
 
+#ifndef __ASSEMBLER__
+long check_erratum_neoverse_n2_3701773(long cpu_rev);
+#endif /* __ASSEMBLER__ */
+
 #endif /* NEOVERSE_N2_H */
diff --git a/include/lib/cpus/aarch64/neoverse_v3.h b/include/lib/cpus/aarch64/neoverse_v3.h
index a31bdd3..5a828c0 100644
--- a/include/lib/cpus/aarch64/neoverse_v3.h
+++ b/include/lib/cpus/aarch64/neoverse_v3.h
@@ -30,4 +30,8 @@
  ******************************************************************************/
 #define NEOVERSE_V3_CPUACTLR6_EL1                                S3_0_C15_C8_1
 
+#ifndef __ASSEMBLER__
+long check_erratum_neoverse_v3_3701767(long cpu_rev);
+#endif /* __ASSEMBLER__ */
+
 #endif /* NEOVERSE_V3_H */
diff --git a/include/lib/cpus/errata.h b/include/lib/cpus/errata.h
index 04271e3..e0ea741 100644
--- a/include/lib/cpus/errata.h
+++ b/include/lib/cpus/errata.h
@@ -4,12 +4,11 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef ERRATA_REPORT_H
-#define ERRATA_REPORT_H
+#ifndef ERRATA_H
+#define ERRATA_H
 
 #include <lib/cpus/cpu_ops.h>
 
-
 #define ERRATUM_WA_FUNC_SIZE	CPU_WORD_SIZE
 #define ERRATUM_CHECK_FUNC_SIZE	CPU_WORD_SIZE
 #define ERRATUM_ID_SIZE		4
@@ -36,21 +35,6 @@
 void print_errata_status(void);
 void errata_print_msg(unsigned int status, const char *cpu, const char *id);
 
-#if ERRATA_A75_764081
-bool errata_a75_764081_applies(void);
-#else
-static inline bool errata_a75_764081_applies(void)
-{
-	return false;
-}
-#endif
-
-#if ERRATA_A520_2938996 || ERRATA_X4_2726228
-unsigned int check_if_affected_core(void);
-#endif
-
-int check_wa_cve_2024_7881(void);
-
 /*
  * NOTE that this structure will be different on AArch32 and AArch64. The
  * uintptr_t will reflect the change and the alignment will be correct in both.
@@ -69,6 +53,26 @@
 
 CASSERT(sizeof(struct erratum_entry) == ERRATUM_ENTRY_SIZE,
 	assert_erratum_entry_asm_c_different_sizes);
+
+/*
+ * Runtime errata helpers.
+ */
+#if ERRATA_A75_764081
+bool errata_a75_764081_applies(void);
+#else
+static inline bool errata_a75_764081_applies(void)
+{
+       return false;
+}
+#endif
+
+#if ERRATA_A520_2938996 || ERRATA_X4_2726228
+unsigned int check_if_affected_core(void);
+#endif
+
+int check_wa_cve_2024_7881(void);
+bool errata_ich_vmcr_el2_applies(void);
+
 #else
 
 /*
@@ -97,4 +101,4 @@
 /* Macro to get CPU revision code for checking errata version compatibility. */
 #define CPU_REV(r, p)		((r << 4) | p)
 
-#endif /* ERRATA_REPORT_H */
+#endif /* ERRATA_H */
diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h
index 6c13166..e63a42e 100644
--- a/include/lib/el3_runtime/aarch64/context.h
+++ b/include/lib/el3_runtime/aarch64/context.h
@@ -509,8 +509,6 @@
 void el1_sysregs_context_restore(el1_sysregs_t *regs);
 
 #if CTX_INCLUDE_EL2_REGS
-void el2_sysregs_context_save_common(el2_sysregs_t *regs);
-void el2_sysregs_context_restore_common(el2_sysregs_t *regs);
 #if ENABLE_SPE_FOR_LOWER_ELS
 void el2_sysregs_context_save_spe(el2_sysregs_t *regs);
 void el2_sysregs_context_restore_spe(el2_sysregs_t *regs);
diff --git a/lib/cpus/aarch64/cortex_a710.S b/lib/cpus/aarch64/cortex_a710.S
index 76ae8f6..b9b9204 100644
--- a/lib/cpus/aarch64/cortex_a710.S
+++ b/lib/cpus/aarch64/cortex_a710.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -22,6 +22,8 @@
 #error "Cortex A710 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
 #endif
 
+.global check_erratum_cortex_a710_3701772
+
 #if WORKAROUND_CVE_2022_23960
 	wa_cve_2022_23960_bhb_vector_table CORTEX_A710_BHB_LOOP_COUNT, cortex_a710
 #endif /* WORKAROUND_CVE_2022_23960 */
@@ -218,6 +220,10 @@
 
 check_erratum_chosen cortex_a710, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 
+add_erratum_entry cortex_a710, ERRATUM(3701772), ERRATA_A710_3701772, NO_APPLY_AT_RESET
+
+check_erratum_ls cortex_a710, ERRATUM(3701772), CPU_REV(2, 1)
+
 	/* ----------------------------------------------------
 	 * HW will do the cache maintenance while powering down
 	 * ----------------------------------------------------
diff --git a/lib/cpus/aarch64/cortex_a715.S b/lib/cpus/aarch64/cortex_a715.S
index 16be161..737d7b8 100644
--- a/lib/cpus/aarch64/cortex_a715.S
+++ b/lib/cpus/aarch64/cortex_a715.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -22,6 +22,8 @@
 #error "Cortex-A715 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
 #endif
 
+.global check_erratum_cortex_a715_3699560
+
 #if WORKAROUND_CVE_2022_23960
 	wa_cve_2022_23960_bhb_vector_table CORTEX_A715_BHB_LOOP_COUNT, cortex_a715
 #endif /* WORKAROUND_CVE_2022_23960 */
@@ -127,6 +129,10 @@
 
 check_erratum_chosen cortex_a715, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 
+add_erratum_entry cortex_a715, ERRATUM(3699560), ERRATA_A715_3699560, NO_APPLY_AT_RESET
+
+check_erratum_ls cortex_a715, ERRATUM(3699560), CPU_REV(1, 3)
+
 cpu_reset_func_start cortex_a715
 	/* Disable speculative loads */
 	msr	SSBS, xzr
diff --git a/lib/cpus/aarch64/cortex_a720.S b/lib/cpus/aarch64/cortex_a720.S
index 9cc3cbc..e69ec24 100644
--- a/lib/cpus/aarch64/cortex_a720.S
+++ b/lib/cpus/aarch64/cortex_a720.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -22,6 +22,8 @@
 #error "Cortex A720 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
 #endif
 
+.global check_erratum_cortex_a720_3699561
+
 #if WORKAROUND_CVE_2022_23960
         wa_cve_2022_23960_bhb_vector_table CORTEX_A720_BHB_LOOP_COUNT, cortex_a720
 #endif /* WORKAROUND_CVE_2022_23960 */
@@ -72,6 +74,10 @@
 
 check_erratum_chosen cortex_a720, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 
+add_erratum_entry cortex_a720, ERRATUM(3699561), ERRATA_A720_3699561, NO_APPLY_AT_RESET
+
+check_erratum_ls cortex_a720, ERRATUM(3699561), CPU_REV(0, 2)
+
 cpu_reset_func_start cortex_a720
 	/* Disable speculative loads */
 	msr	SSBS, xzr
diff --git a/lib/cpus/aarch64/cortex_x2.S b/lib/cpus/aarch64/cortex_x2.S
index 0a39f01..c226d51 100644
--- a/lib/cpus/aarch64/cortex_x2.S
+++ b/lib/cpus/aarch64/cortex_x2.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -22,6 +22,12 @@
 #error "Cortex X2 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
 #endif
 
+.global check_erratum_cortex_x2_3701772
+
+add_erratum_entry cortex_x2, ERRATUM(3701772), ERRATA_X2_3701772, NO_APPLY_AT_RESET
+
+check_erratum_ls cortex_x2, ERRATUM(3701772), CPU_REV(2, 1)
+
 #if WORKAROUND_CVE_2022_23960
 	wa_cve_2022_23960_bhb_vector_table CORTEX_X2_BHB_LOOP_COUNT, cortex_x2
 #endif /* WORKAROUND_CVE_2022_23960 */
diff --git a/lib/cpus/aarch64/cortex_x3.S b/lib/cpus/aarch64/cortex_x3.S
index db3ec74..30a4a14 100644
--- a/lib/cpus/aarch64/cortex_x3.S
+++ b/lib/cpus/aarch64/cortex_x3.S
@@ -22,6 +22,12 @@
 #error "Cortex-X3 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
 #endif
 
+.global check_erratum_cortex_x3_3701769
+
+add_erratum_entry cortex_x3, ERRATUM(3701769), ERRATA_X3_3701769, NO_APPLY_AT_RESET
+
+check_erratum_ls cortex_x3, ERRATUM(3701769), CPU_REV(1, 2)
+
 #if WORKAROUND_CVE_2022_23960
 	wa_cve_2022_23960_bhb_vector_table CORTEX_X3_BHB_LOOP_COUNT, cortex_x3
 #endif /* WORKAROUND_CVE_2022_23960 */
diff --git a/lib/cpus/aarch64/cortex_x4.S b/lib/cpus/aarch64/cortex_x4.S
index ebcb5aa..dbf6f54 100644
--- a/lib/cpus/aarch64/cortex_x4.S
+++ b/lib/cpus/aarch64/cortex_x4.S
@@ -23,6 +23,7 @@
 #endif
 
 .global check_erratum_cortex_x4_2726228
+.global check_erratum_cortex_x4_3701758
 
 #if WORKAROUND_CVE_2022_23960
         wa_cve_2022_23960_bhb_vector_table CORTEX_X4_BHB_LOOP_COUNT, cortex_x4
@@ -119,6 +120,10 @@
 
 check_erratum_chosen cortex_x4, CVE(2024, 7881), WORKAROUND_CVE_2024_7881
 
+add_erratum_entry cortex_x4, ERRATUM(3701758), ERRATA_X4_3701758, NO_APPLY_AT_RESET
+
+check_erratum_ls cortex_x4, ERRATUM(3701758), CPU_REV(0, 3)
+
 cpu_reset_func_start cortex_x4
 	/* Disable speculative loads */
 	msr	SSBS, xzr
diff --git a/lib/cpus/aarch64/neoverse_n2.S b/lib/cpus/aarch64/neoverse_n2.S
index ac739c0..ec04eac 100644
--- a/lib/cpus/aarch64/neoverse_n2.S
+++ b/lib/cpus/aarch64/neoverse_n2.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -20,6 +20,12 @@
 #error "Neoverse-N2 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
 #endif
 
+.global check_erratum_neoverse_n2_3701773
+
+add_erratum_entry neoverse_n2, ERRATUM(3701773), ERRATA_N2_3701773, NO_APPLY_AT_RESET
+
+check_erratum_ls neoverse_n2, ERRATUM(3701773), CPU_REV(0, 3)
+
 #if WORKAROUND_CVE_2022_23960
 	wa_cve_2022_23960_bhb_vector_table NEOVERSE_N2_BHB_LOOP_COUNT, neoverse_n2
 #endif /* WORKAROUND_CVE_2022_23960 */
diff --git a/lib/cpus/aarch64/neoverse_v3.S b/lib/cpus/aarch64/neoverse_v3.S
index d7e8252..716e777 100644
--- a/lib/cpus/aarch64/neoverse_v3.S
+++ b/lib/cpus/aarch64/neoverse_v3.S
@@ -22,6 +22,12 @@
 #error "Neoverse V3 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
 #endif
 
+.global check_erratum_neoverse_v3_3701767
+
+add_erratum_entry neoverse_v3, ERRATUM(3701767), ERRATA_V3_3701767, NO_APPLY_AT_RESET
+
+check_erratum_ls neoverse_v3, ERRATUM(3701767), CPU_REV(0, 2)
+
 #if WORKAROUND_CVE_2022_23960
 	wa_cve_2022_23960_bhb_vector_table NEOVERSE_V3_BHB_LOOP_COUNT, neoverse_v3
 #endif /* WORKAROUND_CVE_2022_23960 */
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index 242819a..31b3d85 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -568,6 +568,11 @@
 # still open.
 CPU_FLAG_LIST += ERRATA_V1_2779461
 
+# Flag to apply erratum 3701767 workaround during context save/restore of
+# ICH_VMCR_EL2 reg. This erratum applies to revisions r0p0, r0p1 and r0p2 of
+# the Neoverse V3 cpu and is still open.
+CPU_FLAG_LIST += ERRATA_V3_3701767
+
 # Flag to apply erratum 1987031 workaround during reset. This erratum applies
 # to revisions r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is still open.
 CPU_FLAG_LIST += ERRATA_A710_1987031
@@ -646,6 +651,11 @@
 # open.
 CPU_FLAG_LIST += ERRATA_A710_2778471
 
+# Flag to apply erratum  3701772 workaround during context save/restore of
+# ICH_VMCR_EL2 reg. This erratum applies to revisions r0p0, r1p0, r2p0, r2p1
+# of the Cortex-A710 cpu and is still open.
+CPU_FLAG_LIST += ERRATA_A710_3701772
+
 # Flag to apply erratum 2002655 workaround during reset. This erratum applies
 # to revisions r0p0 of the Neoverse-N2 cpu and is fixed in r0p1.
 CPU_FLAG_LIST += ERRATA_N2_2002655
@@ -727,6 +737,11 @@
 # to r0p0, r0p1, r0p2 of the Neoverse N2 cpu, it is fixed in r0p3.
 CPU_FLAG_LIST += ERRATA_N2_2779511
 
+# Flag to apply erratum 3701773 workaround during context save/restore of
+# ICH_VMCR_EL2 reg. This erratum applies to revisions r0p0, r0p1, r0p2 and r0p3
+# of the Neoverse N2 cpu and is still open.
+CPU_FLAG_LIST += ERRATA_N2_3701773
+
 # Flag to apply erratum 2002765 workaround during reset. This erratum applies
 # to revisions r0p0, r1p0, and r2p0 of the Cortex-X2 cpu and is still open.
 CPU_FLAG_LIST += ERRATA_X2_2002765
@@ -785,6 +800,11 @@
 # to revisions r0p0, r1p0, r2p0, r2p1 of the Cortex-X2 cpu and it is still open.
 CPU_FLAG_LIST += ERRATA_X2_2778471
 
+# Flag to apply erratum 3701772 workaround during context save/restore of
+# ICH_VMCR_EL2 reg. This erratum applies to revisions r0p0, r1p0, r2p0 and r2p1
+# of the Cortex-X2 cpu and is still open.
+CPU_FLAG_LIST += ERRATA_X2_3701772
+
 # Flag to apply erratum 2070301 workaround on reset. This erratum applies
 # to revisions r0p0, r1p0, r1p1 and r1p2 of the Cortex-X3 cpu and is
 # still open.
@@ -822,6 +842,11 @@
 # to revisions r0p0, r1p0 and r1p1 of the Cortex-X3 cpu, it is fixed in r1p2.
 CPU_FLAG_LIST += ERRATA_X3_2743088
 
+# Flag to apply erratum 3701769 workaround during context save/restore of
+# ICH_VMCR_EL2 reg. This erratum applies to revisions r0p0, r1p0, r1p1 and r1p2
+# of the Cortex-X3 cpu and is still open.
+CPU_FLAG_LIST += ERRATA_X3_3701769
+
 # Flag to apply erratum 2779509 workaround on reset. This erratum applies
 # to revisions r0p0, r1p0, r1p1 of the Cortex-X3 cpu, it is fixed in r1p2.
 CPU_FLAG_LIST += ERRATA_X3_2779509
@@ -859,6 +884,11 @@
 # to revisions r0p0 and r0p1 of the Cortex-X4 cpu. It is fixed in r0p2.
 CPU_FLAG_LIST += ERRATA_X4_3076789
 
+# Flag to apply erratum 3701758 workaround during context save/restore of
+# ICH_VMCR_EL2 reg. This erratum applies to revisions r0p0, r0p1, r0p2 and r0p3
+# of the Cortex-X4 cpu and is still open.
+CPU_FLAG_LIST += ERRATA_X4_3701758
+
 # Flag to apply erratum 1922240 workaround during reset. This erratum applies
 # to revision r0p0 of the Cortex-A510 cpu and is fixed in r0p1.
 CPU_FLAG_LIST += ERRATA_A510_1922240
@@ -984,6 +1014,11 @@
 # only to revision r0p0, r1p0 and r1p1. It is fixed in r1p2.
 CPU_FLAG_LIST += ERRATA_A715_2728106
 
+# Flag to apply erratum 3699560 workaround during context save/restore of
+# ICH_VMCR_EL2 reg. This erratum applies to revisions r0p0, r1p0, r1p2, r1p3
+# of the Cortex-A715 cpu and is still open.
+CPU_FLAG_LIST += ERRATA_A715_3699560
+
 # Flag to apply erratum 2792132 workaround during reset. This erratum applies
 # to revisions r0p0 and r0p1. It is fixed in r0p2.
 CPU_FLAG_LIST += ERRATA_A720_2792132
@@ -1000,12 +1035,17 @@
 # to revisions r0p0 and r0p1. It is fixed in r0p2.
 CPU_FLAG_LIST += ERRATA_A720_2940794
 
+# Flag to apply erratum 3699561 workaround during context save/restore of
+# ICH_VMCR_EL2 reg. This erratum applies to revisions r0p0, r0p1, r0p2 of
+# the Cortex-A720 cpu and is still open.
+CPU_FLAG_LIST += ERRATA_A720_3699561
+
 # Flag to apply DSU erratum 798953. This erratum applies to DSUs revision r0p0.
 # Applying the workaround results in higher DSU power consumption on idle.
 CPU_FLAG_LIST += ERRATA_DSU_798953
 
 # Flag to apply DSU erratum 936184. This erratum applies to DSUs containing
-# the ACP interface and revision < r2p0. Applying the workaround results in
+# the ACP interface and revision < r0p0. Applying the workaround results in
 # higher DSU power consumption on idle.
 CPU_FLAG_LIST += ERRATA_DSU_936184
 
diff --git a/lib/cpus/errata_common.c b/lib/cpus/errata_common.c
index 6ca7ef1..ae806a0 100644
--- a/lib/cpus/errata_common.c
+++ b/lib/cpus/errata_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,11 +8,18 @@
 
 #include <arch.h>
 #include <arch_helpers.h>
-#include <cortex_a520.h>
 #include <cortex_a75.h>
+#include <cortex_a520.h>
+#include <cortex_a710.h>
+#include <cortex_a715.h>
+#include <cortex_a720.h>
+#include <cortex_x2.h>
+#include <cortex_x3.h>
 #include <cortex_x4.h>
 #include <lib/cpus/cpu_ops.h>
 #include <lib/cpus/errata.h>
+#include <neoverse_n2.h>
+#include <neoverse_v3.h>
 
 #if ERRATA_A520_2938996 || ERRATA_X4_2726228
 unsigned int check_if_affected_core(void)
@@ -42,3 +49,68 @@
 }
 #endif /* ERRATA_A75_764081 */
 
+bool errata_ich_vmcr_el2_applies(void)
+{
+	switch (EXTRACT_PARTNUM(read_midr())) {
+#if ERRATA_A710_3701772
+	case EXTRACT_PARTNUM(CORTEX_A710_MIDR):
+		if (check_erratum_cortex_a710_3701772(cpu_get_rev_var()) == ERRATA_APPLIES)
+			return true;
+		break;
+#endif /* ERRATA_A710_3701772 */
+
+#if ERRATA_A715_3699560
+	case EXTRACT_PARTNUM(CORTEX_A715_MIDR):
+		if (check_erratum_cortex_a715_3699560(cpu_get_rev_var()) == ERRATA_APPLIES)
+			return true;
+		break;
+#endif /* ERRATA_A715_3699560 */
+
+#if ERRATA_A720_3699561
+	case EXTRACT_PARTNUM(CORTEX_A720_MIDR):
+		if (check_erratum_cortex_a720_3699561(cpu_get_rev_var()) == ERRATA_APPLIES)
+			return true;;
+		break;
+#endif /* ERRATA_A720_3699561 */
+
+#if ERRATA_X2_3701772
+	case EXTRACT_PARTNUM(CORTEX_X2_MIDR):
+		if (check_erratum_cortex_x2_3701772(cpu_get_rev_var()) == ERRATA_APPLIES)
+			return true;
+		break;
+#endif /* ERRATA_X2_3701772 */
+
+#if ERRATA_X3_3701769
+	case EXTRACT_PARTNUM(CORTEX_X3_MIDR):
+		if (check_erratum_cortex_x3_3701769(cpu_get_rev_var()) == ERRATA_APPLIES)
+			return true;
+		break;
+#endif /* ERRATA_X3_3701769 */
+
+#if ERRATA_X4_3701758
+	case EXTRACT_PARTNUM(CORTEX_X4_MIDR):
+		if (check_erratum_cortex_x4_3701758(cpu_get_rev_var()) == ERRATA_APPLIES)
+			return true;
+		break;
+#endif /* ERRATA_X4_3701758 */
+
+#if ERRATA_N2_3701773
+	case EXTRACT_PARTNUM(NEOVERSE_N2_MIDR):
+		if (check_erratum_neoverse_n2_3701773(cpu_get_rev_var()) == ERRATA_APPLIES)
+			return true;
+		break;
+#endif /* ERRATA_N2_3701773 */
+
+#if ERRATA_V3_3701767
+	case EXTRACT_PARTNUM(NEOVERSE_V3_MIDR):
+		if (check_erratum_neoverse_v3_3701767(cpu_get_rev_var()) == ERRATA_APPLIES)
+			return true;
+		break;
+#endif /* ERRATA_V3_3701767 */
+
+	default:
+		break;
+	}
+
+	return false;
+}
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index b126b9c..13dba56 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -11,8 +11,6 @@
 #include <el3_common_macros.S>
 
 #if CTX_INCLUDE_EL2_REGS
-	.global	el2_sysregs_context_save_common
-	.global	el2_sysregs_context_restore_common
 #if ENABLE_SPE_FOR_LOWER_ELS
 	.global	el2_sysregs_context_save_spe
 	.global	el2_sysregs_context_restore_spe
@@ -72,166 +70,6 @@
 
 #if CTX_INCLUDE_EL2_REGS
 
-/* -----------------------------------------------------
- * The following functions strictly follow the AArch64
- * PCS to use x9-x16 (temporary caller-saved registers)
- * to save/restore EL2 system register context.
- * el2_sysregs_context_save/restore_common functions
- * save and restore registers that are common to all
- * configurations. The rest of the functions save and
- * restore EL2 system registers that are present when a
- * particular feature is enabled. All functions assume
- * that 'x0' is pointing to a 'el2_sys_regs' structure
- * where the register context will be saved/restored.
- *
- * The following registers are not added.
- * AMEVCNTVOFF0<n>_EL2
- * AMEVCNTVOFF1<n>_EL2
- * ICH_AP0R<n>_EL2
- * ICH_AP1R<n>_EL2
- * ICH_LR<n>_EL2
- * -----------------------------------------------------
- */
-func el2_sysregs_context_save_common
-	mrs	x9, actlr_el2
-	mrs	x10, afsr0_el2
-	stp	x9, x10, [x0, #CTX_ACTLR_EL2]
-
-	mrs	x11, afsr1_el2
-	mrs	x12, amair_el2
-	stp	x11, x12, [x0, #CTX_AFSR1_EL2]
-
-	mrs	x13, cnthctl_el2
-	mrs	x14, cntvoff_el2
-	stp	x13, x14, [x0, #CTX_CNTHCTL_EL2]
-
-	mrs	x15, cptr_el2
-	str	x15, [x0, #CTX_CPTR_EL2]
-
-#if CTX_INCLUDE_AARCH32_REGS
-	mrs	x16, dbgvcr32_el2
-	str	x16, [x0, #CTX_DBGVCR32_EL2]
-#endif /* CTX_INCLUDE_AARCH32_REGS */
-
-	mrs	x9, elr_el2
-	mrs	x10, esr_el2
-	stp	x9, x10, [x0, #CTX_ELR_EL2]
-
-	mrs	x11, far_el2
-	mrs	x12, hacr_el2
-	stp	x11, x12, [x0, #CTX_FAR_EL2]
-
-	mrs	x13, hcr_el2
-	mrs	x14, hpfar_el2
-	stp	x13, x14, [x0, #CTX_HCR_EL2]
-
-	mrs	x15, hstr_el2
-	mrs	x16, ICC_SRE_EL2
-	stp	x15, x16, [x0, #CTX_HSTR_EL2]
-
-	mrs	x9, ICH_HCR_EL2
-	mrs	x10, ICH_VMCR_EL2
-	stp	x9, x10, [x0, #CTX_ICH_HCR_EL2]
-
-	mrs	x11, mair_el2
-	mrs	x12, mdcr_el2
-	stp	x11, x12, [x0, #CTX_MAIR_EL2]
-
-	mrs	x14, sctlr_el2
-	str	x14, [x0, #CTX_SCTLR_EL2]
-
-	mrs	x15, spsr_el2
-	mrs	x16, sp_el2
-	stp	x15, x16, [x0, #CTX_SPSR_EL2]
-
-	mrs	x9, tcr_el2
-	mrs	x10, tpidr_el2
-	stp	x9, x10, [x0, #CTX_TCR_EL2]
-
-	mrs	x11, ttbr0_el2
-	mrs	x12, vbar_el2
-	stp	x11, x12, [x0, #CTX_TTBR0_EL2]
-
-	mrs	x13, vmpidr_el2
-	mrs	x14, vpidr_el2
-	stp	x13, x14, [x0, #CTX_VMPIDR_EL2]
-
-	mrs	x15, vtcr_el2
-	mrs	x16, vttbr_el2
-	stp	x15, x16, [x0, #CTX_VTCR_EL2]
-	ret
-endfunc el2_sysregs_context_save_common
-
-func el2_sysregs_context_restore_common
-	ldp	x9, x10, [x0, #CTX_ACTLR_EL2]
-	msr	actlr_el2, x9
-	msr	afsr0_el2, x10
-
-	ldp	x11, x12, [x0, #CTX_AFSR1_EL2]
-	msr	afsr1_el2, x11
-	msr	amair_el2, x12
-
-	ldp	x13, x14, [x0, #CTX_CNTHCTL_EL2]
-	msr	cnthctl_el2, x13
-	msr	cntvoff_el2, x14
-
-	ldr	x15, [x0, #CTX_CPTR_EL2]
-	msr	cptr_el2, x15
-
-#if CTX_INCLUDE_AARCH32_REGS
-	ldr	x16, [x0, #CTX_DBGVCR32_EL2]
-	msr	dbgvcr32_el2, x16
-#endif /* CTX_INCLUDE_AARCH32_REGS */
-
-	ldp	x9, x10, [x0, #CTX_ELR_EL2]
-	msr	elr_el2, x9
-	msr	esr_el2, x10
-
-	ldp	x11, x12, [x0, #CTX_FAR_EL2]
-	msr	far_el2, x11
-	msr	hacr_el2, x12
-
-	ldp	x13, x14, [x0, #CTX_HCR_EL2]
-	msr	hcr_el2, x13
-	msr	hpfar_el2, x14
-
-	ldp	x15, x16, [x0, #CTX_HSTR_EL2]
-	msr	hstr_el2, x15
-	msr	ICC_SRE_EL2, x16
-
-	ldp	x9, x10, [x0, #CTX_ICH_HCR_EL2]
-	msr	ICH_HCR_EL2, x9
-	msr	ICH_VMCR_EL2, x10
-
-	ldp	x11, x12, [x0, #CTX_MAIR_EL2]
-	msr	mair_el2, x11
-	msr	mdcr_el2, x12
-
-	ldr	x14, [x0, #CTX_SCTLR_EL2]
-	msr	sctlr_el2, x14
-
-	ldp	x15, x16, [x0, #CTX_SPSR_EL2]
-	msr	spsr_el2, x15
-	msr	sp_el2, x16
-
-	ldp	x9, x10, [x0, #CTX_TCR_EL2]
-	msr	tcr_el2, x9
-	msr	tpidr_el2, x10
-
-	ldp	x11, x12, [x0, #CTX_TTBR0_EL2]
-	msr	ttbr0_el2, x11
-	msr	vbar_el2, x12
-
-	ldp	x13, x14, [x0, #CTX_VMPIDR_EL2]
-	msr	vmpidr_el2, x13
-	msr	vpidr_el2, x14
-
-	ldp	x15, x16, [x0, #CTX_VTCR_EL2]
-	msr	vtcr_el2, x15
-	msr	vttbr_el2, x16
-	ret
-endfunc el2_sysregs_context_restore_common
-
 #if ENABLE_SPE_FOR_LOWER_ELS
 func el2_sysregs_context_save_spe
 	mrs	x13, PMSCR_EL2
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index ed22beb..5887bee 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2025, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2022, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -794,6 +794,160 @@
 }
 
 #if CTX_INCLUDE_EL2_REGS
+/* ---------------------------------------------------------------------------
+ * The following registers are not added:
+ * ICH_AP0R<n>_EL2
+ * ICH_AP1R<n>_EL2
+ * ICH_LR<n>_EL2
+ *
+ * NOTE: For a system with S-EL2 present but not enabled, accessing
+ * ICC_SRE_EL2 is undefined from EL3. To workaround this change the
+ * SCR_EL3.NS = 1 before accessing this register.
+ * ---------------------------------------------------------------------------
+ */
+static void el2_sysregs_context_save_gic(el2_sysregs_t *ctx, uint32_t security_state)
+{
+	u_register_t scr_el3 = read_scr_el3();
+
+#if defined(SPD_spmd) && SPMD_SPM_AT_SEL2
+	write_ctx_reg(ctx, CTX_ICC_SRE_EL2, read_icc_sre_el2());
+#else
+	write_scr_el3(scr_el3 | SCR_NS_BIT);
+	isb();
+
+	write_ctx_reg(ctx, CTX_ICC_SRE_EL2, read_icc_sre_el2());
+
+	write_scr_el3(scr_el3);
+	isb();
+
+#endif
+	write_ctx_reg(ctx, CTX_ICH_HCR_EL2, read_ich_hcr_el2());
+
+	if (errata_ich_vmcr_el2_applies()) {
+		if (security_state == SECURE) {
+			write_scr_el3(scr_el3 & ~SCR_NS_BIT);
+		} else {
+			write_scr_el3(scr_el3 | SCR_NS_BIT);
+		}
+		isb();
+	}
+
+	write_ctx_reg(ctx, CTX_ICH_VMCR_EL2, read_ich_vmcr_el2());
+
+	if (errata_ich_vmcr_el2_applies()) {
+		write_scr_el3(scr_el3);
+		isb();
+	}
+}
+
+static void el2_sysregs_context_restore_gic(el2_sysregs_t *ctx, uint32_t security_state)
+{
+	u_register_t scr_el3 = read_scr_el3();
+
+#if defined(SPD_spmd) && SPMD_SPM_AT_SEL2
+	write_icc_sre_el2(read_ctx_reg(ctx, CTX_ICC_SRE_EL2));
+#else
+	write_scr_el3(scr_el3 | SCR_NS_BIT);
+	isb();
+
+	write_icc_sre_el2(read_ctx_reg(ctx, CTX_ICC_SRE_EL2));
+
+	write_scr_el3(scr_el3);
+	isb();
+#endif
+	write_ich_hcr_el2(read_ctx_reg(ctx, CTX_ICH_HCR_EL2));
+
+	if (errata_ich_vmcr_el2_applies()) {
+		if (security_state == SECURE) {
+			write_scr_el3(scr_el3 & ~SCR_NS_BIT);
+		} else {
+			write_scr_el3(scr_el3 | SCR_NS_BIT);
+		}
+		isb();
+	}
+
+	write_ich_vmcr_el2(read_ctx_reg(ctx, CTX_ICH_VMCR_EL2));
+
+	if (errata_ich_vmcr_el2_applies()) {
+		write_scr_el3(scr_el3);
+		isb();
+	}
+}
+
+/* -----------------------------------------------------
+ * The following registers are not added:
+ * AMEVCNTVOFF0<n>_EL2
+ * AMEVCNTVOFF1<n>_EL2
+ * -----------------------------------------------------
+ */
+static void el2_sysregs_context_save_common(el2_sysregs_t *ctx)
+{
+	write_ctx_reg(ctx, CTX_ACTLR_EL2, read_actlr_el2());
+	write_ctx_reg(ctx, CTX_AFSR0_EL2, read_afsr0_el2());
+	write_ctx_reg(ctx, CTX_AFSR1_EL2, read_afsr1_el2());
+	write_ctx_reg(ctx, CTX_AMAIR_EL2, read_amair_el2());
+	write_ctx_reg(ctx, CTX_CNTHCTL_EL2, read_cnthctl_el2());
+	write_ctx_reg(ctx, CTX_CNTVOFF_EL2, read_cntvoff_el2());
+	write_ctx_reg(ctx, CTX_CPTR_EL2, read_cptr_el2());
+	if (CTX_INCLUDE_AARCH32_REGS) {
+		write_ctx_reg(ctx, CTX_DBGVCR32_EL2, read_dbgvcr32_el2());
+	}
+	write_ctx_reg(ctx, CTX_ELR_EL2, read_elr_el2());
+	write_ctx_reg(ctx, CTX_ESR_EL2, read_esr_el2());
+	write_ctx_reg(ctx, CTX_FAR_EL2, read_far_el2());
+	write_ctx_reg(ctx, CTX_HACR_EL2, read_hacr_el2());
+	write_ctx_reg(ctx, CTX_HCR_EL2, read_hcr_el2());
+	write_ctx_reg(ctx, CTX_HPFAR_EL2, read_hpfar_el2());
+	write_ctx_reg(ctx, CTX_HSTR_EL2, read_hstr_el2());
+	write_ctx_reg(ctx, CTX_MAIR_EL2, read_mair_el2());
+	write_ctx_reg(ctx, CTX_MDCR_EL2, read_mdcr_el2());
+	write_ctx_reg(ctx, CTX_SCTLR_EL2, read_sctlr_el2());
+	write_ctx_reg(ctx, CTX_SPSR_EL2, read_spsr_el2());
+	write_ctx_reg(ctx, CTX_SP_EL2, read_sp_el2());
+	write_ctx_reg(ctx, CTX_TCR_EL2, read_tcr_el2());
+	write_ctx_reg(ctx, CTX_TPIDR_EL2, read_tpidr_el2());
+	write_ctx_reg(ctx, CTX_TTBR0_EL2, read_ttbr0_el2());
+	write_ctx_reg(ctx, CTX_VBAR_EL2, read_vbar_el2());
+	write_ctx_reg(ctx, CTX_VMPIDR_EL2, read_vmpidr_el2());
+	write_ctx_reg(ctx, CTX_VPIDR_EL2, read_vpidr_el2());
+	write_ctx_reg(ctx, CTX_VTCR_EL2, read_vtcr_el2());
+	write_ctx_reg(ctx, CTX_VTTBR_EL2, read_vttbr_el2());
+}
+
+static void el2_sysregs_context_restore_common(el2_sysregs_t *ctx)
+{
+	write_actlr_el2(read_ctx_reg(ctx, CTX_ACTLR_EL2));
+	write_afsr0_el2(read_ctx_reg(ctx, CTX_AFSR0_EL2));
+	write_afsr1_el2(read_ctx_reg(ctx, CTX_AFSR1_EL2));
+	write_amair_el2(read_ctx_reg(ctx, CTX_AMAIR_EL2));
+	write_cnthctl_el2(read_ctx_reg(ctx, CTX_CNTHCTL_EL2));
+	write_cntvoff_el2(read_ctx_reg(ctx, CTX_CNTVOFF_EL2));
+	write_cptr_el2(read_ctx_reg(ctx, CTX_CPTR_EL2));
+	if (CTX_INCLUDE_AARCH32_REGS) {
+		write_dbgvcr32_el2(read_ctx_reg(ctx, CTX_DBGVCR32_EL2));
+	}
+	write_elr_el2(read_ctx_reg(ctx, CTX_ELR_EL2));
+	write_esr_el2(read_ctx_reg(ctx, CTX_ESR_EL2));
+	write_far_el2(read_ctx_reg(ctx, CTX_FAR_EL2));
+	write_hacr_el2(read_ctx_reg(ctx, CTX_HACR_EL2));
+	write_hcr_el2(read_ctx_reg(ctx, CTX_HCR_EL2));
+	write_hpfar_el2(read_ctx_reg(ctx, CTX_HPFAR_EL2));
+	write_hstr_el2(read_ctx_reg(ctx, CTX_HSTR_EL2));
+	write_mair_el2(read_ctx_reg(ctx, CTX_MAIR_EL2));
+	write_mdcr_el2(read_ctx_reg(ctx, CTX_MDCR_EL2));
+	write_sctlr_el2(read_ctx_reg(ctx, CTX_SCTLR_EL2));
+	write_spsr_el2(read_ctx_reg(ctx, CTX_SPSR_EL2));
+	write_sp_el2(read_ctx_reg(ctx, CTX_SP_EL2));
+	write_tcr_el2(read_ctx_reg(ctx, CTX_TCR_EL2));
+	write_tpidr_el2(read_ctx_reg(ctx, CTX_TPIDR_EL2));
+	write_ttbr0_el2(read_ctx_reg(ctx, CTX_TTBR0_EL2));
+	write_vbar_el2(read_ctx_reg(ctx, CTX_VBAR_EL2));
+	write_vmpidr_el2(read_ctx_reg(ctx, CTX_VMPIDR_EL2));
+	write_vpidr_el2(read_ctx_reg(ctx, CTX_VPIDR_EL2));
+	write_vtcr_el2(read_ctx_reg(ctx, CTX_VTCR_EL2));
+	write_vttbr_el2(read_ctx_reg(ctx, CTX_VTTBR_EL2));
+}
+
 /*******************************************************************************
  * Save EL2 sysreg context
  ******************************************************************************/
@@ -816,11 +970,13 @@
 		el2_sysregs_ctx = get_el2_sysregs_ctx(ctx);
 
 		el2_sysregs_context_save_common(el2_sysregs_ctx);
+		el2_sysregs_context_save_gic(el2_sysregs_ctx, security_state);
+
 #if ENABLE_SPE_FOR_LOWER_ELS
 		el2_sysregs_context_save_spe(el2_sysregs_ctx);
 #endif
 #if CTX_INCLUDE_MTE_REGS
-		el2_sysregs_context_save_mte(el2_sysregs_ctx);
+		write_ctx_reg(el2_sysregs_ctx, CTX_TFSR_EL2, read_tfsr_el2());
 #endif
 #if ENABLE_MPAM_FOR_LOWER_ELS
 		el2_sysregs_context_save_mpam(el2_sysregs_ctx);
@@ -874,11 +1030,13 @@
 		el2_sysregs_ctx = get_el2_sysregs_ctx(ctx);
 
 		el2_sysregs_context_restore_common(el2_sysregs_ctx);
+		el2_sysregs_context_restore_gic(el2_sysregs_ctx, security_state);
+
 #if ENABLE_SPE_FOR_LOWER_ELS
 		el2_sysregs_context_restore_spe(el2_sysregs_ctx);
 #endif
 #if CTX_INCLUDE_MTE_REGS
-		el2_sysregs_context_restore_mte(el2_sysregs_ctx);
+		write_tfsr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_TFSR_EL2));
 #endif
 #if ENABLE_MPAM_FOR_LOWER_ELS
 		el2_sysregs_context_restore_mpam(el2_sysregs_ctx);
diff --git a/services/std_svc/errata_abi/cpu_errata_info.h b/services/std_svc/errata_abi/cpu_errata_info.h
index 2d59fc9..21a23e1 100644
--- a/services/std_svc/errata_abi/cpu_errata_info.h
+++ b/services/std_svc/errata_abi/cpu_errata_info.h
@@ -8,6 +8,7 @@
 #define ERRATA_CPUSPEC_H
 
 #include <stdint.h>
+#include <arch.h>
 #include <arch_helpers.h>
 
 #if __aarch64__
@@ -31,8 +32,6 @@
 /* Default values for unused memory in the array */
 #define UNDEF_ERRATA		{UINT_MAX, UCHAR_MAX, UCHAR_MAX}
 
-#define EXTRACT_PARTNUM(x)	((x >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
-
 #define RXPX_RANGE(x, y, z)	(((x >= y) && (x <= z)) ? true : false)
 
 /*