Skip to content

Commit ae344bc

Browse files
Anshuman Khandualwilldeacon
authored andcommitted
arm64: Handle BRBE booting requirements
To use the Branch Record Buffer Extension (BRBE), some configuration is necessary at EL3 and EL2. This patch documents the requirements and adds the initial EL2 setup code, which largely consists of configuring the fine-grained traps and initializing a couple of BRBE control registers. Before this patch, __init_el2_fgt() would initialize HDFGRTR_EL2 and HDFGWTR_EL2 with the same value, relying on the read/write trap controls for a register occupying the same bit position in either register. The 'nBRBIDR' trap control only exists in bit 59 of HDFGRTR_EL2, while bit 59 of HDFGWTR_EL2 is RES0, and so this assumption no longer holds. To handle HDFGRTR_EL2 and HDFGWTR_EL2 having (slightly) different bit layouts, __init_el2_fgt() is changed to accumulate the HDFGRTR_EL2 and HDFGWTR_EL2 control bits separately. While making this change the open-coded value (1 << 62) is replaced with HDFG{R,W}TR_EL2_nPMSNEVFR_EL1_MASK. The BRBCR_EL1 and BRBCR_EL2 registers are unusual and require special initialisation: even though they are subject to E2H renaming, both have an effect regardless of HCR_EL2.TGE, even when running at EL2. So we must initialize BRBCR_EL2 in case we run in nVHE mode. This is handled in __init_el2_brbe() with a comment to explain the situation. Cc: Marc Zyngier <maz@kernel.org> Cc: Oliver Upton <oliver.upton@linux.dev> Reviewed-by: Leo Yan <leo.yan@arm.com> Tested-by: James Clark <james.clark@linaro.org> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com> [Mark: rewrite commit message, fix typo in comment] Signed-off-by: Mark Rutland <mark.rutland@arm.com> Co-developed-by: Rob Herring (Arm) <robh@kernel.org> Signed-off-by: Rob Herring (Arm) <robh@kernel.org> tested-by: Adam Young <admiyo@os.amperecomputing.com> Acked-by: Mark Rutland <mark.rutland@arm.com> Link: https://lore.kernel.org/r/20250611-arm-brbe-v19-v23-2-e7775563036e@kernel.org Signed-off-by: Will Deacon <will@kernel.org>
1 parent 52e4a56 commit ae344bc

2 files changed

Lines changed: 89 additions & 3 deletions

File tree

Documentation/arch/arm64/booting.rst

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,27 @@ Before jumping into the kernel, the following conditions must be met:
388388

389389
- SMCR_EL2.EZT0 (bit 30) must be initialised to 0b1.
390390

391+
For CPUs with the Branch Record Buffer Extension (FEAT_BRBE):
392+
393+
- If EL3 is present:
394+
395+
- MDCR_EL3.SBRBE (bits 33:32) must be initialised to 0b01 or 0b11.
396+
397+
- If the kernel is entered at EL1 and EL2 is present:
398+
399+
- BRBCR_EL2.CC (bit 3) must be initialised to 0b1.
400+
- BRBCR_EL2.MPRED (bit 4) must be initialised to 0b1.
401+
402+
- HDFGRTR_EL2.nBRBDATA (bit 61) must be initialised to 0b1.
403+
- HDFGRTR_EL2.nBRBCTL (bit 60) must be initialised to 0b1.
404+
- HDFGRTR_EL2.nBRBIDR (bit 59) must be initialised to 0b1.
405+
406+
- HDFGWTR_EL2.nBRBDATA (bit 61) must be initialised to 0b1.
407+
- HDFGWTR_EL2.nBRBCTL (bit 60) must be initialised to 0b1.
408+
409+
- HFGITR_EL2.nBRBIALL (bit 56) must be initialised to 0b1.
410+
- HFGITR_EL2.nBRBINJ (bit 55) must be initialised to 0b1.
411+
391412
For CPUs with the Performance Monitors Extension (FEAT_PMUv3p9):
392413

393414
- If EL3 is present:

arch/arm64/include/asm/el2_setup.h

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -189,27 +189,91 @@
189189
.Lskip_set_cptr_\@:
190190
.endm
191191

192+
/*
193+
* Configure BRBE to permit recording cycle counts and branch mispredicts.
194+
*
195+
* At any EL, to record cycle counts BRBE requires that both BRBCR_EL2.CC=1 and
196+
* BRBCR_EL1.CC=1.
197+
*
198+
* At any EL, to record branch mispredicts BRBE requires that both
199+
* BRBCR_EL2.MPRED=1 and BRBCR_EL1.MPRED=1.
200+
*
201+
* Set {CC,MPRED} in BRBCR_EL2 in case nVHE mode is used and we are
202+
* executing in EL1.
203+
*/
204+
.macro __init_el2_brbe
205+
mrs x1, id_aa64dfr0_el1
206+
ubfx x1, x1, #ID_AA64DFR0_EL1_BRBE_SHIFT, #4
207+
cbz x1, .Lskip_brbe_\@
208+
209+
mov_q x0, BRBCR_ELx_CC | BRBCR_ELx_MPRED
210+
msr_s SYS_BRBCR_EL2, x0
211+
.Lskip_brbe_\@:
212+
.endm
213+
192214
/* Disable any fine grained traps */
193215
.macro __init_el2_fgt
194216
mrs x1, id_aa64mmfr0_el1
195217
ubfx x1, x1, #ID_AA64MMFR0_EL1_FGT_SHIFT, #4
196218
cbz x1, .Lskip_fgt_\@
197219

198220
mov x0, xzr
221+
mov x2, xzr
199222
mrs x1, id_aa64dfr0_el1
200223
ubfx x1, x1, #ID_AA64DFR0_EL1_PMSVer_SHIFT, #4
201224
cmp x1, #3
202225
b.lt .Lskip_spe_fgt_\@
203226
/* Disable PMSNEVFR_EL1 read and write traps */
204-
orr x0, x0, #(1 << 62)
227+
orr x0, x0, #HDFGRTR_EL2_nPMSNEVFR_EL1_MASK
228+
orr x2, x2, #HDFGWTR_EL2_nPMSNEVFR_EL1_MASK
205229

206230
.Lskip_spe_fgt_\@:
231+
mrs x1, id_aa64dfr0_el1
232+
ubfx x1, x1, #ID_AA64DFR0_EL1_BRBE_SHIFT, #4
233+
cbz x1, .Lskip_brbe_fgt_\@
234+
235+
/*
236+
* Disable read traps for the following registers
237+
*
238+
* [BRBSRC|BRBTGT|RBINF]_EL1
239+
* [BRBSRCINJ|BRBTGTINJ|BRBINFINJ|BRBTS]_EL1
240+
*/
241+
orr x0, x0, #HDFGRTR_EL2_nBRBDATA_MASK
242+
243+
/*
244+
* Disable write traps for the following registers
245+
*
246+
* [BRBSRCINJ|BRBTGTINJ|BRBINFINJ|BRBTS]_EL1
247+
*/
248+
orr x2, x2, #HDFGWTR_EL2_nBRBDATA_MASK
249+
250+
/* Disable read and write traps for [BRBCR|BRBFCR]_EL1 */
251+
orr x0, x0, #HDFGRTR_EL2_nBRBCTL_MASK
252+
orr x2, x2, #HDFGWTR_EL2_nBRBCTL_MASK
253+
254+
/* Disable read traps for BRBIDR_EL1 */
255+
orr x0, x0, #HDFGRTR_EL2_nBRBIDR_MASK
256+
257+
.Lskip_brbe_fgt_\@:
207258

208259
.Lset_debug_fgt_\@:
209260
msr_s SYS_HDFGRTR_EL2, x0
210-
msr_s SYS_HDFGWTR_EL2, x0
261+
msr_s SYS_HDFGWTR_EL2, x2
211262

212263
mov x0, xzr
264+
mov x2, xzr
265+
266+
mrs x1, id_aa64dfr0_el1
267+
ubfx x1, x1, #ID_AA64DFR0_EL1_BRBE_SHIFT, #4
268+
cbz x1, .Lskip_brbe_insn_fgt_\@
269+
270+
/* Disable traps for BRBIALL instruction */
271+
orr x2, x2, #HFGITR_EL2_nBRBIALL_MASK
272+
273+
/* Disable traps for BRBINJ instruction */
274+
orr x2, x2, #HFGITR_EL2_nBRBINJ_MASK
275+
276+
.Lskip_brbe_insn_fgt_\@:
213277
mrs x1, id_aa64pfr1_el1
214278
ubfx x1, x1, #ID_AA64PFR1_EL1_SME_SHIFT, #4
215279
cbz x1, .Lskip_sme_fgt_\@
@@ -250,7 +314,7 @@
250314
.Lset_fgt_\@:
251315
msr_s SYS_HFGRTR_EL2, x0
252316
msr_s SYS_HFGWTR_EL2, x0
253-
msr_s SYS_HFGITR_EL2, xzr
317+
msr_s SYS_HFGITR_EL2, x2
254318

255319
mrs x1, id_aa64pfr0_el1 // AMU traps UNDEF without AMU
256320
ubfx x1, x1, #ID_AA64PFR0_EL1_AMU_SHIFT, #4
@@ -311,6 +375,7 @@
311375
__init_el2_hcrx
312376
__init_el2_timers
313377
__init_el2_debug
378+
__init_el2_brbe
314379
__init_el2_lor
315380
__init_el2_stage2
316381
__init_el2_gicv3

0 commit comments

Comments
 (0)