aboutsummaryrefslogtreecommitdiff
path: root/xen-hvm.c
diff options
context:
space:
mode:
authorStefano Stabellini <stefano.stabellini@eu.citrix.com>2016-01-13 14:59:09 +0000
committerMichael S. Tsirkin <mst@redhat.com>2016-02-06 20:44:10 +0200
commit428c3ece97179557f2753071fb0ca97a03437267 (patch)
tree6aa26f91ad4b268c0d51e8b3819bb4381a446fda /xen-hvm.c
parentd66b969b0d9c8eefdcbff4b48535b0fe1501d139 (diff)
fix MSI injection on Xen
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>
Diffstat (limited to 'xen-hvm.c')
-rw-r--r--xen-hvm.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/xen-hvm.c b/xen-hvm.c
index 1c9fb12955..6861c51ef9 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);