target-arm: In cpsr_write() ignore mode switches from User mode

The only case where we can attempt a cpsr_write() mode switch from
User is from the gdbstub; all other cases are handled in the
calling code (notably translate.c). Architecturally attempts to
alter the mode bits from user mode are simply ignored (and not
treated as a bad mode switch, which in v8 sets CPSR.IL). Make
mode switches from User ignored in cpsr_write() as well, for
consistency.

Backports commit cb01d3912c8b000ed26d5fe95f6c194b3e3ba7a6 from qemu
This commit is contained in:
Peter Maydell 2018-02-20 22:18:46 -05:00 committed by Lioncash
parent 553e230088
commit a468baff61
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7

View file

@ -4619,6 +4619,7 @@ 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)) {
/* Attempt to switch to an invalid mode: this is UNPREDICTABLE.