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

target/arm: Add MTE system registers

This is TFSRE0_EL1, TFSR_EL1, TFSR_EL2, TFSR_EL3,
RGSR_EL1, GCR_EL1, GMID_EL1, and PSTATE.TCO.

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

authored by

Richard Henderson and committed by
Peter Maydell
4b779ceb 32983328

+128
+4
target/arm/cpu.h
··· 502 502 uint64_t pmccfiltr_el0; /* Performance Monitor Filter Register */ 503 503 uint64_t vpidr_el2; /* Virtualization Processor ID Register */ 504 504 uint64_t vmpidr_el2; /* Virtualization Multiprocessor ID Register */ 505 + uint64_t tfsr_el[4]; /* tfsre0_el1 is index 0. */ 506 + uint64_t gcr_el1; 507 + uint64_t rgsr_el1; 505 508 } cp15; 506 509 507 510 struct { ··· 1282 1285 #define PSTATE_SS (1U << 21) 1283 1286 #define PSTATE_PAN (1U << 22) 1284 1287 #define PSTATE_UAO (1U << 23) 1288 + #define PSTATE_TCO (1U << 25) 1285 1289 #define PSTATE_V (1U << 28) 1286 1290 #define PSTATE_C (1U << 29) 1287 1291 #define PSTATE_Z (1U << 30)
+94
target/arm/helper.c
··· 5881 5881 { K(3, 0, 1, 2, 0), K(3, 4, 1, 2, 0), K(3, 5, 1, 2, 0), 5882 5882 "ZCR_EL1", "ZCR_EL2", "ZCR_EL12", isar_feature_aa64_sve }, 5883 5883 5884 + { K(3, 0, 5, 6, 0), K(3, 4, 5, 6, 0), K(3, 5, 5, 6, 0), 5885 + "TFSR_EL1", "TFSR_EL2", "TFSR_EL12", isar_feature_aa64_mte }, 5886 + 5884 5887 /* TODO: ARMv8.2-SPE -- PMSCR_EL2 */ 5885 5888 /* TODO: ARMv8.4-Trace -- TRFCR_EL2 */ 5886 5889 }; ··· 6855 6858 }; 6856 6859 #endif /*CONFIG_USER_ONLY*/ 6857 6860 6861 + static CPAccessResult access_aa64_tid5(CPUARMState *env, const ARMCPRegInfo *ri, 6862 + bool isread) 6863 + { 6864 + if ((arm_current_el(env) < 2) && (arm_hcr_el2_eff(env) & HCR_TID5)) { 6865 + return CP_ACCESS_TRAP_EL2; 6866 + } 6867 + 6868 + return CP_ACCESS_OK; 6869 + } 6870 + 6871 + static CPAccessResult access_mte(CPUARMState *env, const ARMCPRegInfo *ri, 6872 + bool isread) 6873 + { 6874 + int el = arm_current_el(env); 6875 + 6876 + if (el < 2 && 6877 + arm_feature(env, ARM_FEATURE_EL2) && 6878 + !(arm_hcr_el2_eff(env) & HCR_ATA)) { 6879 + return CP_ACCESS_TRAP_EL2; 6880 + } 6881 + if (el < 3 && 6882 + arm_feature(env, ARM_FEATURE_EL3) && 6883 + !(env->cp15.scr_el3 & SCR_ATA)) { 6884 + return CP_ACCESS_TRAP_EL3; 6885 + } 6886 + return CP_ACCESS_OK; 6887 + } 6888 + 6889 + static uint64_t tco_read(CPUARMState *env, const ARMCPRegInfo *ri) 6890 + { 6891 + return env->pstate & PSTATE_TCO; 6892 + } 6893 + 6894 + static void tco_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t val) 6895 + { 6896 + env->pstate = (env->pstate & ~PSTATE_TCO) | (val & PSTATE_TCO); 6897 + } 6898 + 6899 + static const ARMCPRegInfo mte_reginfo[] = { 6900 + { .name = "TFSRE0_EL1", .state = ARM_CP_STATE_AA64, 6901 + .opc0 = 3, .opc1 = 0, .crn = 5, .crm = 6, .opc2 = 1, 6902 + .access = PL1_RW, .accessfn = access_mte, 6903 + .fieldoffset = offsetof(CPUARMState, cp15.tfsr_el[0]) }, 6904 + { .name = "TFSR_EL1", .state = ARM_CP_STATE_AA64, 6905 + .opc0 = 3, .opc1 = 0, .crn = 5, .crm = 6, .opc2 = 0, 6906 + .access = PL1_RW, .accessfn = access_mte, 6907 + .fieldoffset = offsetof(CPUARMState, cp15.tfsr_el[1]) }, 6908 + { .name = "TFSR_EL2", .state = ARM_CP_STATE_AA64, 6909 + .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 6, .opc2 = 0, 6910 + .access = PL2_RW, .accessfn = access_mte, 6911 + .fieldoffset = offsetof(CPUARMState, cp15.tfsr_el[2]) }, 6912 + { .name = "TFSR_EL3", .state = ARM_CP_STATE_AA64, 6913 + .opc0 = 3, .opc1 = 6, .crn = 5, .crm = 6, .opc2 = 0, 6914 + .access = PL3_RW, 6915 + .fieldoffset = offsetof(CPUARMState, cp15.tfsr_el[3]) }, 6916 + { .name = "RGSR_EL1", .state = ARM_CP_STATE_AA64, 6917 + .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 5, 6918 + .access = PL1_RW, .accessfn = access_mte, 6919 + .fieldoffset = offsetof(CPUARMState, cp15.rgsr_el1) }, 6920 + { .name = "GCR_EL1", .state = ARM_CP_STATE_AA64, 6921 + .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 6, 6922 + .access = PL1_RW, .accessfn = access_mte, 6923 + .fieldoffset = offsetof(CPUARMState, cp15.gcr_el1) }, 6924 + { .name = "GMID_EL1", .state = ARM_CP_STATE_AA64, 6925 + .opc0 = 3, .opc1 = 1, .crn = 0, .crm = 0, .opc2 = 4, 6926 + .access = PL1_R, .accessfn = access_aa64_tid5, 6927 + .type = ARM_CP_CONST, .resetvalue = GMID_EL1_BS }, 6928 + { .name = "TCO", .state = ARM_CP_STATE_AA64, 6929 + .opc0 = 3, .opc1 = 3, .crn = 4, .crm = 2, .opc2 = 7, 6930 + .type = ARM_CP_NO_RAW, 6931 + .access = PL0_RW, .readfn = tco_read, .writefn = tco_write }, 6932 + REGINFO_SENTINEL 6933 + }; 6934 + 6935 + static const ARMCPRegInfo mte_tco_ro_reginfo[] = { 6936 + { .name = "TCO", .state = ARM_CP_STATE_AA64, 6937 + .opc0 = 3, .opc1 = 3, .crn = 4, .crm = 2, .opc2 = 7, 6938 + .type = ARM_CP_CONST, .access = PL0_RW, }, 6939 + REGINFO_SENTINEL 6940 + }; 6858 6941 #endif 6859 6942 6860 6943 static CPAccessResult access_predinv(CPUARMState *env, const ARMCPRegInfo *ri, ··· 7980 8063 } 7981 8064 } 7982 8065 #endif /*CONFIG_USER_ONLY*/ 8066 + 8067 + /* 8068 + * If full MTE is enabled, add all of the system registers. 8069 + * If only "instructions available at EL0" are enabled, 8070 + * then define only a RAZ/WI version of PSTATE.TCO. 8071 + */ 8072 + if (cpu_isar_feature(aa64_mte, cpu)) { 8073 + define_arm_cp_regs(cpu, mte_reginfo); 8074 + } else if (cpu_isar_feature(aa64_mte_insn_reg, cpu)) { 8075 + define_arm_cp_regs(cpu, mte_tco_ro_reginfo); 8076 + } 7983 8077 #endif 7984 8078 7985 8079 if (cpu_isar_feature(any_predinv, cpu)) {
+9
target/arm/internals.h
··· 1159 1159 if (isar_feature_aa64_uao(id)) { 1160 1160 valid |= PSTATE_UAO; 1161 1161 } 1162 + if (isar_feature_aa64_mte(id)) { 1163 + valid |= PSTATE_TCO; 1164 + } 1162 1165 1163 1166 return valid; 1164 1167 } ··· 1233 1236 void arm_log_exception(int idx); 1234 1237 1235 1238 #endif /* !CONFIG_USER_ONLY */ 1239 + 1240 + /* 1241 + * The log2 of the words in the tag block, for GMID_EL1.BS. 1242 + * The is the maximum, 256 bytes, which manipulates 64-bits of tags. 1243 + */ 1244 + #define GMID_EL1_BS 6 1236 1245 1237 1246 #endif
+21
target/arm/translate-a64.c
··· 1619 1619 s->base.is_jmp = DISAS_UPDATE_EXIT; 1620 1620 break; 1621 1621 1622 + case 0x1c: /* TCO */ 1623 + if (dc_isar_feature(aa64_mte, s)) { 1624 + /* Full MTE is enabled -- set the TCO bit as directed. */ 1625 + if (crm & 1) { 1626 + set_pstate_bits(PSTATE_TCO); 1627 + } else { 1628 + clear_pstate_bits(PSTATE_TCO); 1629 + } 1630 + t1 = tcg_const_i32(s->current_el); 1631 + gen_helper_rebuild_hflags_a64(cpu_env, t1); 1632 + tcg_temp_free_i32(t1); 1633 + /* Many factors, including TCO, go into MTE_ACTIVE. */ 1634 + s->base.is_jmp = DISAS_UPDATE_NOCHAIN; 1635 + } else if (dc_isar_feature(aa64_mte_insn_reg, s)) { 1636 + /* Only "instructions accessible at EL0" -- PSTATE.TCO is WI. */ 1637 + s->base.is_jmp = DISAS_NEXT; 1638 + } else { 1639 + goto do_unallocated; 1640 + } 1641 + break; 1642 + 1622 1643 default: 1623 1644 do_unallocated: 1624 1645 unallocated_encoding(s);