summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Gibson2015-09-30 04:13:54 +0200
committerAlex Williamson2015-10-05 20:38:41 +0200
commit7a140a57c69293a2f19b045f40953a87879e8c76 (patch)
tree0e417501391643f168c97b4b70f5d63c717073f4
parentvfio: Check guest IOVA ranges against host IOMMU capabilities (diff)
downloadqemu-7a140a57c69293a2f19b045f40953a87879e8c76.tar.gz
qemu-7a140a57c69293a2f19b045f40953a87879e8c76.tar.xz
qemu-7a140a57c69293a2f19b045f40953a87879e8c76.zip
vfio: Record host IOMMU's available IO page sizes
Depending on the host IOMMU type we determine and record the available page sizes for IOMMU translation. We'll need this for other validation in future patches. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Thomas Huth <thuth@redhat.com> Reviewed-by: Laurent Vivier <lvivier@redhat.com> Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
-rw-r--r--hw/vfio/common.c13
-rw-r--r--include/hw/vfio/vfio-common.h1
2 files changed, 14 insertions, 0 deletions
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 2faf49206b..f666de2c96 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -677,6 +677,7 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as)
if (ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_TYPE1_IOMMU) ||
ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_TYPE1v2_IOMMU)) {
bool v2 = !!ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_TYPE1v2_IOMMU);
+ struct vfio_iommu_type1_info info;
ret = ioctl(group->fd, VFIO_GROUP_SET_CONTAINER, &fd);
if (ret) {
@@ -702,6 +703,15 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as)
*/
container->min_iova = 0;
container->max_iova = (hwaddr)-1;
+
+ /* Assume just 4K IOVA page size */
+ container->iova_pgsizes = 0x1000;
+ info.argsz = sizeof(info);
+ ret = ioctl(fd, VFIO_IOMMU_GET_INFO, &info);
+ /* Ignore errors */
+ if ((ret == 0) && (info.flags & VFIO_IOMMU_INFO_PGSIZES)) {
+ container->iova_pgsizes = info.iova_pgsizes;
+ }
} else if (ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_SPAPR_TCE_IOMMU)) {
struct vfio_iommu_spapr_tce_info info;
@@ -744,6 +754,9 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as)
}
container->min_iova = info.dma32_window_start;
container->max_iova = container->min_iova + info.dma32_window_size - 1;
+
+ /* Assume just 4K IOVA pages for now */
+ container->iova_pgsizes = 0x1000;
} else {
error_report("vfio: No available IOMMU models");
ret = -EINVAL;
diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index 27a14c0fd1..f037f3c425 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -71,6 +71,7 @@ typedef struct VFIOContainer {
* future
*/
hwaddr min_iova, max_iova;
+ uint64_t iova_pgsizes;
QLIST_HEAD(, VFIOGuestIOMMU) giommu_list;
QLIST_HEAD(, VFIOGroup) group_list;
QLIST_ENTRY(VFIOContainer) next;