Message ID | 20250130182309.717346-10-peter.maydell@linaro.org (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | target/arm: Clean up some corner cases of sysreg traps | expand |
On 1/30/25 10:23, Peter Maydell wrote: > In the CPAccessResult enum, the CP_ACCESS_TRAP* values indicate the > equivalent of the pseudocode AArch64.SystemAccessTrap(..., 0x18), > causing a trap to a specified exception level with a syndrome value > giving information about the failing instructions. In the > pseudocode, such traps are always taken to a specified target EL. We > support that for target EL of 2 or 3 via CP_ACCESS_TRAP_EL2 and > CP_ACCESS_TRAP_EL3, but the only way to take the access trap to EL1 > currently is to use CP_ACCESS_TRAP, which takes the trap to the > "usual target EL" (EL1 if in EL0, otherwise to the current EL). > > Add CP_ACCESS_TRAP_EL1 so that access functions can follow the > pseudocode more closely. > > (Note that for the common case in the pseudocode of "trap to > EL2 if HCR_EL2.TGE is set, otherwise trap to EL1", we handle > this in raise_exception(), so access functions don't need to > special case it and can use CP_ACCESS_TRAP_EL1.) > > Signed-off-by: Peter Maydell<peter.maydell@linaro.org> > --- > target/arm/cpregs.h | 1 + > target/arm/tcg/op_helper.c | 6 ++++-- > 2 files changed, 5 insertions(+), 2 deletions(-) Reviewed-by: Richard Henderson <richard.henderson@linaro.org> r~
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h index 1759d9defbe..fbf5798069d 100644 --- a/target/arm/cpregs.h +++ b/target/arm/cpregs.h @@ -331,6 +331,7 @@ typedef enum CPAccessResult { * 0xc or 0x18). */ CP_ACCESS_TRAP = (1 << 2), + CP_ACCESS_TRAP_EL1 = CP_ACCESS_TRAP | 1, CP_ACCESS_TRAP_EL2 = CP_ACCESS_TRAP | 2, CP_ACCESS_TRAP_EL3 = CP_ACCESS_TRAP | 3, diff --git a/target/arm/tcg/op_helper.c b/target/arm/tcg/op_helper.c index 1ba727e8e9f..c427118655d 100644 --- a/target/arm/tcg/op_helper.c +++ b/target/arm/tcg/op_helper.c @@ -781,7 +781,7 @@ const void *HELPER(access_check_cp_reg)(CPUARMState *env, uint32_t key, * the other trap takes priority. So we take the "check HSTR_EL2" path * for all of those cases.) */ - if (res != CP_ACCESS_OK && ((res & CP_ACCESS_EL_MASK) == 0) && + if (res != CP_ACCESS_OK && ((res & CP_ACCESS_EL_MASK) < 2) && arm_current_el(env) == 0) { goto fail; } @@ -887,6 +887,9 @@ const void *HELPER(access_check_cp_reg)(CPUARMState *env, uint32_t key, case 0: target_el = exception_target_el(env); break; + case 1: + assert(arm_current_el(env) < 2); + break; case 2: assert(arm_current_el(env) != 3); assert(arm_is_el2_enabled(env)); @@ -895,7 +898,6 @@ const void *HELPER(access_check_cp_reg)(CPUARMState *env, uint32_t key, assert(arm_feature(env, ARM_FEATURE_EL3)); break; default: - /* No "direct" traps to EL1 */ g_assert_not_reached(); }
In the CPAccessResult enum, the CP_ACCESS_TRAP* values indicate the equivalent of the pseudocode AArch64.SystemAccessTrap(..., 0x18), causing a trap to a specified exception level with a syndrome value giving information about the failing instructions. In the pseudocode, such traps are always taken to a specified target EL. We support that for target EL of 2 or 3 via CP_ACCESS_TRAP_EL2 and CP_ACCESS_TRAP_EL3, but the only way to take the access trap to EL1 currently is to use CP_ACCESS_TRAP, which takes the trap to the "usual target EL" (EL1 if in EL0, otherwise to the current EL). Add CP_ACCESS_TRAP_EL1 so that access functions can follow the pseudocode more closely. (Note that for the common case in the pseudocode of "trap to EL2 if HCR_EL2.TGE is set, otherwise trap to EL1", we handle this in raise_exception(), so access functions don't need to special case it and can use CP_ACCESS_TRAP_EL1.) Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- target/arm/cpregs.h | 1 + target/arm/tcg/op_helper.c | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-)