From: "Alex Bennée" <alex.bennee@linaro.org>
To: Peter Maydell <peter.maydell@linaro.org>
Cc: qemu-arm@nongnu.org, qemu-devel@nongnu.org
Subject: Re: [PATCH 05/14] target/arm: Make CP_ACCESS_TRAPs to AArch32 EL3 be Monitor traps
Date: Wed, 05 Feb 2025 12:51:59 +0000 [thread overview]
Message-ID: <874j18a70w.fsf@draig.linaro.org> (raw)
In-Reply-To: <20250130182309.717346-6-peter.maydell@linaro.org> (Peter Maydell's message of "Thu, 30 Jan 2025 18:23:00 +0000")
Peter Maydell <peter.maydell@linaro.org> writes:
> In system register access pseudocode the common pattern for
> AArch32 registers with access traps to EL3 is:
>
> at EL1 and EL2:
> if HaveEL(EL3) && !ELUsingAArch32(EL3) && (SCR_EL3.TERR == 1) then
> AArch64.AArch32SystemAccessTrap(EL3, 0x03);
> elsif HaveEL(EL3) && ELUsingAArch32(EL3) && (SCR.TERR == 1) then
> AArch32.TakeMonitorTrapException();
> at EL3:
> if (PSTATE.M != M32_Monitor) && (SCR.TERR == 1) then
> AArch32.TakeMonitorTrapException();
I was confused a little by my copy which was:
elsif HaveEL(EL3) && !ELUsingAArch32(EL3) && SCR_EL3.TERR == '1' then
if EL3SDDUndef() then
UNDEFINED;
else
AArch64.AArch32SystemAccessTrap(EL3, 0x03);
But I think EL3SDDUndef() is always false for us as we don't have an
external debug interface.
>
> (taking as an example the ERRIDR access pseudocode).
>
> This implements the behaviour of (in this case) SCR.TERR that
> "Accesses to the specified registers from modes other than Monitor
> mode generate a Monitor Trap exception" and of SCR_EL3.TERR that
> "Accesses of the specified Error Record registers at EL2 and EL1
> are trapped to EL3, unless the instruction generates a higher
> priority exception".
>
> In QEMU we don't implement this pattern correctly in two ways:
> * in access_check_cp_reg() we turn the CP_ACCESS_TRAP_EL3 into
> an UNDEF, not a trap to Monitor mode
> * in the access functions, we check trap bits like SCR.TERR
> only when arm_current_el(env) < 3 -- this is correct for
> AArch64 EL3, but misses the "trap non-Monitor-mode execution
> at EL3 into Monitor mode" case for AArch32 EL3
>
> In this commit we fix the first of these two issues, by
> making access_check_cp_reg() handle CP_ACCESS_TRAP_EL3
> as a Monitor trap. This is a kind of exception that we haven't
> yet implemented(!), so we need a new EXCP_MON_TRAP for it.
>
> This diverges from the pseudocode approach, where every access check
> function explicitly checks for "if EL3 is AArch32" and takes a
> monitor trap; if we wanted to be closer to the pseudocode we could
> add a new CP_ACCESS_TRAP_MONITOR and make all the accessfns use it
> when appropriate. But because there are no non-standard cases in the
> pseudocode (i.e. where either it raises a Monitor trap that doesn't
> correspond to an AArch64 SystemAccessTrap or where it raises a
> SystemAccessTrap that doesn't correspond to a Monitor trap), handling
> this all in one place seems less likely to result in future bugs
> where we forgot again about this special case when writing an
> accessor.
>
> (The cc of stable here is because "hw/intc/arm_gicv3_cpuif: Don't
> downgrade monitor traps for AArch32 EL3" which is also cc:stable
> will implicitly use the new EXCP_MON_TRAP code path.)
>
> Cc: qemu-stable@nongnu.org
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
> target/arm/cpu.h | 1 +
> target/arm/helper.c | 11 +++++++++++
> target/arm/tcg/op_helper.c | 13 ++++++++++++-
> 3 files changed, 24 insertions(+), 1 deletion(-)
>
> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> index 2213c277348..4cb672c120b 100644
> --- a/target/arm/cpu.h
> +++ b/target/arm/cpu.h
> @@ -62,6 +62,7 @@
> #define EXCP_NMI 26
> #define EXCP_VINMI 27
> #define EXCP_VFNMI 28
> +#define EXCP_MON_TRAP 29 /* AArch32 trap to Monitor mode */
> /* NB: add new EXCP_ defines to the array in arm_log_exception() too */
>
> #define ARMV7M_EXCP_RESET 1
> diff --git a/target/arm/helper.c b/target/arm/helper.c
> index 5d9eca35c04..c5cd27b249f 100644
> --- a/target/arm/helper.c
> +++ b/target/arm/helper.c
> @@ -9684,6 +9684,7 @@ void arm_log_exception(CPUState *cs)
> [EXCP_NMI] = "NMI",
> [EXCP_VINMI] = "Virtual IRQ NMI",
> [EXCP_VFNMI] = "Virtual FIQ NMI",
> + [EXCP_MON_TRAP] = "Monitor Trap",
> };
>
> if (idx >= 0 && idx < ARRAY_SIZE(excnames)) {
> @@ -10250,6 +10251,16 @@ static void arm_cpu_do_interrupt_aarch32(CPUState *cs)
> mask = CPSR_A | CPSR_I | CPSR_F;
> offset = 0;
> break;
> + case EXCP_MON_TRAP:
> + new_mode = ARM_CPU_MODE_MON;
> + addr = 0x04;
> + mask = CPSR_A | CPSR_I | CPSR_F;
> + if (env->thumb) {
> + offset = 2;
> + } else {
> + offset = 4;
> + }
> + break;
> default:
> cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
> return; /* Never happens. Keep compiler happy. */
> diff --git a/target/arm/tcg/op_helper.c b/target/arm/tcg/op_helper.c
> index 1161d301b71..1ba727e8e9f 100644
> --- a/target/arm/tcg/op_helper.c
> +++ b/target/arm/tcg/op_helper.c
> @@ -758,6 +758,7 @@ const void *HELPER(access_check_cp_reg)(CPUARMState *env, uint32_t key,
> const ARMCPRegInfo *ri = get_arm_cp_reginfo(cpu->cp_regs, key);
> CPAccessResult res = CP_ACCESS_OK;
> int target_el;
> + uint32_t excp;
>
> assert(ri != NULL);
>
> @@ -851,8 +852,18 @@ const void *HELPER(access_check_cp_reg)(CPUARMState *env, uint32_t key,
> }
>
> fail:
> + excp = EXCP_UDEF;
> switch (res & ~CP_ACCESS_EL_MASK) {
> case CP_ACCESS_TRAP:
> + /*
> + * If EL3 is AArch32 then there's no syndrome register; the cases
> + * where we would raise a SystemAccessTrap to AArch64 EL3 all become
> + * raising a Monitor trap exception. (Because there's no visible
> + * syndrome it doesn't matter what we pass to raise_exception().)
> + */
> + if ((res & CP_ACCESS_EL_MASK) == 3 && !arm_el_is_aa64(env, 3)) {
> + excp = EXCP_MON_TRAP;
> + }
> break;
> case CP_ACCESS_TRAP_UNCATEGORIZED:
> /* Only CP_ACCESS_TRAP traps are direct to a specified EL */
> @@ -888,7 +899,7 @@ const void *HELPER(access_check_cp_reg)(CPUARMState *env, uint32_t key,
> g_assert_not_reached();
> }
>
> - raise_exception(env, EXCP_UDEF, syndrome, target_el);
> + raise_exception(env, excp, syndrome, target_el);
> }
>
> const void *HELPER(lookup_cp_reg)(CPUARMState *env, uint32_t key)
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
--
Alex Bennée
Virtualisation Tech Lead @ Linaro
next prev parent reply other threads:[~2025-02-05 12:52 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-01-30 18:22 [PATCH 00/14] target/arm: Clean up some corner cases of sysreg traps Peter Maydell
2025-01-30 18:22 ` [PATCH 01/14] target/arm: Report correct syndrome for UNDEFINED CNTPS_*_EL1 from EL2 and NS EL1 Peter Maydell
2025-02-05 8:59 ` Alex Bennée
2025-02-10 18:44 ` Richard Henderson
2025-01-30 18:22 ` [PATCH 02/14] target/arm: Report correct syndrome for UNDEFINED AT ops with wrong NSE, NS Peter Maydell
2025-02-10 18:46 ` Richard Henderson
2025-01-30 18:22 ` [PATCH 03/14] target/arm: Report correct syndrome for UNDEFINED S1E2 AT ops at EL3 Peter Maydell
2025-02-10 18:58 ` Richard Henderson
2025-01-30 18:22 ` [PATCH 04/14] target/arm: Report correct syndrome for UNDEFINED LOR sysregs when NS=0 Peter Maydell
2025-02-05 12:05 ` Alex Bennée
2025-02-10 18:59 ` Richard Henderson
2025-01-30 18:23 ` [PATCH 05/14] target/arm: Make CP_ACCESS_TRAPs to AArch32 EL3 be Monitor traps Peter Maydell
2025-02-05 12:51 ` Alex Bennée [this message]
2025-02-05 14:39 ` Peter Maydell
2025-02-10 19:13 ` Richard Henderson
2025-01-30 18:23 ` [PATCH 06/14] hw/intc/arm_gicv3_cpuif: Don't downgrade monitor traps for AArch32 EL3 Peter Maydell
2025-02-05 14:29 ` Alex Bennée
2025-02-10 19:15 ` Richard Henderson
2025-01-30 18:23 ` [PATCH 07/14] target/arm: Honour SDCR.TDCC and SCR.TERR in AArch32 EL3 non-Monitor modes Peter Maydell
2025-02-05 14:40 ` Alex Bennée
2025-02-10 19:20 ` Richard Henderson
2025-01-30 18:23 ` [PATCH 08/14] hw/intc/arm_gicv3_cpuif(): Remove redundant tests of is_a64() Peter Maydell
2025-02-05 14:42 ` Alex Bennée
2025-02-10 19:23 ` Richard Henderson
2025-01-30 18:23 ` [PATCH 09/14] target/arm: Support CP_ACCESS_TRAP_EL1 as a CPAccessResult Peter Maydell
2025-02-10 19:26 ` Richard Henderson
2025-01-30 18:23 ` [PATCH 10/14] target/arm: Use CP_ACCESS_TRAP_EL1 for traps that are always to EL1 Peter Maydell
2025-02-10 19:29 ` Richard Henderson
2025-01-30 18:23 ` [PATCH 11/14] target/arm: Use TRAP_UNCATEGORIZED for XScale CPAR traps Peter Maydell
2025-02-01 7:31 ` Philippe Mathieu-Daudé
2025-02-10 19:30 ` Richard Henderson
2025-01-30 18:23 ` [PATCH 12/14] target/arm: Remove CP_ACCESS_TRAP handling Peter Maydell
2025-02-10 19:34 ` Richard Henderson
2025-02-11 9:51 ` Peter Maydell
2025-01-30 18:23 ` [PATCH 13/14] target/arm: Rename CP_ACCESS_TRAP_UNCATEGORIZED to CP_ACCESS_UNDEFINED Peter Maydell
2025-02-01 7:32 ` Philippe Mathieu-Daudé
2025-02-10 19:36 ` Richard Henderson
2025-01-30 18:23 ` [PATCH 14/14] target/arm: Correct errors in WFI/WFE trapping Peter Maydell
2025-02-10 19:53 ` Richard Henderson
2025-02-10 10:27 ` [PATCH 00/14] target/arm: Clean up some corner cases of sysreg traps Peter Maydell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=874j18a70w.fsf@draig.linaro.org \
--to=alex.bennee@linaro.org \
--cc=peter.maydell@linaro.org \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).