I see the following attached code in your patch. It is pointless to check msi->table_base against the value read from physical device if this function is a virtual function of SR-IOV device. VFs are required to have BARs zeroed by specifications. And for VFs, unless you can read these values from corresponding PF, you will have to trust the "table_base" passed from dom0 via hypercall. Actually, this parameter is specifically introduced for enabling SR-IOV.
I am not familiar with this patch and hence its story. But I think it would be very simple for you to fix this up?
BTW: I vaguely recall that MSI-X table base might not be the first page of the corresponding BAR register.
+ if ( !dev->msix_nr_entries )
+ {
+ u64 pba_paddr;
+ u32 pba_offset;
+
+ ASSERT(!dev->msix_used_entries);
+ WARN_ON(msi->table_base != read_pci_mem_bar(bus, slot, func, bir));
+
+ dev->msix_nr_entries = nr_entries;
+ dev->msix_table.first = PFN_DOWN(table_paddr);
+ dev->msix_table.last = PFN_DOWN(table_paddr +
+ nr_entries * PCI_MSIX_ENTRY_SIZE - 1);
+ WARN_ON(rangeset_overlaps_range(mmio_ro_ranges, dev->msix_table.first,
+ dev->msix_table.last));
+
+ pba_offset = pci_conf_read32(bus, slot, func,
+ msix_pba_offset_reg(pos));
+ bir = (u8)(pba_offset & PCI_MSIX_BIRMASK);
+ pba_paddr = read_pci_mem_bar(bus, slot, func, bir);
+ WARN_ON(!pba_paddr);
+ pba_paddr += pba_offset & ~PCI_MSIX_BIRMASK;
+
+ dev->msix_pba.first = PFN_DOWN(pba_paddr);
+ dev->msix_pba.last = PFN_DOWN(pba_paddr +
+ BITS_TO_LONGS(nr_entries) - 1);
+ WARN_ON(rangeset_overlaps_range(mmio_ro_ranges, dev->msix_pba.first,
+ dev->msix_pba.last));
+
+ if ( rangeset_add_range(mmio_ro_ranges, dev->msix_table.first,
+ dev->msix_table.last) )
+ WARN();
+ if ( rangeset_add_range(mmio_ro_ranges, dev->msix_pba.first,
+ dev->msix_pba.last) )
+ WARN();
+
+ if ( dev->domain )
+ p2m_change_entry_type_global(p2m_get_hostp2m(dev->domain),
+ p2m_mmio_direct, p2m_mmio_direct);
+ if ( !dev->domain || !paging_mode_translate(dev->domain) )
+ {
+ struct domain *d = dev->domain;