[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 01/30] target-arm: Correct handling of writes to CPSR
From: |
Peter Maydell |
Subject: |
[Qemu-devel] [PULL 01/30] target-arm: Correct handling of writes to CPSR mode bits from gdb in usermode |
Date: |
Fri, 4 Mar 2016 11:41:24 +0000 |
In helper.c the expression
(env->uncached_cpsr & CPSR_M) != CPSR_USER
is always true; the right hand side was supposed to be ARM_CPU_MODE_USR
(an error in commit cb01d391).
Since the incorrect expression was always true, this just meant that
commit cb01d391 had no effect.
However simply changing the RHS here would reveal a logic error: if
the mode is USR we wish to completely ignore the attempt to set the
mode bits, which means that we must clear the CPSR_M bits from mask
to avoid the uncached_cpsr bits being updated at the end of the
function.
Move the condition into the correct place in the code, fix its RHS
constant, and add a comment about the fact that we must be doing a
gdbstub write if we're in user mode.
Fixes: https://bugs.launchpad.net/qemu/+bug/1550503
Signed-off-by: Peter Maydell <address@hidden>
Reviewed-by: Sergey Fedorov <address@hidden>
Message-id: address@hidden
---
target-arm/helper.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 18c8296..935f13b 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -5490,9 +5490,16 @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t
mask,
env->daif |= val & CPSR_AIF & mask;
if (write_type != CPSRWriteRaw &&
- (env->uncached_cpsr & CPSR_M) != CPSR_USER &&
((env->uncached_cpsr ^ val) & mask & CPSR_M)) {
- if (bad_mode_switch(env, val & CPSR_M, write_type)) {
+ if ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR) {
+ /* Note that we can only get here in USR mode if this is a
+ * gdb stub write; for this case we follow the architectural
+ * behaviour for guest writes in USR mode of ignoring an attempt
+ * to switch mode. (Those are caught by translate.c for writes
+ * triggered by guest instructions.)
+ */
+ mask &= ~CPSR_M;
+ } else if (bad_mode_switch(env, val & CPSR_M, write_type)) {
/* Attempt to switch to an invalid mode: this is UNPREDICTABLE in
* v7, and has defined behaviour in v8:
* + leave CPSR.M untouched
--
1.9.1
- [Qemu-devel] [PULL 00/30] target-arm queue, Peter Maydell, 2016/03/04
- [Qemu-devel] [PULL 02/30] virt: Lift the maximum RAM limit from 30GB to 255GB, Peter Maydell, 2016/03/04
- [Qemu-devel] [PULL 04/30] sdhci: Implement DeviceClass reset, Peter Maydell, 2016/03/04
- [Qemu-devel] [PULL 03/30] sd.c: Handle NULL block backend in sd_get_inserted(), Peter Maydell, 2016/03/04
- [Qemu-devel] [PULL 01/30] target-arm: Correct handling of writes to CPSR mode bits from gdb in usermode,
Peter Maydell <=
- [Qemu-devel] [PULL 12/30] linux-user: arm: pass env to get_user_code_*, Peter Maydell, 2016/03/04
- [Qemu-devel] [PULL 10/30] bcm2835_mbox/property: replace ldl_phys/stl_phys with endian-specific accesses, Peter Maydell, 2016/03/04
- [Qemu-devel] [PULL 16/30] linux-user: arm: set CPSR.E/SCTLR.E0E correctly for BE mode, Peter Maydell, 2016/03/04
- [Qemu-devel] [PULL 07/30] hw/arm/virt: Load bios image to MemoryRegion, not physaddr, Peter Maydell, 2016/03/04
- [Qemu-devel] [PULL 14/30] target-arm: cpu: Move cpu_is_big_endian to header, Peter Maydell, 2016/03/04
- [Qemu-devel] [PULL 22/30] target-arm: introduce tbflag for endianness, Peter Maydell, 2016/03/04
- [Qemu-devel] [PULL 06/30] loader: Add load_image_mr() to load ROM image to a MemoryRegion, Peter Maydell, 2016/03/04
- [Qemu-devel] [PULL 19/30] target-arm: pass DisasContext to gen_aa32_ld*/st*, Peter Maydell, 2016/03/04
- [Qemu-devel] [PULL 08/30] hw/arm/virt: Make first flash device Secure-only if booting secure, Peter Maydell, 2016/03/04
- [Qemu-devel] [PULL 15/30] arm: cpu: handle BE32 user-mode as BE, Peter Maydell, 2016/03/04