@@ -83,7 +83,6 @@ typedef struct VFIOLegacyContainer {
unsigned iommu_type;
Error *error;
bool initialized;
- bool dirty_pages_supported;
uint64_t dirty_pgsizes;
uint64_t max_dirty_bitmap_size;
unsigned long pgsizes;
@@ -186,11 +185,6 @@ VFIOAddressSpace *vfio_get_address_space(AddressSpace *as);
void vfio_put_address_space(VFIOAddressSpace *space);
bool vfio_devices_all_running_and_saving(VFIOLegacyContainer *container);
-/* container->fd */
-int vfio_set_dirty_page_tracking(VFIOLegacyContainer *container, bool start);
-int vfio_query_dirty_bitmap(VFIOLegacyContainer *container, VFIOBitmap *vbmap,
- hwaddr iova, hwaddr size);
-
void vfio_disable_irqindex(VFIODevice *vbasedev, int index);
void vfio_unmask_single_irqindex(VFIODevice *vbasedev, int index);
void vfio_mask_single_irqindex(VFIODevice *vbasedev, int index);
@@ -66,6 +66,7 @@ typedef struct {
struct VFIOContainer {
VFIOIOMMUBackendOpsClass *ops;
VFIOAddressSpace *space;
+ bool dirty_pages_supported;
QLIST_HEAD(, VFIOGuestIOMMU) giommu_list;
QLIST_HEAD(, VFIOHostDMAWindow) hostwin_list;
QLIST_ENTRY(VFIOContainer) next;
@@ -77,6 +78,11 @@ int vfio_container_dma_map(VFIOContainer *bcontainer,
int vfio_container_dma_unmap(VFIOContainer *bcontainer,
hwaddr iova, ram_addr_t size,
IOMMUTLBEntry *iotlb);
+int vfio_container_set_dirty_page_tracking(VFIOContainer *bcontainer,
+ bool start);
+int vfio_container_query_dirty_bitmap(VFIOContainer *bcontainer,
+ VFIOBitmap *vbmap,
+ hwaddr iova, hwaddr size);
int vfio_container_add_section_window(VFIOContainer *bcontainer,
MemoryRegionSection *section,
Error **errp);
@@ -1149,7 +1149,8 @@ static void vfio_listener_log_global_start(MemoryListener *listener)
if (vfio_devices_all_device_dirty_tracking(container)) {
ret = vfio_devices_dma_logging_start(container);
} else {
- ret = vfio_set_dirty_page_tracking(container, true);
+ ret = vfio_container_set_dirty_page_tracking(&container->bcontainer,
+ true);
}
if (ret) {
@@ -1169,7 +1170,8 @@ static void vfio_listener_log_global_stop(MemoryListener *listener)
if (vfio_devices_all_device_dirty_tracking(container)) {
vfio_devices_dma_logging_stop(container);
} else {
- ret = vfio_set_dirty_page_tracking(container, false);
+ ret = vfio_container_set_dirty_page_tracking(&container->bcontainer,
+ false);
}
if (ret) {
@@ -1237,7 +1239,8 @@ int vfio_get_dirty_bitmap(VFIOLegacyContainer *container, uint64_t iova,
VFIOBitmap vbmap;
int ret;
- if (!container->dirty_pages_supported && !all_device_dirty_tracking) {
+ if (!container->bcontainer.dirty_pages_supported &&
+ !all_device_dirty_tracking) {
cpu_physical_memory_set_dirty_range(ram_addr, size,
tcg_enabled() ? DIRTY_CLIENTS_ALL :
DIRTY_CLIENTS_NOCODE);
@@ -1252,7 +1255,8 @@ int vfio_get_dirty_bitmap(VFIOLegacyContainer *container, uint64_t iova,
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);
+ ret = vfio_container_query_dirty_bitmap(&container->bcontainer, &vbmap,
+ iova, size);
}
if (ret) {
@@ -48,6 +48,28 @@ int vfio_container_dma_unmap(VFIOContainer *bcontainer,
return bcontainer->ops->dma_unmap(bcontainer, iova, size, iotlb);
}
+int vfio_container_set_dirty_page_tracking(VFIOContainer *bcontainer,
+ bool start)
+{
+ /* Fallback to all pages dirty if dirty page sync isn't supported */
+ if (!bcontainer->ops->set_dirty_page_tracking) {
+ return 0;
+ }
+
+ return bcontainer->ops->set_dirty_page_tracking(bcontainer, start);
+}
+
+int vfio_container_query_dirty_bitmap(VFIOContainer *bcontainer,
+ VFIOBitmap *vbmap,
+ hwaddr iova, hwaddr size)
+{
+ if (!bcontainer->ops->query_dirty_bitmap) {
+ return -EINVAL;
+ }
+
+ return bcontainer->ops->query_dirty_bitmap(bcontainer, vbmap, iova, size);
+}
+
int vfio_container_add_section_window(VFIOContainer *bcontainer,
MemoryRegionSection *section,
Error **errp)
@@ -75,6 +97,7 @@ void vfio_container_init(VFIOContainer *bcontainer,
{
bcontainer->ops = ops;
bcontainer->space = space;
+ bcontainer->dirty_pages_supported = false;
QLIST_INIT(&bcontainer->giommu_list);
QLIST_INIT(&bcontainer->hostwin_list);
}
@@ -139,7 +139,7 @@ static int vfio_legacy_dma_unmap(VFIOContainer *bcontainer, hwaddr iova,
if (iotlb && vfio_devices_all_running_and_mig_active(container)) {
if (!vfio_devices_all_device_dirty_tracking(container) &&
- container->dirty_pages_supported) {
+ container->bcontainer.dirty_pages_supported) {
return vfio_dma_unmap_bitmap(container, iova, size, iotlb);
}
@@ -308,14 +308,18 @@ static void vfio_legacy_del_section_window(VFIOContainer *bcontainer,
}
}
-int vfio_set_dirty_page_tracking(VFIOLegacyContainer *container, bool start)
+static int vfio_legacy_set_dirty_page_tracking(VFIOContainer *bcontainer,
+ bool start)
{
+ VFIOLegacyContainer *container = container_of(bcontainer,
+ VFIOLegacyContainer,
+ bcontainer);
int ret;
struct vfio_iommu_type1_dirty_bitmap dirty = {
.argsz = sizeof(dirty),
};
- if (!container->dirty_pages_supported) {
+ if (!bcontainer->dirty_pages_supported) {
return 0;
}
@@ -335,9 +339,13 @@ int vfio_set_dirty_page_tracking(VFIOLegacyContainer *container, bool start)
return ret;
}
-int vfio_query_dirty_bitmap(VFIOLegacyContainer *container, VFIOBitmap *vbmap,
- hwaddr iova, hwaddr size)
+static int vfio_legacy_query_dirty_bitmap(VFIOContainer *bcontainer,
+ VFIOBitmap *vbmap,
+ hwaddr iova, hwaddr size)
{
+ VFIOLegacyContainer *container = container_of(bcontainer,
+ VFIOLegacyContainer,
+ bcontainer);
struct vfio_iommu_type1_dirty_bitmap *dbitmap;
struct vfio_iommu_type1_dirty_bitmap_get *range;
int ret;
@@ -546,7 +554,7 @@ static void vfio_get_iommu_info_migration(VFIOLegacyContainer *container,
* qemu_real_host_page_size to mark those dirty.
*/
if (cap_mig->pgsize_bitmap & qemu_real_host_page_size()) {
- container->dirty_pages_supported = true;
+ container->bcontainer.dirty_pages_supported = true;
container->max_dirty_bitmap_size = cap_mig->max_dirty_bitmap_size;
container->dirty_pgsizes = cap_mig->pgsize_bitmap;
}
@@ -634,7 +642,6 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as,
container = g_malloc0(sizeof(*container));
container->fd = fd;
container->error = NULL;
- container->dirty_pages_supported = false;
container->dma_max_mappings = 0;
QLIST_INIT(&container->vrdl_list);
bcontainer = &container->bcontainer;
@@ -1173,6 +1180,8 @@ static void vfio_iommu_backend_legacy_ops_class_init(ObjectClass *oc,
ops->dma_map = vfio_legacy_dma_map;
ops->dma_unmap = vfio_legacy_dma_unmap;
+ ops->set_dirty_page_tracking = vfio_legacy_set_dirty_page_tracking;
+ ops->query_dirty_bitmap = vfio_legacy_query_dirty_bitmap;
ops->add_window = vfio_legacy_add_section_window;
ops->del_window = vfio_legacy_del_section_window;
}