qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Alexey Kardashevskiy <aik@ozlabs.ru>
To: David Gibson <david@gibson.dropbear.id.au>,
	agraf@suse.de, crosthwaite.peter@gmail.com
Cc: qemu-ppc@nongnu.org, qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [RFC for-2.7 08/11] pseries: Start using qdt library for building device tree
Date: Thu, 21 Apr 2016 14:04:16 +1000	[thread overview]
Message-ID: <57185140.5030801@ozlabs.ru> (raw)
In-Reply-To: <1461119601-4936-9-git-send-email-david@gibson.dropbear.id.au>

On 04/20/2016 12:33 PM, David Gibson wrote:
> This starts the process of converting the pseries machine type to use
> the qdt library code to build the guest's device tree instead of
> working directly and awkwardly with the flattened device tree format.
>
> For now we just convert the first section of spapr_build_fdt() which
> creates a tree sequentially, so that it builds the qdt then flattens
> it.  This leaves a lot of code which still manipulates the fdt after
> that point, but the intention is to convert those to work with the qdt
> format in future.
>
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>


9 patches or 11 look good as they do one right thing at the time.

But this one does:
1. replace _FDT() with qdt_setprop_xxx
2. "consolidates" spapr_events_fdt_skel() (other code movements got own 
patches but not this one)
3. moves bits around like the hyperrtas property composer.

This all makes it harder to verify that you have not lost anything in 
transition...

I'd also expect this patch to be the second (right after "qdt: 
IEEE1275-style device tree utility code") or after all "consolidation" 
patches (this would make even more sense), and this patch would convert all 
_FDTs, and then remove _FDT() macro. Or "in future" from the commit log 
means "nearest future"? :)


btw after all these device tree rendering code gathered in one place - how 
many of the original justification points are still valid? Persistent 
handles or being slow should not be problems anymore (as it is sequential 
device tree rendering, without reordering).


> ---
>   hw/ppc/spapr.c         | 236 ++++++++++++++++++++++++-------------------------
>   hw/ppc/spapr_events.c  |  19 ----
>   include/hw/ppc/spapr.h |   1 -
>   3 files changed, 117 insertions(+), 139 deletions(-)
>
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index aef44a2..d04d403 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -66,6 +66,8 @@
>   #include "hw/compat.h"
>   #include "qemu/cutils.h"
>
> +#include "qemu/qdt.h"
> +
>   #include <libfdt.h>
>
>   /* SLOF memory layout:
> @@ -710,47 +712,27 @@ static void *spapr_build_fdt(sPAPRMachineState *spapr,
>       char *bootlist;
>       void *fdt;
>       sPAPRPHBState *phb;
> -    uint32_t start_prop = cpu_to_be32(spapr->initrd_base);
> -    uint32_t end_prop = cpu_to_be32(spapr->initrd_base + spapr->initrd_size);
> -    GString *hypertas = g_string_sized_new(256);
> -    GString *qemu_hypertas = g_string_sized_new(256);
> -    uint32_t refpoints[] = {cpu_to_be32(0x4), cpu_to_be32(0x4)};
> -    uint32_t interrupt_server_ranges_prop[] = {0, cpu_to_be32(max_cpus)};
> -    unsigned char vec5[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x80};
>       char *buf;
> +    QDTNode *root;
>
> -    add_str(hypertas, "hcall-pft");
> -    add_str(hypertas, "hcall-term");
> -    add_str(hypertas, "hcall-dabr");
> -    add_str(hypertas, "hcall-interrupt");
> -    add_str(hypertas, "hcall-tce");
> -    add_str(hypertas, "hcall-vio");
> -    add_str(hypertas, "hcall-splpar");
> -    add_str(hypertas, "hcall-bulk");
> -    add_str(hypertas, "hcall-set-mode");
> -    add_str(qemu_hypertas, "hcall-memop1");
> -
> -    fdt = g_malloc0(FDT_MAX_SIZE);
> -    _FDT((fdt_create(fdt, FDT_MAX_SIZE)));
> +    root = qdt_new_tree();
>
> -    _FDT((fdt_finish_reservemap(fdt)));
> +    /* / (root node) */
>
> -    /* Root node */
> -    _FDT((fdt_begin_node(fdt, "")));
> -    _FDT((fdt_property_string(fdt, "device_type", "chrp")));
> -    _FDT((fdt_property_string(fdt, "model", "IBM pSeries (emulated by qemu)")));
> -    _FDT((fdt_property_string(fdt, "compatible", "qemu,pseries")));
> +    qdt_setprop_string(root, "device_type", "chrp");
> +    qdt_setprop_string(root, "model", "IBM pSeries (emulated by qemu)");
> +    qdt_setprop_string(root, "compatible", "qemu,pseries");
>
>       /*
>        * Add info to guest to indentify which host is it being run on
>        * and what is the uuid of the guest
>        */
>       if (kvmppc_get_host_model(&buf)) {
> -        _FDT((fdt_property_string(fdt, "host-model", buf)));
> +        qdt_setprop_string(root, "host-model", buf);
>           g_free(buf);
>       }
>       if (kvmppc_get_host_serial(&buf)) {
> -        _FDT((fdt_property_string(fdt, "host-serial", buf)));
> +        qdt_setprop_string(root, "host-serial", buf);
>           g_free(buf);
>       }
>
> @@ -761,138 +743,154 @@ static void *spapr_build_fdt(sPAPRMachineState *spapr,
>                             qemu_uuid[11], qemu_uuid[12], qemu_uuid[13],
>                             qemu_uuid[14], qemu_uuid[15]);
>
> -    _FDT((fdt_property_string(fdt, "vm,uuid", buf)));
> +    qdt_setprop_string(root, "vm,uuid", buf);
>       if (qemu_uuid_set) {
> -        _FDT((fdt_property_string(fdt, "system-id", buf)));
> +        qdt_setprop_string(root, "system-id", buf);
>       }
>       g_free(buf);
>
>       if (qemu_get_vm_name()) {
> -        _FDT((fdt_property_string(fdt, "ibm,partition-name",
> -                                  qemu_get_vm_name())));
> +        qdt_setprop_string(root, "ibm,partition-name", qemu_get_vm_name());
>       }
>
> -    _FDT((fdt_property_cell(fdt, "#address-cells", 0x2)));
> -    _FDT((fdt_property_cell(fdt, "#size-cells", 0x2)));
> +    qdt_setprop_cells(root, "#address-cells", 0x2);
> +    qdt_setprop_cells(root, "#size-cells", 0x2);
>
>       /* /chosen */
> -    _FDT((fdt_begin_node(fdt, "chosen")));
> -
> -    /* Set Form1_affinity */
> -    _FDT((fdt_property(fdt, "ibm,architecture-vec-5", vec5, sizeof(vec5))));
> -
> -    _FDT((fdt_property_string(fdt, "bootargs", machine->kernel_cmdline)));
> -    _FDT((fdt_property(fdt, "linux,initrd-start",
> -                       &start_prop, sizeof(start_prop))));
> -    _FDT((fdt_property(fdt, "linux,initrd-end",
> -                       &end_prop, sizeof(end_prop))));
> -    if (spapr->kernel_size) {
> -        uint64_t kprop[2] = { cpu_to_be64(KERNEL_LOAD_ADDR),
> -                              cpu_to_be64(spapr->kernel_size) };
> -
> -        _FDT((fdt_property(fdt, "qemu,boot-kernel", &kprop, sizeof(kprop))));
> -        if (spapr->kernel_le) {
> -            _FDT((fdt_property(fdt, "qemu,boot-kernel-le", NULL, 0)));
> +    {
> +        QDTNode *chosen = qdt_add_subnode(root, "chosen");
> +
> +        /* Set Form1_affinity */
> +        qdt_setprop_bytes(chosen, "ibm,architecture-vec-5",
> +                          0x0, 0x0, 0x0, 0x0, 0x0, 0x80);
> +
> +        qdt_setprop_string(chosen, "bootargs", machine->kernel_cmdline);
> +        qdt_setprop_cells(chosen, "linux,initrd-start",
> +                          spapr->initrd_base);
> +        qdt_setprop_cells(chosen, "linux,initrd-end",
> +                          spapr->initrd_base + spapr->initrd_size);
> +        if (spapr->kernel_size) {
> +            qdt_setprop_u64s(chosen, "qemu,boot-kernel",
> +                             KERNEL_LOAD_ADDR, spapr->kernel_size);
> +            if (spapr->kernel_le) {
> +                qdt_setprop_empty(chosen, "qemu,boot-kernel-le");
> +            }
>           }
> +        if (boot_menu) {
> +            qdt_setprop_cells(chosen, "qemu,boot-menu", boot_menu);
> +        }
> +        qdt_setprop_cells(chosen, "qemu,graphic-width", graphic_width);
> +        qdt_setprop_cells(chosen, "qemu,graphic-height", graphic_height);
> +        qdt_setprop_cells(chosen, "qemu,graphic-depth", graphic_depth);
>       }
> -    if (boot_menu) {
> -        _FDT((fdt_property_cell(fdt, "qemu,boot-menu", boot_menu)));
> -    }
> -    _FDT((fdt_property_cell(fdt, "qemu,graphic-width", graphic_width)));
> -    _FDT((fdt_property_cell(fdt, "qemu,graphic-height", graphic_height)));
> -    _FDT((fdt_property_cell(fdt, "qemu,graphic-depth", graphic_depth)));
> -
> -    _FDT((fdt_end_node(fdt)));
>
>       /* RTAS */
> -    _FDT((fdt_begin_node(fdt, "rtas")));
> +    {
> +        QDTNode *rtas = qdt_add_subnode(root, "rtas");
> +        GString *hypertas = g_string_sized_new(256);
> +        GString *qemu_hypertas = g_string_sized_new(256);
>
> -    if (!kvm_enabled() || kvmppc_spapr_use_multitce()) {
> -        add_str(hypertas, "hcall-multi-tce");
> -    }
> -    _FDT((fdt_property(fdt, "ibm,hypertas-functions", hypertas->str,
> -                       hypertas->len)));
> -    g_string_free(hypertas, TRUE);
> -    _FDT((fdt_property(fdt, "qemu,hypertas-functions", qemu_hypertas->str,
> -                       qemu_hypertas->len)));
> -    g_string_free(qemu_hypertas, TRUE);
> +        add_str(hypertas, "hcall-pft");
> +        add_str(hypertas, "hcall-term");
> +        add_str(hypertas, "hcall-dabr");
> +        add_str(hypertas, "hcall-interrupt");
> +        add_str(hypertas, "hcall-tce");
> +        add_str(hypertas, "hcall-vio");
> +        add_str(hypertas, "hcall-splpar");
> +        add_str(hypertas, "hcall-bulk");
> +        add_str(hypertas, "hcall-set-mode");
> +        add_str(qemu_hypertas, "hcall-memop1");
>
> -    _FDT((fdt_property(fdt, "ibm,associativity-reference-points",
> -        refpoints, sizeof(refpoints))));
> +        if (!kvm_enabled() || kvmppc_spapr_use_multitce()) {
> +            add_str(hypertas, "hcall-multi-tce");
> +        }
> +        qdt_setprop(rtas, "ibm,hypertas-functions",
> +                    hypertas->str, hypertas->len);
> +        g_string_free(hypertas, TRUE);
> +        qdt_setprop(rtas, "qemu,hypertas-functions",
> +                    qemu_hypertas->str, qemu_hypertas->len);
> +        g_string_free(qemu_hypertas, TRUE);
>
> -    _FDT((fdt_property_cell(fdt, "rtas-error-log-max", RTAS_ERROR_LOG_MAX)));
> -    _FDT((fdt_property_cell(fdt, "rtas-event-scan-rate",
> -                            RTAS_EVENT_SCAN_RATE)));
> +        qdt_setprop_cells(rtas, "ibm,associativity-reference-points", 0x4, 0x4);
>
> -    if (msi_nonbroken) {
> -        _FDT((fdt_property(fdt, "ibm,change-msix-capable", NULL, 0)));
> -    }
> +        qdt_setprop_cells(rtas, "rtas-error-log-max", RTAS_ERROR_LOG_MAX);
> +        qdt_setprop_cells(rtas, "rtas-event-scan-rate", RTAS_EVENT_SCAN_RATE);
>
> -    /*
> -     * According to PAPR, rtas ibm,os-term does not guarantee a return
> -     * back to the guest cpu.
> -     *
> -     * While an additional ibm,extended-os-term property indicates that
> -     * rtas call return will always occur. Set this property.
> -     */
> -    _FDT((fdt_property(fdt, "ibm,extended-os-term", NULL, 0)));
> +        if (msi_nonbroken) {
> +            qdt_setprop_empty(rtas, "ibm,change-msix-capable");
> +        }
> +
> +        /*
> +         * According to PAPR, rtas ibm,os-term does not guarantee a
> +         * return back to the guest cpu.
> +         *
> +         * While an additional ibm,extended-os-term property indicates
> +         * that rtas call return will always occur. Set this property.
> +         */
> +        qdt_setprop_empty(rtas, "ibm,extended-os-term");
> +    }
>
> -    _FDT((fdt_end_node(fdt)));
> +    /* /interrupt controller */
> +    {
> +        QDTNode *xics = qdt_add_subnode(root, "interrupt-controller");
>
> -    /* interrupt controller */
> -    _FDT((fdt_begin_node(fdt, "interrupt-controller")));
> +        qdt_setprop_string(xics, "device_type",
> +                           "PowerPC-External-Interrupt-Presentation");
> +        qdt_setprop_string(xics, "compatible", "IBM,ppc-xicp");
> +        qdt_setprop_empty(xics, "interrupt-controller");
> +        qdt_setprop_cells(xics, "ibm,interrupt-server-ranges", 0, max_cpus);
> +        qdt_setprop_cells(xics, "#interrupt-cells", 2);
> +        qdt_set_phandle(xics, PHANDLE_XICP);
> +    }
>
> -    _FDT((fdt_property_string(fdt, "device_type",
> -                              "PowerPC-External-Interrupt-Presentation")));
> -    _FDT((fdt_property_string(fdt, "compatible", "IBM,ppc-xicp")));
> -    _FDT((fdt_property(fdt, "interrupt-controller", NULL, 0)));
> -    _FDT((fdt_property(fdt, "ibm,interrupt-server-ranges",
> -                       interrupt_server_ranges_prop,
> -                       sizeof(interrupt_server_ranges_prop))));
> -    _FDT((fdt_property_cell(fdt, "#interrupt-cells", 2)));
> -    _FDT((fdt_property_cell(fdt, "linux,phandle", PHANDLE_XICP)));
> -    _FDT((fdt_property_cell(fdt, "phandle", PHANDLE_XICP)));
> +    /* /vdevice */
> +    {
> +        QDTNode *vdevice = qdt_add_subnode(root, "vdevice");
>
> -    _FDT((fdt_end_node(fdt)));
> +        qdt_setprop_string(vdevice, "device_type", "vdevice");
> +        qdt_setprop_string(vdevice, "compatible", "IBM,vdevice");
> +        qdt_setprop_cells(vdevice, "#address-cells", 0x1);
> +        qdt_setprop_cells(vdevice, "#size-cells", 0x0);
> +        qdt_setprop_cells(vdevice, "#interrupt-cells", 0x2);
> +        qdt_setprop_empty(vdevice, "interrupt-controller");
> +    }
>
> -    /* vdevice */
> -    _FDT((fdt_begin_node(fdt, "vdevice")));
>
> -    _FDT((fdt_property_string(fdt, "device_type", "vdevice")));
> -    _FDT((fdt_property_string(fdt, "compatible", "IBM,vdevice")));
> -    _FDT((fdt_property_cell(fdt, "#address-cells", 0x1)));
> -    _FDT((fdt_property_cell(fdt, "#size-cells", 0x0)));
> -    _FDT((fdt_property_cell(fdt, "#interrupt-cells", 0x2)));
> -    _FDT((fdt_property(fdt, "interrupt-controller", NULL, 0)));
> +    /* /event-sources */
> +    {
> +        QDTNode *event_sources = qdt_add_subnode(root, "event-sources");
> +        QDTNode *epow;
>
> -    _FDT((fdt_end_node(fdt)));
> +        qdt_setprop_empty(event_sources, "interrupt-controller");
> +        qdt_setprop_cells(event_sources, "#interrupt-cells", 2);
> +        qdt_setprop_cells(event_sources, "interrupt-ranges",
> +                          spapr->check_exception_irq, 1);
>
> -    /* event-sources */
> -    spapr_events_fdt_skel(fdt, spapr->check_exception_irq);
> +        epow = qdt_add_subnode(event_sources, "epow-events");
> +        qdt_setprop_cells(epow, "interrupts", spapr->check_exception_irq, 0);
> +    }
>
> -    /* /hypervisor node */
> +    /* /hypervisor */
>       if (kvm_enabled()) {
> -        uint8_t hypercall[16];
> +        QDTNode *hypervisor = qdt_add_subnode(root, "hypervisor");
>
>           /* indicate KVM hypercall interface */
> -        _FDT((fdt_begin_node(fdt, "hypervisor")));
> -        _FDT((fdt_property_string(fdt, "compatible", "linux,kvm")));
> +        qdt_setprop_string(hypervisor, "compatible", "linux,kvm");
>           if (kvmppc_has_cap_fixup_hcalls()) {
> +            uint8_t hypercall[16];
>               /*
>                * Older KVM versions with older guest kernels were broken with the
>                * magic page, don't allow the guest to map it.
>                */
>               if (!kvmppc_get_hypercall(first_cpu->env_ptr, hypercall,
>                                         sizeof(hypercall))) {
> -                _FDT((fdt_property(fdt, "hcall-instructions", hypercall,
> -                                   sizeof(hypercall))));
> +                qdt_setprop(hypervisor, "hcall-instructions",
> +                            hypercall, sizeof(hypercall));
>               }
>           }
> -        _FDT((fdt_end_node(fdt)));
>       }
>
> -    _FDT((fdt_end_node(fdt))); /* close root node */
> -    _FDT((fdt_finish(fdt)));
> +    fdt = qdt_flatten(root, FDT_MAX_SIZE, &error_fatal);
>
>       /* open out the base tree into a temp buffer for the final tweaks */
>       _FDT((fdt_open_into(fdt, fdt, FDT_MAX_SIZE)));
> diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c
> index 269ab7e..cce219f 100644
> --- a/hw/ppc/spapr_events.c
> +++ b/hw/ppc/spapr_events.c
> @@ -220,25 +220,6 @@ struct hp_log_full {
>           }                                                          \
>       } while (0)
>
> -void spapr_events_fdt_skel(void *fdt, uint32_t check_exception_irq)
> -{
> -    uint32_t irq_ranges[] = {cpu_to_be32(check_exception_irq), cpu_to_be32(1)};
> -    uint32_t interrupts[] = {cpu_to_be32(check_exception_irq), 0};
> -
> -    _FDT((fdt_begin_node(fdt, "event-sources")));
> -
> -    _FDT((fdt_property(fdt, "interrupt-controller", NULL, 0)));
> -    _FDT((fdt_property_cell(fdt, "#interrupt-cells", 2)));
> -    _FDT((fdt_property(fdt, "interrupt-ranges",
> -                       irq_ranges, sizeof(irq_ranges))));
> -
> -    _FDT((fdt_begin_node(fdt, "epow-events")));
> -    _FDT((fdt_property(fdt, "interrupts", interrupts, sizeof(interrupts))));
> -    _FDT((fdt_end_node(fdt)));
> -
> -    _FDT((fdt_end_node(fdt)));
> -}
> -
>   static void rtas_event_log_queue(int log_type, void *data, bool exception)
>   {
>       sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
> index ebad34f..40d3724 100644
> --- a/include/hw/ppc/spapr.h
> +++ b/include/hw/ppc/spapr.h
> @@ -560,7 +560,6 @@ struct sPAPREventLogEntry {
>   };
>
>   void spapr_events_init(sPAPRMachineState *sm);
> -void spapr_events_fdt_skel(void *fdt, uint32_t epow_irq);
>   int spapr_h_cas_compose_response(sPAPRMachineState *sm,
>                                    target_ulong addr, target_ulong size,
>                                    bool cpu_update, bool memory_update);
>


-- 
Alexey

  reply	other threads:[~2016-04-21  4:04 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-04-20  2:33 [Qemu-devel] [RFC for-2.7 00/11] A new infrastructure for guest device trees David Gibson
2016-04-20  2:33 ` [Qemu-devel] [RFC for-2.7 01/11] qdt: IEEE1275-style device tree utility code David Gibson
2016-04-21  6:01   ` Alexey Kardashevskiy
2016-04-22  4:15     ` David Gibson
2016-04-26 11:00   ` Thomas Huth
2016-04-27  6:02     ` David Gibson
2016-04-27  6:43       ` Markus Armbruster
2016-04-27  7:06         ` Thomas Huth
2016-04-27  7:28           ` Markus Armbruster
2016-04-27  7:56             ` Thomas Huth
2016-04-27  8:36               ` Markus Armbruster
2016-04-27 23:49             ` David Gibson
2016-04-20  2:33 ` [Qemu-devel] [RFC for-2.7 02/11] pseries: Split device tree construction from device tree load David Gibson
2016-04-20 18:15   ` Thomas Huth
2016-04-21  5:31   ` Alexey Kardashevskiy
2016-04-20  2:33 ` [Qemu-devel] [RFC for-2.7 03/11] pseries: Remove rtas_addr and fdt_addr fields from machinestate David Gibson
2016-04-20 18:19   ` Thomas Huth
2016-04-21  5:32   ` Alexey Kardashevskiy
2016-04-20  2:33 ` [Qemu-devel] [RFC for-2.7 04/11] pseries: Make spapr_create_fdt_skel() get information from machine state David Gibson
2016-04-21  5:32   ` Alexey Kardashevskiy
2016-04-26 17:41   ` Thomas Huth
2016-04-20  2:33 ` [Qemu-devel] [RFC for-2.7 05/11] pseries: Build device tree only at reset time David Gibson
2016-04-21  5:32   ` Alexey Kardashevskiy
2016-04-26 18:13   ` Thomas Huth
2016-04-27  6:07     ` David Gibson
2016-04-20  2:33 ` [Qemu-devel] [RFC for-2.7 06/11] pseries: Consolidate RTAS loading David Gibson
2016-04-21  5:32   ` Alexey Kardashevskiy
2016-04-27  9:12   ` Thomas Huth
2016-04-20  2:33 ` [Qemu-devel] [RFC for-2.7 07/11] pseries: Move adding of fdt reserve map entries David Gibson
2016-04-21  5:14   ` Alexey Kardashevskiy
2016-04-21  5:52     ` David Gibson
2016-04-21  6:03       ` Alexey Kardashevskiy
2016-04-22  4:22         ` David Gibson
2016-04-27  9:19   ` Thomas Huth
2016-04-20  2:33 ` [Qemu-devel] [RFC for-2.7 08/11] pseries: Start using qdt library for building device tree David Gibson
2016-04-21  4:04   ` Alexey Kardashevskiy [this message]
2016-04-27  6:13     ` David Gibson
2016-04-20  2:33 ` [Qemu-devel] [RFC for-2.7 09/11] pseries: Consolidate construction of /chosen device tree node David Gibson
2016-04-21  5:32   ` Alexey Kardashevskiy
2016-04-20  2:33 ` [Qemu-devel] [RFC for-2.7 10/11] pseries: Consolidate construction of /rtas " David Gibson
2016-04-21  5:32   ` Alexey Kardashevskiy
2016-04-20  2:33 ` [Qemu-devel] [RFC for-2.7 11/11] pseries: Remove unused callbacks from sPAPR VIO bus state David Gibson
2016-04-21  5:31   ` Alexey Kardashevskiy
2016-04-27  6:22     ` David Gibson

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=57185140.5030801@ozlabs.ru \
    --to=aik@ozlabs.ru \
    --cc=agraf@suse.de \
    --cc=crosthwaite.peter@gmail.com \
    --cc=david@gibson.dropbear.id.au \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-ppc@nongnu.org \
    /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;
as well as URLs for NNTP newsgroup(s).