aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2017-09-21 10:18:02 +0100
committerPeter Maydell <peter.maydell@linaro.org>2017-09-21 10:18:02 +0100
commit211ad3b412fe1b8edcb7db0bb97e766a39b2be14 (patch)
tree7d7d312ebc27ee49c12cc0411ac22e4034c74db4
parentb62b7ed0fc9c58e373b8946c9bd2e193be98dae6 (diff)
parenta8036336609d2e184fc3543a4c439c0ba7d7f3a2 (diff)
Merge remote-tracking branch 'remotes/sstabellini/tags/xen-20170920-tag' into staging
Xen 2017/09/20 # gpg: Signature made Thu 21 Sep 2017 03:20:02 BST # gpg: using RSA key 0x894F8F4870E1AE90 # gpg: Good signature from "Stefano Stabellini <stefano.stabellini@eu.citrix.com>" # gpg: aka "Stefano Stabellini <sstabellini@kernel.org>" # Primary key fingerprint: D04E 33AB A51F 67BA 07D3 0AEA 894F 8F48 70E1 AE90 * remotes/sstabellini/tags/xen-20170920-tag: xen/pt: allow QEMU to request MSI unmasking at bind time xen-disk: use g_new0 to fix build Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--hw/block/xen_disk.c2
-rw-r--r--hw/xen/xen_pt.h1
-rw-r--r--hw/xen/xen_pt_config_init.c20
-rw-r--r--hw/xen/xen_pt_msi.c13
4 files changed, 30 insertions, 6 deletions
diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c
index d42ed7070d..536e2ee735 100644
--- a/hw/block/xen_disk.c
+++ b/hw/block/xen_disk.c
@@ -1232,7 +1232,7 @@ static int blk_connect(struct XenDevice *xendev)
return -1;
}
- domids = g_malloc0_n(blkdev->nr_ring_ref, sizeof(uint32_t));
+ domids = g_new0(uint32_t, blkdev->nr_ring_ref);
for (i = 0; i < blkdev->nr_ring_ref; i++) {
domids[i] = blkdev->xendev.dom;
}
diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h
index 191d9caea1..aa39a9aa5f 100644
--- a/hw/xen/xen_pt.h
+++ b/hw/xen/xen_pt.h
@@ -180,6 +180,7 @@ typedef struct XenPTMSI {
uint32_t addr_hi; /* guest message upper address */
uint16_t data; /* guest message data */
uint32_t ctrl_offset; /* saved control offset */
+ uint32_t mask; /* guest mask bits */
int pirq; /* guest pirq corresponding */
bool initialized; /* when guest MSI is initialized */
bool mapped; /* when pirq is mapped */
diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c
index 1f04ec5eec..a3ce33e78b 100644
--- a/hw/xen/xen_pt_config_init.c
+++ b/hw/xen/xen_pt_config_init.c
@@ -1315,6 +1315,22 @@ static int xen_pt_msgdata_reg_write(XenPCIPassthroughState *s,
return 0;
}
+static int xen_pt_mask_reg_write(XenPCIPassthroughState *s, XenPTReg *cfg_entry,
+ uint32_t *val, uint32_t dev_value,
+ uint32_t valid_mask)
+{
+ int rc;
+
+ rc = xen_pt_long_reg_write(s, cfg_entry, val, dev_value, valid_mask);
+ if (rc) {
+ return rc;
+ }
+
+ s->msi->mask = *val;
+
+ return 0;
+}
+
/* MSI Capability Structure reg static information table */
static XenPTRegInfo xen_pt_emu_reg_msi[] = {
/* Next Pointer reg */
@@ -1393,7 +1409,7 @@ static XenPTRegInfo xen_pt_emu_reg_msi[] = {
.emu_mask = 0xFFFFFFFF,
.init = xen_pt_mask_reg_init,
.u.dw.read = xen_pt_long_reg_read,
- .u.dw.write = xen_pt_long_reg_write,
+ .u.dw.write = xen_pt_mask_reg_write,
},
/* Mask reg (if PCI_MSI_FLAGS_MASKBIT set, for 64-bit devices) */
{
@@ -1404,7 +1420,7 @@ static XenPTRegInfo xen_pt_emu_reg_msi[] = {
.emu_mask = 0xFFFFFFFF,
.init = xen_pt_mask_reg_init,
.u.dw.read = xen_pt_long_reg_read,
- .u.dw.write = xen_pt_long_reg_write,
+ .u.dw.write = xen_pt_mask_reg_write,
},
/* Pending reg (if PCI_MSI_FLAGS_MASKBIT set, for 32-bit devices) */
{
diff --git a/hw/xen/xen_pt_msi.c b/hw/xen/xen_pt_msi.c
index ff9a79f5d2..6d1e3bdeb4 100644
--- a/hw/xen/xen_pt_msi.c
+++ b/hw/xen/xen_pt_msi.c
@@ -24,6 +24,7 @@
#define XEN_PT_GFLAGS_SHIFT_DM 9
#define XEN_PT_GFLAGSSHIFT_DELIV_MODE 12
#define XEN_PT_GFLAGSSHIFT_TRG_MODE 15
+#define XEN_PT_GFLAGSSHIFT_UNMASKED 16
#define latch(fld) latch[PCI_MSIX_ENTRY_##fld / sizeof(uint32_t)]
@@ -155,7 +156,8 @@ static int msi_msix_update(XenPCIPassthroughState *s,
int pirq,
bool is_msix,
int msix_entry,
- int *old_pirq)
+ int *old_pirq,
+ bool masked)
{
PCIDevice *d = &s->dev;
uint8_t gvec = msi_vector(data);
@@ -171,6 +173,8 @@ static int msi_msix_update(XenPCIPassthroughState *s,
table_addr = s->msix->mmio_base_addr;
}
+ gflags |= masked ? 0 : (1u << XEN_PT_GFLAGSSHIFT_UNMASKED);
+
rc = xc_domain_update_msi_irq(xen_xc, xen_domid, gvec,
pirq, gflags, table_addr);
@@ -273,8 +277,10 @@ int xen_pt_msi_setup(XenPCIPassthroughState *s)
int xen_pt_msi_update(XenPCIPassthroughState *s)
{
XenPTMSI *msi = s->msi;
+
+ /* Current MSI emulation in QEMU only supports 1 vector */
return msi_msix_update(s, msi_addr64(msi), msi->data, msi->pirq,
- false, 0, &msi->pirq);
+ false, 0, &msi->pirq, msi->mask & 1);
}
void xen_pt_msi_disable(XenPCIPassthroughState *s)
@@ -355,7 +361,8 @@ static int xen_pt_msix_update_one(XenPCIPassthroughState *s, int entry_nr,
}
rc = msi_msix_update(s, entry->addr, entry->data, pirq, true,
- entry_nr, &entry->pirq);
+ entry_nr, &entry->pirq,
+ vec_ctrl & PCI_MSIX_ENTRY_CTRL_MASKBIT);
if (!rc) {
entry->updated = false;