From: Peter Maydell <peter.maydell@linaro.org>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PULL 06/19] target-arm: Don't allow AArch32 to access RES0 CPSR bits
Date: Tue, 19 Aug 2014 19:09:31 +0100 [thread overview]
Message-ID: <1408471784-2652-7-git-send-email-peter.maydell@linaro.org> (raw)
In-Reply-To: <1408471784-2652-1-git-send-email-peter.maydell@linaro.org>
The CPSR has a new-in-v8 execution state bit (IL), and
also some state which has effects in AArch32 but appears
only in the SPSR format (SS) but is RES0 in the CPSR.
Add the IL bit to CPSR_EXEC, and enforce that guest direct
reads and writes to CPSR can't read or write the RES0
bits, so the guest can't get at the SS bit which we store
in uncached_cpsr. This includes not permitting exception
returns to copy reserved bits from an SPSR into CPSR.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
---
target-arm/cpu.h | 12 ++++++++++--
target-arm/op_helper.c | 2 +-
target-arm/translate.c | 13 +++++++------
3 files changed, 18 insertions(+), 9 deletions(-)
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 79205ba..8380c13 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -411,7 +411,13 @@ int arm_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
#define CPSR_E (1U << 9)
#define CPSR_IT_2_7 (0xfc00U)
#define CPSR_GE (0xfU << 16)
-#define CPSR_RESERVED (0xfU << 20)
+#define CPSR_IL (1U << 20)
+/* Note that the RESERVED bits include bit 21, which is PSTATE_SS in
+ * an AArch64 SPSR but RES0 in AArch32 SPSR and CPSR. In QEMU we use
+ * env->uncached_cpsr bit 21 to store PSTATE.SS when executing in AArch32,
+ * where it is live state but not accessible to the AArch32 code.
+ */
+#define CPSR_RESERVED (0x7U << 21)
#define CPSR_J (1U << 24)
#define CPSR_IT_0_1 (3U << 25)
#define CPSR_Q (1U << 27)
@@ -428,7 +434,9 @@ int arm_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
/* Bits writable in user mode. */
#define CPSR_USER (CPSR_NZCV | CPSR_Q | CPSR_GE)
/* Execution state bits. MRS read as zero, MSR writes ignored. */
-#define CPSR_EXEC (CPSR_T | CPSR_IT | CPSR_J)
+#define CPSR_EXEC (CPSR_T | CPSR_IT | CPSR_J | CPSR_IL)
+/* Mask of bits which may be set by exception return copying them from SPSR */
+#define CPSR_ERET_MASK (~CPSR_RESERVED)
#define TTBCR_N (7U << 0) /* TTBCR.EAE==0 */
#define TTBCR_T0SZ (7U << 0) /* TTBCR.EAE==1 */
diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
index 25ad902..180a4a0 100644
--- a/target-arm/op_helper.c
+++ b/target-arm/op_helper.c
@@ -258,7 +258,7 @@ void HELPER(exception_with_syndrome)(CPUARMState *env, uint32_t excp,
uint32_t HELPER(cpsr_read)(CPUARMState *env)
{
- return cpsr_read(env) & ~CPSR_EXEC;
+ return cpsr_read(env) & ~(CPSR_EXEC | CPSR_RESERVED);
}
void HELPER(cpsr_write)(CPUARMState *env, uint32_t val, uint32_t mask)
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 4012185..4cde309 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -3908,9 +3908,10 @@ static uint32_t msr_mask(CPUARMState *env, DisasContext *s, int flags, int spsr)
mask &= ~(CPSR_E | CPSR_GE);
if (!arm_feature(env, ARM_FEATURE_THUMB2))
mask &= ~CPSR_IT;
- /* Mask out execution state bits. */
- if (!spsr)
- mask &= ~CPSR_EXEC;
+ /* Mask out execution state and reserved bits. */
+ if (!spsr) {
+ mask &= ~(CPSR_EXEC | CPSR_RESERVED);
+ }
/* Mask out privileged bits. */
if (IS_USER(s))
mask &= CPSR_USER;
@@ -3954,7 +3955,7 @@ static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
TCGv_i32 tmp;
store_reg(s, 15, pc);
tmp = load_cpu_field(spsr);
- gen_set_cpsr(tmp, 0xffffffff);
+ gen_set_cpsr(tmp, CPSR_ERET_MASK);
tcg_temp_free_i32(tmp);
s->is_jmp = DISAS_UPDATE;
}
@@ -3962,7 +3963,7 @@ static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
/* Generate a v6 exception return. Marks both values as dead. */
static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
{
- gen_set_cpsr(cpsr, 0xffffffff);
+ gen_set_cpsr(cpsr, CPSR_ERET_MASK);
tcg_temp_free_i32(cpsr);
store_reg(s, 15, pc);
s->is_jmp = DISAS_UPDATE;
@@ -8836,7 +8837,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
if ((insn & (1 << 22)) && !user) {
/* Restore CPSR from SPSR. */
tmp = load_cpu_field(spsr);
- gen_set_cpsr(tmp, 0xffffffff);
+ gen_set_cpsr(tmp, CPSR_ERET_MASK);
tcg_temp_free_i32(tmp);
s->is_jmp = DISAS_UPDATE;
}
--
1.9.1
next prev parent reply other threads:[~2014-08-19 18:11 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-08-19 18:09 [Qemu-devel] [PULL 00/19] target-arm queue Peter Maydell
2014-08-19 18:09 ` [Qemu-devel] [PULL 01/19] target-arm: Fix return address for A64 BRK instructions Peter Maydell
2014-08-19 18:09 ` [Qemu-devel] [PULL 02/19] target-arm: Collect up the debug cp register definitions Peter Maydell
2014-08-19 18:09 ` [Qemu-devel] [PULL 03/19] target-arm: Allow STATE_BOTH reginfo descriptions for more than cp14 Peter Maydell
2014-08-19 18:09 ` [Qemu-devel] [PULL 04/19] target-arm: Provide both 32 and 64 bit versions of debug registers Peter Maydell
2014-08-19 18:09 ` [Qemu-devel] [PULL 05/19] target-arm: Adjust debug ID registers per-CPU Peter Maydell
2014-08-19 18:09 ` Peter Maydell [this message]
2014-08-19 18:09 ` [Qemu-devel] [PULL 07/19] target-arm: Correctly handle PSTATE.SS when taking exception to AArch32 Peter Maydell
2014-08-19 18:09 ` [Qemu-devel] [PULL 08/19] target-arm: Set PSTATE.SS correctly on exception return from AArch64 Peter Maydell
2014-08-19 18:09 ` [Qemu-devel] [PULL 09/19] target-arm: A64: Avoid duplicate exit_tb(0) in non-linked goto_tb Peter Maydell
2014-08-19 18:09 ` [Qemu-devel] [PULL 10/19] target-arm: Implement ARMv8 single-step handling for A64 code Peter Maydell
2014-08-19 18:09 ` [Qemu-devel] [PULL 11/19] target-arm: Implement ARMv8 single-stepping for AArch32 code Peter Maydell
2014-08-19 18:09 ` [Qemu-devel] [PULL 12/19] target-arm: Implement MDSCR_EL1 as having state Peter Maydell
2014-08-19 18:09 ` [Qemu-devel] [PULL 13/19] target-arm: Rename QEMU PSCI v0.1 definitions Peter Maydell
2014-08-19 18:09 ` [Qemu-devel] [PULL 14/19] arm/virt: Use PSCI v0.2 function IDs in the DT when KVM uses PSCI v0.2 Peter Maydell
2014-08-19 18:09 ` [Qemu-devel] [PULL 15/19] arm: cortex-a9: Fix cache-line size and associativity Peter Maydell
2014-08-19 18:09 ` [Qemu-devel] [PULL 16/19] loader: Add load_image_gzipped function Peter Maydell
2014-08-19 18:09 ` [Qemu-devel] [PULL 17/19] aarch64: Allow -kernel option to take a gzip-compressed kernel Peter Maydell
2014-08-19 18:09 ` [Qemu-devel] [PULL 18/19] arm: armv7m: Rename address_space_mem -> system_memory Peter Maydell
2014-08-19 18:09 ` [Qemu-devel] [PULL 19/19] arm: stellaris: Remove misleading address_space_mem var Peter Maydell
2014-08-20 9:49 ` [Qemu-devel] [PULL 00/19] target-arm queue Peter Maydell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1408471784-2652-7-git-send-email-peter.maydell@linaro.org \
--to=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).