All of lore.kernel.org
 help / color / mirror / Atom feed
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

  reply	other threads:[~2025-02-05 12:52 UTC|newest]

Thread overview: 41+ 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-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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.