[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 05/29] target/arm: Fix routing of singlestep exceptio
From: |
Peter Maydell |
Subject: |
[Qemu-devel] [PULL 05/29] target/arm: Fix routing of singlestep exceptions |
Date: |
Fri, 16 Aug 2019 14:16:55 +0100 |
When generating an architectural single-step exception we were
routing it to the "default exception level", which is to say
the same exception level we execute at except that EL0 exceptions
go to EL1. This is incorrect because the debug exception level
can be configured by the guest for situations such as single
stepping of EL0 and EL1 code by EL2.
We have to track the target debug exception level in the TB
flags, because it is dependent on CPU state like HCR_EL2.TGE
and MDCR_EL2.TDE. (That we were previously calling the
arm_debug_target_el() function to determine dc->ss_same_el
is itself a bug, though one that would only have manifested
as incorrect syndrome information.) Since we are out of TB
flag bits unless we want to expand into the cs_base field,
we share some bits with the M-profile only HANDLER and
STACKCHECK bits, since only A-profile has this singlestep.
Fixes: https://bugs.launchpad.net/qemu/+bug/1838913
Signed-off-by: Peter Maydell <address@hidden>
Reviewed-by: Alex Bennée <address@hidden>
Tested-by: Alex Bennée <address@hidden>
Message-id: address@hidden
---
target/arm/cpu.h | 5 +++++
target/arm/translate.h | 15 +++++++++++----
target/arm/helper.c | 6 ++++++
target/arm/translate-a64.c | 2 +-
target/arm/translate.c | 4 +++-
5 files changed, 26 insertions(+), 6 deletions(-)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 67f2af0e169..d12c7460859 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -3148,6 +3148,11 @@ FIELD(TBFLAG_ANY, PSTATE_SS, 26, 1)
/* Target EL if we take a floating-point-disabled exception */
FIELD(TBFLAG_ANY, FPEXC_EL, 24, 2)
FIELD(TBFLAG_ANY, BE_DATA, 23, 1)
+/*
+ * For A-profile only, target EL for debug exceptions.
+ * Note that this overlaps with the M-profile-only HANDLER and STACKCHECK bits.
+ */
+FIELD(TBFLAG_ANY, DEBUG_TARGET_EL, 21, 2)
/* Bit usage when in AArch32 state: */
FIELD(TBFLAG_A32, THUMB, 0, 1)
diff --git a/target/arm/translate.h b/target/arm/translate.h
index 45053190baa..b65954c669b 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -50,6 +50,8 @@ typedef struct DisasContext {
uint32_t svc_imm;
int aarch64;
int current_el;
+ /* Debug target exception level for single-step exceptions */
+ int debug_target_el;
GHashTable *cp_regs;
uint64_t features; /* CPU features bits */
/* Because unallocated encodings generate different exception syndrome
@@ -70,8 +72,6 @@ typedef struct DisasContext {
* ie A64 LDX*, LDAX*, A32/T32 LDREX*, LDAEX*.
*/
bool is_ldex;
- /* True if a single-step exception will be taken to the current EL */
- bool ss_same_el;
/* True if v8.3-PAuth is active. */
bool pauth_active;
/* True with v8.5-BTI and SCTLR_ELx.BT* set. */
@@ -251,8 +251,15 @@ static inline void gen_exception(int excp, uint32_t
syndrome,
/* Generate an architectural singlestep exception */
static inline void gen_swstep_exception(DisasContext *s, int isv, int ex)
{
- gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, isv, ex),
- default_exception_el(s));
+ bool same_el = (s->debug_target_el == s->current_el);
+
+ /*
+ * If singlestep is targeting a lower EL than the current one,
+ * then s->ss_active must be false and we can never get here.
+ */
+ assert(s->debug_target_el >= s->current_el);
+
+ gen_exception(EXCP_UDEF, syn_swstep(same_el, isv, ex), s->debug_target_el);
}
/*
diff --git a/target/arm/helper.c b/target/arm/helper.c
index b74c23a9bc0..24806c16ca2 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11170,6 +11170,12 @@ void cpu_get_tb_cpu_state(CPUARMState *env,
target_ulong *pc,
}
}
+ if (!arm_feature(env, ARM_FEATURE_M)) {
+ int target_el = arm_debug_target_el(env);
+
+ flags = FIELD_DP32(flags, TBFLAG_ANY, DEBUG_TARGET_EL, target_el);
+ }
+
*pflags = flags;
*cs_base = 0;
}
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index f6729b96fd0..90850eadc1b 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -14180,7 +14180,7 @@ static void
aarch64_tr_init_disas_context(DisasContextBase *dcbase,
dc->ss_active = FIELD_EX32(tb_flags, TBFLAG_ANY, SS_ACTIVE);
dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE_SS);
dc->is_ldex = false;
- dc->ss_same_el = (arm_debug_target_el(env) == dc->current_el);
+ dc->debug_target_el = FIELD_EX32(tb_flags, TBFLAG_ANY, DEBUG_TARGET_EL);
/* Bound the number of insns to execute to those left on the page. */
bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 19b9d8f2725..b32508cd2f9 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -11882,7 +11882,9 @@ static void arm_tr_init_disas_context(DisasContextBase
*dcbase, CPUState *cs)
dc->ss_active = FIELD_EX32(tb_flags, TBFLAG_ANY, SS_ACTIVE);
dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE_SS);
dc->is_ldex = false;
- dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
+ if (!arm_feature(env, ARM_FEATURE_M)) {
+ dc->debug_target_el = FIELD_EX32(tb_flags, TBFLAG_ANY,
DEBUG_TARGET_EL);
+ }
dc->page_start = dc->base.pc_first & TARGET_PAGE_MASK;
--
2.20.1
- [Qemu-devel] [PULL 06/29] target/arm: Pass in pc to thumb_insn_is_16bit, (continued)
- [Qemu-devel] [PULL 06/29] target/arm: Pass in pc to thumb_insn_is_16bit, Peter Maydell, 2019/08/16
- [Qemu-devel] [PULL 07/29] target/arm: Introduce pc_curr, Peter Maydell, 2019/08/16
- [Qemu-devel] [PULL 02/29] hw/misc/zynq_slcr: use standard register definition, Peter Maydell, 2019/08/16
- [Qemu-devel] [PULL 09/29] target/arm: Introduce add_reg_for_lit, Peter Maydell, 2019/08/16
- [Qemu-devel] [PULL 08/29] target/arm: Introduce read_pc, Peter Maydell, 2019/08/16
- [Qemu-devel] [PULL 16/29] target/arm: Remove helper_double_saturate, Peter Maydell, 2019/08/16
- [Qemu-devel] [PULL 14/29] target/arm: Remove offset argument to gen_exception_bkpt_insn, Peter Maydell, 2019/08/16
- [Qemu-devel] [PULL 13/29] target/arm: Replace offset with pc in gen_exception_internal_insn, Peter Maydell, 2019/08/16
- [Qemu-devel] [PULL 19/29] target/arm/helper: zcr: Add build bug next to value range assumption, Peter Maydell, 2019/08/16
- [Qemu-devel] [PULL 17/29] target/arm/cpu64: Ensure kvm really supports aarch64=off, Peter Maydell, 2019/08/16
- [Qemu-devel] [PULL 05/29] target/arm: Fix routing of singlestep exceptions,
Peter Maydell <=
- [Qemu-devel] [PULL 10/29] target/arm: Remove redundant s->pc & ~1, Peter Maydell, 2019/08/16
- [Qemu-devel] [PULL 11/29] target/arm: Replace s->pc with s->base.pc_next, Peter Maydell, 2019/08/16
- [Qemu-devel] [PULL 15/29] target/arm: Use unallocated_encoding for aarch32, Peter Maydell, 2019/08/16
- [Qemu-devel] [PULL 12/29] target/arm: Replace offset with pc in gen_exception_insn, Peter Maydell, 2019/08/16
- [Qemu-devel] [PULL 18/29] target/arm/cpu: Ensure we can use the pmu with kvm, Peter Maydell, 2019/08/16
- [Qemu-devel] [PULL 20/29] target/arm/cpu: Use div-round-up to determine predicate register array size, Peter Maydell, 2019/08/16
- [Qemu-devel] [PULL 21/29] target/arm/kvm64: Fix error returns, Peter Maydell, 2019/08/16
- [Qemu-devel] [PULL 24/29] target/arm: Use tcg_gen_deposit_i32 for PKHBT, PKHTB, Peter Maydell, 2019/08/16
- [Qemu-devel] [PULL 27/29] target/arm: Use tcg_gen_rotri_i32 for gen_swap_half, Peter Maydell, 2019/08/16
- [Qemu-devel] [PULL 23/29] target/arm: Use tcg_gen_extract_i32 for shifter_out_im, Peter Maydell, 2019/08/16