From: Peter Maydell <peter.maydell@linaro.org>
To: qemu-devel@nongnu.org
Subject: [PULL 05/41] target/arm: Make CP_ACCESS_TRAPs to AArch32 EL3 be Monitor traps
Date: Thu, 20 Feb 2025 16:20:46 +0000 [thread overview]
Message-ID: <20250220162123.626941-6-peter.maydell@linaro.org> (raw)
In-Reply-To: <20250220162123.626941-1-peter.maydell@linaro.org>
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();
(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>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20250130182309.717346-6-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 6f6cf5c888b..83ceaa58c2c 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 4a0db087dd0..2bf39a2051d 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)
--
2.43.0
next prev parent reply other threads:[~2025-02-20 16:23 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-20 16:20 [PULL 00/41] target-arm queue Peter Maydell
2025-02-20 16:20 ` [PULL 01/41] target/arm: Report correct syndrome for UNDEFINED CNTPS_*_EL1 from EL2 and NS EL1 Peter Maydell
2025-02-20 16:20 ` [PULL 02/41] target/arm: Report correct syndrome for UNDEFINED AT ops with wrong NSE, NS Peter Maydell
2025-02-20 16:20 ` [PULL 03/41] target/arm: Report correct syndrome for UNDEFINED S1E2 AT ops at EL3 Peter Maydell
2025-02-20 16:20 ` [PULL 04/41] target/arm: Report correct syndrome for UNDEFINED LOR sysregs when NS=0 Peter Maydell
2025-02-20 16:20 ` Peter Maydell [this message]
2025-02-20 16:20 ` [PULL 06/41] hw/intc/arm_gicv3_cpuif: Don't downgrade monitor traps for AArch32 EL3 Peter Maydell
2025-02-20 16:20 ` [PULL 07/41] target/arm: Honour SDCR.TDCC and SCR.TERR in AArch32 EL3 non-Monitor modes Peter Maydell
2025-02-20 16:20 ` [PULL 08/41] hw/intc/arm_gicv3_cpuif(): Remove redundant tests of is_a64() Peter Maydell
2025-02-20 16:20 ` [PULL 09/41] target/arm: Support CP_ACCESS_TRAP_EL1 as a CPAccessResult Peter Maydell
2025-02-20 16:20 ` [PULL 10/41] target/arm: Use CP_ACCESS_TRAP_EL1 for traps that are always to EL1 Peter Maydell
2025-02-20 16:20 ` [PULL 11/41] target/arm: Use TRAP_UNCATEGORIZED for XScale CPAR traps Peter Maydell
2025-02-20 16:20 ` [PULL 12/41] target/arm: Remove CP_ACCESS_TRAP handling Peter Maydell
2025-02-20 16:20 ` [PULL 13/41] target/arm: Rename CP_ACCESS_TRAP_UNCATEGORIZED to CP_ACCESS_UNDEFINED Peter Maydell
2025-02-20 16:20 ` [PULL 14/41] target/arm: Correct errors in WFI/WFE trapping Peter Maydell
2025-02-20 16:20 ` [PULL 15/41] hw/arm/exynos4210: Replace magic 32 by proper 'GIC_INTERNAL' definition Peter Maydell
2025-02-20 16:20 ` [PULL 16/41] hw/arm/exynos4210: Specify explicitly the GIC has 64 external IRQs Peter Maydell
2025-02-20 16:20 ` [PULL 17/41] hw/arm/realview: " Peter Maydell
2025-02-20 16:20 ` [PULL 18/41] hw/arm/xilinx_zynq: Replace IRQ_OFFSET -> GIC_INTERNAL Peter Maydell
2025-02-20 16:21 ` [PULL 19/41] hw/arm/xilinx_zynq: Specify explicitly the GIC has 64 external IRQs Peter Maydell
2025-02-20 16:21 ` [PULL 20/41] hw/arm/vexpress: " Peter Maydell
2025-02-20 16:21 ` [PULL 21/41] hw/arm/highbank: Specify explicitly the GIC has 128 " Peter Maydell
2025-02-20 16:21 ` [PULL 22/41] hw/cpu/arm_mpcore: Remove default values for GIC " Peter Maydell
2025-02-20 16:21 ` [PULL 23/41] Kconfig: Extract CONFIG_USB_CHIPIDEA from CONFIG_IMX Peter Maydell
2025-02-20 16:21 ` [PULL 24/41] target/arm: Use uint32_t in t32_expandimm_imm() Peter Maydell
2025-02-20 16:21 ` [PULL 25/41] roms: Update vbootrom to 1287b6e Peter Maydell
2025-02-20 16:21 ` [PULL 26/41] pc-bios: Add NPCM8XX vBootrom Peter Maydell
2025-02-20 16:21 ` [PULL 27/41] hw/ssi: Make flash size a property in NPCM7XX FIU Peter Maydell
2025-02-20 16:21 ` [PULL 28/41] hw/misc: Rename npcm7xx_gcr to npcm_gcr Peter Maydell
2025-02-20 16:21 ` [PULL 29/41] hw/misc: Move NPCM7XX GCR to NPCM GCR Peter Maydell
2025-02-20 16:21 ` [PULL 30/41] hw/misc: Add nr_regs and cold_reset_values " Peter Maydell
2025-02-20 16:21 ` [PULL 31/41] hw/misc: Add support for NPCM8XX GCR Peter Maydell
2025-02-20 16:21 ` [PULL 32/41] hw/misc: Store DRAM size in NPCM8XX GCR Module Peter Maydell
2025-02-20 16:21 ` [PULL 33/41] hw/misc: Support 8-bytes memop in NPCM GCR module Peter Maydell
2025-02-20 16:21 ` [PULL 34/41] hw/misc: Rename npcm7xx_clk to npcm_clk Peter Maydell
2025-02-20 16:21 ` [PULL 35/41] hw/misc: Move NPCM7XX CLK to NPCM CLK Peter Maydell
2025-02-20 16:21 ` [PULL 36/41] hw/misc: Add nr_regs and cold_reset_values " Peter Maydell
2025-02-20 16:21 ` [PULL 37/41] hw/misc: Support NPCM8XX CLK Module Registers Peter Maydell
2025-02-20 16:21 ` [PULL 38/41] hw/net: Add NPCM8XX PCS Module Peter Maydell
2025-02-20 16:21 ` [PULL 39/41] hw/arm: Add NPCM8XX SoC Peter Maydell
2025-02-20 16:21 ` [PULL 40/41] hw/arm: Add NPCM845 Evaluation board Peter Maydell
2025-02-20 16:21 ` [PULL 41/41] docs/system/arm: Add Description for NPCM8XX SoC Peter Maydell
2025-02-21 21:02 ` [PULL 00/41] target-arm queue Stefan Hajnoczi
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=20250220162123.626941-6-peter.maydell@linaro.org \
--to=peter.maydell@linaro.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).