info.iova_pgsizes = 4096;
}
vfio_host_win_add(container, 0, (hwaddr)-1, info.iova_pgsizes);
+ container->pgsizes = info.iova_pgsizes;
} else if (ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_SPAPR_TCE_IOMMU) ||
ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_SPAPR_TCE_v2_IOMMU)) {
struct vfio_iommu_spapr_tce_info info;
}
if (v2) {
+ container->pgsizes = info.ddw.pgsizes;
/*
* There is a default window in just created container.
* To make region_add/del simpler, we better remove this
}
} else {
/* The default table uses 4K pages */
+ container->pgsizes = 0x1000;
vfio_host_win_add(container, info.dma32_window_start,
info.dma32_window_start +
info.dma32_window_size - 1,
#include "hw/vfio/vfio-common.h"
#include "hw/hw.h"
+#include "exec/ram_addr.h"
#include "qemu/error-report.h"
#include "trace.h"
{
int ret;
IOMMUMemoryRegion *iommu_mr = IOMMU_MEMORY_REGION(section->mr);
- unsigned pagesize = memory_region_iommu_get_min_page_size(iommu_mr);
+ uint64_t pagesize = memory_region_iommu_get_min_page_size(iommu_mr);
unsigned entries, pages;
struct vfio_iommu_spapr_tce_create create = { .argsz = sizeof(create) };
+ long systempagesize = qemu_getrampagesize();
+
+ /*
+ * The host might not support the guest supported IOMMU page size,
+ * so we will use smaller physical IOMMU pages to back them.
+ */
+ if (pagesize > systempagesize) {
+ pagesize = systempagesize;
+ }
+ pagesize = 1ULL << (63 - clz64(container->pgsizes &
+ (pagesize | (pagesize - 1))));
+ if (!pagesize) {
+ error_report("Host doesn't support page size 0x%"PRIx64
+ ", the supported mask is 0x%lx",
+ memory_region_iommu_get_min_page_size(iommu_mr),
+ container->pgsizes);
+ return -EINVAL;
+ }
/*
* FIXME: For VFIO iommu types which have KVM acceleration to