[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH RFCv2 3/8] vfio/iommufd: Probe and request hwpt dirty tracking ca
From: |
Joao Martins |
Subject: |
[PATCH RFCv2 3/8] vfio/iommufd: Probe and request hwpt dirty tracking capability |
Date: |
Mon, 12 Feb 2024 13:56:38 +0000 |
Probe hardware dirty tracking support by querying device hw capabilities
via IOMMUFD_GET_HW_INFO.
In preparation to using the dirty tracking UAPI, request dirty tracking in
the HWPT flags when the device doesn't support dirty page tracking or has
it disabled; or when support when the VF backing IOMMU supports dirty
tracking. The latter is in the possibility of a device being attached
that doesn't have a dirty tracker.
Signed-off-by: Joao Martins <joao.m.martins@oracle.com>
---
hw/vfio/common.c | 18 ++++++++++++++++++
hw/vfio/iommufd.c | 25 ++++++++++++++++++++++++-
include/hw/vfio/vfio-common.h | 2 ++
3 files changed, 44 insertions(+), 1 deletion(-)
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index f7f85160be88..d8fc7077f839 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -216,6 +216,24 @@ bool vfio_devices_all_device_dirty_tracking(const
VFIOContainerBase *bcontainer)
return true;
}
+bool vfio_device_migration_supported(VFIODevice *vbasedev)
+{
+ if (!vbasedev->migration) {
+ return false;
+ }
+
+ return vbasedev->migration->mig_flags & VFIO_MIGRATION_STOP_COPY;
+}
+
+bool vfio_device_dirty_pages_supported(VFIODevice *vbasedev)
+{
+ if (vbasedev->pre_copy_dirty_page_tracking == ON_OFF_AUTO_OFF) {
+ return false;
+ }
+
+ return !vbasedev->dirty_pages_supported;
+}
+
/*
* Check if all VFIO devices are running and migration is active, which is
* essentially equivalent to the migration being in pre-copy phase.
diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
index ca7ec45e725c..edacb6d72748 100644
--- a/hw/vfio/iommufd.c
+++ b/hw/vfio/iommufd.c
@@ -219,11 +219,26 @@ static int iommufd_cdev_detach_ioas_hwpt(VFIODevice
*vbasedev, Error **errp)
return ret;
}
+static bool iommufd_dirty_pages_supported(IOMMUFDDevice *iommufd_dev,
+ Error **errp)
+{
+ uint64_t caps;
+ int r;
+
+ r = iommufd_device_get_hw_capabilities(iommufd_dev, &caps, errp);
+ if (r) {
+ return false;
+ }
+
+ return caps & IOMMU_HW_CAP_DIRTY_TRACKING;
+}
+
static int iommufd_cdev_autodomains_get(VFIODevice *vbasedev,
VFIOIOMMUFDContainer *container,
Error **errp)
{
int iommufd = vbasedev->iommufd_dev.iommufd->fd;
+ uint32_t flags = 0;
VFIOIOASHwpt *hwpt;
Error *err = NULL;
int ret = -EINVAL;
@@ -245,9 +260,15 @@ static int iommufd_cdev_autodomains_get(VFIODevice
*vbasedev,
}
}
+ if ((vfio_device_migration_supported(vbasedev) &&
+ !vfio_device_dirty_pages_supported(vbasedev)) ||
+ iommufd_dirty_pages_supported(&vbasedev->iommufd_dev, &err)) {
+ flags = IOMMU_HWPT_ALLOC_DIRTY_TRACKING;
+ }
+
ret = iommufd_backend_alloc_hwpt(iommufd,
vbasedev->iommufd_dev.devid,
- container->ioas_id, 0, 0, 0,
+ container->ioas_id, flags, 0, 0,
NULL, &hwpt_id);
if (ret) {
error_append_hint(&err,
@@ -271,6 +292,8 @@ static int iommufd_cdev_autodomains_get(VFIODevice
*vbasedev,
vbasedev->hwpt = hwpt;
QLIST_INSERT_HEAD(&hwpt->device_list, vbasedev, hwpt_next);
QLIST_INSERT_HEAD(&container->hwpt_list, hwpt, next);
+ container->bcontainer.dirty_pages_supported =
+ (flags & IOMMU_HWPT_ALLOC_DIRTY_TRACKING);
return 0;
}
diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index 7f7d823221e2..a3e691c126c6 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -271,6 +271,8 @@ bool
vfio_devices_all_running_and_mig_active(const VFIOContainerBase *bcontainer);
bool
vfio_devices_all_device_dirty_tracking(const VFIOContainerBase *bcontainer);
+bool vfio_device_migration_supported(VFIODevice *vbasedev);
+bool vfio_device_dirty_pages_supported(VFIODevice *vbasedev);
int vfio_devices_query_dirty_bitmap(const VFIOContainerBase *bcontainer,
VFIOBitmap *vbmap, hwaddr iova,
hwaddr size);
--
2.39.3