[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v2 13/20] vfio/common: Add device dirty page bitmap sync
From: |
Avihai Horon |
Subject: |
[PATCH v2 13/20] vfio/common: Add device dirty page bitmap sync |
Date: |
Wed, 22 Feb 2023 19:49:08 +0200 |
From: Joao Martins <joao.m.martins@oracle.com>
Add device dirty page bitmap sync functionality. This uses the device
DMA logging uAPI to sync dirty page bitmap from the device.
Device dirty page bitmap sync is used only if all devices within a
container support device dirty page tracking.
Signed-off-by: Joao Martins <joao.m.martins@oracle.com>
Signed-off-by: Avihai Horon <avihaih@nvidia.com>
---
hw/vfio/common.c | 95 +++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 86 insertions(+), 9 deletions(-)
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 3ab5d8d442..797eb2c26e 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -356,6 +356,9 @@ static void vfio_bitmap_dealloc(VFIOBitmap *vbmap)
g_free(vbmap);
}
+static int vfio_get_dirty_bitmap(VFIOContainer *container, uint64_t iova,
+ uint64_t size, ram_addr_t ram_addr);
+
bool vfio_mig_active(void)
{
VFIOGroup *group;
@@ -631,10 +634,16 @@ static int vfio_dma_unmap(VFIOContainer *container,
.iova = iova,
.size = size,
};
+ bool need_dirty_sync = false;
+ int ret;
- if (iotlb && container->dirty_pages_supported &&
- vfio_devices_all_running_and_mig_active(container)) {
- return vfio_dma_unmap_bitmap(container, iova, size, iotlb);
+ if (iotlb && vfio_devices_all_running_and_mig_active(container)) {
+ if (!vfio_devices_all_device_dirty_tracking(container) &&
+ container->dirty_pages_supported) {
+ return vfio_dma_unmap_bitmap(container, iova, size, iotlb);
+ }
+
+ need_dirty_sync = true;
}
while (ioctl(container->fd, VFIO_IOMMU_UNMAP_DMA, &unmap)) {
@@ -660,10 +669,12 @@ static int vfio_dma_unmap(VFIOContainer *container,
return -errno;
}
- if (iotlb && vfio_devices_all_running_and_mig_active(container)) {
- cpu_physical_memory_set_dirty_range(iotlb->translated_addr, size,
- tcg_enabled() ? DIRTY_CLIENTS_ALL :
- DIRTY_CLIENTS_NOCODE);
+ if (need_dirty_sync) {
+ ret = vfio_get_dirty_bitmap(container, iova, size,
+ iotlb->translated_addr);
+ if (ret) {
+ return ret;
+ }
}
vfio_erase_mapping(container, iova, size);
@@ -1633,6 +1644,65 @@ static void vfio_listener_log_global_stop(MemoryListener
*listener)
}
}
+static int vfio_device_dma_logging_report(VFIODevice *vbasedev, hwaddr iova,
+ hwaddr size, void *bitmap)
+{
+ uint64_t buf[DIV_ROUND_UP(sizeof(struct vfio_device_feature) +
+ sizeof(struct vfio_device_feature_dma_logging_report),
+ sizeof(uint64_t))] = {};
+ struct vfio_device_feature *feature = (struct vfio_device_feature *)buf;
+ struct vfio_device_feature_dma_logging_report *report =
+ (struct vfio_device_feature_dma_logging_report *)feature->data;
+
+ report->iova = iova;
+ report->length = size;
+ report->page_size = qemu_real_host_page_size();
+ report->bitmap = (uint64_t)bitmap;
+
+ feature->argsz = sizeof(buf);
+ feature->flags =
+ VFIO_DEVICE_FEATURE_GET | VFIO_DEVICE_FEATURE_DMA_LOGGING_REPORT;
+
+ if (ioctl(vbasedev->fd, VFIO_DEVICE_FEATURE, feature)) {
+ return -errno;
+ }
+
+ return 0;
+}
+
+static int vfio_devices_query_dirty_bitmap(VFIOContainer *container,
+ VFIOBitmap *vbmap, hwaddr iova,
+ hwaddr size)
+{
+ VFIODevice *vbasedev;
+ VFIOGroup *group;
+ int ret;
+
+ if (vfio_have_giommu(container)) {
+ /* Device dirty page tracking currently doesn't support vIOMMU */
+ bitmap_set(vbmap->bitmap, 0, vbmap->pages);
+
+ return 0;
+ }
+
+ QLIST_FOREACH(group, &container->group_list, container_next) {
+ QLIST_FOREACH(vbasedev, &group->device_list, next) {
+ ret = vfio_device_dma_logging_report(vbasedev, iova, size,
+ vbmap->bitmap);
+ if (ret) {
+ error_report("%s: Failed to get DMA logging report, iova: "
+ "0x%" HWADDR_PRIx ", size: 0x%" HWADDR_PRIx
+ ", err: %d (%s)",
+ vbasedev->name, iova, size, ret, strerror(-ret));
+
+ return ret;
+ }
+ }
+ }
+
+ return 0;
+}
+
static int vfio_query_dirty_bitmap(VFIOContainer *container, VFIOBitmap *vbmap,
hwaddr iova, hwaddr size)
{
@@ -1673,10 +1743,12 @@ static int vfio_query_dirty_bitmap(VFIOContainer
*container, VFIOBitmap *vbmap,
static int vfio_get_dirty_bitmap(VFIOContainer *container, uint64_t iova,
uint64_t size, ram_addr_t ram_addr)
{
+ bool all_device_dirty_tracking =
+ vfio_devices_all_device_dirty_tracking(container);
VFIOBitmap *vbmap;
int ret;
- if (!container->dirty_pages_supported) {
+ if (!container->dirty_pages_supported && !all_device_dirty_tracking) {
cpu_physical_memory_set_dirty_range(ram_addr, size,
tcg_enabled() ? DIRTY_CLIENTS_ALL :
DIRTY_CLIENTS_NOCODE);
@@ -1688,7 +1760,12 @@ static int vfio_get_dirty_bitmap(VFIOContainer
*container, uint64_t iova,
return -errno;
}
- ret = vfio_query_dirty_bitmap(container, vbmap, iova, size);
+ if (all_device_dirty_tracking) {
+ ret = vfio_devices_query_dirty_bitmap(container, vbmap, iova, size);
+ } else {
+ ret = vfio_query_dirty_bitmap(container, vbmap, iova, size);
+ }
+
if (ret) {
goto out;
}
--
2.26.3
- Re: [PATCH v2 11/20] vfio/common: Add device dirty page tracking start/stop, (continued)
- [PATCH v2 10/20] vfio/common: Record DMA mapped IOVA ranges, Avihai Horon, 2023/02/22
- Re: [PATCH v2 10/20] vfio/common: Record DMA mapped IOVA ranges, Alex Williamson, 2023/02/22
- Re: [PATCH v2 10/20] vfio/common: Record DMA mapped IOVA ranges, Joao Martins, 2023/02/23
- Re: [PATCH v2 10/20] vfio/common: Record DMA mapped IOVA ranges, Alex Williamson, 2023/02/23
- Re: [PATCH v2 10/20] vfio/common: Record DMA mapped IOVA ranges, Joao Martins, 2023/02/23
- Re: [PATCH v2 10/20] vfio/common: Record DMA mapped IOVA ranges, Alex Williamson, 2023/02/23
- Re: [PATCH v2 10/20] vfio/common: Record DMA mapped IOVA ranges, Joao Martins, 2023/02/23
[PATCH v2 12/20] vfio/common: Extract code from vfio_get_dirty_bitmap() to new function, Avihai Horon, 2023/02/22
[PATCH v2 14/20] vfio/common: Extract vIOMMU code from vfio_sync_dirty_bitmap(), Avihai Horon, 2023/02/22
[PATCH v2 13/20] vfio/common: Add device dirty page bitmap sync,
Avihai Horon <=
[PATCH v2 15/20] memory/iommu: Add IOMMU_ATTR_MAX_IOVA attribute, Avihai Horon, 2023/02/22
[PATCH v2 16/20] intel-iommu: Implement get_attr() method, Avihai Horon, 2023/02/22
[PATCH v2 17/20] vfio/common: Support device dirty page tracking with vIOMMU, Avihai Horon, 2023/02/22
- Re: [PATCH v2 17/20] vfio/common: Support device dirty page tracking with vIOMMU, Alex Williamson, 2023/02/22
- Re: [PATCH v2 17/20] vfio/common: Support device dirty page tracking with vIOMMU, Jason Gunthorpe, 2023/02/22
- Re: [PATCH v2 17/20] vfio/common: Support device dirty page tracking with vIOMMU, Alex Williamson, 2023/02/23
- Re: [PATCH v2 17/20] vfio/common: Support device dirty page tracking with vIOMMU, Jason Gunthorpe, 2023/02/23
- Re: [PATCH v2 17/20] vfio/common: Support device dirty page tracking with vIOMMU, Joao Martins, 2023/02/23
- Re: [PATCH v2 17/20] vfio/common: Support device dirty page tracking with vIOMMU, Alex Williamson, 2023/02/23
- Re: [PATCH v2 17/20] vfio/common: Support device dirty page tracking with vIOMMU, Jason Gunthorpe, 2023/02/23