155 lines
6.5 KiB
Diff
155 lines
6.5 KiB
Diff
|
|
From d09cb3d1907e3afbae9b3ea345c9973e207614bf Mon Sep 17 00:00:00 2001
|
||
|
|
From: Joao Martins <joao.m.martins@oracle.com>
|
||
|
|
Date: Mon, 22 Jul 2024 22:13:24 +0100
|
||
|
|
Subject: [PATCH] vfio/iommufd: Implement VFIOIOMMUClass::query_dirty_bitmap
|
||
|
|
support
|
||
|
|
MIME-Version: 1.0
|
||
|
|
Content-Type: text/plain; charset=UTF-8
|
||
|
|
Content-Transfer-Encoding: 8bit
|
||
|
|
|
||
|
|
ioctl(iommufd, IOMMU_HWPT_GET_DIRTY_BITMAP, arg) is the UAPI
|
||
|
|
that fetches the bitmap that tells what was dirty in an IOVA
|
||
|
|
range.
|
||
|
|
|
||
|
|
A single bitmap is allocated and used across all the hwpts
|
||
|
|
sharing an IOAS which is then used in log_sync() to set Qemu
|
||
|
|
global bitmaps.
|
||
|
|
|
||
|
|
Signed-off-by: Joao Martins <joao.m.martins@oracle.com>
|
||
|
|
Reviewed-by: Cédric Le Goater <clg@redhat.com>
|
||
|
|
Reviewed-by: Eric Auger <eric.auger@redhat.com>
|
||
|
|
Reviewed-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
|
||
|
|
[Shameer: changed iommufd_query_dirty_bitmap() declaration]
|
||
|
|
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
|
||
|
|
---
|
||
|
|
backends/iommufd.c | 29 +++++++++++++++++++++++++++++
|
||
|
|
backends/trace-events | 1 +
|
||
|
|
hw/vfio/iommufd.c | 32 ++++++++++++++++++++++++++++++++
|
||
|
|
include/sysemu/iommufd.h | 4 ++++
|
||
|
|
4 files changed, 66 insertions(+)
|
||
|
|
|
||
|
|
diff --git a/backends/iommufd.c b/backends/iommufd.c
|
||
|
|
index 785d3fbbad..c1260766f0 100644
|
||
|
|
--- a/backends/iommufd.c
|
||
|
|
+++ b/backends/iommufd.c
|
||
|
|
@@ -277,6 +277,35 @@ bool iommufd_backend_set_dirty_tracking(IOMMUFDBackend *be,
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
+bool iommufd_backend_get_dirty_bitmap(IOMMUFDBackend *be,
|
||
|
|
+ uint32_t hwpt_id,
|
||
|
|
+ uint64_t iova, ram_addr_t size,
|
||
|
|
+ uint64_t page_size, uint64_t *data,
|
||
|
|
+ Error **errp)
|
||
|
|
+{
|
||
|
|
+ int ret;
|
||
|
|
+ struct iommu_hwpt_get_dirty_bitmap get_dirty_bitmap = {
|
||
|
|
+ .size = sizeof(get_dirty_bitmap),
|
||
|
|
+ .hwpt_id = hwpt_id,
|
||
|
|
+ .iova = iova,
|
||
|
|
+ .length = size,
|
||
|
|
+ .page_size = page_size,
|
||
|
|
+ .data = (uintptr_t)data,
|
||
|
|
+ };
|
||
|
|
+
|
||
|
|
+ ret = ioctl(be->fd, IOMMU_HWPT_GET_DIRTY_BITMAP, &get_dirty_bitmap);
|
||
|
|
+ trace_iommufd_backend_get_dirty_bitmap(be->fd, hwpt_id, iova, size,
|
||
|
|
+ page_size, ret ? errno : 0);
|
||
|
|
+ if (ret) {
|
||
|
|
+ error_setg_errno(errp, errno,
|
||
|
|
+ "IOMMU_HWPT_GET_DIRTY_BITMAP (iova: 0x%"HWADDR_PRIx
|
||
|
|
+ " size: 0x"RAM_ADDR_FMT") failed", iova, size);
|
||
|
|
+ return false;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ return true;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
bool iommufd_backend_get_device_info(IOMMUFDBackend *be, uint32_t devid,
|
||
|
|
uint32_t *type, void *data, uint32_t len,
|
||
|
|
uint64_t *caps, Error **errp)
|
||
|
|
diff --git a/backends/trace-events b/backends/trace-events
|
||
|
|
index fe3297ca15..b02433710a 100644
|
||
|
|
--- a/backends/trace-events
|
||
|
|
+++ b/backends/trace-events
|
||
|
|
@@ -17,3 +17,4 @@ iommufd_backend_alloc_ioas(int iommufd, uint32_t ioas, int ret) " iommufd=%d ioa
|
||
|
|
iommufd_backend_alloc_hwpt(int iommufd, uint32_t dev_id, uint32_t pt_id, uint32_t flags, uint32_t hwpt_type, uint32_t len, uint64_t data_ptr, uint32_t out_hwpt_id, int ret) " iommufd=%d dev_id=%u pt_id=%u flags=0x%x hwpt_type=%u len=%u data_ptr=0x%"PRIx64" out_hwpt=%u (%d)"
|
||
|
|
iommufd_backend_free_id(int iommufd, uint32_t id, int ret) " iommufd=%d id=%d (%d)"
|
||
|
|
iommufd_backend_set_dirty(int iommufd, uint32_t hwpt_id, bool start, int ret) " iommufd=%d hwpt=%u enable=%d (%d)"
|
||
|
|
+iommufd_backend_get_dirty_bitmap(int iommufd, uint32_t hwpt_id, uint64_t iova, uint64_t size, uint64_t page_size, int ret) " iommufd=%d hwpt=%u iova=0x%"PRIx64" size=0x%"PRIx64" page_size=0x%"PRIx64" (%d)"
|
||
|
|
diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
|
||
|
|
index 11e1392527..3d4f902ae5 100644
|
||
|
|
--- a/hw/vfio/iommufd.c
|
||
|
|
+++ b/hw/vfio/iommufd.c
|
||
|
|
@@ -25,6 +25,7 @@
|
||
|
|
#include "qemu/cutils.h"
|
||
|
|
#include "qemu/chardev_open.h"
|
||
|
|
#include "pci.h"
|
||
|
|
+#include "exec/ram_addr.h"
|
||
|
|
|
||
|
|
static int iommufd_cdev_map(const VFIOContainerBase *bcontainer, hwaddr iova,
|
||
|
|
ram_addr_t size, void *vaddr, bool readonly)
|
||
|
|
@@ -152,6 +153,36 @@ err:
|
||
|
|
return -EINVAL;
|
||
|
|
}
|
||
|
|
|
||
|
|
+static int iommufd_query_dirty_bitmap(const VFIOContainerBase *bcontainer,
|
||
|
|
+ VFIOBitmap *vbmap, hwaddr iova,
|
||
|
|
+ hwaddr size)
|
||
|
|
+{
|
||
|
|
+ VFIOIOMMUFDContainer *container = container_of(bcontainer,
|
||
|
|
+ VFIOIOMMUFDContainer,
|
||
|
|
+ bcontainer);
|
||
|
|
+ unsigned long page_size = qemu_real_host_page_size();
|
||
|
|
+ VFIOIOASHwpt *hwpt;
|
||
|
|
+
|
||
|
|
+ QLIST_FOREACH(hwpt, &container->hwpt_list, next) {
|
||
|
|
+ if (!iommufd_hwpt_dirty_tracking(hwpt)) {
|
||
|
|
+ continue;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ if (!iommufd_backend_get_dirty_bitmap(container->be, hwpt->hwpt_id,
|
||
|
|
+ iova, size, page_size,
|
||
|
|
+ (uint64_t *)vbmap->bitmap,
|
||
|
|
+ NULL)) {
|
||
|
|
+ error_report("Failed to get dirty bitmap for iova: 0x%"PRIx64
|
||
|
|
+ " size: 0x%"PRIx64" err: %d", (uint64_t)iova,
|
||
|
|
+ (uint64_t)size, errno);
|
||
|
|
+
|
||
|
|
+ return -EINVAL;
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ return 0;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
static int iommufd_cdev_getfd(const char *sysfs_path, Error **errp)
|
||
|
|
{
|
||
|
|
long int ret = -ENOTTY;
|
||
|
|
@@ -793,6 +824,7 @@ static void vfio_iommu_iommufd_class_init(ObjectClass *klass, void *data)
|
||
|
|
vioc->detach_device = iommufd_cdev_detach;
|
||
|
|
vioc->pci_hot_reset = iommufd_cdev_pci_hot_reset;
|
||
|
|
vioc->set_dirty_page_tracking = iommufd_set_dirty_page_tracking;
|
||
|
|
+ vioc->query_dirty_bitmap = iommufd_query_dirty_bitmap;
|
||
|
|
};
|
||
|
|
|
||
|
|
static bool hiod_iommufd_vfio_realize(HostIOMMUDevice *hiod, void *opaque,
|
||
|
|
diff --git a/include/sysemu/iommufd.h b/include/sysemu/iommufd.h
|
||
|
|
index 4f1dbe827c..3b28c8a81c 100644
|
||
|
|
--- a/include/sysemu/iommufd.h
|
||
|
|
+++ b/include/sysemu/iommufd.h
|
||
|
|
@@ -59,6 +59,10 @@ bool iommufd_backend_alloc_hwpt(IOMMUFDBackend *be, uint32_t dev_id,
|
||
|
|
Error **errp);
|
||
|
|
bool iommufd_backend_set_dirty_tracking(IOMMUFDBackend *be, uint32_t hwpt_id,
|
||
|
|
bool start, Error **errp);
|
||
|
|
+bool iommufd_backend_get_dirty_bitmap(IOMMUFDBackend *be, uint32_t hwpt_id,
|
||
|
|
+ uint64_t iova, ram_addr_t size,
|
||
|
|
+ uint64_t page_size, uint64_t *data,
|
||
|
|
+ Error **errp);
|
||
|
|
|
||
|
|
#define TYPE_HOST_IOMMU_DEVICE_IOMMUFD TYPE_HOST_IOMMU_DEVICE "-iommufd"
|
||
|
|
#endif
|
||
|
|
--
|
||
|
|
2.41.0.windows.1
|
||
|
|
|