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:
Richard Henderson 2020-06-25 20:31:41 -07:00 committed by Peter Maydell
parent 337a03f07f
commit 8bce44a2f6
3 changed files with 107 additions and 6 deletions

View file

@ -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);