[PATCH] hw/xen-pt: Rework mapping of MSI-X related page
Anthony PERARD <[email protected]> Fri, 31 Jul 2026 17:32:05 +0200
| Newsgroups | org.xenproject.lists.xen-devel,org.nongnu.qemu-devel |
|---|---|
| Message-ID | <1785511954.8631fc262581453bbf619ec5b2062170.19fb8ce47f6000e099@vates.tech> |
The mmap() call appears to only map the MSI-X entries but mmap will map full pages, make that evident with ROUND_UP(). pci_msix_read() will read past the current length given to mmap() as the memory region "xen-pci-pt-msix" is been given a whole page as size. Also adjust the munmap() call to use the same length as used in mmap(). And fix the pointer phys_iomem_base as it has been adjusted with table_offset_adjust after the mmap() call. Lastly, adjust the memory region "xen-pci-pt-msix" size with msix->table_offset_adjust in case the offset isn't 0, and use ROUND_UP instead of open coding it. Signed-off-by: Anthony PERARD <[email protected]> --- hw/xen/xen_pt_msi.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/hw/xen/xen_pt_msi.c b/hw/xen/xen_pt_msi.c index df15ccf0d030..f94f1adcd576 100644 --- a/hw/xen/xen_pt_msi.c +++ b/hw/xen/xen_pt_msi.c @@ -561,12 +561,6 @@ int xen_pt_msix_init(XenPCIPassthroughState *s, uint32_t base) msix->msix_entry[i].pirq = XEN_PT_UNASSIGNED_PIRQ; } - memory_region_init_io(&msix->mmio, OBJECT(s), &pci_msix_ops, - s, "xen-pci-pt-msix", - (total_entries * PCI_MSIX_ENTRY_SIZE - + XC_PAGE_SIZE - 1) - & XC_PAGE_MASK); - rc = xen_host_pci_get_long(hd, base + PCI_MSIX_TABLE, &table_off); if (rc) { XEN_PT_ERR(d, "Failed to read PCI_MSIX_TABLE field\n"); @@ -588,7 +582,9 @@ int xen_pt_msix_init(XenPCIPassthroughState *s, uint32_t base) msix->table_offset_adjust = table_off & 0x0fff; msix->phys_iomem_base = mmap(NULL, - total_entries * PCI_MSIX_ENTRY_SIZE + msix->table_offset_adjust, + ROUND_UP(total_entries * PCI_MSIX_ENTRY_SIZE + + msix->table_offset_adjust, + XC_PAGE_SIZE), PROT_READ, MAP_SHARED | MAP_LOCKED, fd, @@ -605,6 +601,13 @@ int xen_pt_msix_init(XenPCIPassthroughState *s, uint32_t base) XEN_PT_LOG(d, "mapping physical MSI-X table to %p\n", msix->phys_iomem_base); + memory_region_init_io(&msix->mmio, OBJECT(s), &pci_msix_ops, + s, "xen-pci-pt-msix", + ROUND_UP(total_entries * PCI_MSIX_ENTRY_SIZE + + msix->table_offset_adjust, + XC_PAGE_SIZE) + - msix->table_offset_adjust); + memory_region_add_subregion_overlap(&s->bar[bar_index], table_off, &msix->mmio, 2); /* Priority: pci default + 1 */ @@ -629,8 +632,10 @@ void xen_pt_msix_unmap(XenPCIPassthroughState *s) if (msix->phys_iomem_base) { XEN_PT_LOG(&s->dev, "unmapping physical MSI-X table from %p\n", msix->phys_iomem_base); - munmap(msix->phys_iomem_base, msix->total_entries * PCI_MSIX_ENTRY_SIZE - + msix->table_offset_adjust); + munmap(msix->phys_iomem_base - msix->table_offset_adjust, + ROUND_UP(msix->total_entries * PCI_MSIX_ENTRY_SIZE + + msix->table_offset_adjust, + XC_PAGE_SIZE)); } memory_region_del_subregion(&s->bar[msix->bar_index], &msix->mmio); -- Anthony Perard | Vates XCP-ng Developer XCP-ng & Xen Orchestra - Vates solutions web: https://vates.tech