[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 18/26] target/arm: Set FPCCR.S when executing M-prof
From: |
Peter Maydell |
Subject: |
[Qemu-devel] [PATCH 18/26] target/arm: Set FPCCR.S when executing M-profile floating point insns |
Date: |
Tue, 16 Apr 2019 13:57:36 +0100 |
The M-profile FPCCR.S bit indicates the security status of
the floating point context. In the pseudocode ExecuteFPCheck()
function it is unconditionally set to match the current
security state whenever a floating point instruction is
executed.
Implement this by adding a new TB flag which tracks whether
FPCCR.S is different from the current security state, so
that we only need to emit the code to update it in the
less-common case when it is not already set correctly.
Note that we will add the handling for the other work done
by ExecuteFPCheck() in later commits.
Signed-off-by: Peter Maydell <address@hidden>
---
target/arm/cpu.h | 2 ++
target/arm/translate.h | 1 +
target/arm/helper.c | 5 +++++
target/arm/translate.c | 20 ++++++++++++++++++++
4 files changed, 28 insertions(+)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index a4e4d17e787..95924303dd5 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -3154,6 +3154,8 @@ FIELD(TBFLAG_A32, NS, 6, 1)
FIELD(TBFLAG_A32, VFPEN, 7, 1)
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
+/* For M profile only, set if FPCCR.S does not match current security state */
+FIELD(TBFLAG_A32, FPCCR_S_WRONG, 20, 1)
/* For M profile only, Handler (ie not Thread) mode */
FIELD(TBFLAG_A32, HANDLER, 21, 1)
/* For M profile only, whether we should generate stack-limit checks */
diff --git a/target/arm/translate.h b/target/arm/translate.h
index 912cc2a4a52..26b2c29bb57 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -40,6 +40,7 @@ typedef struct DisasContext {
bool v7m_handler_mode;
bool v8m_secure; /* true if v8M and we're in Secure mode */
bool v8m_stackcheck; /* true if we need to perform v8M stack limit checks
*/
+ bool v8m_fpccr_s_wrong; /* true if v8M FPCCR.S != v8m_secure */
/* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI
* so that top level loop can generate correct syndrome information.
*/
diff --git a/target/arm/helper.c b/target/arm/helper.c
index d8a9620b870..539da192e4e 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -13422,6 +13422,11 @@ void cpu_get_tb_cpu_state(CPUARMState *env,
target_ulong *pc,
flags = FIELD_DP32(flags, TBFLAG_A32, STACKCHECK, 1);
}
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
+ FIELD_EX32(env->v7m.fpccr[M_REG_S], V7M_FPCCR, S) != env->v7m.secure) {
+ flags = FIELD_DP32(flags, TBFLAG_A32, FPCCR_S_WRONG, 1);
+ }
+
*pflags = flags;
*cs_base = 0;
}
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 9172a382c4d..a4fb811d6f2 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -3420,6 +3420,25 @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
}
}
+ if (arm_dc_feature(s, ARM_FEATURE_M)) {
+ /* Handle M-profile lazy FP state mechanics */
+
+ /* Update ownership of FP context: set FPCCR.S to match current state
*/
+ if (s->v8m_fpccr_s_wrong) {
+ TCGv_i32 tmp;
+
+ tmp = load_cpu_field(v7m.fpccr[M_REG_S]);
+ if (s->v8m_secure) {
+ tcg_gen_ori_i32(tmp, tmp, R_V7M_FPCCR_S_MASK);
+ } else {
+ tcg_gen_andi_i32(tmp, tmp, ~R_V7M_FPCCR_S_MASK);
+ }
+ store_cpu_field(tmp, v7m.fpccr[M_REG_S]);
+ /* Don't need to do this for any further FP insns in this TB */
+ s->v8m_fpccr_s_wrong = false;
+ }
+ }
+
if (extract32(insn, 28, 4) == 0xf) {
/*
* Encodings with T=1 (Thumb) or unconditional (ARM):
@@ -13340,6 +13359,7 @@ static void arm_tr_init_disas_context(DisasContextBase
*dcbase, CPUState *cs)
dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
regime_is_secure(env, dc->mmu_idx);
dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_A32, STACKCHECK);
+ dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
dc->cp_regs = cpu->cp_regs;
dc->features = env->features;
--
2.20.1
- [Qemu-devel] [PATCH 14/26] target/arm: Allow for floating point in callee stack integrity check, (continued)
- [Qemu-devel] [PATCH 14/26] target/arm: Allow for floating point in callee stack integrity check, Peter Maydell, 2019/04/16
- [Qemu-devel] [PATCH 13/26] target/arm: Clean excReturn bits when tail chaining, Peter Maydell, 2019/04/16
- [Qemu-devel] [PATCH 16/26] target/arm: Move NS TBFLAG from bit 19 to bit 6, Peter Maydell, 2019/04/16
- [Qemu-devel] [PATCH 17/26] target/arm: Overlap VECSTRIDE and XSCALE_CPAR TB flags, Peter Maydell, 2019/04/16
- [Qemu-devel] [PATCH 15/26] target/arm: Handle floating point registers in exception return, Peter Maydell, 2019/04/16
- [Qemu-devel] [PATCH 18/26] target/arm: Set FPCCR.S when executing M-profile floating point insns,
Peter Maydell <=
- [Qemu-devel] [PATCH 20/26] target/arm: New helper function arm_v7m_mmu_idx_all(), Peter Maydell, 2019/04/16
- [Qemu-devel] [PATCH 19/26] target/arm: Activate M-profile floating point context when FPCCR.ASPEN is set, Peter Maydell, 2019/04/16
- [Qemu-devel] [PATCH 21/26] target/arm: New function armv7m_nvic_set_pending_lazyfp(), Peter Maydell, 2019/04/16
- [Qemu-devel] [PATCH 23/26] target/arm: Implement M-profile lazy FP state preservation, Peter Maydell, 2019/04/16
- [Qemu-devel] [PATCH 24/26] target/arm: Implement VLSTM for v7M CPUs with an FPU, Peter Maydell, 2019/04/16