QEMU-Arm Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Fabiano Rosas <farosas@suse.de>
To: "Peter Xu" <peterx@redhat.com>,
	"Daniel P. Berrangé" <berrange@redhat.com>
Cc: qemu-devel@nongnu.org, qemu-arm@nongnu.org,
	"Cédric Le Goater" <clg@redhat.com>,
	"Philippe Mathieu-Daudé" <philmd@mailo.com>,
	"Vladimir Sementsov-Ogievskiy" <vsementsov@yandex-team.ru>,
	"Peter Maydell" <peter.maydell@linaro.org>,
	"Dr . David Alan Gilbert" <dave@treblig.org>,
	"Eric Blake" <eblake@redhat.com>,
	"Akihiko Odaki" <odaki@rsg.ci.i.u-tokyo.ac.jp>,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	"Kevin Wolf" <kwolf@redhat.com>,
	"Sana Sharma" <sansshar@redhat.com>,
	"Marc-André Lureau" <marcandre.lureau@redhat.com>,
	"Juraj Marcin" <jmarcin@redhat.com>,
	qemu-rust@nongnu.org, "Markus Armbruster" <armbru@redhat.com>,
	"Mark Cave-Ayland" <mark.caveayland@nutanix.com>
Subject: Re: [PATCH v2 10/10] migration: Switch to TYPE_OBJECT with object properties
Date: Wed, 10 Jun 2026 17:18:15 -0300	[thread overview]
Message-ID: <87se6u40ag.fsf@suse.de> (raw)
In-Reply-To: <87wlw641f3.fsf@suse.de>

Fabiano Rosas <farosas@suse.de> writes:

> Peter Xu <peterx@redhat.com> writes:
>
>> On Wed, Jun 10, 2026 at 05:13:47PM +0100, Daniel P. Berrangé wrote:
>>> On Tue, Jun 09, 2026 at 01:25:14PM -0400, Peter Xu wrote:
>>> > The migration object used to depend on TYPE_DEVICE due to:
>>> > 
>>> > - Usage of qdev properties
>>> > - Apply compat properties and global properties
>>> > 
>>> > This patch re-based the object to TYPE_OBJECT with the changes:
>>> > 
>>> > - Switch to object properties API
>>> > - Manually apply both compat and global properties in post_init()
>>> > 
>>> > Note that to avoid too many property getter/setter helpers, this patch used
>>> > the object_property_add_*_ptr_def() APIs so that an pointer is passed to
>>> > bind to the property.  Such API is used for most of the conversions.
>>> > 
>>> > After patch, the migration object initializes instance properties within
>>> > its instance_init() callback, in migrate_params_init().
>>> > 
>>> > One side effect of this change is, since we switched to a loop to add all
>>> > capabilities, the name of the properties representing a migration
>>> > capability may chance from previously hard-coded ones (many with x-).  It's
>>> > fine since it's only used in -global so it's only for debugging.
>>> > 
>>> > Similarly, I removed "x-" from other properites that used to start with
>>> > "x-" but actually are not experimental.
>>> 
>>> Mixing such a change into a refactoring commit is bad practice,
>>> can you keep property changes separated.
>>
>> Sure.
>>
>>> 
>>> > After the whole conversion, we don't need migration_properties or the count
>>> > anymore, hence can be removed.  While at it, we can also remove two
>>> > DEFINE_PROP*() API that only migration uses (DEFINE_PROP_STR_OR_NULL, and
>>> > DEFINE_PROP_MIG_CAP).
>>> > 
>>> > Signed-off-by: Peter Xu <peterx@redhat.com>
>>> > ---
>>> >  migration/options.h   |   8 +-
>>> >  migration/migration.c |  35 ++-
>>> >  migration/options.c   | 526 ++++++++++++++++++++++++++----------------
>>> >  3 files changed, 351 insertions(+), 218 deletions(-)
>>> 
>>> 
>>> > diff --git a/migration/options.c b/migration/options.c
>>> > index 5cbfd29099..1cc99382d3 100644
>>> > --- a/migration/options.c
>>> > +++ b/migration/options.c
>>> > @@ -54,7 +54,7 @@
>>> 
>>> 
>>> > +static void migration_object_init_props_bool(MigrationState *s)
>>> >  {
>>> > -    const Property *prop = opaque;
>>> > -    StrOrNull **ptr = object_field_prop_ptr(obj, prop);
>>> > -    StrOrNull *str_or_null = *ptr;
>>> > +    Object *obj = OBJECT(s);
>>> > +    int i;
>>> >  
>>> > -    /*
>>> > -     * The property should never be NULL because it's part of
>>> > -     * s->parameters and a default value is always set by qdev. It
>>> > -     * should also never be QNULL as the setter doesn't allow it.
>>> > -     */
>>> > -    assert(str_or_null && str_or_null->type != QTYPE_QNULL);
>>> > -    visit_type_str(v, name, &str_or_null->u.s, errp);
>>> > +    struct MigPropBool {
>>> > +        const char *name;
>>> > +        void *ptr;
>>> > +        bool defvar;
>>> > +    } bool_list[] = {
>>> > +        {
>>> > +            "store-global-state",
>>> > +            &s->store_global_state,
>>> > +            true,
>>> > +        },
>>> > +        {
>>> > +            "send-configuration",
>>> > +            &s->send_configuration,
>>> > +            true,
>>> > +        },
>>> > +        {
>>> > +            "send-section-footer",
>>> > +            &s->send_section_footer,
>>> > +            true,
>>> > +        },
>>> > +        {
>>> > +            "send-switchover-start",
>>> > +            &s->send_switchover_start,
>>> > +            true,
>>> > +        },
>>> > +        {
>>> > +            "x-preempt-pre-7-2",
>>> > +            &s->preempt_pre_7_2,
>>> > +            false,
>>> > +        },
>>> > +        {
>>> > +            "x-cpu-throttle-tailslow",
>>> > +            &s->parameters.cpu_throttle_tailslow,
>>> > +            false,
>>> > +        },
>>> > +        {
>>> > +            "multifd-clean-tls-termination",
>>> > +            &s->multifd_clean_tls_termination,
>>> > +            true,
>>> > +        },
>>> > +        {
>>> > +            "multifd-flush-after-each-section",
>>> > +            &s->multifd_flush_after_each_section,
>>> > +            false,
>>> > +        },
>>> > +    };
>>> > +    struct MigPropBool *prop;
>>> 
>>> This approach to declaring properties is pretty unpleasant
>>> to follow IMHO. Being a custom different approach from every
>>> other object impl is not a good thing.
>>
>> [I asked this question elsewhere, I'll keep the discussion there]
>>
>>> 
>>> > +
>>> > +    for (i = 0; i < ARRAY_SIZE(bool_list); i++) {
>>> > +        prop = &bool_list[i];
>>> > +        object_property_add_bool_ptr_def(obj, prop->name,
>>> > +                                         prop->ptr, prop->defvar);
>>> > +    }
>>> 
>>> Using instance level properties is the old way to do things,
>>> it is preferred to use class level properties instead.
>>> 
>>> This means you can't use the "ptr" concept to directly reference
>>> the instance fields and have to provide setters / getters explicitly
>>> instead, but as you've shown with the TLS properties,  a macro can
>>> make it simple to define the repetitive getters/setters.
>>
>> If pointer is unwanted, I can switch to some more macro magic.  But since
>> this series got rewrote the 3rd time..  I'll make sure it's extremely
>> required before doing it..
>>
>>> > +static void migration_object_init_props_enum(MigrationState *s)
>>> > +{
>>> > +    Object *obj = OBJECT(s);
>>> > +    ObjectProperty *prop;
>>> > +
>>> > +    prop = object_property_add_enum(obj, "multifd-compression",
>>> > +                                    "MultiFDCompression",
>>> > +                                    &MultiFDCompression_lookup,
>>> > +                                    mig_prop_multifd_compression_get,
>>> > +                                    mig_prop_multifd_compression_set);
>>> > +    object_property_set_default_str(prop, DEFAULT_MIGRATE_MULTIFD_COMPRESSION);
>>> > +
>>> > +    prop = object_property_add_enum(obj, "mode", "MigMode", &MigMode_lookup,
>>> > +                                    mig_prop_mode_get, mig_prop_mode_set);
>>> > +    object_property_set_default_str(prop, "normal");
>>> > +
>>> > +    prop = object_property_add_enum(obj, "zero-page-detection",
>>> > +                                    "ZeroPageDetection",
>>> > +                                    &ZeroPageDetection_lookup,
>>> > +                                    mig_prop_zero_page_detection_get,
>>> > +                                    mig_prop_zero_page_detection_set);
>>> > +    object_property_set_default_str(prop, "multifd");
>>> > +}
>>> 
>>> Perhaps I'm missing something, but I'm not seeing the point in
>>> using the set_default methods - in fact I'm not really sure why
>>> they exist in QOM at all.
>>> 
>>> I'd expect all defaults to be set in the instance _init method.
>>> ie why isn't this done as:
>>> 
>>>    void migrate_params_init(MigrationState *s)
>>>    {
>>>       s->parameters.mode = MIG_MODE_NORMAL;
>>>       s->parameters.zero_page_detection = ZERO_PAGE_DETECTION_MULTIFD;
>>>       .... all other defaults...
>>>    }
>>
>> Yes frankly I asked myself the same question when looking at this.
>>
>> I still saw quite some defvar references, type_print_class_properties() can
>> be one example where we dump help message with default values but without
>> the need to apply.  I didn't check the rest.  If the concept exists and if
>> we will be using qobj props, IMHO sticking with it is defintely safer so
>> that all qom future defvar changes will apply and it'll just work there.
>>
>>> 
>>> 
>>> > +
>>> > +static void migration_object_init_properties(MigrationState *s)
>>> > +{
>>> > +    migration_object_init_props_bool(s);
>>> > +    migration_object_init_props_uint8(s);
>>> > +    migration_object_init_props_uint32(s);
>>> > +    migration_object_init_props_uint64(s);
>>> > +    migration_object_init_props_size(s);
>>> > +    migration_object_init_props_caps(s);
>>> > +    migration_object_init_props_tls(s);
>>> > +    migration_object_init_props_enum(s);
>>> > +}
>>> 
>>> ...and class properties be registered in migrate_params_class_init()
>>> and the grouping per type isn't helpful IMHO, just put all the
>>> object_class_property_add calls inline in one place.
>>
>> I still want to avoid long functions, one way or another.
>>
>> Hopefully it makes sense when I have those arrays to init different type of
>> props it makes sense to split with this, but I'm open to other way to
>> split.  I still want to not make it a extremely long function.
>>
>
> I see why you did it that way, it's mostly a limitation of the object
> code in that it requires the type of the default value only to convert
> it to a QObject internally. IMO, this is backwards, the object.c code
> should take the QObject and let the caller do the conversion.
>
> I rewrote this part of the code using a ObjectProperties object as
> intermediary, instead of MigProp*. I think this looks easier to parse,
> although it's longer.
>
> -->8--
> From a6529d119d25ecc00f92686e2cddf1d81dc43183 Mon Sep 17 00:00:00 2001
> From: Fabiano Rosas <farosas@suse.de>
> Date: Wed, 10 Jun 2026 16:49:52 -0300
> Subject: [PATCH] poc
>
> ---
>  migration/options.c | 114 ++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 114 insertions(+)
>
> diff --git a/migration/options.c b/migration/options.c
> index 5a74aef0ad..7ab1079284 100644
> --- a/migration/options.c
> +++ b/migration/options.c
> @@ -90,6 +90,120 @@
>  #define DEFAULT_MIGRATE_VCPU_DIRTY_LIMIT            1       /* MB/s */
>  #define DEFAULT_MIGRATE_X_RDMA_CHUNK_SIZE           MiB
>  
> +#define defstr(def) QOBJECT(qstring_from_str((const char *)def))
> +#define defbool(def) QOBJECT(qbool_from_bool((bool)def))
> +#define defint(def) QOBJECT(qnum_from_int((int64_t)def))
> +#define defuint(def) QOBJECT(qnum_from_uint(def))
> +
> +#define defuint8 defuint
> +#define defuint16 defuint
> +#define defuint32 defuint
> +#define defuint64 defuint
> +#define defenum defstr
> +#define defStrOrNull defstr
> +#define defMigMode defenum
> +#define defMultiFDCompression defenum
> +#define defZeroPageDetection defenum
> +
> +#define DEFPROP_PTR_ACCESSOR(_t)                                        \
> +    static void property_visit_type_##_t(Object *obj, Visitor *v,       \
> +                                         const char *name, void *opaque, \
> +                                         Error **errp)                  \
> +    {                                                                   \
> +        visit_type_##_t(v, name, opaque, errp);                         \
> +    }                                                                   \

I'm trying to convert this Object to a QDict here. Then we could pass
the name of the struct field as the opaque and set/get via dict
operations and this function could be generic for all parameters.

> +                                                                        \
> +    static inline ObjectProperty prop_##_t(const char *name, void *opaque, \
> +                                           uint64_t def)                \
> +    {                                                                   \
> +        return (ObjectProperty) {                                       \
> +            .name = (char *)name,                                       \
> +            .type = (char *)"##_t",                                     \
> +            .opaque = opaque,                                           \
> +            .get = property_visit_type_##_t,                            \
> +            .set = property_visit_type_##_t,                            \
> +            .defval = def##_t(def),                                     \
> +        };                                                              \
> +    }                                                                   \
> +
> +DEFPROP_PTR_ACCESSOR(str);
> +DEFPROP_PTR_ACCESSOR(bool);
> +DEFPROP_PTR_ACCESSOR(int);
> +DEFPROP_PTR_ACCESSOR(uint8);
> +DEFPROP_PTR_ACCESSOR(uint16);
> +DEFPROP_PTR_ACCESSOR(uint32);
> +DEFPROP_PTR_ACCESSOR(uint64);
> +DEFPROP_PTR_ACCESSOR(StrOrNull);
> +DEFPROP_PTR_ACCESSOR(MigMode);
> +DEFPROP_PTR_ACCESSOR(MultiFDCompression);
> +DEFPROP_PTR_ACCESSOR(ZeroPageDetection);
> +
> +static void migration_object_init_properties(MigrationState *s)
> +{
> +    Object *obj = OBJECT(s);
> +    ObjectProperty props_list[] = {
> +        prop_bool("store-global-state", &s->store_global_state, true),
> +        prop_bool("send-configuration", &s->send_configuration, true),
> +        prop_bool("send-section-footer", &s->send_section_footer, true),
> +        prop_bool("send-switchover-start", &s->send_switchover_start, true),
> +        prop_bool("x-preempt-pre-7-2", &s->preempt_pre_7_2, false),
> +        prop_bool("x-cpu-throttle-tailslow", &s->parameters.cpu_throttle_tailslow, false),
> +        prop_bool("multifd-clean-tls-termination", &s->multifd_clean_tls_termination, true),
> +        prop_bool("multifd-flush-after-each-section", &s->multifd_flush_after_each_section, false),
> +
> +        prop_uint8("clear-bitmap-shift", &s->clear_bitmap_shift, CLEAR_BITMAP_SHIFT_DEFAULT),
> +        prop_uint8("throttle-trigger-threshold", &s->parameters.throttle_trigger_threshold, DEFAULT_MIGRATE_THROTTLE_TRIGGER_THRESHOLD),
> +        prop_uint8("cpu-throttle-initial", &s->parameters.cpu_throttle_initial, DEFAULT_MIGRATE_CPU_THROTTLE_INITIAL),
> +        prop_uint8("cpu-throttle-increment", &s->parameters.cpu_throttle_increment, DEFAULT_MIGRATE_CPU_THROTTLE_INCREMENT),
> +        prop_uint8("multifd-channels", &s->parameters.multifd_channels, DEFAULT_MIGRATE_MULTIFD_CHANNELS),
> +        prop_uint8("multifd-zlib-level", &s->parameters.multifd_zlib_level, DEFAULT_MIGRATE_MULTIFD_ZLIB_LEVEL),
> +        prop_uint8("multifd-qatzip-level", &s->parameters.multifd_qatzip_level, DEFAULT_MIGRATE_MULTIFD_QATZIP_LEVEL),
> +        prop_uint8("multifd-zstd-level", &s->parameters.multifd_zstd_level, DEFAULT_MIGRATE_MULTIFD_ZSTD_LEVEL),
> +        prop_uint8("max-cpu-throttle", &s->parameters.max_cpu_throttle, DEFAULT_MIGRATE_MAX_CPU_THROTTLE),
> +
> +        prop_uint32("x-checkpoint-delay", &s->parameters.x_checkpoint_delay, DEFAULT_MIGRATE_X_CHECKPOINT_DELAY),
> +
> +        prop_uint64("downtime-limit", &s->parameters.downtime_limit, DEFAULT_MIGRATE_SET_DOWNTIME),
> +        prop_uint64("x-vcpu-dirty-limit-period", &s->parameters.x_vcpu_dirty_limit_period, DEFAULT_MIGRATE_VCPU_DIRTY_LIMIT_PERIOD),
> +        prop_uint64("vcpu-dirty-limit", &s->parameters.vcpu_dirty_limit, DEFAULT_MIGRATE_VCPU_DIRTY_LIMIT),
> +        prop_uint64("x-rdma-chunk-size", &s->parameters.x_rdma_chunk_size, DEFAULT_MIGRATE_X_RDMA_CHUNK_SIZE),
> +        prop_uint64("xbzrle-cache-size", &s->parameters.xbzrle_cache_size, DEFAULT_MIGRATE_XBZRLE_CACHE_SIZE),
> +        prop_uint64("max-postcopy-bandwidth", &s->parameters.max_postcopy_bandwidth, DEFAULT_MIGRATE_MAX_POSTCOPY_BANDWIDTH),
> +        prop_uint64("announce-initial", &s->parameters.announce_initial, DEFAULT_MIGRATE_ANNOUNCE_INITIAL),
> +        prop_uint64("announce-max", &s->parameters.announce_max, DEFAULT_MIGRATE_ANNOUNCE_MAX),
> +        prop_uint64("announce-rounds", &s->parameters.announce_rounds, DEFAULT_MIGRATE_ANNOUNCE_ROUNDS),
> +        prop_uint64("announce-step", &s->parameters.announce_step, DEFAULT_MIGRATE_ANNOUNCE_STEP),
> +        prop_uint64("max-bandwidth", &s->parameters.max_bandwidth, MAX_THROTTLE),
> +        prop_uint64("avail-switchover-bandwidth", &s->parameters.avail_switchover_bandwidth, 0),
> +
> +        prop_StrOrNull("tls-creds", &s->parameters.tls_creds, (uint64_t)""),
> +        prop_StrOrNull("tls-hostname", &s->parameters.tls_hostname, (uint64_t)""),
> +        prop_StrOrNull("tls-authz", &s->parameters.tls_authz, (uint64_t)""),
> +
> +        prop_MigMode("mode", &s->parameters.mode, (uint64_t)"normal"),
> +        prop_MultiFDCompression("multifd-compression", &s->parameters.multifd_compression, (uint64_t)DEFAULT_MIGRATE_MULTIFD_COMPRESSION),
> +        prop_ZeroPageDetection("zero-page-detection", &s->parameters.zero_page_detection, (uint64_t)"multifd"),
> +    };
> +
> +    for (int i = 0; i < ARRAY_SIZE(props_list); i++) {
> +        ObjectProperty *new;
> +        ObjectProperty *in = &props_list[i];
> +
> +        new = object_property_add(obj, in->name, in->type, in->get, in->set,
> +                                  in->release, in->opaque);
> +        object_property_set_default(new, in->defval);
> +    }
> +
> +    /* Migration capabilities are always turned off by default */
> +    for (int i = 0; i < MIGRATION_CAPABILITY__MAX; i++) {
> +        ObjectProperty prop, *new;
> +
> +        prop = prop_bool(MigrationCapability_str(i), &s->capabilities[i], false);
> +        new = object_property_add(obj, prop.name, prop.type, prop.get, prop.set,
> +                                  NULL, prop.opaque);
> +        object_property_set_default(new, prop.defval);
> +    }
> +}
>  
>  bool migrate_auto_converge(void)
>  {


  reply	other threads:[~2026-06-10 20:18 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-09 17:25 [PATCH v2 00/10] migration/qom: Remove TYPE_DEVICE dependency on migration object Peter Xu
2026-06-09 17:25 ` [PATCH v2 01/10] migration: Use OBJECT_DECLARE_SIMPLE_TYPE Peter Xu
2026-06-09 22:55   ` Fabiano Rosas
2026-06-10 13:56   ` Daniel P. Berrangé
2026-06-10 15:15   ` Mark Cave-Ayland
2026-06-09 17:25 ` [PATCH v2 02/10] qdev: Export global_props() Peter Xu
2026-06-09 22:55   ` Fabiano Rosas
2026-06-10 15:18   ` Mark Cave-Ayland
2026-06-09 17:25 ` [PATCH v2 03/10] qdev: Introduce DEFINE_PROP_*_NODEFAULT for bool/uint32 Peter Xu
2026-06-10 15:25   ` Mark Cave-Ayland
2026-06-09 17:25 ` [PATCH v2 04/10] hw/arm: Use nodefault version of qdev props when not needed Peter Xu
2026-06-10 15:31   ` Mark Cave-Ayland
2026-06-09 17:25 ` [PATCH v2 05/10] qom: Create object-property-ptr.[ch] Peter Xu
2026-06-10 16:15   ` Daniel P. Berrangé
2026-06-10 18:39     ` Peter Xu
2026-06-10 20:37       ` Fabiano Rosas
2026-06-11 13:52       ` Daniel P. Berrangé
2026-06-11 14:36         ` Fabiano Rosas
2026-06-11 14:40           ` Daniel P. Berrangé
2026-06-16 21:02             ` Peter Xu
2026-06-17 12:25               ` Fabiano Rosas
2026-06-17 12:27                 ` Daniel P. Berrangé
2026-06-11 12:54   ` Mark Cave-Ayland
2026-06-11 13:53     ` Peter Xu
2026-06-09 17:25 ` [PATCH v2 06/10] qom: Add object_property_add_bool_ptr() Peter Xu
2026-06-09 23:18   ` Fabiano Rosas
2026-06-11 12:59   ` Mark Cave-Ayland
2026-06-09 17:25 ` [PATCH v2 07/10] qom: Add object_property_add_size_ptr() Peter Xu
2026-06-09 23:18   ` Fabiano Rosas
2026-06-09 17:25 ` [PATCH v2 08/10] qom: Add object_property_add_*_ptr_def() Peter Xu
2026-06-09 23:21   ` Fabiano Rosas
2026-06-11 14:03   ` Mark Cave-Ayland
2026-06-09 17:25 ` [PATCH v2 09/10] qom: Allow default values for instance properties Peter Xu
2026-06-10 16:19   ` Daniel P. Berrangé
2026-06-11 14:08   ` Mark Cave-Ayland
2026-06-11 14:17     ` Daniel P. Berrangé
2026-06-11 15:24       ` Mark Cave-Ayland
2026-06-09 17:25 ` [PATCH v2 10/10] migration: Switch to TYPE_OBJECT with object properties Peter Xu
2026-06-10 16:13   ` Daniel P. Berrangé
2026-06-10 18:46     ` Peter Xu
2026-06-10 19:53       ` Fabiano Rosas
2026-06-10 20:18         ` Fabiano Rosas [this message]
2026-06-10 16:29   ` Daniel P. Berrangé
2026-06-10 18:51     ` Peter Xu
2026-06-09 22:54 ` [PATCH v2 00/10] migration/qom: Remove TYPE_DEVICE dependency on migration object Fabiano Rosas
2026-06-10 18:30   ` Peter Xu
2026-06-11 13:31     ` Daniel P. Berrangé

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87se6u40ag.fsf@suse.de \
    --to=farosas@suse.de \
    --cc=armbru@redhat.com \
    --cc=berrange@redhat.com \
    --cc=clg@redhat.com \
    --cc=dave@treblig.org \
    --cc=eblake@redhat.com \
    --cc=jmarcin@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=marcandre.lureau@redhat.com \
    --cc=mark.caveayland@nutanix.com \
    --cc=odaki@rsg.ci.i.u-tokyo.ac.jp \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=peterx@redhat.com \
    --cc=philmd@mailo.com \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-rust@nongnu.org \
    --cc=sansshar@redhat.com \
    --cc=vsementsov@yandex-team.ru \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox