int xen_pt_msix_init(XenPCIPassthroughState *s, uint32_t base)

{

    uint8_t id = 0;

    uint16_t control = 0;

    uint32_t table_off = 0;

    int i, total_entries, bar_index;

    XenHostPCIDevice *hd = &s->real_device;

    PCIDevice *d = &s->dev;

    int fd = -1;

    XenPTMSIX *msix = NULL;

    int rc = 0;



    rc = xen_host_pci_get_byte(hd, base + PCI_CAP_LIST_ID, &id);

    if (rc) {

        return rc;

    }



    if (id != PCI_CAP_ID_MSIX) {

        XEN_PT_ERR(d, "Invalid id %#x base %#x\n", id, base);

        return -1;

    }



    xen_host_pci_get_word(hd, base + PCI_MSIX_FLAGS, &control);

    total_entries = control & PCI_MSIX_FLAGS_QSIZE;

    total_entries += 1;



    s->msix = g_malloc0(sizeof (XenPTMSIX)

                        + total_entries * sizeof (XenPTMSIXEntry));

    msix = s->msix;



    msix->total_entries = total_entries;

    for (i = 0; i < total_entries; i++) {

        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);



    xen_host_pci_get_long(hd, base + PCI_MSIX_TABLE, &table_off);

    bar_index = msix->bar_index = table_off & PCI_MSIX_FLAGS_BIRMASK;

    table_off = table_off & ~PCI_MSIX_FLAGS_BIRMASK;

    msix->table_base = s->real_device.io_regions[bar_index].base_addr;

    XEN_PT_LOG(d, "get MSI-X table BAR base 0x%"PRIx64"\n", msix->table_base);



    fd = open("/dev/mem", O_RDWR);

    if (fd == -1) {

        rc = -errno;

        XEN_PT_ERR(d, "Can't open /dev/mem: %s\n", strerror(errno));

        goto error_out;

    }

    XEN_PT_LOG(d, "table_off = %#x, total_entries = %d\n",

               table_off, total_entries);

    msix->table_offset_adjust = table_off & 0x0fff;

    msix->phys_iomem_base =

        mmap(NULL,

             total_entries * PCI_MSIX_ENTRY_SIZE + msix->table_offset_adjust,

             PROT_READ,

             MAP_SHARED | MAP_LOCKED,

             fd,

             msix->table_base + table_off - msix->table_offset_adjust);

    close(fd);

    if (msix->phys_iomem_base == MAP_FAILED) {

        rc = -errno;

        XEN_PT_ERR(d, "Can't map physical MSI-X table: %s\n", strerror(errno));

        goto error_out;

    }

    msix->phys_iomem_base = (char *)msix->phys_iomem_base

        + msix->table_offset_adjust;



    XEN_PT_LOG(d, "mapping physical MSI-X table to %p\n",

               msix->phys_iomem_base);



    memory_region_add_subregion_overlap(&s->bar[bar_index], table_off,

                                        &msix->mmio,

                                        2); /* Priority: pci default + 1 */



    return 0;



error_out:

    g_free(s->msix);

    s->msix = NULL;

    return rc;

}

int xen_pt_msix_init(XenPCIPassthroughState *s, uint32_t base)

{

    uint8_t id = 0;

    uint16_t control = 0;

    uint32_t table_off = 0;

    int i, total_entries, bar_index;

    XenHostPCIDevice *hd = &s->real_device;

    PCIDevice *d = &s->dev;

    int fd = -1;

    XenPTMSIX *msix = NULL;

    int rc = 0;



    rc = xen_host_pci_get_byte(hd, base + PCI_CAP_LIST_ID, &id);

    if (rc) {

        return rc;

    }



    if (id != PCI_CAP_ID_MSIX) {

        XEN_PT_ERR(d, "Invalid id %#x base %#x\n", id, base);

        return -1;

    }



    xen_host_pci_get_word(hd, base + PCI_MSIX_FLAGS, &control);

    total_entries = control & PCI_MSIX_FLAGS_QSIZE;

    total_entries += 1;



    s->msix = g_malloc0(sizeof (XenPTMSIX)

                        + total_entries * sizeof (XenPTMSIXEntry));

    msix = s->msix;



    msix->total_entries = total_entries;

    for (i = 0; i < total_entries; i++) {

        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);



    xen_host_pci_get_long(hd, base + PCI_MSIX_TABLE, &table_off);

    bar_index = msix->bar_index = table_off & PCI_MSIX_FLAGS_BIRMASK;

    table_off = table_off & ~PCI_MSIX_FLAGS_BIRMASK;

    msix->table_base = s->real_device.io_regions[bar_index].base_addr;

    XEN_PT_LOG(d, "get MSI-X table BAR base 0x%"PRIx64"\n", msix->table_base);



    fd = open("/dev/mem", O_RDWR);

    if (fd == -1) {

        rc = -errno;

        XEN_PT_ERR(d, "Can't open /dev/mem: %s\n", strerror(errno));

        goto error_out;

    }

    XEN_PT_LOG(d, "table_off = %#x, total_entries = %d\n",

               table_off, total_entries);

    msix->table_offset_adjust = table_off & 0x0fff;

    msix->phys_iomem_base =

        mmap(NULL,

             total_entries * PCI_MSIX_ENTRY_SIZE + msix->table_offset_adjust,

             PROT_READ,

             MAP_SHARED | MAP_LOCKED,

             fd,

             msix->table_base + table_off - msix->table_offset_adjust);

    close(fd);

    if (msix->phys_iomem_base == MAP_FAILED) {

        rc = -errno;

        XEN_PT_ERR(d, "Can't map physical MSI-X table: %s\n", strerror(errno));

        goto error_out;

    }

    msix->phys_iomem_base = (char *)msix->phys_iomem_base

        + msix->table_offset_adjust;



    XEN_PT_LOG(d, "mapping physical MSI-X table to %p\n",

               msix->phys_iomem_base);



    memory_region_add_subregion_overlap(&s->bar[bar_index], table_off,

                                        &msix->mmio,

                                        2); 



    return 0;



error_out:

    g_free(s->msix);

    s->msix = NULL;

    return rc;

}

    xen_host_pci_get_word(hd, base + PCI_MSIX_FLAGS, &control);     xen_host_pci_get_long(hd, base + PCI_MSIX_TABLE, &table_off);
int FUNC_0(XenPCIPassthroughState *VAR_0, uint32_t VAR_1)

{

    uint8_t id = 0;

    uint16_t control = 0;

    uint32_t table_off = 0;

    int VAR_2, VAR_3, VAR_4;

    XenHostPCIDevice *hd = &VAR_0->real_device;

    PCIDevice *d = &VAR_0->dev;

    int VAR_5 = -1;

    XenPTMSIX *msix = NULL;

    int VAR_6 = 0;



    VAR_6 = xen_host_pci_get_byte(hd, VAR_1 + PCI_CAP_LIST_ID, &id);

    if (VAR_6) {

        return VAR_6;

    }



    if (id != PCI_CAP_ID_MSIX) {

        XEN_PT_ERR(d, "Invalid id %#x VAR_1 %#x\n", id, VAR_1);

        return -1;

    }



    xen_host_pci_get_word(hd, VAR_1 + PCI_MSIX_FLAGS, &control);

    VAR_3 = control & PCI_MSIX_FLAGS_QSIZE;

    VAR_3 += 1;



    VAR_0->msix = g_malloc0(sizeof (XenPTMSIX)

                        + VAR_3 * sizeof (XenPTMSIXEntry));

    msix = VAR_0->msix;



    msix->VAR_3 = VAR_3;

    for (VAR_2 = 0; VAR_2 < VAR_3; VAR_2++) {

        msix->msix_entry[VAR_2].pirq = XEN_PT_UNASSIGNED_PIRQ;

    }



    memory_region_init_io(&msix->mmio, OBJECT(VAR_0), &pci_msix_ops,

                          VAR_0, "xen-pci-pt-msix",

                          (VAR_3 * PCI_MSIX_ENTRY_SIZE

                           + XC_PAGE_SIZE - 1)

                          & XC_PAGE_MASK);



    xen_host_pci_get_long(hd, VAR_1 + PCI_MSIX_TABLE, &table_off);

    VAR_4 = msix->VAR_4 = table_off & PCI_MSIX_FLAGS_BIRMASK;

    table_off = table_off & ~PCI_MSIX_FLAGS_BIRMASK;

    msix->table_base = VAR_0->real_device.io_regions[VAR_4].base_addr;

    XEN_PT_LOG(d, "get MSI-X table BAR VAR_1 0x%"PRIx64"\n", msix->table_base);



    VAR_5 = open("/dev/mem", O_RDWR);

    if (VAR_5 == -1) {

        VAR_6 = -errno;

        XEN_PT_ERR(d, "Can't open /dev/mem: %VAR_0\n", strerror(errno));

        goto error_out;

    }

    XEN_PT_LOG(d, "table_off = %#x, VAR_3 = %d\n",

               table_off, VAR_3);

    msix->table_offset_adjust = table_off & 0x0fff;

    msix->phys_iomem_base =

        mmap(NULL,

             VAR_3 * PCI_MSIX_ENTRY_SIZE + msix->table_offset_adjust,

             PROT_READ,

             MAP_SHARED | MAP_LOCKED,

             VAR_5,

             msix->table_base + table_off - msix->table_offset_adjust);

    close(VAR_5);

    if (msix->phys_iomem_base == MAP_FAILED) {

        VAR_6 = -errno;

        XEN_PT_ERR(d, "Can't map physical MSI-X table: %VAR_0\n", strerror(errno));

        goto error_out;

    }

    msix->phys_iomem_base = (char *)msix->phys_iomem_base

        + msix->table_offset_adjust;



    XEN_PT_LOG(d, "mapping physical MSI-X table to %p\n",

               msix->phys_iomem_base);



    memory_region_add_subregion_overlap(&VAR_0->bar[VAR_4], table_off,

                                        &msix->mmio,

                                        2); 



    return 0;



error_out:

    g_free(VAR_0->msix);

    VAR_0->msix = NULL;

    return VAR_6;

}

int FUNC_0(XenPCIPassthroughState *VAR_0, uint32_t VAR_1)
{ uint8_t id = 0; uint16_t control = 0; uint32_t table_off = 0; int VAR_2, VAR_3, VAR_4; XenHostPCIDevice *hd = &VAR_0->real_device; PCIDevice *d = &VAR_0->dev; int VAR_5 = -1; XenPTMSIX *msix = NULL; int VAR_6 = 0; VAR_6 = xen_host_pci_get_byte(hd, VAR_1 + PCI_CAP_LIST_ID, &id); if (VAR_6) { return VAR_6; } if (id != PCI_CAP_ID_MSIX) { XEN_PT_ERR(d, "Invalid id %#x VAR_1 %#x\n", id, VAR_1); return -1; } xen_host_pci_get_word(hd, VAR_1 + PCI_MSIX_FLAGS, &control); VAR_3 = control & PCI_MSIX_FLAGS_QSIZE; VAR_3 += 1; VAR_0->msix = g_malloc0(sizeof (XenPTMSIX)
+ VAR_3 * sizeof (XenPTMSIXEntry)); msix = VAR_0->msix; msix->VAR_3 = VAR_3; for (VAR_2 = 0; VAR_2 < VAR_3; VAR_2++) { msix->msix_entry[VAR_2].pirq = XEN_PT_UNASSIGNED_PIRQ; } memory_region_init_io(&msix->mmio, OBJECT(VAR_0), &pci_msix_ops,
VAR_0, "xen-pci-pt-msix",
(VAR_3 * PCI_MSIX_ENTRY_SIZE
+ XC_PAGE_SIZE - 1)
& XC_PAGE_MASK); xen_host_pci_get_long(hd, VAR_1 + PCI_MSIX_TABLE, &table_off); VAR_4 = msix->VAR_4 = table_off & PCI_MSIX_FLAGS_BIRMASK; table_off = table_off & ~PCI_MSIX_FLAGS_BIRMASK; msix->table_base = VAR_0->real_device.io_regions[VAR_4].base_addr; XEN_PT_LOG(d, "get MSI-X table BAR VAR_1 0x%"PRIx64"\n", msix->table_base); VAR_5 = open("/dev/mem", O_RDWR); if (VAR_5 == -1) { VAR_6 = -errno; XEN_PT_ERR(d, "Can't open /dev/mem: %VAR_0\n", strerror(errno)); goto error_out; } XEN_PT_LOG(d, "table_off = %#x, VAR_3 = %d\n",
table_off, VAR_3); msix->table_offset_adjust = table_off & 0x0fff; msix->phys_iomem_base =
mmap(NULL,
VAR_3 * PCI_MSIX_ENTRY_SIZE + msix->table_offset_adjust,
PROT_READ,
MAP_SHARED | MAP_LOCKED,
VAR_5,
msix->table_base + table_off - msix->table_offset_adjust); close(VAR_5); if (msix->phys_iomem_base == MAP_FAILED) { VAR_6 = -errno; XEN_PT_ERR(d, "Can't map physical MSI-X table: %VAR_0\n", strerror(errno)); goto error_out; } msix->phys_iomem_base = (char *)msix->phys_iomem_base
+ msix->table_offset_adjust; XEN_PT_LOG(d, "mapping physical MSI-X table to %p\n",
msix->phys_iomem_base); memory_region_add_subregion_overlap(&VAR_0->bar[VAR_4], table_off,
&msix->mmio,
2); return 0; error_out:
g_free(VAR_0->msix); VAR_0->msix = NULL; return VAR_6; }