[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 26/35] target/arm: Allow access to SPSR_hyp from hyp mode
From: |
Peter Maydell |
Subject: |
[PULL 26/35] target/arm: Allow access to SPSR_hyp from hyp mode |
Date: |
Thu, 15 Feb 2024 17:35:29 +0000 |
Architecturally, the AArch32 MSR/MRS to/from banked register
instructions are UNPREDICTABLE for attempts to access a banked
register that the guest could access in a more direct way (e.g.
using this insn to access r8_fiq when already in FIQ mode). QEMU has
chosen to UNDEF on all of these.
However, for the case of accessing SPSR_hyp from hyp mode, it turns
out that real hardware permits this, with the same effect as if the
guest had directly written to SPSR. Further, there is some
guest code out there that assumes it can do this, because it
happens to work on hardware: an example Cortex-R52 startup code
fragment uses this, and it got copied into various other places,
including Zephyr. Zephyr was fixed to not use this:
https://github.com/zephyrproject-rtos/zephyr/issues/47330
but other examples are still out there, like the selftest
binary for the MPS3-AN536.
For convenience of being able to run guest code, permit
this UNPREDICTABLE access instead of UNDEFing it.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20240206132931.38376-5-peter.maydell@linaro.org
---
target/arm/tcg/op_helper.c | 43 ++++++++++++++++++++++++++------------
target/arm/tcg/translate.c | 19 +++++++++++------
2 files changed, 43 insertions(+), 19 deletions(-)
diff --git a/target/arm/tcg/op_helper.c b/target/arm/tcg/op_helper.c
index b5ac26061c7..c199b69fbff 100644
--- a/target/arm/tcg/op_helper.c
+++ b/target/arm/tcg/op_helper.c
@@ -570,10 +570,24 @@ static void msr_mrs_banked_exc_checks(CPUARMState *env,
uint32_t tgtmode,
*/
int curmode = env->uncached_cpsr & CPSR_M;
- if (regno == 17) {
- /* ELR_Hyp: a special case because access from tgtmode is OK */
- if (curmode != ARM_CPU_MODE_HYP && curmode != ARM_CPU_MODE_MON) {
- goto undef;
+ if (tgtmode == ARM_CPU_MODE_HYP) {
+ /*
+ * Handle Hyp target regs first because some are special cases
+ * which don't want the usual "not accessible from tgtmode" check.
+ */
+ switch (regno) {
+ case 16 ... 17: /* ELR_Hyp, SPSR_Hyp */
+ if (curmode != ARM_CPU_MODE_HYP && curmode != ARM_CPU_MODE_MON) {
+ goto undef;
+ }
+ break;
+ case 13:
+ if (curmode != ARM_CPU_MODE_MON) {
+ goto undef;
+ }
+ break;
+ default:
+ g_assert_not_reached();
}
return;
}
@@ -604,13 +618,6 @@ static void msr_mrs_banked_exc_checks(CPUARMState *env,
uint32_t tgtmode,
}
}
- if (tgtmode == ARM_CPU_MODE_HYP) {
- /* SPSR_Hyp, r13_hyp: accessible from Monitor mode only */
- if (curmode != ARM_CPU_MODE_MON) {
- goto undef;
- }
- }
-
return;
undef:
@@ -625,7 +632,12 @@ void HELPER(msr_banked)(CPUARMState *env, uint32_t value,
uint32_t tgtmode,
switch (regno) {
case 16: /* SPSRs */
- env->banked_spsr[bank_number(tgtmode)] = value;
+ if (tgtmode == (env->uncached_cpsr & CPSR_M)) {
+ /* Only happens for SPSR_Hyp access in Hyp mode */
+ env->spsr = value;
+ } else {
+ env->banked_spsr[bank_number(tgtmode)] = value;
+ }
break;
case 17: /* ELR_Hyp */
env->elr_el[2] = value;
@@ -659,7 +671,12 @@ uint32_t HELPER(mrs_banked)(CPUARMState *env, uint32_t
tgtmode, uint32_t regno)
switch (regno) {
case 16: /* SPSRs */
- return env->banked_spsr[bank_number(tgtmode)];
+ if (tgtmode == (env->uncached_cpsr & CPSR_M)) {
+ /* Only happens for SPSR_Hyp access in Hyp mode */
+ return env->spsr;
+ } else {
+ return env->banked_spsr[bank_number(tgtmode)];
+ }
case 17: /* ELR_Hyp */
return env->elr_el[2];
case 13:
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
index 5fa82497238..f947c62c6be 100644
--- a/target/arm/tcg/translate.c
+++ b/target/arm/tcg/translate.c
@@ -2822,13 +2822,20 @@ static bool msr_banked_access_decode(DisasContext *s,
int r, int sysm, int rn,
break;
case ARM_CPU_MODE_HYP:
/*
- * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
- * (and so we can forbid accesses from EL2 or below). elr_hyp
- * can be accessed also from Hyp mode, so forbid accesses from
- * EL0 or EL1.
+ * r13_hyp can only be accessed from Monitor mode, and so we
+ * can forbid accesses from EL2 or below.
+ * elr_hyp can be accessed also from Hyp mode, so forbid
+ * accesses from EL0 or EL1.
+ * SPSR_hyp is supposed to be in the same category as r13_hyp
+ * and UNPREDICTABLE if accessed from anything except Monitor
+ * mode. However there is some real-world code that will do
+ * it because at least some hardware happens to permit the
+ * access. (Notably a standard Cortex-R52 startup code fragment
+ * does this.) So we permit SPSR_hyp from Hyp mode also, to allow
+ * this (incorrect) guest code to run.
*/
- if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2 ||
- (s->current_el < 3 && *regno != 17)) {
+ if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2
+ || (s->current_el < 3 && *regno != 16 && *regno != 17)) {
goto undef;
}
break;
--
2.34.1
- [PULL 18/35] hw/arm/smmuv3: add support for stage 1 access fault, (continued)
- [PULL 18/35] hw/arm/smmuv3: add support for stage 1 access fault, Peter Maydell, 2024/02/15
- [PULL 09/35] hw/block/tc58128: Don't emit deprecation warning under qtest, Peter Maydell, 2024/02/15
- [PULL 17/35] tests/qtest: Fix GMAC test to run on a machine in upstream QEMU, Peter Maydell, 2024/02/15
- [PULL 12/35] hw/arm/virt: Wire up non-secure EL2 virtual timer IRQ, Peter Maydell, 2024/02/15
- [PULL 15/35] tests/qtest/npcm7xx_emc-test: Connect all NICs to a backend, Peter Maydell, 2024/02/15
- [PULL 19/35] hw/arm/stellaris: Convert ADC controller to Resettable interface, Peter Maydell, 2024/02/15
- [PULL 21/35] hw/arm/stellaris: Add missing QOM 'machine' parent, Peter Maydell, 2024/02/15
- [PULL 23/35] target/arm: Use new CBAR encoding for all v8 CPUs, not all aarch64 CPUs, Peter Maydell, 2024/02/15
- [PULL 29/35] hw/misc/mps2-scc: Make changes needed for AN536 FPGA image, Peter Maydell, 2024/02/15
- [PULL 07/35] target/arm: Fix SVE/SME gross MTE suppression checks, Peter Maydell, 2024/02/15
- [PULL 26/35] target/arm: Allow access to SPSR_hyp from hyp mode,
Peter Maydell <=
- [PULL 28/35] hw/misc/mps2-scc: Factor out which-board conditionals, Peter Maydell, 2024/02/15
- [PULL 25/35] target/arm: Add Cortex-R52 IMPDEF sysregs, Peter Maydell, 2024/02/15
- [PULL 34/35] hw/arm/mps3r: Add remaining devices, Peter Maydell, 2024/02/15
- [PULL 30/35] hw/arm/mps3r: Initial skeleton for mps3-an536 board, Peter Maydell, 2024/02/15
- [PULL 03/35] target/arm: Fix nregs computation in do_{ld,st}_zpa, Peter Maydell, 2024/02/15
- [PULL 06/35] target/arm: Handle mte in do_ldrq, do_ldro, Peter Maydell, 2024/02/15
- [PULL 31/35] hw/arm/mps3r: Add CPUs, GIC, and per-CPU RAM, Peter Maydell, 2024/02/15
- [PULL 35/35] docs: Add documentation for the mps3-an536 board, Peter Maydell, 2024/02/15
- [PULL 20/35] hw/arm/stellaris: Convert I2C controller to Resettable interface, Peter Maydell, 2024/02/15
- [PULL 32/35] hw/arm/mps3r: Add UARTs, Peter Maydell, 2024/02/15