From 9b6c64f8f81b5ec861b6838523730897b144e0b2 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Thu, 25 Feb 2021 22:51:21 -0500 Subject: [PATCH] target/arm: Create tagged ram when MTE is enabled Backports commit 8bce44a2f6beb388a3f157652b46e99929839a96 from qemu --- qemu/target/arm/cpu.c | 32 ++++++++++++++++++++++++++++---- qemu/target/arm/cpu.h | 6 ++++++ 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/qemu/target/arm/cpu.c b/qemu/target/arm/cpu.c index d7bc4385..fd4e8c17 100644 --- a/qemu/target/arm/cpu.c +++ b/qemu/target/arm/cpu.c @@ -1007,16 +1007,40 @@ static int arm_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **err init_cpreg_list(cpu); #ifndef CONFIG_USER_ONLY - if (cpu->has_el3 || arm_feature(env, ARM_FEATURE_M_SECURITY)) { - cs->num_ases = 2; + bool has_secure = cpu->has_el3 || arm_feature(env, ARM_FEATURE_M_SECURITY); + /* + * We must set cs->num_ases to the final value before + * the first call to cpu_address_space_init. + */ + if (cpu->tag_memory != NULL) { + cs->num_ases = 3 + has_secure; + } else { + cs->num_ases = 1 + has_secure; + } + + if (has_secure) { if (!cpu->secure_memory) { cpu->secure_memory = cs->memory; } cpu_address_space_init(cs, ARMASIdx_S, "cpu-secure-memory", cpu->secure_memory); - } else { - cs->num_ases = 1; + } + if (cpu->tag_memory != NULL) { + cpu_address_space_init(cs, ARMASIdx_TagNS, "cpu-tag-memory", + cpu->tag_memory); + if (has_secure) { + cpu_address_space_init(cs, ARMASIdx_TagS, "cpu-tag-memory", + cpu->secure_tag_memory); + } + } else if (cpu_isar_feature(aa64_mte, cpu)) { + /* + * Since there is no tag memory, we can't meaningfully support MTE + * to its fullest. To avoid problems later, when we would come to + * use the tag memory, downgrade support to insns only. + */ + cpu->isar.id_aa64pfr1 = + FIELD_DP64(cpu->isar.id_aa64pfr1, ID_AA64PFR1, MTE, 1); } cpu_address_space_init(cs, ARMASIdx_NS, "cpu-memory", cs->memory); diff --git a/qemu/target/arm/cpu.h b/qemu/target/arm/cpu.h index 21c24fa4..d6c1d19c 100644 --- a/qemu/target/arm/cpu.h +++ b/qemu/target/arm/cpu.h @@ -771,6 +771,10 @@ struct ARMCPU { /* MemoryRegion to use for secure physical accesses */ MemoryRegion *secure_memory; + /* MemoryRegion to use for allocation tag accesses */ + MemoryRegion *tag_memory; + MemoryRegion *secure_tag_memory; + /* 'compatible' string for this CPU for Linux device trees */ const char *dtb_compatible; @@ -2876,6 +2880,8 @@ int cpu_mmu_index(CPUARMState *env, bool ifetch); typedef enum ARMASIdx { ARMASIdx_NS = 0, ARMASIdx_S = 1, + ARMASIdx_TagNS = 2, + ARMASIdx_TagS = 3, } ARMASIdx; /* Return the Exception Level targeted by debug exceptions. */