summaryrefslogtreecommitdiffstats
path: root/target/arm/mte_helper.c
diff options
context:
space:
mode:
authorPeter Collingbourne2021-02-19 21:18:20 +0100
committerPeter Maydell2021-03-05 16:17:35 +0100
commit2d928adf8a9148510e1b2041145b8a873f4d26df (patch)
tree7d372839f158d3e291011814bdf0259a9313c98e /target/arm/mte_helper.c
parentvirtio-mmio: improve virtio-mmio get_dev_path alog (diff)
downloadqemu-2d928adf8a9148510e1b2041145b8a873f4d26df.tar.gz
qemu-2d928adf8a9148510e1b2041145b8a873f4d26df.tar.xz
qemu-2d928adf8a9148510e1b2041145b8a873f4d26df.zip
target/arm: Use TCF0 and TFSRE0 for unprivileged tag checks
Section D6.7 of the ARM ARM states: For the purpose of determining Tag Check Fault handling, unprivileged load and store instructions are treated as if executed at EL0 when executed at either: - EL1, when the Effective value of PSTATE.UAO is 0. - EL2, when both the Effective value of HCR_EL2.{E2H, TGE} is {1, 1} and the Effective value of PSTATE.UAO is 0. ARM has confirmed a defect in the pseudocode function AArch64.TagCheckFault that makes it inconsistent with the above wording. The remedy is to adjust references to PSTATE.EL in that function to instead refer to AArch64.AccessUsesEL(acctype), so that unprivileged instructions use SCTLR_EL1.TCF0 and TFSRE0_EL1. The exception type for synchronous tag check faults remains unchanged. This patch implements the described change by partially reverting commits 50244cc76abc and cc97b0019bb5. Signed-off-by: Peter Collingbourne <pcc@google.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20210219201820.2672077-1-pcc@google.com Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target/arm/mte_helper.c')
-rw-r--r--target/arm/mte_helper.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
index 1c569336ea..0bbb9ec346 100644
--- a/target/arm/mte_helper.c
+++ b/target/arm/mte_helper.c
@@ -550,10 +550,14 @@ static void mte_check_fail(CPUARMState *env, uint32_t desc,
reg_el = regime_el(env, arm_mmu_idx);
sctlr = env->cp15.sctlr_el[reg_el];
- el = arm_current_el(env);
- if (el == 0) {
+ switch (arm_mmu_idx) {
+ case ARMMMUIdx_E10_0:
+ case ARMMMUIdx_E20_0:
+ el = 0;
tcf = extract64(sctlr, 38, 2);
- } else {
+ break;
+ default:
+ el = reg_el;
tcf = extract64(sctlr, 40, 2);
}
@@ -570,7 +574,8 @@ static void mte_check_fail(CPUARMState *env, uint32_t desc,
env->exception.vaddress = dirty_ptr;
is_write = FIELD_EX32(desc, MTEDESC, WRITE);
- syn = syn_data_abort_no_iss(el != 0, 0, 0, 0, 0, is_write, 0x11);
+ syn = syn_data_abort_no_iss(arm_current_el(env) != 0, 0, 0, 0, 0,
+ is_write, 0x11);
raise_exception(env, EXCP_DATA_ABORT, syn, exception_target_el(env));
/* noreturn, but fall through to the assert anyway */