diff options
Diffstat (limited to 'target/arm/cpu.c')
-rw-r--r-- | target/arm/cpu.c | 52 |
1 files changed, 48 insertions, 4 deletions
diff --git a/target/arm/cpu.c b/target/arm/cpu.c index afe81e9b6c..5050e1843a 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -1252,6 +1252,25 @@ void arm_cpu_post_init(Object *obj) if (kvm_enabled()) { kvm_arm_add_vcpu_properties(obj); } + +#ifndef CONFIG_USER_ONLY + if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64) && + cpu_isar_feature(aa64_mte, cpu)) { + object_property_add_link(obj, "tag-memory", + TYPE_MEMORY_REGION, + (Object **)&cpu->tag_memory, + qdev_prop_allow_set_link_before_realize, + OBJ_PROP_LINK_STRONG); + + if (arm_feature(&cpu->env, ARM_FEATURE_EL3)) { + object_property_add_link(obj, "secure-tag-memory", + TYPE_MEMORY_REGION, + (Object **)&cpu->secure_tag_memory, + qdev_prop_allow_set_link_before_realize, + OBJ_PROP_LINK_STRONG); + } + } +#endif } static void arm_cpu_finalizefn(Object *obj) @@ -1741,18 +1760,43 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) #ifndef CONFIG_USER_ONLY MachineState *ms = MACHINE(qdev_get_machine()); unsigned int smp_cpus = ms->smp.cpus; + bool has_secure = cpu->has_el3 || arm_feature(env, ARM_FEATURE_M_SECURITY); - if (cpu->has_el3 || arm_feature(env, ARM_FEATURE_M_SECURITY)) { - cs->num_ases = 2; + /* + * 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); /* No core_count specified, default to smp_cpus. */ |