diff options
author | Michael S. Tsirkin <mst@redhat.com> | 2011-12-05 21:48:43 +0200 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2012-04-11 13:24:59 +0300 |
commit | 4490c71191b59dce2dd88f5f9ab49f2c92ab410c (patch) | |
tree | ae77269b55fbcd12c83b9ba4f3d83c19ca292794 /hw/ivshmem.c | |
parent | fbbaf9ae88286f18b2ab32fb4174ebdbdc1d5919 (diff) |
ivshmem: add missing msix calls
ivshmem used msix but didn't call it on either reset or
config write paths. This used to partically work since
guests don't use all of msi-x configuration fields,
and reset is rarely used, but the patch 'msix: track function masked
in pci device state' broke that. Fix by adding appropriate calls.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reported-by: Cam Macdonell <cam@cs.ualberta.ca>
Tested-by: Cam Macdonell <cam@cs.ualberta.ca>
Diffstat (limited to 'hw/ivshmem.c')
-rw-r--r-- | hw/ivshmem.c | 48 |
1 files changed, 33 insertions, 15 deletions
diff --git a/hw/ivshmem.c b/hw/ivshmem.c index b80aa8f1de..c2bdd926c5 100644 --- a/hw/ivshmem.c +++ b/hw/ivshmem.c @@ -509,11 +509,29 @@ static void ivshmem_read(void *opaque, const uint8_t * buf, int flags) return; } +/* Select the MSI-X vectors used by device. + * ivshmem maps events to vectors statically, so + * we just enable all vectors on init and after reset. */ +static void ivshmem_use_msix(IVShmemState * s) +{ + int i; + + if (!msix_present(&s->dev)) { + return; + } + + for (i = 0; i < s->vectors; i++) { + msix_vector_use(&s->dev, i); + } +} + static void ivshmem_reset(DeviceState *d) { IVShmemState *s = DO_UPCAST(IVShmemState, dev.qdev, d); s->intrstatus = 0; + msix_reset(&s->dev); + ivshmem_use_msix(s); return; } @@ -544,12 +562,8 @@ static uint64_t ivshmem_get_size(IVShmemState * s) { return value; } -static void ivshmem_setup_msi(IVShmemState * s) { - - int i; - - /* allocate the MSI-X vectors */ - +static void ivshmem_setup_msi(IVShmemState * s) +{ memory_region_init(&s->msix_bar, "ivshmem-msix", 4096); if (!msix_init(&s->dev, s->vectors, &s->msix_bar, 1, 0)) { pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, @@ -560,13 +574,10 @@ static void ivshmem_setup_msi(IVShmemState * s) { exit(1); } - /* 'activate' the vectors */ - for (i = 0; i < s->vectors; i++) { - msix_vector_use(&s->dev, i); - } - /* allocate QEMU char devices for receiving interrupts */ s->eventfd_table = g_malloc0(s->vectors * sizeof(EventfdEntry)); + + ivshmem_use_msix(s); } static void ivshmem_save(QEMUFile* f, void *opaque) @@ -590,7 +601,7 @@ static int ivshmem_load(QEMUFile* f, void *opaque, int version_id) IVSHMEM_DPRINTF("ivshmem_load\n"); IVShmemState *proxy = opaque; - int ret, i; + int ret; if (version_id > 0) { return -EINVAL; @@ -608,9 +619,7 @@ static int ivshmem_load(QEMUFile* f, void *opaque, int version_id) if (ivshmem_has_feature(proxy, IVSHMEM_MSI)) { msix_load(&proxy->dev, f); - for (i = 0; i < proxy->vectors; i++) { - msix_vector_use(&proxy->dev, i); - } + ivshmem_use_msix(proxy); } else { proxy->intrstatus = qemu_get_be32(f); proxy->intrmask = qemu_get_be32(f); @@ -619,6 +628,13 @@ static int ivshmem_load(QEMUFile* f, void *opaque, int version_id) return 0; } +static void ivshmem_write_config(PCIDevice *pci_dev, uint32_t address, + uint32_t val, int len) +{ + pci_default_write_config(pci_dev, address, val, len); + msix_write_config(pci_dev, address, val, len); +} + static int pci_ivshmem_init(PCIDevice *dev) { IVShmemState *s = DO_UPCAST(IVShmemState, dev, dev); @@ -744,6 +760,8 @@ static int pci_ivshmem_init(PCIDevice *dev) } + s->dev.config_write = ivshmem_write_config; + return 0; } |