int vfio_spapr_create_window(VFIOContainer *container,

                             MemoryRegionSection *section,

                             hwaddr *pgsize)

{

    int ret;

    IOMMUMemoryRegion *iommu_mr = IOMMU_MEMORY_REGION(section->mr);

    unsigned pagesize = memory_region_iommu_get_min_page_size(iommu_mr);

    unsigned entries, pages;

    struct vfio_iommu_spapr_tce_create create = { .argsz = sizeof(create) };



    /*

     * FIXME: For VFIO iommu types which have KVM acceleration to

     * avoid bouncing all map/unmaps through qemu this way, this

     * would be the right place to wire that up (tell the KVM

     * device emulation the VFIO iommu handles to use).

     */

    create.window_size = int128_get64(section->size);

    create.page_shift = ctz64(pagesize);

    /*

     * SPAPR host supports multilevel TCE tables, there is some

     * heuristic to decide how many levels we want for our table:

     * 0..64 = 1; 65..4096 = 2; 4097..262144 = 3; 262145.. = 4

     */

    entries = create.window_size >> create.page_shift;

    pages = MAX((entries * sizeof(uint64_t)) / getpagesize(), 1);

    pages = MAX(pow2ceil(pages) - 1, 1); /* Round up */

    create.levels = ctz64(pages) / 6 + 1;



    ret = ioctl(container->fd, VFIO_IOMMU_SPAPR_TCE_CREATE, &create);

    if (ret) {

        error_report("Failed to create a window, ret = %d (%m)", ret);

        return -errno;

    }



    if (create.start_addr != section->offset_within_address_space) {

        vfio_spapr_remove_window(container, create.start_addr);



        error_report("Host doesn't support DMA window at %"HWADDR_PRIx", must be %"PRIx64,

                     section->offset_within_address_space,

                     (uint64_t)create.start_addr);

        return -EINVAL;

    }

    trace_vfio_spapr_create_window(create.page_shift,

                                   create.window_size,

                                   create.start_addr);

    *pgsize = pagesize;



    return 0;

}

int vfio_spapr_create_window(VFIOContainer *container,

                             MemoryRegionSection *section,

                             hwaddr *pgsize)

{

    int ret;

    IOMMUMemoryRegion *iommu_mr = IOMMU_MEMORY_REGION(section->mr);

    unsigned pagesize = memory_region_iommu_get_min_page_size(iommu_mr);

    unsigned entries, pages;

    struct vfio_iommu_spapr_tce_create create = { .argsz = sizeof(create) };



    











    create.window_size = int128_get64(section->size);

    create.page_shift = ctz64(pagesize);

    









    entries = create.window_size >> create.page_shift;

    pages = MAX((entries * sizeof(uint64_t)) / getpagesize(), 1);

    pages = MAX(pow2ceil(pages) - 1, 1); 

    create.levels = ctz64(pages) / 6 + 1;



    ret = ioctl(container->fd, VFIO_IOMMU_SPAPR_TCE_CREATE, &create);

    if (ret) {

        error_report("Failed to create a window, ret = %d (%m)", ret);

        return -errno;

    }



    if (create.start_addr != section->offset_within_address_space) {

        vfio_spapr_remove_window(container, create.start_addr);



        error_report("Host doesn't support DMA window at %"HWADDR_PRIx", must be %"PRIx64,

                     section->offset_within_address_space,

                     (uint64_t)create.start_addr);

        return -EINVAL;

    }

    trace_vfio_spapr_create_window(create.page_shift,

                                   create.window_size,

                                   create.start_addr);

    *pgsize = pagesize;



    return 0;

}

int FUNC_0(VFIOContainer *VAR_0,

                             MemoryRegionSection *VAR_1,

                             hwaddr *VAR_2)

{

    int VAR_3;

    IOMMUMemoryRegion *iommu_mr = IOMMU_MEMORY_REGION(VAR_1->mr);

    unsigned VAR_4 = memory_region_iommu_get_min_page_size(iommu_mr);

    unsigned VAR_5, VAR_6;

    struct vfio_iommu_spapr_tce_create VAR_7 = { .argsz = sizeof(VAR_7) };



    











    VAR_7.window_size = int128_get64(VAR_1->size);

    VAR_7.page_shift = ctz64(VAR_4);

    









    VAR_5 = VAR_7.window_size >> VAR_7.page_shift;

    VAR_6 = MAX((VAR_5 * sizeof(uint64_t)) / getpagesize(), 1);

    VAR_6 = MAX(pow2ceil(VAR_6) - 1, 1); 

    VAR_7.levels = ctz64(VAR_6) / 6 + 1;



    VAR_3 = ioctl(VAR_0->fd, VFIO_IOMMU_SPAPR_TCE_CREATE, &VAR_7);

    if (VAR_3) {

        error_report("Failed to VAR_7 a window, VAR_3 = %d (%m)", VAR_3);

        return -errno;

    }



    if (VAR_7.start_addr != VAR_1->offset_within_address_space) {

        vfio_spapr_remove_window(VAR_0, VAR_7.start_addr);



        error_report("Host doesn't support DMA window at %"HWADDR_PRIx", must be %"PRIx64,

                     VAR_1->offset_within_address_space,

                     (uint64_t)VAR_7.start_addr);

        return -EINVAL;

    }

    trace_vfio_spapr_create_window(VAR_7.page_shift,

                                   VAR_7.window_size,

                                   VAR_7.start_addr);

    *VAR_2 = VAR_4;



    return 0;

}

int FUNC_0(VFIOContainer *VAR_0,
MemoryRegionSection *VAR_1,
hwaddr *VAR_2)
{ int VAR_3; IOMMUMemoryRegion *iommu_mr = IOMMU_MEMORY_REGION(VAR_1->mr); unsigned VAR_4 = memory_region_iommu_get_min_page_size(iommu_mr); unsigned VAR_5, VAR_6; struct vfio_iommu_spapr_tce_create VAR_7 = { .argsz = sizeof(VAR_7) }; VAR_7.window_size = int128_get64(VAR_1->size); VAR_7.page_shift = ctz64(VAR_4); VAR_5 = VAR_7.window_size >> VAR_7.page_shift; VAR_6 = MAX((VAR_5 * sizeof(uint64_t)) / getpagesize(), 1); VAR_6 = MAX(pow2ceil(VAR_6) - 1, 1); VAR_7.levels = ctz64(VAR_6) / 6 + 1; VAR_3 = ioctl(VAR_0->fd, VFIO_IOMMU_SPAPR_TCE_CREATE, &VAR_7); if (VAR_3) { error_report("Failed to VAR_7 a window, VAR_3 = %d (%m)", VAR_3); return -errno; } if (VAR_7.start_addr != VAR_1->offset_within_address_space) { vfio_spapr_remove_window(VAR_0, VAR_7.start_addr); error_report("Host doesn't support DMA window at %"HWADDR_PRIx", must be %"PRIx64,
VAR_1->offset_within_address_space,
(uint64_t)VAR_7.start_addr); return -EINVAL; } trace_vfio_spapr_create_window(VAR_7.page_shift,
VAR_7.window_size,
VAR_7.start_addr); *VAR_2 = VAR_4; return 0; }