diff options
author | Boyan Karatotev <boyan.karatotev@arm.com> | 2022-12-06 09:03:42 +0000 |
---|---|---|
committer | Boyan Karatotev <boyan.karatotev@arm.com> | 2023-05-05 13:16:18 +0100 |
commit | 1d6d6802dd547c8b378a9a47572ee72e68cceb3b (patch) | |
tree | 19fadcc58926f0b34dcff47a64d9f0893958f890 /lib/el3_runtime/aarch64/context.S | |
parent | 1d0d5e40206c693e24b0a4de7dbcfc4b79f3138e (diff) | |
download | arm-trusted-firmware-1d6d6802dd547c8b378a9a47572ee72e68cceb3b.tar.gz |
fix(pmu): unconditionally save PMCR_EL0
Reading back a RES0 bit does not necessarily mean it will be read as 0.
The Arm ARM explicitly warns against doing this. The PMU initialisation
code tries to set such bits to 1 (in MDCR_EL3) regardless of whether
they are in use or are RES0, checking their value could be wrong and
PMCR_EL0 might not end up being saved.
Save PMCR_EL0 unconditionally to prevent this. Remove the security state
change as the outgoing state is not relevant to what the root world
context should look like.
Signed-off-by: Boyan Karatotev <boyan.karatotev@arm.com>
Change-Id: Id43667d37b0e2da3ded0beaf23fa0d4f9013f470
Diffstat (limited to 'lib/el3_runtime/aarch64/context.S')
-rw-r--r-- | lib/el3_runtime/aarch64/context.S | 61 |
1 files changed, 1 insertions, 60 deletions
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S index 769117163..456ed5113 100644 --- a/lib/el3_runtime/aarch64/context.S +++ b/lib/el3_runtime/aarch64/context.S @@ -596,48 +596,12 @@ endfunc fpregs_context_restore stp x28, x29, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X28] mrs x18, sp_el0 str x18, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_SP_EL0] - - /* ---------------------------------------------------------- - * Check if earlier initialization of MDCR_EL3.SCCD/MCCD to 1 - * has failed. - * - * MDCR_EL3: - * MCCD bit set, Prohibits the Cycle Counter PMCCNTR_EL0 from - * counting at EL3. - * SCCD bit set, Secure Cycle Counter Disable. Prohibits PMCCNTR_EL0 - * from counting in Secure state. - * If these bits are not set, meaning that FEAT_PMUv3p5/7 is - * not implemented and PMCR_EL0 should be saved in non-secure - * context. - * ---------------------------------------------------------- - */ - mov_imm x10, (MDCR_SCCD_BIT | MDCR_MCCD_BIT) - mrs x9, mdcr_el3 - tst x9, x10 - bne 1f - - /* ---------------------------------------------------------- - * If control reaches here, it ensures the Secure Cycle - * Counter (PMCCNTR_EL0) is not prohibited from counting at - * EL3 and in secure states. - * Henceforth, PMCR_EL0 to be saved before world switch. - * ---------------------------------------------------------- - */ mrs x9, pmcr_el0 - - /* Check caller's security state */ - mrs x10, scr_el3 - tst x10, #SCR_NS_BIT - beq 2f - - /* Save PMCR_EL0 if called from Non-secure state */ str x9, [sp, #CTX_EL3STATE_OFFSET + CTX_PMCR_EL0] - /* Disable cycle counter when event counting is prohibited */ -2: orr x9, x9, #PMCR_EL0_DP_BIT + orr x9, x9, #PMCR_EL0_DP_BIT msr pmcr_el0, x9 isb -1: #if CTX_INCLUDE_PAUTH_REGS /* ---------------------------------------------------------- * Save the ARMv8.3-PAuth keys as they are not banked @@ -715,31 +679,8 @@ func restore_gp_pmcr_pauth_regs msr APGAKeyLo_EL1, x8 msr APGAKeyHi_EL1, x9 #endif /* CTX_INCLUDE_PAUTH_REGS */ - - /* ---------------------------------------------------------- - * Restore PMCR_EL0 when returning to Non-secure state if - * Secure Cycle Counter is not disabled in MDCR_EL3 when - * ARMv8.5-PMU is implemented. - * ---------------------------------------------------------- - */ - mrs x0, scr_el3 - tst x0, #SCR_NS_BIT - beq 2f - - /* ---------------------------------------------------------- - * Back to Non-secure state. - * Check if earlier initialization MDCR_EL3.SCCD/MCCD to 1 - * failed, meaning that FEAT_PMUv3p5/7 is not implemented and - * PMCR_EL0 should be restored from non-secure context. - * ---------------------------------------------------------- - */ - mov_imm x1, (MDCR_SCCD_BIT | MDCR_MCCD_BIT) - mrs x0, mdcr_el3 - tst x0, x1 - bne 2f ldr x0, [sp, #CTX_EL3STATE_OFFSET + CTX_PMCR_EL0] msr pmcr_el0, x0 -2: ldp x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0] ldp x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2] ldp x4, x5, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X4] |