aboutsummaryrefslogtreecommitdiff
path: root/hw/pci
diff options
context:
space:
mode:
Diffstat (limited to 'hw/pci')
-rw-r--r--hw/pci/msi.c9
-rw-r--r--hw/pci/msix.c12
2 files changed, 18 insertions, 3 deletions
diff --git a/hw/pci/msi.c b/hw/pci/msi.c
index 8efa23d376..85f21b8c4b 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 4fea7edc89..eb4ef113d1 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)