Merge changes Id942c20c,Idd286bea,I8917a26e,Iec8c3477,If3c25dcd, ... into integration

* changes:
  feat(cpufeat): enable FEAT_PAuth to FEAT_STATE_CHECKED
  perf(cpufeat): centralise PAuth key saving
  refactor(cpufeat): convert FEAT_PAuth setup to C
  refactor(cpufeat): prepare FEAT_PAuth for FEATURE_DETECTION
  chore(cpufeat): remove PAuth presence checks
  feat(cpufeat): enable FEAT_BTI to FEAT_STATE_CHECKED
diff --git a/Makefile b/Makefile
index 3dbf11a..4f6afaf 100644
--- a/Makefile
+++ b/Makefile
@@ -492,6 +492,12 @@
 include ${PLAT_MAKEFILE_FULL}
 
 ################################################################################
+# Setup arch_features based on ARM_ARCH_MAJOR, ARM_ARCH_MINOR provided from
+# platform.
+################################################################################
+
+include ${MAKE_HELPERS_DIRECTORY}arch_features.mk
+################################################################################
 # Process BRANCH_PROTECTION value and set
 # Pointer Authentication and Branch Target Identification flags
 ################################################################################
@@ -517,30 +523,29 @@
 	# Turn on branch target identification mechanism
 	BP_OPTION := bti
 	ENABLE_BTI := 1
+else ifeq (${BRANCH_PROTECTION},5)
+	# Turn on branch target identification mechanism
+	BP_OPTION := standard
+	ENABLE_BTI := 2
+	ENABLE_PAUTH := 2
 else
         $(error Unknown BRANCH_PROTECTION value ${BRANCH_PROTECTION})
 endif #(BRANCH_PROTECTION)
 
-ifeq ($(ENABLE_PAUTH),1)
-	CTX_INCLUDE_PAUTH_REGS := 1
+ifneq ($(ENABLE_PAUTH),0)
+	CTX_INCLUDE_PAUTH_REGS	:= ${ENABLE_PAUTH}
 endif
 ifneq (${BP_OPTION},none)
 	TF_CFLAGS_aarch64	+=	-mbranch-protection=${BP_OPTION}
 endif #(BP_OPTION)
 
 # Pointer Authentication sources
-ifeq (${ENABLE_PAUTH}, 1)
+ifneq (${ENABLE_PAUTH},0)
 # arm/common/aarch64/arm_pauth.c contains a sample platform hook to complete the
 # Pauth support. As it's not secure, it must be reimplemented for real platforms
-	BL_COMMON_SOURCES	+=	lib/extensions/pauth/pauth_helpers.S
+	BL_COMMON_SOURCES	+=	lib/extensions/pauth/pauth.c
 endif
 
-################################################################################
-# Setup arch_features based on ARM_ARCH_MAJOR, ARM_ARCH_MINOR provided from
-# platform.
-################################################################################
-include ${MAKE_HELPERS_DIRECTORY}arch_features.mk
-
 ####################################################
 # Enable required options for Memory Stack Tagging.
 ####################################################
@@ -917,13 +922,13 @@
 # If pointer authentication is used in the firmware, make sure that all the
 # registers associated to it are also saved and restored.
 # Not doing it would leak the value of the keys used by EL3 to EL1 and S-EL1.
-ifeq ($(ENABLE_PAUTH),1)
+ifneq ($(ENABLE_PAUTH),0)
 	ifeq ($(CTX_INCLUDE_PAUTH_REGS),0)
-                $(error Pointer Authentication requires CTX_INCLUDE_PAUTH_REGS=1)
+                $(error Pointer Authentication requires CTX_INCLUDE_PAUTH_REGS to be enabled)
 	endif
 endif #(ENABLE_PAUTH)
 
-ifeq ($(CTX_INCLUDE_PAUTH_REGS),1)
+ifneq ($(CTX_INCLUDE_PAUTH_REGS),0)
 	ifneq (${ARCH},aarch64)
                 $(error CTX_INCLUDE_PAUTH_REGS requires AArch64)
 	endif
diff --git a/bl1/aarch64/bl1_exceptions.S b/bl1/aarch64/bl1_exceptions.S
index eaaf59a..3e3e002 100644
--- a/bl1/aarch64/bl1_exceptions.S
+++ b/bl1/aarch64/bl1_exceptions.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -224,15 +224,6 @@
 	 */
 	bl	prepare_el3_entry
 
-#if ENABLE_PAUTH
-	/* -----------------------------------------------------
-	 * Load and program stored APIAKey firmware key.
-	 * Re-enable pointer authentication in EL3, as it was
-	 * disabled before jumping to the next boot image.
-	 * -----------------------------------------------------
-	 */
-	bl	pauth_load_bl1_apiakey_enable
-#endif
 	/* -----------------------------------------------------
 	 * Populate the parameters for the SMC handler. We
 	 * already have x0-x4 in place. x5 will point to a
diff --git a/bl1/bl1_main.c b/bl1/bl1_main.c
index 2b3a827..db14ec6 100644
--- a/bl1/bl1_main.c
+++ b/bl1/bl1_main.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.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -52,14 +52,6 @@
 
 	/* Perform late platform-specific setup */
 	bl1_plat_arch_setup();
-
-#if CTX_INCLUDE_PAUTH_REGS
-	/*
-	 * Assert that the ARMv8.3-PAuth registers are present or an access
-	 * fault will be triggered when they are being saved or restored.
-	 */
-	assert(is_armv8_3_pauth_present());
-#endif /* CTX_INCLUDE_PAUTH_REGS */
 }
 
 /*******************************************************************************
@@ -127,12 +119,6 @@
 	/* Perform platform setup in BL1. */
 	bl1_platform_setup();
 
-#if ENABLE_PAUTH
-	/* Store APIAKey_EL1 key */
-	bl1_apiakey[0] = read_apiakeylo_el1();
-	bl1_apiakey[1] = read_apiakeyhi_el1();
-#endif /* ENABLE_PAUTH */
-
 	/* Get the image id of next image to load and run. */
 	image_id = bl1_plat_get_next_image_id();
 
diff --git a/bl2/aarch64/bl2_entrypoint.S b/bl2/aarch64/bl2_entrypoint.S
index a021e42..756c16d 100644
--- a/bl2/aarch64/bl2_entrypoint.S
+++ b/bl2/aarch64/bl2_entrypoint.S
@@ -48,6 +48,10 @@
 	mov	x1, #(SCTLR_I_BIT | SCTLR_A_BIT | SCTLR_SA_BIT)
 	mrs	x0, sctlr_el1
 	orr	x0, x0, x1
+#if ENABLE_BTI
+	/* Enable PAC branch type compatibility */
+	bic     x0, x0, #(SCTLR_BT0_BIT | SCTLR_BT1_BIT)
+#endif
 	bic	x0, x0, #SCTLR_DSSBS_BIT
 	msr	sctlr_el1, x0
 	isb
diff --git a/bl2/bl2_main.c b/bl2/bl2_main.c
index f12c1a5..dbe9453 100644
--- a/bl2/bl2_main.c
+++ b/bl2/bl2_main.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.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -50,14 +50,6 @@
 
 	/* Perform late platform-specific setup */
 	bl2_el3_plat_arch_setup();
-
-#if CTX_INCLUDE_PAUTH_REGS
-	/*
-	 * Assert that the ARMv8.3-PAuth registers are present or an access
-	 * fault will be triggered when they are being saved or restored.
-	 */
-	assert(is_armv8_3_pauth_present());
-#endif /* CTX_INCLUDE_PAUTH_REGS */
 }
 #else /* RESET_TO_BL2 */
 
@@ -75,14 +67,6 @@
 
 	/* Perform late platform-specific setup */
 	bl2_plat_arch_setup();
-
-#if CTX_INCLUDE_PAUTH_REGS
-	/*
-	 * Assert that the ARMv8.3-PAuth registers are present or an access
-	 * fault will be triggered when they are being saved or restored.
-	 */
-	assert(is_armv8_3_pauth_present());
-#endif /* CTX_INCLUDE_PAUTH_REGS */
 }
 #endif /* RESET_TO_BL2 */
 
@@ -136,12 +120,12 @@
 	disable_mmu_icache_secure();
 #endif /* !__aarch64__ */
 
-#if ENABLE_PAUTH
 	/*
 	 * Disable pointer authentication before running next boot image
 	 */
-	pauth_disable_el1();
-#endif /* ENABLE_PAUTH */
+	if (is_feat_pauth_supported()) {
+		pauth_disable_el1();
+	}
 
 #if ENABLE_RUNTIME_INSTRUMENTATION
 	PMF_CAPTURE_TIMESTAMP(bl_svc, BL2_EXIT, PMF_CACHE_MAINT);
@@ -164,12 +148,12 @@
 #endif
 	console_flush();
 
-#if ENABLE_PAUTH
 	/*
 	 * Disable pointer authentication before running next boot image
 	 */
-	pauth_disable_el3();
-#endif /* ENABLE_PAUTH */
+	if (is_feat_pauth_supported()) {
+		pauth_disable_el3();
+	}
 
 	bl2_run_next_image(next_bl_ep_info);
 #endif /* BL2_RUNS_AT_EL3 */
diff --git a/bl2u/aarch64/bl2u_entrypoint.S b/bl2u/aarch64/bl2u_entrypoint.S
index 15978b6..8fc34b3 100644
--- a/bl2u/aarch64/bl2u_entrypoint.S
+++ b/bl2u/aarch64/bl2u_entrypoint.S
@@ -45,6 +45,10 @@
 	mov	x1, #(SCTLR_I_BIT | SCTLR_A_BIT | SCTLR_SA_BIT)
 	mrs	x0, sctlr_el1
 	orr	x0, x0, x1
+#if ENABLE_BTI
+	/* Enable PAC branch type compatibility */
+	bic     x0, x0, #(SCTLR_BT0_BIT | SCTLR_BT1_BIT)
+#endif
 	bic	x0, x0, #SCTLR_DSSBS_BIT
 	msr	sctlr_el1, x0
 	isb
diff --git a/bl31/aarch64/crash_reporting.S b/bl31/aarch64/crash_reporting.S
index b5bf575..7b61692 100644
--- a/bl31/aarch64/crash_reporting.S
+++ b/bl31/aarch64/crash_reporting.S
@@ -397,8 +397,26 @@
 	ldr	x4, [x0, #REGSZ * 7]
 
 #if ENABLE_PAUTH
+#if ENABLE_PAUTH == 2
+	/* Skip if not present in hardware */
+	is_feat_pauth_present_asm x0, x1
+	beq	1f
+#endif
+	/*
+	 * The assembler must see support for xpaci. So turn the compiler
+	 * extension on. GCC prior to 10 doesn't understand the PAuth extension
+	 * but it does understand armv8.3-a in general. Avoid using 8.3 if
+	 * the compiler understands "pauth" so we don't downgrade a higher
+	 * -march that was specified on the commandline.
+	 */
+#if __GNUC__ < 10
+	.arch armv8.3-a
+#else
+	.arch_extension pauth
+#endif
 	/* Demangle address */
 	xpaci	x4
+1:
 #endif
 	bl	asm_print_hex
 	bl	asm_print_newline
diff --git a/bl31/aarch64/ea_delegate.S b/bl31/aarch64/ea_delegate.S
index fce17e1..3f1b3ea 100644
--- a/bl31/aarch64/ea_delegate.S
+++ b/bl31/aarch64/ea_delegate.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2025, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2022, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -46,11 +46,6 @@
 	 */
 	bl	prepare_el3_entry
 
-#if ENABLE_PAUTH
-	/* Load and program APIAKey firmware key */
-	bl	pauth_load_bl31_apiakey
-#endif
-
 	/* Setup exception class and syndrome arguments for platform handler */
 	mov	x0, #ERROR_EA_SYNC
 	mrs	x1, esr_el3
@@ -78,11 +73,6 @@
 	 */
 	bl	prepare_el3_entry
 
-#if ENABLE_PAUTH
-	/* Load and program APIAKey firmware key */
-	bl	pauth_load_bl31_apiakey
-#endif
-
 	/* Setup exception class and syndrome arguments for platform handler */
 	mov	x0, #ERROR_EA_ASYNC
 	mrs	x1, esr_el3
diff --git a/bl31/aarch64/runtime_exceptions.S b/bl31/aarch64/runtime_exceptions.S
index 7423805..6537aa7 100644
--- a/bl31/aarch64/runtime_exceptions.S
+++ b/bl31/aarch64/runtime_exceptions.S
@@ -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.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -340,11 +340,6 @@
 	 */
 	bl	prepare_el3_entry
 
-#if ENABLE_PAUTH
-	/* Load and program APIAKey firmware key */
-	bl	pauth_load_bl31_apiakey
-#endif
-
 	/*
 	 * Populate the parameters for the SMC handler.
 	 * We already have x0-x4 in place. x5 will point to a cookie (not used
@@ -536,11 +531,6 @@
 	 */
 	bl	prepare_el3_entry
 
-#if ENABLE_PAUTH
-	/* Load and program APIAKey firmware key */
-	bl	pauth_load_bl31_apiakey
-#endif
-
 	/* Save the EL3 system registers needed to return from this exception */
 	mrs	x0, spsr_el3
 	mrs	x1, elr_el3
diff --git a/bl31/bl31_main.c b/bl31/bl31_main.c
index 0cd0c79..5944b91 100644
--- a/bl31/bl31_main.c
+++ b/bl31/bl31_main.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.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -104,14 +104,6 @@
 	/* Perform late platform-specific setup */
 	bl31_plat_arch_setup();
 
-#if CTX_INCLUDE_PAUTH_REGS
-	/*
-	 * Assert that the ARMv8.3-PAuth registers are present or an access
-	 * fault will be triggered when they are being saved or restored.
-	 */
-	assert(is_armv8_3_pauth_present());
-#endif /* CTX_INCLUDE_PAUTH_REGS */
-
 	/* Prints context_memory allocated for all the security states */
 	report_ctx_memory_usage();
 }
diff --git a/bl32/tsp/aarch64/tsp_entrypoint.S b/bl32/tsp/aarch64/tsp_entrypoint.S
index e5ea88c..b4e7a7a 100644
--- a/bl32/tsp/aarch64/tsp_entrypoint.S
+++ b/bl32/tsp/aarch64/tsp_entrypoint.S
@@ -94,6 +94,10 @@
 	mov	x1, #(SCTLR_I_BIT | SCTLR_A_BIT | SCTLR_SA_BIT)
 	mrs	x0, sctlr_el1
 	orr	x0, x0, x1
+#if ENABLE_BTI
+	/* Enable PAC branch type compatibility */
+	bic     x0, x0, #(SCTLR_BT0_BIT | SCTLR_BT1_BIT)
+#endif
 	bic	x0, x0, #SCTLR_DSSBS_BIT
 	msr	sctlr_el1, x0
 	isb
diff --git a/bl32/tsp/tsp_common.c b/bl32/tsp/tsp_common.c
index 6095549..e69c054 100644
--- a/bl32/tsp/tsp_common.c
+++ b/bl32/tsp/tsp_common.c
@@ -74,14 +74,6 @@
 
 	/* Perform late platform-specific setup. */
 	tsp_plat_arch_setup();
-
-#if ENABLE_PAUTH
-	/*
-	 * Assert that the ARMv8.3-PAuth registers are present or an access
-	 * fault will be triggered when they are being saved or restored.
-	 */
-	assert(is_armv8_3_pauth_present());
-#endif /* ENABLE_PAUTH */
 }
 
 /*******************************************************************************
diff --git a/common/backtrace/backtrace.c b/common/backtrace/backtrace.c
index f994ae5..479c4fd 100644
--- a/common/backtrace/backtrace.c
+++ b/common/backtrace/backtrace.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,6 +8,7 @@
 #include <stdbool.h>
 #include <stdint.h>
 
+#include <arch_features.h>
 #include <arch_helpers.h>
 #include <common/debug.h>
 #include <drivers/console.h>
@@ -41,15 +42,14 @@
 {
 	uintptr_t ret = address;
 
-#if ENABLE_PAUTH
 	/*
 	 * When pointer authentication is enabled, the LR value saved on the
 	 * stack contains a PAC. It must be stripped to retrieve the return
 	 * address.
 	 */
-
-	xpaci(ret);
-#endif
+	if (is_feat_pauth_supported()) {
+		ret = xpaci(address);
+	}
 
 	return ret;
 }
diff --git a/common/feat_detect.c b/common/feat_detect.c
index 821ccb8..4d285d3 100644
--- a/common/feat_detect.c
+++ b/common/feat_detect.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -66,7 +66,7 @@
 static void read_feat_pauth(void)
 {
 #if (ENABLE_PAUTH == FEAT_STATE_ALWAYS) || (CTX_INCLUDE_PAUTH_REGS == FEAT_STATE_ALWAYS)
-	feat_detect_panic(is_armv8_3_pauth_present(), "PAUTH");
+	feat_detect_panic(is_feat_pauth_present(), "PAUTH");
 #endif
 }
 
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index b5814bb..2a42269 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -113,12 +113,16 @@
 -  ``BRANCH_PROTECTION``: Numeric value to enable ARMv8.3 Pointer Authentication
    and ARMv8.5 Branch Target Identification support for TF-A BL images themselves.
    If enabled, it is needed to use a compiler that supports the option
-   ``-mbranch-protection``. Selects the branch protection features to use:
--  0: Default value turns off all types of branch protection
+   ``-mbranch-protection``. The value of the ``-march`` (via ``ARM_ARCH_MINOR``
+   and ``ARM_ARCH_MAJOR``) option will control which instructions will be
+   emitted (HINT space or not). Selects the branch protection features to use:
+-  0: Default value turns off all types of branch protection (FEAT_STATE_DISABLED)
 -  1: Enables all types of branch protection features
 -  2: Return address signing to its standard level
 -  3: Extend the signing to include leaf functions
 -  4: Turn on branch target identification mechanism
+-  5: Enables all types of branch protection features, only if present in
+   hardware (FEAT_STATE_CHECK).
 
    The table below summarizes ``BRANCH_PROTECTION`` values, GCC compilation options
    and resulting PAuth/BTI features.
@@ -136,6 +140,8 @@
    +-------+--------------+-------+-----+
    |   4   |     bti      |   N   |  Y  |
    +-------+--------------+-------+-----+
+   |   5   |   dynamic    |   Y   |  Y  |
+   +-------+--------------+-------+-----+
 
    This option defaults to 0.
    Note that Pointer Authentication is enabled for Non-secure world
@@ -198,11 +204,13 @@
 -  ``CTX_INCLUDE_PAUTH_REGS``: Numeric value to enable the Pointer
    Authentication for Secure world. This will cause the ARMv8.3-PAuth registers
    to be included when saving and restoring the CPU context as part of world
-   switch. This flag can take values 0 to 2, to align with ``ENABLE_FEAT``
-   mechanism. Default value is 0.
+   switch. Automatically enabled when ``BRANCH_PROTECTION`` is enabled. This flag
+   can take values 0 to 2, to align with ``ENABLE_FEAT`` mechanism. Default value
+   is 0.
 
    Note that Pointer Authentication is enabled for Non-secure world irrespective
-   of the value of this flag if the CPU supports it.
+   of the value of this flag if the CPU supports it. Alternatively, when
+   ``BRANCH_PROTECTION`` is enabled, this flag is superseded.
 
 -  ``CTX_INCLUDE_SVE_REGS``: Boolean option that, when set to 1, will cause the
    SVE registers to be included when saving and restoring the CPU context. Note
diff --git a/include/arch/aarch32/arch_features.h b/include/arch/aarch32/arch_features.h
index 243ac15..47a2659 100644
--- a/include/arch/aarch32/arch_features.h
+++ b/include/arch/aarch32/arch_features.h
@@ -204,5 +204,9 @@
 static inline bool is_feat_ls64_accdata_present(void) { return false; }
 __attribute__((always_inline))
 static inline bool is_feat_mops_supported(void) { return false; }
+__attribute__((always_inline))
+static inline bool is_feat_bti_supported(void) { return false; }
+__attribute__((always_inline))
+static inline bool is_feat_pauth_supported(void) { return false; }
 
 #endif /* ARCH_FEATURES_H */
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
index 43ff2cc..e3068d1 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -176,9 +176,9 @@
 			((ID_AA64ISAR2_GPA3_MASK << ID_AA64ISAR2_GPA3_SHIFT) |
 			(ID_AA64ISAR2_APA3_MASK << ID_AA64ISAR2_APA3_SHIFT)), 1U)
 
-/* PAUTH */
+/* FEAT_PAUTH: Pointer Authentication */
 __attribute__((always_inline))
-static inline bool is_armv8_3_pauth_present(void)
+static inline bool is_feat_pauth_present(void)
 {
 	uint64_t mask_id_aa64isar1 =
 		(ID_AA64ISAR1_GPI_MASK << ID_AA64ISAR1_GPI_SHIFT) |
@@ -193,14 +193,16 @@
 	return ((read_id_aa64isar1_el1() & mask_id_aa64isar1) != 0U ||
 		is_feat_pacqarma3_present());
 }
+CREATE_FEATURE_SUPPORTED(feat_pauth, is_feat_pauth_present, ENABLE_PAUTH)
+CREATE_FEATURE_SUPPORTED(ctx_pauth, is_feat_pauth_present, CTX_INCLUDE_PAUTH_REGS)
 
 /* FEAT_TTST: Small translation tables */
 CREATE_FEATURE_PRESENT(feat_ttst, id_aa64mmfr2_el1, ID_AA64MMFR2_EL1_ST_SHIFT,
 			ID_AA64MMFR2_EL1_ST_MASK, 1U)
 
 /* FEAT_BTI: Branch target identification */
-CREATE_FEATURE_PRESENT(feat_bti, id_aa64pfr1_el1, ID_AA64PFR1_EL1_BT_SHIFT,
-			ID_AA64PFR1_EL1_BT_MASK, BTI_IMPLEMENTED)
+CREATE_FEATURE_FUNCS(feat_bti, id_aa64pfr1_el1, ID_AA64PFR1_EL1_BT_SHIFT,
+			ID_AA64PFR1_EL1_BT_MASK, BTI_IMPLEMENTED, ENABLE_BTI)
 
 /* FEAT_MTE2: Memory tagging extension */
 CREATE_FEATURE_FUNCS(feat_mte2, id_aa64pfr1_el1, ID_AA64PFR1_EL1_MTE_SHIFT,
diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h
index 569182a..9419583 100644
--- a/include/arch/aarch64/arch_helpers.h
+++ b/include/arch/aarch64/arch_helpers.h
@@ -238,7 +238,15 @@
 /*******************************************************************************
  * Strip Pointer Authentication Code
  ******************************************************************************/
-DEFINE_SYSOP_PARAM_FUNC(xpaci)
+static inline u_register_t xpaci(u_register_t arg)
+{
+	register u_register_t x0 asm("x0") = arg;
+
+	/* `xpaci x0` for compatibility with older compiler and/or older -march */
+	__asm__ (".arch armv8.3-a; xpaci %0\n" : "+r" (x0));
+
+	return x0;
+}
 
 void flush_dcache_range(uintptr_t addr, size_t size);
 void flush_dcache_to_popa_range(uintptr_t addr, size_t size);
diff --git a/include/arch/aarch64/asm_macros.S b/include/arch/aarch64/asm_macros.S
index dce07d9..da51bf8 100644
--- a/include/arch/aarch64/asm_macros.S
+++ b/include/arch/aarch64/asm_macros.S
@@ -329,7 +329,7 @@
 	.endm
 
 	/*
-	* is_feat_sysreg128_present_asm - Set flags and reg if FEAT_SYSREG128
+	* is_feat_XYZ_present_asm - Set flags and reg if FEAT_XYZ
 	* is enabled at runtime.
 	*
 	* Arguments:
@@ -342,6 +342,15 @@
 	ands	\reg, \reg, #(ID_AA64ISAR2_SYSREG128_MASK << ID_AA64ISAR2_SYSREG128_SHIFT)
 	.endm
 
+	.macro is_feat_pauth_present_asm reg:req, clobber:req
+	mrs	\reg, ID_AA64ISAR1_EL1
+	mov_imm	\clobber, ((ID_AA64ISAR1_GPI_MASK << ID_AA64ISAR1_GPI_SHIFT) \
+			 | (ID_AA64ISAR1_GPA_MASK << ID_AA64ISAR1_GPA_SHIFT) \
+			 | (ID_AA64ISAR1_API_MASK << ID_AA64ISAR1_API_SHIFT) \
+			 | (ID_AA64ISAR1_APA_MASK << ID_AA64ISAR1_APA_SHIFT))
+	tst	\reg, \clobber
+	.endm
+
 .macro call_reset_handler
 #if !(defined(IMAGE_BL2) && ENABLE_RME)
 	/* ---------------------------------------------------------------------
diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S
index 2f2aeaf..07dffb1 100644
--- a/include/arch/aarch64/el3_common_macros.S
+++ b/include/arch/aarch64/el3_common_macros.S
@@ -32,10 +32,15 @@
 	 *  load or store one or more registers have an alignment check that the
 	 *  address being accessed is aligned to the size of the data element(s)
 	 *  being accessed.
+	 *
+	 * SCTLR_EL3.BT: PAuth instructions are compatible with bti jc
 	 * ---------------------------------------------------------------------
 	 */
-	mov	x1, #(SCTLR_I_BIT | SCTLR_A_BIT | SCTLR_SA_BIT)
+	mov_imm	x1, (SCTLR_I_BIT | SCTLR_A_BIT | SCTLR_SA_BIT)
 	mrs	x0, sctlr_el3
+#if ENABLE_BTI
+	bic	x0, x0, #SCTLR_BT_BIT
+#endif
 	orr	x0, x0, x1
 	msr	sctlr_el3, x0
 	isb
diff --git a/include/common/bl_common.h b/include/common/bl_common.h
index 2f065ec..db4bb9a 100644
--- a/include/common/bl_common.h
+++ b/include/common/bl_common.h
@@ -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.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -199,8 +199,6 @@
 void setup_page_tables(const struct mmap_region *bl_regions,
 			   const struct mmap_region *plat_regions);
 
-void bl_handle_pauth(void);
-
 #endif /*__ASSEMBLER__*/
 
 #endif /* BL_COMMON_H */
diff --git a/include/lib/extensions/pauth.h b/include/lib/extensions/pauth.h
index dbc2226..db47b80 100644
--- a/include/lib/extensions/pauth.h
+++ b/include/lib/extensions/pauth.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,12 +7,34 @@
 #ifndef PAUTH_H
 #define PAUTH_H
 
-/*******************************************************************************
- * ARMv8.3-PAuth support functions
- ******************************************************************************/
+#if ENABLE_PAUTH
+/* Platform hook to generate the APIAKey */
+uint128_t plat_init_apkey(void);
 
-/* Disable ARMv8.3 pointer authentication in EL1/EL3 */
+void pauth_init(void);
+void pauth_enable_el1(void);
+void pauth_enable_el3(void);
+void pauth_enable_el2(void);
 void pauth_disable_el1(void);
 void pauth_disable_el3(void);
-
+#else
+static inline void pauth_init(void)
+{
+}
+static inline void pauth_enable_el1(void)
+{
+}
+static inline void pauth_enable_el3(void)
+{
+}
+static inline void pauth_enable_el2(void)
+{
+}
+static inline void pauth_disable_el1(void)
+{
+}
+static inline void pauth_disable_el3(void)
+{
+}
+#endif
 #endif /* PAUTH_H */
diff --git a/include/lib/libc/cdefs.h b/include/lib/libc/cdefs.h
index 5febe9d..3bd4a70 100644
--- a/include/lib/libc/cdefs.h
+++ b/include/lib/libc/cdefs.h
@@ -17,6 +17,7 @@
 #define __section(x)	__attribute__((__section__(x)))
 #define __fallthrough	__attribute__((__fallthrough__))
 #define __noinline	__attribute__((__noinline__))
+#define __no_pauth	__attribute__((target("branch-protection=none")))
 #if RECLAIM_INIT_CODE
 /*
  * Add each function to a section that is unique so the functions can still
diff --git a/include/lib/utils_def.h b/include/lib/utils_def.h
index 6d8a06a..098506a 100644
--- a/include/lib/utils_def.h
+++ b/include/lib/utils_def.h
@@ -61,6 +61,9 @@
 #define HI(addr)			(addr >> 32)
 #define LO(addr)			(addr & 0xffffffff)
 
+#define HI_64(addr)			(addr >> 64)
+#define LO_64(addr)			(addr & 0xffffffffffffffff)
+
 /*
  * This variant of div_round_up can be used in macro definition but should not
  * be used in C code as the `div` parameter is evaluated twice.
diff --git a/include/lib/xlat_tables/xlat_tables_defs.h b/include/lib/xlat_tables/xlat_tables_defs.h
index 5434a9a..f540fa5 100644
--- a/include/lib/xlat_tables/xlat_tables_defs.h
+++ b/include/lib/xlat_tables/xlat_tables_defs.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -62,10 +62,8 @@
 #define OSH			(U(0x2) << 6)
 #define ISH			(U(0x3) << 6)
 
-#ifdef __aarch64__
 /* Guarded Page bit */
 #define GP			(ULL(1) << 50)
-#endif
 
 #define TABLE_ADDR_MASK		ULL(0x0000FFFFFFFFF000)
 
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index 243a372..7929901 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -343,11 +343,11 @@
 	.endm /* restore_mpam3_el3 */
 
 /* ------------------------------------------------------------------
- * The following macro is used to save and restore all the general
- * purpose and ARMv8.3-PAuth (if enabled) registers.
- * It also checks if the Secure Cycle Counter (PMCCNTR_EL0)
- * is disabled in EL3/Secure (ARMv8.5-PMU), wherein PMCCNTR_EL0
- * needs not to be saved/restored during world switch.
+ * The following macro is used to save all the general purpose
+ * registers and swap the FEAT_PAUTH keys with BL31's keys in
+ * cpu_data. It also checks if the Secure Cycle Counter (PMCCNTR_EL0)
+ * is disabled in EL3/Secure (ARMv8.5-PMU), wherein PMCCNTR_EL0 needs
+ * not to be saved/restored during world switch.
  *
  * Ideally we would only save and restore the callee saved registers
  * when a world switch occurs but that type of implementation is more
@@ -379,6 +379,11 @@
 	mrs	x9, pmcr_el0
 	str	x9, [sp, #CTX_EL3STATE_OFFSET + CTX_PMCR_EL0]
 #if CTX_INCLUDE_PAUTH_REGS
+#if CTX_INCLUDE_PAUTH_REGS == 2
+	/* Skip if not present in hardware */
+	is_feat_pauth_present_asm x9, x10
+	beq	no_pauth_\@
+#endif
 	/* ----------------------------------------------------------
  	 * Save the ARMv8.3-PAuth keys as they are not banked
  	 * by exception level
@@ -402,6 +407,25 @@
 	stp	x24, x25, [x19, #CTX_PACDAKEY_LO]
 	stp	x26, x27, [x19, #CTX_PACDBKEY_LO]
 	stp	x28, x29, [x19, #CTX_PACGAKEY_LO]
+#if ENABLE_PAUTH
+#if IMAGE_BL31
+	/* tpidr_el3 contains the address of the cpu_data structure */
+	mrs	x9, tpidr_el3
+	/* Load APIAKey from cpu_data */
+	ldp	x10, x11, [x9, #CPU_DATA_APIAKEY_OFFSET]
+#endif /* IMAGE_BL31 */
+
+#if IMAGE_BL1
+	/* BL1 does not use cpu_data and has dedicated storage */
+	adr_l	x9, bl1_apiakey
+	ldp	x10, x11, [x9]
+#endif /* IMAGE_BL1 */
+
+	/* Program instruction key A */
+	msr	APIAKeyLo_EL1, x10
+	msr	APIAKeyHi_EL1, x11
+no_pauth_\@:
+#endif /* ENABLE_PAUTH */
 #endif /* CTX_INCLUDE_PAUTH_REGS */
 	.endm /* save_gp_pmcr_pauth_regs */
 
@@ -442,6 +466,11 @@
  */
 func restore_gp_pmcr_pauth_regs
 #if CTX_INCLUDE_PAUTH_REGS
+#if CTX_INCLUDE_PAUTH_REGS == 2
+	/* Skip if not present in hardware */
+	is_feat_pauth_present_asm x0, x1
+	beq	no_pauth
+#endif
  	/* Restore the ARMv8.3 PAuth keys */
 	add	x10, sp, #CTX_PAUTH_REGS_OFFSET
 
@@ -461,6 +490,7 @@
 	msr	APDBKeyHi_EL1, x7
 	msr	APGAKeyLo_EL1, x8
 	msr	APGAKeyHi_EL1, x9
+no_pauth:
 #endif /* CTX_INCLUDE_PAUTH_REGS */
 
 	/* PMUv3 is presumed to be always present */
diff --git a/lib/el3_runtime/aarch64/context_debug.c b/lib/el3_runtime/aarch64/context_debug.c
index b37bcb7..1ae7f6b 100644
--- a/lib/el3_runtime/aarch64/context_debug.c
+++ b/lib/el3_runtime/aarch64/context_debug.c
@@ -1,11 +1,12 @@
 /*
- * Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <string.h>
 
+#include <arch_features.h>
 #include <common/debug.h>
 #include <context.h>
 #include <lib/el3_runtime/context_mgmt.h>
@@ -65,11 +66,11 @@
 #else
 	size_t el1_total = 0U;
 #endif /* CTX_INCLUDE_EL2_REGS */
-
-#if CTX_INCLUDE_PAUTH_REGS
 	size_t pauth_total = 0U;
-	PRINT_SINGLE_MEM_USAGE_SEP_BLOCK();
-#endif
+
+	if (is_ctx_pauth_supported()) {
+		PRINT_SINGLE_MEM_USAGE_SEP_BLOCK();
+	}
 
 	PRINT_MEM_USAGE_SEPARATOR();
 
@@ -80,9 +81,9 @@
 	printf("|    EL1    ");
 #endif /* CTX_INCLUDE_EL2_REGS */
 
-#if CTX_INCLUDE_PAUTH_REGS
-	printf("|   PAUTH   ");
-#endif
+	if (is_ctx_pauth_supported()) {
+		printf("|   PAUTH   ");
+	}
 
 	printf("|   Other   |   Total   |\n");
 
@@ -96,11 +97,11 @@
 #else
 		size_t el1_size = 0U;
 #endif /* CTX_INCLUDE_EL2_REGS */
-
-#if CTX_INCLUDE_PAUTH_REGS
 		size_t pauth_size = 0U;
-		PRINT_SINGLE_MEM_USAGE_SEP_BLOCK();
-#endif
+
+		if (is_ctx_pauth_supported()) {
+			PRINT_SINGLE_MEM_USAGE_SEP_BLOCK();
+		}
 
 		PRINT_MEM_USAGE_SEPARATOR();
 
@@ -124,12 +125,12 @@
 		printf("| %8luB ", el1_size);
 #endif /* CTX_INCLUDE_EL2_REGS */
 
-#if CTX_INCLUDE_PAUTH_REGS
-		pauth_size = sizeof(ctx->pauth_ctx);
-		size_other -= pauth_size;
-		pauth_total += pauth_size;
-		printf("| %8luB ", pauth_size);
-#endif
+		if (is_ctx_pauth_supported()) {
+			pauth_size = sizeof(ctx->pauth_ctx);
+			size_other -= pauth_size;
+			pauth_total += pauth_size;
+			printf("| %8luB ", pauth_size);
+		}
 		printf("| %8luB | %8luB |\n", size_other, core_total);
 
 		gp_total += gp_size;
@@ -138,15 +139,15 @@
 		total += core_total;
 	}
 
-#if CTX_INCLUDE_PAUTH_REGS
-	PRINT_SINGLE_MEM_USAGE_SEP_BLOCK();
-#endif
+	if (is_ctx_pauth_supported()) {
+		PRINT_SINGLE_MEM_USAGE_SEP_BLOCK();
+	}
 
 	PRINT_MEM_USAGE_SEPARATOR();
 
-#if CTX_INCLUDE_PAUTH_REGS
-	PRINT_SINGLE_MEM_USAGE_SEP_BLOCK();
-#endif
+	if (is_ctx_pauth_supported()) {
+		PRINT_SINGLE_MEM_USAGE_SEP_BLOCK();
+	}
 
 	PRINT_MEM_USAGE_SEPARATOR();
 
@@ -158,15 +159,15 @@
 	printf("| %8luB ", el1_total);
 #endif /* CTX_INCLUDE_EL2_REGS */
 
-#if CTX_INCLUDE_PAUTH_REGS
-	printf("| %8luB ", pauth_total);
-#endif
+	if (is_ctx_pauth_supported()) {
+		printf("| %8luB ", pauth_total);
+	}
 
 	printf("| %8luB | %8luB |\n", other_total, total);
 
-#if CTX_INCLUDE_PAUTH_REGS
-	PRINT_SINGLE_MEM_USAGE_SEP_BLOCK();
-#endif
+	if (is_ctx_pauth_supported()) {
+		PRINT_SINGLE_MEM_USAGE_SEP_BLOCK();
+	}
 	PRINT_MEM_USAGE_SEPARATOR();
 	printf("\n");
 
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 2d1b063..d04e02f 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -30,6 +30,7 @@
 #include <lib/extensions/fgt2.h>
 #include <lib/extensions/fpmr.h>
 #include <lib/extensions/mpam.h>
+#include <lib/extensions/pauth.h>
 #include <lib/extensions/pmuv3.h>
 #include <lib/extensions/sme.h>
 #include <lib/extensions/spe.h>
@@ -227,17 +228,15 @@
 		scr_el3 |= SCR_ATA_BIT;
 	}
 
-#if !CTX_INCLUDE_PAUTH_REGS
 	/*
-	 * Pointer Authentication feature, if present, is always enabled by default
-	 * for Non secure lower exception levels. We do not have an explicit
-	 * flag to set it.
+	 * Pointer Authentication feature, if present, is always enabled by
+	 * default for Non secure lower exception levels. We do not have an
+	 * explicit flag to set it. To prevent the leakage between the worlds
+	 * during world switch, we enable it only for the non-secure world.
+	 *
 	 * CTX_INCLUDE_PAUTH_REGS flag, is explicitly used to enable for lower
 	 * exception levels of secure and realm worlds.
 	 *
-	 * To prevent the leakage between the worlds during world switch,
-	 * we enable it only for the non-secure world.
-	 *
 	 * If the Secure/realm world wants to use pointer authentication,
 	 * CTX_INCLUDE_PAUTH_REGS must be explicitly set to 1, in which case
 	 * it will be enabled globally for all the contexts.
@@ -248,10 +247,9 @@
 	 * SCR_EL3.APK: Set to one to not trap any PAuth key values at ELs other
 	 *  than EL3
 	 */
-	if (is_armv8_3_pauth_present()) {
+	if (!is_ctx_pauth_supported()) {
 		scr_el3 |= SCR_API_BIT | SCR_APK_BIT;
 	}
-#endif /* CTX_INCLUDE_PAUTH_REGS */
 
 #if HANDLE_EA_EL3_FIRST_NS
 	/* SCR_EL3.EA: Route External Abort and SError Interrupt to EL3. */
@@ -468,7 +466,6 @@
 	scr_el3 |= SCR_FIEN_BIT;
 #endif
 
-#if CTX_INCLUDE_PAUTH_REGS
 	/*
 	 * Enable Pointer Authentication globally for all the worlds.
 	 *
@@ -478,10 +475,9 @@
 	 * SCR_EL3.APK: Set to one to not trap any PAuth key values at ELs other
 	 *  than EL3
 	 */
-	if (is_armv8_3_pauth_present()) {
+	if (is_ctx_pauth_supported()) {
 		scr_el3 |= SCR_API_BIT | SCR_APK_BIT;
 	}
-#endif /* CTX_INCLUDE_PAUTH_REGS */
 
 	/*
 	 * SCR_EL3.PIEN: Enable permission indirection and overlay
@@ -848,20 +844,6 @@
 #endif /* IMAGE_BL31 */
 }
 
-/* TODO: move to lib/extensions/pauth when it has been ported to FEAT_STATE */
-static __unused void enable_pauth_el2(void)
-{
-	u_register_t hcr_el2 = read_hcr_el2();
-	/*
-	 * For Armv8.3 pointer authentication feature, disable traps to EL2 when
-	 *  accessing key registers or using pointer authentication instructions
-	 *  from lower ELs.
-	 */
-	hcr_el2 |= (HCR_API_BIT | HCR_APK_BIT);
-
-	write_hcr_el2(hcr_el2);
-}
-
 #if INIT_UNUSED_NS_EL2
 /*******************************************************************************
  * Enable architecture extensions in-place at EL2 on first entry to Non-secure
@@ -908,9 +890,9 @@
 		write_hcrx_el2(read_hcrx_el2() | HCRX_EL2_MSCEn_BIT);
 	}
 
-#if ENABLE_PAUTH
-	enable_pauth_el2();
-#endif /* ENABLE_PAUTH */
+	if (is_feat_pauth_supported()) {
+		pauth_enable_el2();
+	}
 #endif /* IMAGE_BL31 */
 }
 #endif /* INIT_UNUSED_NS_EL2 */
diff --git a/lib/extensions/pauth/pauth.c b/lib/extensions/pauth/pauth.c
new file mode 100644
index 0000000..2dd0d28
--- /dev/null
+++ b/lib/extensions/pauth/pauth.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2025, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <arch.h>
+#include <arch_features.h>
+#include <arch_helpers.h>
+#include <lib/el3_runtime/cpu_data.h>
+#include <lib/extensions/pauth.h>
+
+extern uint64_t bl1_apiakey[2];
+
+void __no_pauth pauth_init_enable_el3(void)
+{
+	if (is_feat_pauth_supported()) {
+		pauth_init();
+		pauth_enable_el3();
+	}
+}
+
+void __no_pauth pauth_init_enable_el1(void)
+{
+	if (is_feat_pauth_supported()) {
+		pauth_init();
+		pauth_enable_el1();
+	}
+}
+
+void pauth_init(void)
+{
+	uint128_t keys = plat_init_apkey();
+	uint64_t key_lo = LO_64(keys);
+	uint64_t key_hi = HI_64(keys);
+
+	/* Program instruction key A used by the Trusted Firmware */
+	write_apiakeylo_el1(key_lo);
+	write_apiakeyhi_el1(key_hi);
+
+#if IMAGE_BL31
+	set_cpu_data(apiakey[0], key_lo);
+	set_cpu_data(apiakey[1], key_hi);
+
+	/*
+	 * In the warmboot entrypoint, cpu_data may have been written before
+	 * data caching was enabled. Flush the caches so nothing stale is read.
+	 */
+#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY)
+	flush_cpu_data(apiakey);
+#endif
+#elif IMAGE_BL1
+	bl1_apiakey[0] = key_lo;
+	bl1_apiakey[1] = key_hi;
+#endif
+}
+
+/*
+ * Begin checking function calls at the current EL. This function must not have
+ * PAuth guards because the signing will be a NOP and attempting to authenticate
+ * will fail. Includes an ISB to avoid accidental failures.
+ */
+void __no_pauth pauth_enable_el3(void)
+{
+	write_sctlr_el3(read_sctlr_el3() | SCTLR_EnIA_BIT);
+	isb();
+}
+
+void __no_pauth pauth_enable_el1(void)
+{
+	write_sctlr_el1(read_sctlr_el1() | SCTLR_EnIA_BIT);
+	isb();
+}
+
+/* Enable PAuth for EL2 */
+void pauth_enable_el2(void)
+{
+	u_register_t hcr_el2 = read_hcr_el2();
+	/*
+	 * For Armv8.3 pointer authentication feature, disable traps to EL2 when
+	 * accessing key registers or using pointer authentication instructions
+	 * from lower ELs.
+	 */
+	hcr_el2 |= (HCR_API_BIT | HCR_APK_BIT);
+
+	write_hcr_el2(hcr_el2);
+}
+
+void __no_pauth pauth_disable_el1(void)
+{
+	write_sctlr_el1(read_sctlr_el1() & ~SCTLR_EnIA_BIT);
+	isb(); /* usually called by caller, here it's for compatibility */
+}
+
+void __no_pauth pauth_disable_el3(void)
+{
+	write_sctlr_el3(read_sctlr_el3() & ~SCTLR_EnIA_BIT);
+	isb(); /* usually called by caller, here it's for compatibility */
+}
diff --git a/lib/extensions/pauth/pauth_helpers.S b/lib/extensions/pauth/pauth_helpers.S
deleted file mode 100644
index fb5fa97..0000000
--- a/lib/extensions/pauth/pauth_helpers.S
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch.h>
-#include <asm_macros.S>
-#include <lib/el3_runtime/cpu_data.h>
-
-	.global	pauth_init_enable_el1
-	.global	pauth_disable_el1
-	.global	pauth_init_enable_el3
-	.global	pauth_disable_el3
-	.globl	pauth_load_bl31_apiakey
-	.globl	pauth_load_bl1_apiakey_enable
-
-/* -------------------------------------------------------------
- * Program APIAKey_EL1 and enable pointer authentication in EL1
- * -------------------------------------------------------------
- */
-func pauth_init_enable_el1
-	stp	x29, x30, [sp, #-16]!
-
-	/* Initialize platform key */
-	bl	plat_init_apkey
-
-	/* Program instruction key A used by the Trusted Firmware */
-	msr	APIAKeyLo_EL1, x0
-	msr	APIAKeyHi_EL1, x1
-
-	/* Enable pointer authentication */
-	mrs	x0, sctlr_el1
-	orr	x0, x0, #SCTLR_EnIA_BIT
-
-#if ENABLE_BTI
-	 /* Enable PAC branch type compatibility */
-	bic	x0, x0, #(SCTLR_BT0_BIT | SCTLR_BT1_BIT)
-#endif
-	msr	sctlr_el1, x0
-	isb
-
-	ldp	x29, x30, [sp], #16
-	ret
-endfunc pauth_init_enable_el1
-
-/* -------------------------------------------------------------
- * Disable pointer authentication in EL1
- * -------------------------------------------------------------
- */
-func pauth_disable_el1
-	mrs	x0, sctlr_el1
-	bic	x0, x0, #SCTLR_EnIA_BIT
-	msr	sctlr_el1, x0
-	isb
-	ret
-endfunc pauth_disable_el1
-
-/* -------------------------------------------------------------
- * Program APIAKey_EL1 and enable pointer authentication in EL3
- * -------------------------------------------------------------
- */
-func pauth_init_enable_el3
-	stp	x29, x30, [sp, #-16]!
-
-	/* Initialize platform key */
-	bl	plat_init_apkey
-
-	/* Program instruction key A used by the Trusted Firmware */
-	msr	APIAKeyLo_EL1, x0
-	msr	APIAKeyHi_EL1, x1
-
-	/* Enable pointer authentication */
-	mrs	x0, sctlr_el3
-	orr	x0, x0, #SCTLR_EnIA_BIT
-
-#if ENABLE_BTI
-	 /* Enable PAC branch type compatibility */
-	bic	x0, x0, #SCTLR_BT_BIT
-#endif
-	msr	sctlr_el3, x0
-	isb
-
-	ldp	x29, x30, [sp], #16
-	ret
-endfunc pauth_init_enable_el3
-
-/* -------------------------------------------------------------
- * Disable pointer authentication in EL3
- * -------------------------------------------------------------
- */
-func pauth_disable_el3
-	mrs	x0, sctlr_el3
-	bic	x0, x0, #SCTLR_EnIA_BIT
-	msr	sctlr_el3, x0
-	isb
-	ret
-endfunc pauth_disable_el3
-
-/* -------------------------------------------------------------
- * The following functions strictly follow the AArch64 PCS
- * to use x9-x17 (temporary caller-saved registers) to load
- * the APIAKey_EL1 and enable pointer authentication.
- * -------------------------------------------------------------
- */
-func pauth_load_bl31_apiakey
-	/* tpidr_el3 contains the address of cpu_data structure */
-	mrs	x9, tpidr_el3
-
-	/* Load apiakey from cpu_data */
-	ldp	x10, x11, [x9, #CPU_DATA_APIAKEY_OFFSET]
-
-	/* Program instruction key A */
-	msr	APIAKeyLo_EL1, x10
-	msr	APIAKeyHi_EL1, x11
-	isb
-	ret
-endfunc pauth_load_bl31_apiakey
-
-func pauth_load_bl1_apiakey_enable
-	/* Load instruction key A used by the Trusted Firmware */
-	adrp	x9, bl1_apiakey
-	add	x9, x9, :lo12:bl1_apiakey
-	ldp	x10, x11, [x9]
-
-	/* Program instruction key A */
-	msr	APIAKeyLo_EL1, x10
-	msr	APIAKeyHi_EL1, x11
-
-	/* Enable pointer authentication */
-	mrs	x9, sctlr_el3
-	orr	x9, x9, #SCTLR_EnIA_BIT
-
-#if ENABLE_BTI
-	 /* Enable PAC branch type compatibility */
-	bic	x9, x9, #SCTLR_BT_BIT
-#endif
-	msr	sctlr_el3, x9
-	isb
-	ret
-endfunc pauth_load_bl1_apiakey_enable
diff --git a/lib/psci/psci_setup.c b/lib/psci/psci_setup.c
index e1b0ae8..0863a82 100644
--- a/lib/psci/psci_setup.c
+++ b/lib/psci/psci_setup.c
@@ -319,11 +319,6 @@
 	/* Having initialized cpu_ops, we can now print errata status */
 	print_errata_status();
 
-#if ENABLE_PAUTH
-	/* Store APIAKey_EL1 key */
-	set_cpu_data(apiakey[0], read_apiakeylo_el1());
-	set_cpu_data(apiakey[1], read_apiakeyhi_el1());
-#endif /* ENABLE_PAUTH */
 }
 
 /******************************************************************************
diff --git a/lib/psci/psci_suspend.c b/lib/psci/psci_suspend.c
index 39d4482..a7b53cb 100644
--- a/lib/psci/psci_suspend.c
+++ b/lib/psci/psci_suspend.c
@@ -324,12 +324,6 @@
 	counter_freq = plat_get_syscnt_freq2();
 	write_cntfrq_el0(counter_freq);
 
-#if ENABLE_PAUTH
-	/* Store APIAKey_EL1 key */
-	set_cpu_data(apiakey[0], read_apiakeylo_el1());
-	set_cpu_data(apiakey[1], read_apiakeyhi_el1());
-#endif /* ENABLE_PAUTH */
-
 	/*
 	 * Call the cpu suspend finish handler registered by the Secure Payload
 	 * Dispatcher to let it do any bookeeping. If the handler encounters an
diff --git a/lib/xlat_tables_v2/xlat_tables_core.c b/lib/xlat_tables_v2/xlat_tables_core.c
index bd7f017..76aba50 100644
--- a/lib/xlat_tables_v2/xlat_tables_core.c
+++ b/lib/xlat_tables_v2/xlat_tables_core.c
@@ -210,17 +210,14 @@
 				desc |= LOWER_ATTRS(ISH);
 			}
 
-			/* Check if Branch Target Identification is enabled */
-#if ENABLE_BTI
 			/* Set GP bit for block and page code entries
 			 * if BTI mechanism is implemented.
 			 */
-			if (is_feat_bti_present() &&
+			if (is_feat_bti_supported() &&
 			   ((attr & (MT_TYPE_MASK | MT_RW |
 				MT_EXECUTE_NEVER)) == MT_CODE)) {
 				desc |= GP;
 			}
-#endif
 		} else {
 			assert(mem_type == MT_NON_CACHEABLE);
 			desc |= LOWER_ATTRS(ATTR_NON_CACHEABLE_INDEX | OSH);
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index 9659e73..d3c2a96 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -356,7 +356,7 @@
 endif
 
 # Pointer Authentication sources
-ifeq ($(BRANCH_PROTECTION),$(filter $(BRANCH_PROTECTION),1 2 3))
+ifeq ($(BRANCH_PROTECTION),$(filter $(BRANCH_PROTECTION),1 2 3 5))
 PLAT_BL_COMMON_SOURCES	+=	plat/arm/common/aarch64/arm_pauth.c
 endif
 
diff --git a/plat/qemu/common/common.mk b/plat/qemu/common/common.mk
index da981e5..751511c 100644
--- a/plat/qemu/common/common.mk
+++ b/plat/qemu/common/common.mk
@@ -148,7 +148,7 @@
 endif
 
 # Pointer Authentication sources
-ifeq ($(BRANCH_PROTECTION),$(filter $(BRANCH_PROTECTION),1 2 3))
+ifeq ($(BRANCH_PROTECTION),$(filter $(BRANCH_PROTECTION),1 2 3 5))
 PLAT_BL_COMMON_SOURCES	+=	plat/arm/common/aarch64/arm_pauth.c
 endif