qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v7 1/1] arm/kvm: add support for MTE


From: Juan Quintela
Subject: Re: [PATCH v7 1/1] arm/kvm: add support for MTE
Date: Fri, 28 Apr 2023 19:50:04 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/28.2 (gnu/linux)

Cornelia Huck <cohuck@redhat.com> wrote:
> 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,

And I was wondering why I was cc'd in a patch that talks about arm, cpus
and architectures O:-)

> 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>
> ---
>  hw/arm/virt.c        | 69 +++++++++++++++++++++++++-------------------
>  target/arm/cpu.c     |  9 +++---
>  target/arm/cpu.h     |  4 +++
>  target/arm/kvm.c     | 35 ++++++++++++++++++++++
>  target/arm/kvm64.c   |  5 ++++
>  target/arm/kvm_arm.h | 19 ++++++++++++
>  6 files changed, 107 insertions(+), 34 deletions(-)
>
> diff --git a/hw/arm/virt.c b/hw/arm/virt.c
> index a89d699f0b76..544a6c5bec8f 100644
> --- a/hw/arm/virt.c
> +++ b/hw/arm/virt.c
> @@ -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");
> -                    exit(1);
> +            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);
> +                    }
>                  }

Pardon my ignorance here, but to try to help with migration.  How is
this mte tag stored?
- 1 array of 8bits per page of memory
- 1 array of 64bits per page of memory
- whatever

Lets asume that it is 1 byte per page. For the explanation it don't
matter, only matters that it is an array of things that are one for each
page.

What I arrived for migration the 1st time that I looked at this problem
is that you can "abuse" multifd and call it a day.

In multifd propper you just send in each page:

- 1 array of page addresses
- 1 array of pages that correspond to the previous addresses

So my suggestion is just to send another array:

- 1 array of page addresses
- 1 array of page tags that correspond to the previous one
- 1 array of pages that correspond to the previous addresses

You put compatiblity marks here and there checking that you are using
mte (and the same version) in both sides and you call that a day.

Notice that this requires the series (still not upstream but already on
the list) that move the zero page detection to the multifd thread,
because I am assuming that zero pages also have tags (yes, it was not a
very impressive guess).

What do you think?  Does this work for you?
What I would need for kvm/tcg would be some way of doing:

- get_the_mte_tag_of_page(page_id)
- set_the_mte_tag_of_page(page_id)

Now you need to tell me if I should do this for each page, or use some
kind of scatter-gather function that allows me to receive the mte tags
from an array of pages.

You could pass this information when we are searching for dirty pages,
but it is going to be complicated doing that (basically we only pass the
dirty page id, nothing else).

Doing this in normal precopy can also be done, but it would be an
exercise in masochism.

Another question, if you are using MTE, all pages have MTE, right?
Or there are other exceptions?

Sorry for my ignorance on this matter.

Later, Juan.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]