From: Gonglei <arei.gong...@huawei.com> QEMU only mmap MSIX_PAGE_SIZE memory for all pci devices in assigned_dev_register_msix_mmio(), meanwhile the set the one page memmory to zero, so the rest memory will be random value (maybe etnry.data is not 0). In the assigned_dev_update_msix_mmio() maybe occur the issue of entry_nr > 256, and the kmod reports the EINVAL error.
Signed-off-by: Gonglei <arei.gong...@huawei.com> --- hw/i386/kvm/pci-assign.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/hw/i386/kvm/pci-assign.c b/hw/i386/kvm/pci-assign.c index 570333f..d25a19e 100644 --- a/hw/i386/kvm/pci-assign.c +++ b/hw/i386/kvm/pci-assign.c @@ -37,6 +37,7 @@ #include "hw/pci/pci.h" #include "hw/pci/msi.h" #include "kvm_i386.h" +#include "qemu/osdep.h" #define MSIX_PAGE_SIZE 0x1000 @@ -59,6 +60,9 @@ #define DEBUG(fmt, ...) #endif +/* the msix-table size readed from pci device config */ +static int msix_table_size; + typedef struct PCIRegion { int type; /* Memory or port I/O */ int valid; @@ -1604,7 +1608,12 @@ static void assigned_dev_msix_reset(AssignedDevice *dev) static int assigned_dev_register_msix_mmio(AssignedDevice *dev) { - dev->msix_table = mmap(NULL, MSIX_PAGE_SIZE, PROT_READ|PROT_WRITE, + msix_table_size = ROUND_UP(dev->msix_max * sizeof(struct MSIXTableEntry), + MSIX_PAGE_SIZE); + + DEBUG("msix_table_size: 0x%x\n", msix_table_size); + + dev->msix_table = mmap(NULL, msix_table_size, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, 0, 0); if (dev->msix_table == MAP_FAILED) { error_report("fail allocate msix_table! %s", strerror(errno)); @@ -1615,7 +1624,7 @@ static int assigned_dev_register_msix_mmio(AssignedDevice *dev) assigned_dev_msix_reset(dev); memory_region_init_io(&dev->mmio, OBJECT(dev), &assigned_dev_msix_mmio_ops, - dev, "assigned-dev-msix", MSIX_PAGE_SIZE); + dev, "assigned-dev-msix", msix_table_size); return 0; } @@ -1627,7 +1636,7 @@ static void assigned_dev_unregister_msix_mmio(AssignedDevice *dev) memory_region_destroy(&dev->mmio); - if (munmap(dev->msix_table, MSIX_PAGE_SIZE) == -1) { + if (munmap(dev->msix_table, msix_table_size) == -1) { error_report("error unmapping msix_table! %s", strerror(errno)); } dev->msix_table = NULL; -- 1.7.12.4