From 6c8172fd083591c6a1f0da47080829054b8be64d Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Thu, 30 Apr 2020 06:18:29 -0400 Subject: [PATCH] target/arm: Disable clean_data_tbi for system mode We must include the tag in the FAR_ELx register when raising an addressing exception. Which means that we should not clear out the tag during translation. We cannot at present comply with this for user mode, so we retain the clean_data_tbi function for the moment, though it no longer does what it says on the tin for system mode. This function is to be replaced with MTE, so don't worry about the slight misnaming. Buglink: https://bugs.launchpad.net/qemu/+bug/1867072 Backports commit 38d931687fa196a7ef860f8583815abc7fd5521a from qemu --- qemu/target/arm/translate-a64.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/qemu/target/arm/translate-a64.c b/qemu/target/arm/translate-a64.c index d8a72151..ff2a5d4d 100644 --- a/qemu/target/arm/translate-a64.c +++ b/qemu/target/arm/translate-a64.c @@ -365,7 +365,18 @@ static void gen_a64_set_pc(DisasContext *s, TCGv_i64 src) static TCGv_i64 clean_data_tbi(DisasContext *s, TCGv_i64 addr) { TCGv_i64 clean = new_tmp_a64(s); + /* + * In order to get the correct value in the FAR_ELx register, + * we must present the memory subsystem with the "dirty" address + * including the TBI. In system mode we can make this work via + * the TLB, dropping the TBI during translation. But for user-only + * mode we don't have that option, and must remove the top byte now. + */ +#ifdef CONFIG_USER_ONLY gen_top_byte_ignore(s, clean, addr, s->tbid); +#else + tcg_gen_mov_i64(s->uc->tcg_ctx, clean, addr); +#endif return clean; }