- SMCR_EL2.EZT0 (bit 30) must be initialised to 0b1.
 
+  For CPUs with the Branch Record Buffer Extension (FEAT_BRBE):
+
+  - If EL3 is present:
+
+    - MDCR_EL3.SBRBE (bits 33:32) must be initialised to 0b01 or 0b11.
+
+  - If the kernel is entered at EL1 and EL2 is present:
+
+    - BRBCR_EL2.CC (bit 3) must be initialised to 0b1.
+    - BRBCR_EL2.MPRED (bit 4) must be initialised to 0b1.
+
+    - HDFGRTR_EL2.nBRBDATA (bit 61) must be initialised to 0b1.
+    - HDFGRTR_EL2.nBRBCTL  (bit 60) must be initialised to 0b1.
+    - HDFGRTR_EL2.nBRBIDR  (bit 59) must be initialised to 0b1.
+
+    - HDFGWTR_EL2.nBRBDATA (bit 61) must be initialised to 0b1.
+    - HDFGWTR_EL2.nBRBCTL  (bit 60) must be initialised to 0b1.
+
+    - HFGITR_EL2.nBRBIALL (bit 56) must be initialised to 0b1.
+    - HFGITR_EL2.nBRBINJ  (bit 55) must be initialised to 0b1.
+
   For CPUs with the Performance Monitors Extension (FEAT_PMUv3p9):
 
  - If EL3 is present:
 
 .Lskip_set_cptr_\@:
 .endm
 
+/*
+ * Configure BRBE to permit recording cycle counts and branch mispredicts.
+ *
+ * At any EL, to record cycle counts BRBE requires that both BRBCR_EL2.CC=1 and
+ * BRBCR_EL1.CC=1.
+ *
+ * At any EL, to record branch mispredicts BRBE requires that both
+ * BRBCR_EL2.MPRED=1 and BRBCR_EL1.MPRED=1.
+ *
+ * Set {CC,MPRED} in BRBCR_EL2 in case nVHE mode is used and we are
+ * executing in EL1.
+ */
+.macro __init_el2_brbe
+       mrs     x1, id_aa64dfr0_el1
+       ubfx    x1, x1, #ID_AA64DFR0_EL1_BRBE_SHIFT, #4
+       cbz     x1, .Lskip_brbe_\@
+
+       mov_q   x0, BRBCR_ELx_CC | BRBCR_ELx_MPRED
+       msr_s   SYS_BRBCR_EL2, x0
+.Lskip_brbe_\@:
+.endm
+
 /* Disable any fine grained traps */
 .macro __init_el2_fgt
        mrs     x1, id_aa64mmfr0_el1
        cbz     x1, .Lskip_fgt_\@
 
        mov     x0, xzr
+       mov     x2, xzr
        mrs     x1, id_aa64dfr0_el1
        ubfx    x1, x1, #ID_AA64DFR0_EL1_PMSVer_SHIFT, #4
        cmp     x1, #3
        b.lt    .Lskip_spe_fgt_\@
        /* Disable PMSNEVFR_EL1 read and write traps */
-       orr     x0, x0, #(1 << 62)
+       orr     x0, x0, #HDFGRTR_EL2_nPMSNEVFR_EL1_MASK
+       orr     x2, x2, #HDFGWTR_EL2_nPMSNEVFR_EL1_MASK
 
 .Lskip_spe_fgt_\@:
+       mrs     x1, id_aa64dfr0_el1
+       ubfx    x1, x1, #ID_AA64DFR0_EL1_BRBE_SHIFT, #4
+       cbz     x1, .Lskip_brbe_fgt_\@
+
+       /*
+        * Disable read traps for the following registers
+        *
+        * [BRBSRC|BRBTGT|RBINF]_EL1
+        * [BRBSRCINJ|BRBTGTINJ|BRBINFINJ|BRBTS]_EL1
+        */
+       orr     x0, x0, #HDFGRTR_EL2_nBRBDATA_MASK
+
+       /*
+        * Disable write traps for the following registers
+        *
+        * [BRBSRCINJ|BRBTGTINJ|BRBINFINJ|BRBTS]_EL1
+        */
+       orr     x2, x2, #HDFGWTR_EL2_nBRBDATA_MASK
+
+       /* Disable read and write traps for [BRBCR|BRBFCR]_EL1 */
+       orr     x0, x0, #HDFGRTR_EL2_nBRBCTL_MASK
+       orr     x2, x2, #HDFGWTR_EL2_nBRBCTL_MASK
+
+       /* Disable read traps for BRBIDR_EL1 */
+       orr     x0, x0, #HDFGRTR_EL2_nBRBIDR_MASK
+
+.Lskip_brbe_fgt_\@:
 
 .Lset_debug_fgt_\@:
        msr_s   SYS_HDFGRTR_EL2, x0
-       msr_s   SYS_HDFGWTR_EL2, x0
+       msr_s   SYS_HDFGWTR_EL2, x2
 
        mov     x0, xzr
+       mov     x2, xzr
+
+       mrs     x1, id_aa64dfr0_el1
+       ubfx    x1, x1, #ID_AA64DFR0_EL1_BRBE_SHIFT, #4
+       cbz     x1, .Lskip_brbe_insn_fgt_\@
+
+       /* Disable traps for BRBIALL instruction */
+       orr     x2, x2, #HFGITR_EL2_nBRBIALL_MASK
+
+       /* Disable traps for BRBINJ instruction */
+       orr     x2, x2, #HFGITR_EL2_nBRBINJ_MASK
+
+.Lskip_brbe_insn_fgt_\@:
        mrs     x1, id_aa64pfr1_el1
        ubfx    x1, x1, #ID_AA64PFR1_EL1_SME_SHIFT, #4
        cbz     x1, .Lskip_sme_fgt_\@
 .Lset_fgt_\@:
        msr_s   SYS_HFGRTR_EL2, x0
        msr_s   SYS_HFGWTR_EL2, x0
-       msr_s   SYS_HFGITR_EL2, xzr
+       msr_s   SYS_HFGITR_EL2, x2
 
        mrs     x1, id_aa64pfr0_el1             // AMU traps UNDEF without AMU
        ubfx    x1, x1, #ID_AA64PFR0_EL1_AMU_SHIFT, #4
        __init_el2_hcrx
        __init_el2_timers
        __init_el2_debug
+       __init_el2_brbe
        __init_el2_lor
        __init_el2_stage2
        __init_el2_gicv3