aboutsummaryrefslogtreecommitdiff
path: root/hw/pci/msix.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2015-05-11 16:21:50 +0100
committerPeter Maydell <peter.maydell@linaro.org>2015-05-11 16:25:33 +0100
commit0403b0f539f40a21da60409b825b4653b273ab39 (patch)
treeef1edb203dc4595528c0f86c502df3a8d2931a2b /hw/pci/msix.c
parent266745cacb848d7cd0ae8889ae262e8718ace4d4 (diff)
parentbc1f7c4c915a7c727741c4d27a2795e1039eacd3 (diff)
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
pc, virtio enhancements Memory hot-unplug support for pc, MSI-X mapping update speedup for virtio-pci, misc refactorings and bugfixes. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> # gpg: Signature made Mon May 11 08:23:43 2015 BST using RSA key ID D28D5469 # gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>" # gpg: aka "Michael S. Tsirkin <mst@redhat.com>" * remotes/mst/tags/for_upstream: (28 commits) acpi: update expected files for memory unplug virtio-scsi: Move DEFINE_VIRTIO_SCSI_FEATURES to virtio-scsi virtio-net: Move DEFINE_VIRTIO_NET_FEATURES to virtio-net pci: Merge pci_nic_init() into pci_nic_init_nofail() acpi: add a missing backslash to the \_SB scope. qmp-event: add event notification for memory hot unplug error acpi: add hardware implementation for memory hot unplug acpi: fix "Memory device control fields" register acpi: extend aml_field() to support UpdateRule acpi, mem-hotplug: add unplug cb for memory device acpi, mem-hotplug: add unplug request cb for memory device acpi, mem-hotplug: add acpi_memory_slot_status() to get MemStatus docs: update documentation for memory hot unplug virtio: coding style tweak pci: remove hard-coded bar size in msix_init_exclusive_bar() virtio-pci: speedup MSI-X masking and unmasking virtio: introduce vector to virtqueues mapping virtio-ccw: using VIRTIO_NO_VECTOR instead of 0 for invalid virtqueue monitor: check return value of qemu_find_net_clients_except() monitor: replace the magic number 255 with MAX_QUEUE_NUM ... Conflicts: hw/s390x/s390-virtio-bus.c [PMM: fixed conflict in s390_virtio_scsi_properties and s390_virtio_net_properties arrays; since the result of the two conflicting patches is to empty the property arrays completely, the conflict resolution is to remove them entirely.] Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/pci/msix.c')
-rw-r--r--hw/pci/msix.c30
1 files changed, 19 insertions, 11 deletions
diff --git a/hw/pci/msix.c b/hw/pci/msix.c
index 031eaabca9..9935f98ae5 100644
--- a/hw/pci/msix.c
+++ b/hw/pci/msix.c
@@ -295,29 +295,37 @@ int msix_init_exclusive_bar(PCIDevice *dev, unsigned short nentries,
{
int ret;
char *name;
+ uint32_t bar_size = 4096;
+ uint32_t bar_pba_offset = bar_size / 2;
+ uint32_t bar_pba_size = (nentries / 8 + 1) * 8;
/*
* Migration compatibility dictates that this remains a 4k
* BAR with the vector table in the lower half and PBA in
- * the upper half. Do not use these elsewhere!
+ * the upper half for nentries which is lower or equal to 128.
+ * No need to care about using more than 65 entries for legacy
+ * machine types who has at most 64 queues.
*/
-#define MSIX_EXCLUSIVE_BAR_SIZE 4096
-#define MSIX_EXCLUSIVE_BAR_TABLE_OFFSET 0
-#define MSIX_EXCLUSIVE_BAR_PBA_OFFSET (MSIX_EXCLUSIVE_BAR_SIZE / 2)
-#define MSIX_EXCLUSIVE_CAP_OFFSET 0
+ if (nentries * PCI_MSIX_ENTRY_SIZE > bar_pba_offset) {
+ bar_pba_offset = nentries * PCI_MSIX_ENTRY_SIZE;
+ }
- if (nentries * PCI_MSIX_ENTRY_SIZE > MSIX_EXCLUSIVE_BAR_PBA_OFFSET) {
- return -EINVAL;
+ if (bar_pba_offset + bar_pba_size > 4096) {
+ bar_size = bar_pba_offset + bar_pba_size;
+ }
+
+ if (bar_size & (bar_size - 1)) {
+ bar_size = 1 << qemu_fls(bar_size);
}
name = g_strdup_printf("%s-msix", dev->name);
- memory_region_init(&dev->msix_exclusive_bar, OBJECT(dev), name, MSIX_EXCLUSIVE_BAR_SIZE);
+ memory_region_init(&dev->msix_exclusive_bar, OBJECT(dev), name, bar_size);
g_free(name);
ret = msix_init(dev, nentries, &dev->msix_exclusive_bar, bar_nr,
- MSIX_EXCLUSIVE_BAR_TABLE_OFFSET, &dev->msix_exclusive_bar,
- bar_nr, MSIX_EXCLUSIVE_BAR_PBA_OFFSET,
- MSIX_EXCLUSIVE_CAP_OFFSET);
+ 0, &dev->msix_exclusive_bar,
+ bar_nr, bar_pba_offset,
+ 0);
if (ret) {
return ret;
}