qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

target/arm: Implement the IRG instruction

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20200626033144.790098-10-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

authored by

Richard Henderson and committed by
Peter Maydell
da54941f 81ae05fa

+98
+1
target/arm/Makefile.objs
··· 86 86 obj-$(TARGET_AARCH64) += translate-a64.o helper-a64.o 87 87 obj-$(TARGET_AARCH64) += translate-sve.o sve_helper.o 88 88 obj-$(TARGET_AARCH64) += pauth_helper.o 89 + obj-$(TARGET_AARCH64) += mte_helper.o
+2
target/arm/helper-a64.h
··· 103 103 DEF_HELPER_FLAGS_3(autdb, TCG_CALL_NO_WG, i64, env, i64, i64) 104 104 DEF_HELPER_FLAGS_2(xpaci, TCG_CALL_NO_RWG_SE, i64, env, i64) 105 105 DEF_HELPER_FLAGS_2(xpacd, TCG_CALL_NO_RWG_SE, i64, env, i64) 106 + 107 + DEF_HELPER_FLAGS_3(irg, TCG_CALL_NO_RWG, i64, env, i64, i64)
+5
target/arm/internals.h
··· 1261 1261 */ 1262 1262 #define GMID_EL1_BS 6 1263 1263 1264 + static inline uint64_t address_with_allocation_tag(uint64_t ptr, int rtag) 1265 + { 1266 + return deposit64(ptr, 56, 4, rtag); 1267 + } 1268 + 1264 1269 #endif
+72
target/arm/mte_helper.c
··· 1 + /* 2 + * ARM v8.5-MemTag Operations 3 + * 4 + * Copyright (c) 2020 Linaro, Ltd. 5 + * 6 + * This library is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU Lesser General Public 8 + * License as published by the Free Software Foundation; either 9 + * version 2.1 of the License, or (at your option) any later version. 10 + * 11 + * This library is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 + * Lesser General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU Lesser General Public 17 + * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18 + */ 19 + 20 + #include "qemu/osdep.h" 21 + #include "cpu.h" 22 + #include "internals.h" 23 + #include "exec/exec-all.h" 24 + #include "exec/cpu_ldst.h" 25 + #include "exec/helper-proto.h" 26 + 27 + 28 + static int choose_nonexcluded_tag(int tag, int offset, uint16_t exclude) 29 + { 30 + if (exclude == 0xffff) { 31 + return 0; 32 + } 33 + if (offset == 0) { 34 + while (exclude & (1 << tag)) { 35 + tag = (tag + 1) & 15; 36 + } 37 + } else { 38 + do { 39 + do { 40 + tag = (tag + 1) & 15; 41 + } while (exclude & (1 << tag)); 42 + } while (--offset > 0); 43 + } 44 + return tag; 45 + } 46 + 47 + uint64_t HELPER(irg)(CPUARMState *env, uint64_t rn, uint64_t rm) 48 + { 49 + int rtag; 50 + 51 + /* 52 + * Our IMPDEF choice for GCR_EL1.RRND==1 is to behave as if 53 + * GCR_EL1.RRND==0, always producing deterministic results. 54 + */ 55 + uint16_t exclude = extract32(rm | env->cp15.gcr_el1, 0, 16); 56 + int start = extract32(env->cp15.rgsr_el1, 0, 4); 57 + int seed = extract32(env->cp15.rgsr_el1, 8, 16); 58 + int offset, i; 59 + 60 + /* RandomTag */ 61 + for (i = offset = 0; i < 4; ++i) { 62 + /* NextRandomTagBit */ 63 + int top = (extract32(seed, 5, 1) ^ extract32(seed, 3, 1) ^ 64 + extract32(seed, 2, 1) ^ extract32(seed, 0, 1)); 65 + seed = (top << 15) | (seed >> 1); 66 + offset |= top << i; 67 + } 68 + rtag = choose_nonexcluded_tag(start, offset, exclude); 69 + env->cp15.rgsr_el1 = rtag | (seed << 8); 70 + 71 + return address_with_allocation_tag(rn, rtag); 72 + }
+18
target/arm/translate-a64.c
··· 226 226 return clean; 227 227 } 228 228 229 + /* Insert a zero tag into src, with the result at dst. */ 230 + static void gen_address_with_allocation_tag0(TCGv_i64 dst, TCGv_i64 src) 231 + { 232 + tcg_gen_andi_i64(dst, src, ~MAKE_64BIT_MASK(56, 4)); 233 + } 234 + 229 235 typedef struct DisasCompare64 { 230 236 TCGCond cond; 231 237 TCGv_i64 value; ··· 5283 5289 break; 5284 5290 case 3: /* SDIV */ 5285 5291 handle_div(s, true, sf, rm, rn, rd); 5292 + break; 5293 + case 4: /* IRG */ 5294 + if (sf == 0 || !dc_isar_feature(aa64_mte_insn_reg, s)) { 5295 + goto do_unallocated; 5296 + } 5297 + if (s->ata) { 5298 + gen_helper_irg(cpu_reg_sp(s, rd), cpu_env, 5299 + cpu_reg_sp(s, rn), cpu_reg(s, rm)); 5300 + } else { 5301 + gen_address_with_allocation_tag0(cpu_reg_sp(s, rd), 5302 + cpu_reg_sp(s, rn)); 5303 + } 5286 5304 break; 5287 5305 case 8: /* LSLV */ 5288 5306 handle_shift_reg(s, A64_SHIFT_TYPE_LSL, sf, rm, rn, rd);