[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[qemu-xen master] target/arm: Don't skip M-profile reset entirely in user mode



commit 3054f772de9c2e97e7c196d4f3e70d58aca1e807
Author:     Peter Maydell <peter.maydell@xxxxxxxxxx>
AuthorDate: Mon Sep 20 09:54:33 2021 +0100
Commit:     Michael Roth <michael.roth@xxxxxxx>
CommitDate: Tue Dec 14 08:56:25 2021 -0600

    target/arm: Don't skip M-profile reset entirely in user mode
    
    Currently all of the M-profile specific code in arm_cpu_reset() is
    inside a !defined(CONFIG_USER_ONLY) ifdef block.  This is
    unintentional: it happened because originally the only
    M-profile-specific handling was the setup of the initial SP and PC
    from the vector table, which is system-emulation only.  But then we
    added a lot of other M-profile setup to the same "if (ARM_FEATURE_M)"
    code block without noticing that it was all inside a not-user-mode
    ifdef.  This has generally been harmless, but with the addition of
    v8.1M low-overhead-loop support we ran into a problem: the reset of
    FPSCR.LTPSIZE to 4 was only being done for system emulation mode, so
    if a user-mode guest tried to execute the LE instruction it would
    incorrectly take a UsageFault.
    
    Adjust the ifdefs so only the really system-emulation specific parts
    are covered.  Because this means we now run some reset code that sets
    up initial values in the FPCCR and similar FPU related registers,
    explicitly set up the registers controlling FPU context handling in
    user-emulation mode so that the FPU works by design and not by
    chance.
    
    Resolves: https://gitlab.com/qemu-project/qemu/-/issues/613
    Cc: qemu-stable@xxxxxxxxxx
    Signed-off-by: Peter Maydell <peter.maydell@xxxxxxxxxx>
    Reviewed-by: Richard Henderson <richard.henderson@xxxxxxxxxx>
    Message-id: 20210914120725.24992-2-peter.maydell@xxxxxxxxxx
    (cherry picked from commit b62ceeaf8096fdbbbfdc6087da0028bc4a4dd77e)
    Signed-off-by: Michael Roth <michael.roth@xxxxxxx>
---
 target/arm/cpu.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 2866dd7658..af60c07ca1 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -265,12 +265,15 @@ static void arm_cpu_reset(DeviceState *dev)
         env->uncached_cpsr = ARM_CPU_MODE_SVC;
     }
     env->daif = PSTATE_D | PSTATE_A | PSTATE_I | PSTATE_F;
+#endif
 
     if (arm_feature(env, ARM_FEATURE_M)) {
+#ifndef CONFIG_USER_ONLY
         uint32_t initial_msp; /* Loaded from 0x0 */
         uint32_t initial_pc; /* Loaded from 0x4 */
         uint8_t *rom;
         uint32_t vecbase;
+#endif
 
         if (cpu_isar_feature(aa32_lob, cpu)) {
             /*
@@ -324,6 +327,8 @@ static void arm_cpu_reset(DeviceState *dev)
             env->v7m.fpccr[M_REG_S] = R_V7M_FPCCR_ASPEN_MASK |
                 R_V7M_FPCCR_LSPEN_MASK | R_V7M_FPCCR_S_MASK;
         }
+
+#ifndef CONFIG_USER_ONLY
         /* Unlike A/R profile, M profile defines the reset LR value */
         env->regs[14] = 0xffffffff;
 
@@ -352,8 +357,22 @@ static void arm_cpu_reset(DeviceState *dev)
         env->regs[13] = initial_msp & 0xFFFFFFFC;
         env->regs[15] = initial_pc & ~1;
         env->thumb = initial_pc & 1;
+#else
+        /*
+         * For user mode we run non-secure and with access to the FPU.
+         * The FPU context is active (ie does not need further setup)
+         * and is owned by non-secure.
+         */
+        env->v7m.secure = false;
+        env->v7m.nsacr = 0xcff;
+        env->v7m.cpacr[M_REG_NS] = 0xf0ffff;
+        env->v7m.fpccr[M_REG_S] &=
+            ~(R_V7M_FPCCR_LSPEN_MASK | R_V7M_FPCCR_S_MASK);
+        env->v7m.control[M_REG_S] |= R_V7M_CONTROL_FPCA_MASK;
+#endif
     }
 
+#ifndef CONFIG_USER_ONLY
     /* AArch32 has a hard highvec setting of 0xFFFF0000.  If we are currently
      * executing as AArch32 then check if highvecs are enabled and
      * adjust the PC accordingly.
--
generated by git-patchbot for /home/xen/git/qemu-xen.git#master



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.