mirror of https://gitee.com/openkylin/qemu.git
target/arm: Create tagged ram when MTE is enabled
Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 20200626033144.790098-44-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
337a03f07f
commit
8bce44a2f6
|
@ -1390,8 +1390,19 @@ static void create_platform_bus(VirtMachineState *vms)
|
|||
sysbus_mmio_get_region(s, 0));
|
||||
}
|
||||
|
||||
static void create_tag_ram(MemoryRegion *tag_sysmem,
|
||||
hwaddr base, hwaddr size,
|
||||
const char *name)
|
||||
{
|
||||
MemoryRegion *tagram = g_new(MemoryRegion, 1);
|
||||
|
||||
memory_region_init_ram(tagram, NULL, name, size / 32, &error_fatal);
|
||||
memory_region_add_subregion(tag_sysmem, base / 32, tagram);
|
||||
}
|
||||
|
||||
static void create_secure_ram(VirtMachineState *vms,
|
||||
MemoryRegion *secure_sysmem)
|
||||
MemoryRegion *secure_sysmem,
|
||||
MemoryRegion *secure_tag_sysmem)
|
||||
{
|
||||
MemoryRegion *secram = g_new(MemoryRegion, 1);
|
||||
char *nodename;
|
||||
|
@ -1409,6 +1420,10 @@ static void create_secure_ram(VirtMachineState *vms,
|
|||
qemu_fdt_setprop_string(vms->fdt, nodename, "status", "disabled");
|
||||
qemu_fdt_setprop_string(vms->fdt, nodename, "secure-status", "okay");
|
||||
|
||||
if (secure_tag_sysmem) {
|
||||
create_tag_ram(secure_tag_sysmem, base, size, "mach-virt.secure-tag");
|
||||
}
|
||||
|
||||
g_free(nodename);
|
||||
}
|
||||
|
||||
|
@ -1665,6 +1680,8 @@ static void machvirt_init(MachineState *machine)
|
|||
const CPUArchIdList *possible_cpus;
|
||||
MemoryRegion *sysmem = get_system_memory();
|
||||
MemoryRegion *secure_sysmem = NULL;
|
||||
MemoryRegion *tag_sysmem = NULL;
|
||||
MemoryRegion *secure_tag_sysmem = NULL;
|
||||
int n, virt_max_cpus;
|
||||
bool firmware_loaded;
|
||||
bool aarch64 = true;
|
||||
|
@ -1819,6 +1836,35 @@ static void machvirt_init(MachineState *machine)
|
|||
"secure-memory", &error_abort);
|
||||
}
|
||||
|
||||
/*
|
||||
* The cpu adds the property if and only if MemTag is supported.
|
||||
* If it is, we must allocate the ram to back that up.
|
||||
*/
|
||||
if (object_property_find(cpuobj, "tag-memory", NULL)) {
|
||||
if (!tag_sysmem) {
|
||||
tag_sysmem = g_new(MemoryRegion, 1);
|
||||
memory_region_init(tag_sysmem, OBJECT(machine),
|
||||
"tag-memory", UINT64_MAX / 32);
|
||||
|
||||
if (vms->secure) {
|
||||
secure_tag_sysmem = g_new(MemoryRegion, 1);
|
||||
memory_region_init(secure_tag_sysmem, OBJECT(machine),
|
||||
"secure-tag-memory", UINT64_MAX / 32);
|
||||
|
||||
/* As with ram, secure-tag takes precedence over tag. */
|
||||
memory_region_add_subregion_overlap(secure_tag_sysmem, 0,
|
||||
tag_sysmem, -1);
|
||||
}
|
||||
}
|
||||
|
||||
object_property_set_link(cpuobj, OBJECT(tag_sysmem),
|
||||
"tag-memory", &error_abort);
|
||||
if (vms->secure) {
|
||||
object_property_set_link(cpuobj, OBJECT(secure_tag_sysmem),
|
||||
"secure-tag-memory", &error_abort);
|
||||
}
|
||||
}
|
||||
|
||||
qdev_realize(DEVICE(cpuobj), NULL, &error_fatal);
|
||||
object_unref(cpuobj);
|
||||
}
|
||||
|
@ -1857,10 +1903,15 @@ static void machvirt_init(MachineState *machine)
|
|||
create_uart(vms, VIRT_UART, sysmem, serial_hd(0));
|
||||
|
||||
if (vms->secure) {
|
||||
create_secure_ram(vms, secure_sysmem);
|
||||
create_secure_ram(vms, secure_sysmem, secure_tag_sysmem);
|
||||
create_uart(vms, VIRT_SECURE_UART, secure_sysmem, serial_hd(1));
|
||||
}
|
||||
|
||||
if (tag_sysmem) {
|
||||
create_tag_ram(tag_sysmem, vms->memmap[VIRT_MEM].base,
|
||||
machine->ram_size, "mach-virt.tag");
|
||||
}
|
||||
|
||||
vms->highmem_ecam &= vms->highmem && (!firmware_loaded || aarch64);
|
||||
|
||||
create_rtc(vms);
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -792,6 +792,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;
|
||||
|
||||
/* For v8M, pointer to the IDAU interface provided by board/SoC */
|
||||
Object *idau;
|
||||
|
||||
|
@ -2985,6 +2989,8 @@ typedef enum ARMMMUIdxBit {
|
|||
typedef enum ARMASIdx {
|
||||
ARMASIdx_NS = 0,
|
||||
ARMASIdx_S = 1,
|
||||
ARMASIdx_TagNS = 2,
|
||||
ARMASIdx_TagS = 3,
|
||||
} ARMASIdx;
|
||||
|
||||
/* Return the Exception Level targeted by debug exceptions. */
|
||||
|
|
Loading…
Reference in New Issue