fix(cm): fix context management SYSREG128 write macros

This patch fixes a bug which was introduced in commit
3065513 related to improper saving of EL1 context in the
context management library code when using 128-bit
system registers.

Bug explanation:
The function el1_sysregs_context_save still used the normal
macros that read all the system registers related to the EL1
context, which then involved casting them to uint64_t and
eventually writing them to a memory structure. This means that
the context management library was saving EL1-related SYSREG128
registers with the upper 64 bits zeroed out.

Alternative macros had previously been introduced for the EL2
context in the aforementioned commit, but not for EL1.

Some refactoring has also been done as part of this patch:
- Re-added "common" back to write_el2_ctx_common_sysreg128
- Added dummy SYSREG128 macros for cases when some features
  are disabled
- Removed some newlines

Change-Id: I15aa2190794ac099a493e5f430220b1c81e1b558
Signed-off-by: Igor Podgainõi <igor.podgainoi@arm.com>
This commit is contained in:
Igor Podgainõi 2024-12-13 14:28:11 +01:00
parent 885503f4f3
commit 6595f4cb39
3 changed files with 17 additions and 13 deletions

View file

@ -194,6 +194,9 @@ typedef struct el1_sysregs {
#define write_el1_ctx_common(ctx, reg, val) ((((ctx)->common).reg) \
= (uint64_t) (val))
#define write_el1_ctx_common_sysreg128(ctx, reg, val) ((((ctx)->common).reg) \
= (sysreg_t) (val))
#if NS_TIMER_SWITCH
#define read_el1_ctx_arch_timer(ctx, reg) (((ctx)->arch_timer).reg)
#define write_el1_ctx_arch_timer(ctx, reg, val) ((((ctx)->arch_timer).reg) \
@ -295,11 +298,11 @@ typedef struct el1_sysregs {
#if ENABLE_FEAT_THE
#define read_el1_ctx_the(ctx, reg) (((ctx)->the).reg)
#define write_el1_ctx_the(ctx, reg, val) ((((ctx)->the).reg) \
= (uint64_t) (val))
#define write_el1_ctx_the_sysreg128(ctx, reg, val) ((((ctx)->the).reg) \
= (sysreg_t) (val))
#else
#define read_el1_ctx_the(ctx, reg) ULL(0)
#define write_el1_ctx_the(ctx, reg, val)
#define write_el1_ctx_the_sysreg128(ctx, reg, val)
#endif /* ENABLE_FEAT_THE */
#if ENABLE_FEAT_SCTLR2

View file

@ -225,7 +225,7 @@ typedef struct el2_sysregs {
#define write_el2_ctx_common(ctx, reg, val) ((((ctx)->common).reg) \
= (uint64_t) (val))
#define write_el2_ctx_sysreg128(ctx, reg, val) ((((ctx)->common).reg) \
#define write_el2_ctx_common_sysreg128(ctx, reg, val) ((((ctx)->common).reg) \
= (sysreg_t) (val))
#if ENABLE_FEAT_MTE2
@ -268,12 +268,12 @@ typedef struct el2_sysregs {
#define read_el2_ctx_vhe(ctx, reg) (((ctx)->vhe).reg)
#define write_el2_ctx_vhe(ctx, reg, val) ((((ctx)->vhe).reg) \
= (uint64_t) (val))
#define write_el2_ctx_vhe_sysreg128(ctx, reg, val) ((((ctx)->vhe).reg) \
= (sysreg_t) (val))
= (sysreg_t) (val))
#else
#define read_el2_ctx_vhe(ctx, reg) ULL(0)
#define write_el2_ctx_vhe(ctx, reg, val)
#define write_el2_ctx_vhe_sysreg128(ctx, reg, val)
#endif /* ENABLE_FEAT_VHE */
#if ENABLE_FEAT_RAS

View file

@ -1364,8 +1364,8 @@ static void el2_sysregs_context_save_common(el2_sysregs_t *ctx)
write_el2_ctx_common(ctx, vpidr_el2, read_vpidr_el2());
write_el2_ctx_common(ctx, vtcr_el2, read_vtcr_el2());
write_el2_ctx_sysreg128(ctx, ttbr0_el2, read_ttbr0_el2());
write_el2_ctx_sysreg128(ctx, vttbr_el2, read_vttbr_el2());
write_el2_ctx_common_sysreg128(ctx, ttbr0_el2, read_ttbr0_el2());
write_el2_ctx_common_sysreg128(ctx, vttbr_el2, read_vttbr_el2());
}
static void el2_sysregs_context_restore_common(el2_sysregs_t *ctx)
@ -1691,15 +1691,12 @@ static void el1_sysregs_context_save(el1_sysregs_t *ctx)
write_el1_ctx_common(ctx, csselr_el1, read_csselr_el1());
write_el1_ctx_common(ctx, sp_el1, read_sp_el1());
write_el1_ctx_common(ctx, esr_el1, read_esr_el1());
write_el1_ctx_common(ctx, ttbr0_el1, read_ttbr0_el1());
write_el1_ctx_common(ctx, ttbr1_el1, read_ttbr1_el1());
write_el1_ctx_common(ctx, mair_el1, read_mair_el1());
write_el1_ctx_common(ctx, amair_el1, read_amair_el1());
write_el1_ctx_common(ctx, actlr_el1, read_actlr_el1());
write_el1_ctx_common(ctx, tpidr_el1, read_tpidr_el1());
write_el1_ctx_common(ctx, tpidr_el0, read_tpidr_el0());
write_el1_ctx_common(ctx, tpidrro_el0, read_tpidrro_el0());
write_el1_ctx_common(ctx, par_el1, read_par_el1());
write_el1_ctx_common(ctx, far_el1, read_far_el1());
write_el1_ctx_common(ctx, afsr0_el1, read_afsr0_el1());
write_el1_ctx_common(ctx, afsr1_el1, read_afsr1_el1());
@ -1708,6 +1705,10 @@ static void el1_sysregs_context_save(el1_sysregs_t *ctx)
write_el1_ctx_common(ctx, mdccint_el1, read_mdccint_el1());
write_el1_ctx_common(ctx, mdscr_el1, read_mdscr_el1());
write_el1_ctx_common_sysreg128(ctx, par_el1, read_par_el1());
write_el1_ctx_common_sysreg128(ctx, ttbr0_el1, read_ttbr0_el1());
write_el1_ctx_common_sysreg128(ctx, ttbr1_el1, read_ttbr1_el1());
if (CTX_INCLUDE_AARCH32_REGS) {
/* Save Aarch32 registers */
write_el1_ctx_aarch32(ctx, spsr_abt, read_spsr_abt());
@ -1772,8 +1773,8 @@ static void el1_sysregs_context_save(el1_sysregs_t *ctx)
}
if (is_feat_the_supported()) {
write_el1_ctx_the(ctx, rcwmask_el1, read_rcwmask_el1());
write_el1_ctx_the(ctx, rcwsmask_el1, read_rcwsmask_el1());
write_el1_ctx_the_sysreg128(ctx, rcwmask_el1, read_rcwmask_el1());
write_el1_ctx_the_sysreg128(ctx, rcwsmask_el1, read_rcwsmask_el1());
}
if (is_feat_sctlr2_supported()) {