arm/kvm: add support for MTE

Extend the 'mte' property for the virt machine to cover KVM as
well. For KVM, we don't allocate tag memory, but instead enable the
capability.

If MTE has been enabled, we need to disable migration, as we do not
yet have a way to migrate the tags as well. Therefore, MTE will stay
off with KVM unless requested explicitly.

Signed-off-by: Cornelia Huck <cohuck@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20230428095533.21747-2-cohuck@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Cornelia Huck 2023-04-28 11:55:33 +02:00 committed by Peter Maydell
parent 96e6d25fdd
commit b320e21c48
6 changed files with 109 additions and 36 deletions

View file

@ -2146,7 +2146,7 @@ static void machvirt_init(MachineState *machine)
exit(1);
}
if (vms->mte && (kvm_enabled() || hvf_enabled())) {
if (vms->mte && hvf_enabled()) {
error_report("mach-virt: %s does not support providing "
"MTE to the guest CPU",
current_accel_name());
@ -2216,39 +2216,48 @@ static void machvirt_init(MachineState *machine)
}
if (vms->mte) {
/* Create the memory region only once, but link to all cpus. */
if (!tag_sysmem) {
/*
* The property exists only if MemTag is supported.
* If it is, we must allocate the ram to back that up.
*/
if (!object_property_find(cpuobj, "tag-memory")) {
error_report("MTE requested, but not supported "
"by the guest CPU");
if (tcg_enabled()) {
/* Create the memory region only once, but link to all cpus. */
if (!tag_sysmem) {
/*
* The property exists only if MemTag is supported.
* If it is, we must allocate the ram to back that up.
*/
if (!object_property_find(cpuobj, "tag-memory")) {
error_report("MTE requested, but not supported "
"by the guest CPU");
exit(1);
}
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, "tag-memory",
OBJECT(tag_sysmem), &error_abort);
if (vms->secure) {
object_property_set_link(cpuobj, "secure-tag-memory",
OBJECT(secure_tag_sysmem),
&error_abort);
}
} else if (kvm_enabled()) {
if (!kvm_arm_mte_supported()) {
error_report("MTE requested, but not supported by KVM");
exit(1);
}
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, "tag-memory", OBJECT(tag_sysmem),
&error_abort);
if (vms->secure) {
object_property_set_link(cpuobj, "secure-tag-memory",
OBJECT(secure_tag_sysmem),
&error_abort);
kvm_arm_enable_mte(cpuobj, &error_abort);
}
}