diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2018-11-13 10:47:59 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2018-11-13 10:47:59 +0000 |
commit | 593cfa2b637b92d37eef949653840dc065cdb960 (patch) | |
tree | 9285153a8e81dcc7ff3de6bc97bc7e5936650129 /target/arm/kvm32.c | |
parent | 89430fc6f80a5aef1d4cbd6fc26b40c30793786c (diff) | |
download | qemu-593cfa2b637b92d37eef949653840dc065cdb960.zip qemu-593cfa2b637b92d37eef949653840dc065cdb960.tar.gz qemu-593cfa2b637b92d37eef949653840dc065cdb960.tar.bz2 |
target/arm: Hyp mode R14 is shared with User and System
Hyp mode is an exception to the general rule that each AArch32
mode has its own r13, r14 and SPSR -- it has a banked r13 and
SPSR but shares its r14 with User and System mode. We were
incorrectly implementing it as banked, which meant that on
entry to Hyp mode r14 was 0 rather than the USR/SYS r14.
We provide a new function r14_bank_number() which is like
the existing bank_number() but provides the index into
env->banked_r14[]; bank_number() provides the index to use
for env->banked_r13[] and env->banked_cpsr[].
All the points in the code that were using bank_number()
to index into env->banked_r14[] are updated for consintency:
* switch_mode() -- this is the only place where we fix
an actual bug
* aarch64_sync_32_to_64() and aarch64_sync_64_to_32():
no behavioural change as we already special-cased Hyp R14
* kvm32.c: no behavioural change since the guest can't ever
be in Hyp mode, but conceptually the right thing to do
* msr_banked()/mrs_banked(): we can never get to the case
that accesses banked_r14[] with tgtmode == ARM_CPU_MODE_HYP,
so no behavioural change
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20181109173553.22341-2-peter.maydell@linaro.org
Diffstat (limited to 'target/arm/kvm32.c')
-rw-r--r-- | target/arm/kvm32.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c index 0f1e94c..cb3fb73 100644 --- a/target/arm/kvm32.c +++ b/target/arm/kvm32.c @@ -318,8 +318,8 @@ int kvm_arch_put_registers(CPUState *cs, int level) memcpy(env->usr_regs, env->regs + 8, 5 * sizeof(uint32_t)); } env->banked_r13[bn] = env->regs[13]; - env->banked_r14[bn] = env->regs[14]; env->banked_spsr[bn] = env->spsr; + env->banked_r14[r14_bank_number(mode)] = env->regs[14]; /* Now we can safely copy stuff down to the kernel */ for (i = 0; i < ARRAY_SIZE(regs); i++) { @@ -430,8 +430,8 @@ int kvm_arch_get_registers(CPUState *cs) memcpy(env->regs + 8, env->usr_regs, 5 * sizeof(uint32_t)); } env->regs[13] = env->banked_r13[bn]; - env->regs[14] = env->banked_r14[bn]; env->spsr = env->banked_spsr[bn]; + env->regs[14] = env->banked_r14[r14_bank_number(mode)]; /* VFP registers */ r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | KVM_REG_ARM_VFP; |