All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Michael S. Tsirkin" <mst@redhat.com>
To: qemu-devel@nongnu.org
Cc: Peter Maydell <peter.maydell@linaro.org>,
	xen-devel@lists.xensource.com,
	Eduardo Habkost <ehabkost@redhat.com>,
	Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Subject: [Qemu-devel] [PULL v2 44/45] fix MSI injection on Xen
Date: Sat, 6 Feb 2016 21:15:13 +0200	[thread overview]
Message-ID: <1454784308-21177-45-git-send-email-mst@redhat.com> (raw)
In-Reply-To: <1454784308-21177-1-git-send-email-mst@redhat.com>

From: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

On Xen MSIs can be remapped into pirqs, which are a type of event
channels. It's mostly for the benefit of PCI passthrough devices, to
avoid the overhead of interacting with the emulated lapic.

However remapping interrupts and MSIs is also supported for emulated
devices, such as the e1000 and virtio-net.

When an interrupt or an MSI is remapped into a pirq, masking and
unmasking is done by masking and unmasking the event channel. The
masking bit on the PCI config space or MSI-X table should be ignored,
but it isn't at the moment.

As a consequence emulated devices which use MSI or MSI-X, such as
virtio-net, don't work properly (the guest doesn't receive any
notifications). The mechanism was working properly when xen_apic was
introduced, but I haven't narrowed down which commit in particular is
causing the regression.

Fix the issue by ignoring the masking bit for MSI and MSI-X which have
been remapped into pirqs.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 include/hw/xen/xen.h |  1 +
 hw/pci/msi.c         |  9 ++++++++-
 hw/pci/msix.c        | 12 ++++++++++--
 hw/xen/xen_pt_msi.c  |  4 +---
 xen-hvm-stub.c       |  5 +++++
 xen-hvm.c            |  9 +++++++++
 6 files changed, 34 insertions(+), 6 deletions(-)

diff --git a/include/hw/xen/xen.h b/include/hw/xen/xen.h
index 1b81b4b..c577354 100644
--- a/include/hw/xen/xen.h
+++ b/include/hw/xen/xen.h
@@ -33,6 +33,7 @@ int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num);
 void xen_piix3_set_irq(void *opaque, int irq_num, int level);
 void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len);
 void xen_hvm_inject_msi(uint64_t addr, uint32_t data);
+int xen_is_pirq_msi(uint32_t msi_data);
 
 qemu_irq *xen_interrupt_controller_init(void);
 
diff --git a/hw/pci/msi.c b/hw/pci/msi.c
index 8efa23d..85f21b8 100644
--- a/hw/pci/msi.c
+++ b/hw/pci/msi.c
@@ -20,6 +20,7 @@
 
 #include "qemu/osdep.h"
 #include "hw/pci/msi.h"
+#include "hw/xen/xen.h"
 #include "qemu/range.h"
 
 /* PCI_MSI_ADDRESS_LO */
@@ -254,13 +255,19 @@ void msi_reset(PCIDevice *dev)
 static bool msi_is_masked(const PCIDevice *dev, unsigned int vector)
 {
     uint16_t flags = pci_get_word(dev->config + msi_flags_off(dev));
-    uint32_t mask;
+    uint32_t mask, data;
+    bool msi64bit = flags & PCI_MSI_FLAGS_64BIT;
     assert(vector < PCI_MSI_VECTORS_MAX);
 
     if (!(flags & PCI_MSI_FLAGS_MASKBIT)) {
         return false;
     }
 
+    data = pci_get_word(dev->config + msi_data_off(dev, msi64bit));
+    if (xen_is_pirq_msi(data)) {
+        return false;
+    }
+
     mask = pci_get_long(dev->config +
                         msi_mask_off(dev, flags & PCI_MSI_FLAGS_64BIT));
     return mask & (1U << vector);
diff --git a/hw/pci/msix.c b/hw/pci/msix.c
index 4fea7ed..eb4ef11 100644
--- a/hw/pci/msix.c
+++ b/hw/pci/msix.c
@@ -19,6 +19,7 @@
 #include "hw/pci/msi.h"
 #include "hw/pci/msix.h"
 #include "hw/pci/pci.h"
+#include "hw/xen/xen.h"
 #include "qemu/range.h"
 
 #define MSIX_CAP_LENGTH 12
@@ -78,8 +79,15 @@ static void msix_clr_pending(PCIDevice *dev, int vector)
 
 static bool msix_vector_masked(PCIDevice *dev, unsigned int vector, bool fmask)
 {
-    unsigned offset = vector * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_VECTOR_CTRL;
-    return fmask || dev->msix_table[offset] & PCI_MSIX_ENTRY_CTRL_MASKBIT;
+    unsigned offset = vector * PCI_MSIX_ENTRY_SIZE;
+    uint32_t *data = (uint32_t *)&dev->msix_table[offset + PCI_MSIX_ENTRY_DATA];
+    /* MSIs on Xen can be remapped into pirqs. In those cases, masking
+     * and unmasking go through the PV evtchn path. */
+    if (xen_is_pirq_msi(*data)) {
+        return false;
+    }
+    return fmask || dev->msix_table[offset + PCI_MSIX_ENTRY_VECTOR_CTRL] &
+        PCI_MSIX_ENTRY_CTRL_MASKBIT;
 }
 
 bool msix_is_masked(PCIDevice *dev, unsigned int vector)
diff --git a/hw/xen/xen_pt_msi.c b/hw/xen/xen_pt_msi.c
index 5624685..9a16f2b 100644
--- a/hw/xen/xen_pt_msi.c
+++ b/hw/xen/xen_pt_msi.c
@@ -115,9 +115,7 @@ static int msi_msix_setup(XenPCIPassthroughState *s,
 
     assert((!is_msix && msix_entry == 0) || is_msix);
 
-    if (gvec == 0) {
-        /* if gvec is 0, the guest is asking for a particular pirq that
-         * is passed as dest_id */
+    if (xen_is_pirq_msi(data)) {
         *ppirq = msi_ext_dest_id(addr >> 32) | msi_dest_id(addr);
         if (!*ppirq) {
             /* this probably identifies an misconfiguration of the guest,
diff --git a/xen-hvm-stub.c b/xen-hvm-stub.c
index a6cb5d3..c500325 100644
--- a/xen-hvm-stub.c
+++ b/xen-hvm-stub.c
@@ -31,6 +31,11 @@ void xen_hvm_inject_msi(uint64_t addr, uint32_t data)
 {
 }
 
+int xen_is_pirq_msi(uint32_t msi_data)
+{
+    return 0;
+}
+
 void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, MemoryRegion *mr,
                    Error **errp)
 {
diff --git a/xen-hvm.c b/xen-hvm.c
index 1c9fb12..6861c51 100644
--- a/xen-hvm.c
+++ b/xen-hvm.c
@@ -13,6 +13,7 @@
 
 #include "hw/pci/pci.h"
 #include "hw/i386/pc.h"
+#include "hw/i386/apic-msidef.h"
 #include "hw/xen/xen_common.h"
 #include "hw/xen/xen_backend.h"
 #include "qmp-commands.h"
@@ -158,6 +159,14 @@ void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len)
     }
 }
 
+int xen_is_pirq_msi(uint32_t msi_data)
+{
+    /* If vector is 0, the msi is remapped into a pirq, passed as
+     * dest_id.
+     */
+    return ((msi_data & MSI_DATA_VECTOR_MASK) >> MSI_DATA_VECTOR_SHIFT) == 0;
+}
+
 void xen_hvm_inject_msi(uint64_t addr, uint32_t data)
 {
     xen_xc_hvm_inject_msi(xen_xc, xen_domid, addr, data);
-- 
MST

WARNING: multiple messages have this Message-ID (diff)
From: "Michael S. Tsirkin" <mst@redhat.com>
To: qemu-devel@nongnu.org
Cc: Peter Maydell <peter.maydell@linaro.org>,
	xen-devel@lists.xensource.com,
	Eduardo Habkost <ehabkost@redhat.com>,
	Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Subject: [PULL v2 44/45] fix MSI injection on Xen
Date: Sat, 6 Feb 2016 21:15:13 +0200	[thread overview]
Message-ID: <1454784308-21177-45-git-send-email-mst@redhat.com> (raw)
In-Reply-To: <1454784308-21177-1-git-send-email-mst@redhat.com>

From: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

On Xen MSIs can be remapped into pirqs, which are a type of event
channels. It's mostly for the benefit of PCI passthrough devices, to
avoid the overhead of interacting with the emulated lapic.

However remapping interrupts and MSIs is also supported for emulated
devices, such as the e1000 and virtio-net.

When an interrupt or an MSI is remapped into a pirq, masking and
unmasking is done by masking and unmasking the event channel. The
masking bit on the PCI config space or MSI-X table should be ignored,
but it isn't at the moment.

As a consequence emulated devices which use MSI or MSI-X, such as
virtio-net, don't work properly (the guest doesn't receive any
notifications). The mechanism was working properly when xen_apic was
introduced, but I haven't narrowed down which commit in particular is
causing the regression.

Fix the issue by ignoring the masking bit for MSI and MSI-X which have
been remapped into pirqs.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 include/hw/xen/xen.h |  1 +
 hw/pci/msi.c         |  9 ++++++++-
 hw/pci/msix.c        | 12 ++++++++++--
 hw/xen/xen_pt_msi.c  |  4 +---
 xen-hvm-stub.c       |  5 +++++
 xen-hvm.c            |  9 +++++++++
 6 files changed, 34 insertions(+), 6 deletions(-)

diff --git a/include/hw/xen/xen.h b/include/hw/xen/xen.h
index 1b81b4b..c577354 100644
--- a/include/hw/xen/xen.h
+++ b/include/hw/xen/xen.h
@@ -33,6 +33,7 @@ int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num);
 void xen_piix3_set_irq(void *opaque, int irq_num, int level);
 void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len);
 void xen_hvm_inject_msi(uint64_t addr, uint32_t data);
+int xen_is_pirq_msi(uint32_t msi_data);
 
 qemu_irq *xen_interrupt_controller_init(void);
 
diff --git a/hw/pci/msi.c b/hw/pci/msi.c
index 8efa23d..85f21b8 100644
--- a/hw/pci/msi.c
+++ b/hw/pci/msi.c
@@ -20,6 +20,7 @@
 
 #include "qemu/osdep.h"
 #include "hw/pci/msi.h"
+#include "hw/xen/xen.h"
 #include "qemu/range.h"
 
 /* PCI_MSI_ADDRESS_LO */
@@ -254,13 +255,19 @@ void msi_reset(PCIDevice *dev)
 static bool msi_is_masked(const PCIDevice *dev, unsigned int vector)
 {
     uint16_t flags = pci_get_word(dev->config + msi_flags_off(dev));
-    uint32_t mask;
+    uint32_t mask, data;
+    bool msi64bit = flags & PCI_MSI_FLAGS_64BIT;
     assert(vector < PCI_MSI_VECTORS_MAX);
 
     if (!(flags & PCI_MSI_FLAGS_MASKBIT)) {
         return false;
     }
 
+    data = pci_get_word(dev->config + msi_data_off(dev, msi64bit));
+    if (xen_is_pirq_msi(data)) {
+        return false;
+    }
+
     mask = pci_get_long(dev->config +
                         msi_mask_off(dev, flags & PCI_MSI_FLAGS_64BIT));
     return mask & (1U << vector);
diff --git a/hw/pci/msix.c b/hw/pci/msix.c
index 4fea7ed..eb4ef11 100644
--- a/hw/pci/msix.c
+++ b/hw/pci/msix.c
@@ -19,6 +19,7 @@
 #include "hw/pci/msi.h"
 #include "hw/pci/msix.h"
 #include "hw/pci/pci.h"
+#include "hw/xen/xen.h"
 #include "qemu/range.h"
 
 #define MSIX_CAP_LENGTH 12
@@ -78,8 +79,15 @@ static void msix_clr_pending(PCIDevice *dev, int vector)
 
 static bool msix_vector_masked(PCIDevice *dev, unsigned int vector, bool fmask)
 {
-    unsigned offset = vector * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_VECTOR_CTRL;
-    return fmask || dev->msix_table[offset] & PCI_MSIX_ENTRY_CTRL_MASKBIT;
+    unsigned offset = vector * PCI_MSIX_ENTRY_SIZE;
+    uint32_t *data = (uint32_t *)&dev->msix_table[offset + PCI_MSIX_ENTRY_DATA];
+    /* MSIs on Xen can be remapped into pirqs. In those cases, masking
+     * and unmasking go through the PV evtchn path. */
+    if (xen_is_pirq_msi(*data)) {
+        return false;
+    }
+    return fmask || dev->msix_table[offset + PCI_MSIX_ENTRY_VECTOR_CTRL] &
+        PCI_MSIX_ENTRY_CTRL_MASKBIT;
 }
 
 bool msix_is_masked(PCIDevice *dev, unsigned int vector)
diff --git a/hw/xen/xen_pt_msi.c b/hw/xen/xen_pt_msi.c
index 5624685..9a16f2b 100644
--- a/hw/xen/xen_pt_msi.c
+++ b/hw/xen/xen_pt_msi.c
@@ -115,9 +115,7 @@ static int msi_msix_setup(XenPCIPassthroughState *s,
 
     assert((!is_msix && msix_entry == 0) || is_msix);
 
-    if (gvec == 0) {
-        /* if gvec is 0, the guest is asking for a particular pirq that
-         * is passed as dest_id */
+    if (xen_is_pirq_msi(data)) {
         *ppirq = msi_ext_dest_id(addr >> 32) | msi_dest_id(addr);
         if (!*ppirq) {
             /* this probably identifies an misconfiguration of the guest,
diff --git a/xen-hvm-stub.c b/xen-hvm-stub.c
index a6cb5d3..c500325 100644
--- a/xen-hvm-stub.c
+++ b/xen-hvm-stub.c
@@ -31,6 +31,11 @@ void xen_hvm_inject_msi(uint64_t addr, uint32_t data)
 {
 }
 
+int xen_is_pirq_msi(uint32_t msi_data)
+{
+    return 0;
+}
+
 void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, MemoryRegion *mr,
                    Error **errp)
 {
diff --git a/xen-hvm.c b/xen-hvm.c
index 1c9fb12..6861c51 100644
--- a/xen-hvm.c
+++ b/xen-hvm.c
@@ -13,6 +13,7 @@
 
 #include "hw/pci/pci.h"
 #include "hw/i386/pc.h"
+#include "hw/i386/apic-msidef.h"
 #include "hw/xen/xen_common.h"
 #include "hw/xen/xen_backend.h"
 #include "qmp-commands.h"
@@ -158,6 +159,14 @@ void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len)
     }
 }
 
+int xen_is_pirq_msi(uint32_t msi_data)
+{
+    /* If vector is 0, the msi is remapped into a pirq, passed as
+     * dest_id.
+     */
+    return ((msi_data & MSI_DATA_VECTOR_MASK) >> MSI_DATA_VECTOR_SHIFT) == 0;
+}
+
 void xen_hvm_inject_msi(uint64_t addr, uint32_t data)
 {
     xen_xc_hvm_inject_msi(xen_xc, xen_domid, addr, data);
-- 
MST

  parent reply	other threads:[~2016-02-06 19:15 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-02-06 19:12 [Qemu-devel] [PULL v2 00/45] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
2016-02-06 19:12 ` [Qemu-devel] [PULL v2 01/45] Fix virtio migration Michael S. Tsirkin
2016-02-06 19:12 ` [Qemu-devel] [PULL v2 02/45] pc: acpi: merge SSDT into DSDT Michael S. Tsirkin
2016-02-06 19:12 ` [Qemu-devel] [PULL v2 03/45] tests: pc: acpi: drop not needed 'expected SSDT' blobs Michael S. Tsirkin
2016-02-06 19:12 ` [Qemu-devel] [PULL v2 04/45] tests: pc: acpi: add expected DSDT.bridge blobs and update DSDT blobs Michael S. Tsirkin
2016-02-06 19:12 ` [Qemu-devel] [PULL v2 05/45] virtio: move VirtQueueElement at the beginning of the structs Michael S. Tsirkin
2016-02-06 19:12 ` [Qemu-devel] [PULL v2 06/45] virtio: move allocation to virtqueue_pop/vring_pop Michael S. Tsirkin
2016-02-06 19:12 ` [Qemu-devel] [PULL v2 07/45] virtio: introduce qemu_get/put_virtqueue_element Michael S. Tsirkin
2016-02-06 19:12 ` [Qemu-devel] [PULL v2 08/45] virtio: introduce virtqueue_alloc_element Michael S. Tsirkin
2016-02-06 19:12 ` [Qemu-devel] [PULL v2 09/45] virtio: slim down allocation of VirtQueueElements Michael S. Tsirkin
2016-02-06 19:12 ` [Qemu-devel] [PULL v2 10/45] vring: " Michael S. Tsirkin
2016-02-06 19:12 ` [Qemu-devel] [PULL v2 11/45] virtio: combine the read of a descriptor Michael S. Tsirkin
2016-02-06 19:12 ` [Qemu-devel] [PULL v2 12/45] virtio: cache used_idx in a VirtQueue field Michael S. Tsirkin
2016-02-06 19:13 ` [Qemu-devel] [PULL v2 13/45] virtio: read avail_idx from VQ only when necessary Michael S. Tsirkin
2016-02-06 19:13 ` [Qemu-devel] [PULL v2 14/45] virtio: combine write of an entry into used ring Michael S. Tsirkin
2016-02-06 19:13 ` [Qemu-devel] [PULL v2 15/45] hw/pxb: add pxb devices to the bridge category Michael S. Tsirkin
2016-02-06 19:13 ` [Qemu-devel] [PULL v2 16/45] vhost-user-test: use correct ROM to speed up and avoid spurious failures Michael S. Tsirkin
2016-02-06 19:13 ` [Qemu-devel] [PULL v2 17/45] hw/pci: ensure that only PCI/PCIe bridges can be attached to pxb/pxb-pcie devices Michael S. Tsirkin
2016-02-06 19:13 ` [Qemu-devel] [PULL v2 18/45] ipmi: replace goto by a return statement Michael S. Tsirkin
2016-02-06 19:13 ` [Qemu-devel] [PULL v2 19/45] ipmi: replace *_MAXCMD defines Michael S. Tsirkin
2016-02-06 19:13 ` [Qemu-devel] [PULL v2 20/45] ipmi: cleanup error_report messages Michael S. Tsirkin
2016-02-06 19:13 ` [Qemu-devel] [PULL v2 21/45] ipmi: fix SDR length value Michael S. Tsirkin
2016-02-06 19:13 ` [Qemu-devel] [PULL v2 22/45] ipmi: introduce a struct ipmi_sdr_compact Michael S. Tsirkin
2016-02-16  7:45   ` Paolo Bonzini
2016-02-16  8:11     ` Cédric Le Goater
2016-02-06 19:13 ` [Qemu-devel] [PULL v2 23/45] ipmi: add get and set SENSOR_TYPE commands Michael S. Tsirkin
2016-02-06 19:13 ` [Qemu-devel] [PULL v2 24/45] ipmi: add GET_SYS_RESTART_CAUSE chassis command Michael S. Tsirkin
2016-02-06 19:13 ` [Qemu-devel] [PULL v2 25/45] ipmi: add ACPI power and GUID commands Michael S. Tsirkin
2016-02-06 19:13 ` [Qemu-devel] [PULL v2 26/45] pc: Move PcGuestInfo declaration to top of file Michael S. Tsirkin
2016-02-06 19:13 ` [Qemu-devel] [PULL v2 27/45] pc: Eliminate struct PcGuestInfoState Michael S. Tsirkin
2016-02-06 19:13 ` [Qemu-devel] [PULL v2 28/45] pc: Simplify pc_memory_init() signature Michael S. Tsirkin
2016-02-06 19:14 ` [Qemu-devel] [PULL v2 29/45] pc: Simplify xen_load_linux() signature Michael S. Tsirkin
2016-02-06 19:14 ` [Qemu-devel] [PULL v2 30/45] acpi: Remove guest_info parameters from functions Michael S. Tsirkin
2016-02-06 19:14 ` [Qemu-devel] [PULL v2 31/45] acpi: Don't save PcGuestInfo on AcpiBuildState Michael S. Tsirkin
2016-02-06 19:14 ` [Qemu-devel] [PULL v2 32/45] pc: Remove compat fields from PcGuestInfo Michael S. Tsirkin
2016-02-06 19:14 ` [Qemu-devel] [PULL v2 33/45] pc: Remove RAM size " Michael S. Tsirkin
2016-02-06 19:14 ` [Qemu-devel] [PULL v2 34/45] pc: Remove PcGuestInfo.isapc_ram_fw field Michael S. Tsirkin
2016-02-06 19:14 ` [Qemu-devel] [PULL v2 35/45] pc: Move PcGuestInfo.fw_cfg to PCMachineState Michael S. Tsirkin
2016-02-06 19:14 ` [Qemu-devel] [PULL v2 36/45] pc: Move APIC and NUMA data from PcGuestInfo " Michael S. Tsirkin
2016-02-06 19:14 ` [Qemu-devel] [PULL v2 37/45] pc: Eliminate PcGuestInfo struct Michael S. Tsirkin
2016-02-06 19:14 ` [Qemu-devel] [PULL v2 38/45] acpi: take oem_id in build_header(), optionally Michael S. Tsirkin
2016-02-06 19:14 ` [Qemu-devel] [PULL v2 39/45] acpi: expose oem_id and oem_table_id in build_rsdt() Michael S. Tsirkin
2016-02-06 19:14 ` [Qemu-devel] [PULL v2 40/45] acpi: add function to extract oem_id and oem_table_id from the user's SLIC Michael S. Tsirkin
2016-02-06 19:14 ` [Qemu-devel] [PULL v2 41/45] pc: set the OEM fields in the RSDT and the FADT from the SLIC Michael S. Tsirkin
2016-02-06 19:15 ` [Qemu-devel] [PULL v2 42/45] dimm: Correct type of MemoryHotplugState->base Michael S. Tsirkin
2016-02-06 19:15 ` [Qemu-devel] [PULL v2 43/45] intel_iommu: large page support Michael S. Tsirkin
2016-02-06 19:15 ` Michael S. Tsirkin [this message]
2016-02-06 19:15   ` [PULL v2 44/45] fix MSI injection on Xen Michael S. Tsirkin
2016-02-12 21:55   ` [Qemu-devel] " Daniel P. Berrange
2016-02-12 21:55     ` Daniel P. Berrange
2016-02-06 19:15 ` [Qemu-devel] [PULL v2 45/45] net: set endianness on all backend devices Michael S. Tsirkin
2016-02-08 12:32 ` [Qemu-devel] [PULL v2 00/45] pc and misc cleanups and fixes, virtio optimizations Peter Maydell

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=1454784308-21177-45-git-send-email-mst@redhat.com \
    --to=mst@redhat.com \
    --cc=ehabkost@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=stefano.stabellini@eu.citrix.com \
    --cc=xen-devel@lists.xensource.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.