From: Alex Williamson <alex.williamson@redhat.com> To: qemu-devel@nongnu.org Cc: Kirti Wankhede <kwankhede@nvidia.com>, Neo Jia <cjia@nvidia.com> Subject: [PULL 13/32] vfio: Add vfio_listener_log_sync to mark dirty pages Date: Mon, 26 Oct 2020 13:34:16 -0600 Message-ID: <160374085615.22414.9118278258571519417.stgit@gimli.home> (raw) In-Reply-To: <160374054442.22414.10832953989449611268.stgit@gimli.home> From: Kirti Wankhede <kwankhede@nvidia.com> vfio_listener_log_sync gets list of dirty pages from container using VFIO_IOMMU_GET_DIRTY_BITMAP ioctl and mark those pages dirty when all devices are stopped and saving state. Return early for the RAM block section of mapped MMIO region. Signed-off-by: Kirti Wankhede <kwankhede@nvidia.com> Reviewed-by: Neo Jia <cjia@nvidia.com> Signed-off-by: Alex Williamson <alex.williamson@redhat.com> --- hw/vfio/common.c | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++ hw/vfio/trace-events | 1 2 files changed, 117 insertions(+) diff --git a/hw/vfio/common.c b/hw/vfio/common.c index d4959c036dd1..2634387df948 100644 --- a/hw/vfio/common.c +++ b/hw/vfio/common.c @@ -29,6 +29,7 @@ #include "hw/vfio/vfio.h" #include "exec/address-spaces.h" #include "exec/memory.h" +#include "exec/ram_addr.h" #include "hw/hw.h" #include "qemu/error-report.h" #include "qemu/main-loop.h" @@ -37,6 +38,7 @@ #include "sysemu/reset.h" #include "trace.h" #include "qapi/error.h" +#include "migration/migration.h" VFIOGroupList vfio_group_list = QLIST_HEAD_INITIALIZER(vfio_group_list); @@ -286,6 +288,39 @@ const MemoryRegionOps vfio_region_ops = { }, }; +/* + * Device state interfaces + */ + +static bool vfio_devices_all_stopped_and_saving(VFIOContainer *container) +{ + VFIOGroup *group; + VFIODevice *vbasedev; + MigrationState *ms = migrate_get_current(); + + if (!migration_is_setup_or_active(ms->state)) { + return false; + } + + QLIST_FOREACH(group, &container->group_list, container_next) { + QLIST_FOREACH(vbasedev, &group->device_list, next) { + VFIOMigration *migration = vbasedev->migration; + + if (!migration) { + return false; + } + + if ((migration->device_state & VFIO_DEVICE_STATE_SAVING) && + !(migration->device_state & VFIO_DEVICE_STATE_RUNNING)) { + continue; + } else { + return false; + } + } + } + return true; +} + /* * DMA - Mapping and unmapping for the "type1" IOMMU interface used on x86 */ @@ -812,9 +847,90 @@ static void vfio_listener_region_del(MemoryListener *listener, } } +static int vfio_get_dirty_bitmap(VFIOContainer *container, uint64_t iova, + uint64_t size, ram_addr_t ram_addr) +{ + struct vfio_iommu_type1_dirty_bitmap *dbitmap; + struct vfio_iommu_type1_dirty_bitmap_get *range; + uint64_t pages; + int ret; + + dbitmap = g_malloc0(sizeof(*dbitmap) + sizeof(*range)); + + dbitmap->argsz = sizeof(*dbitmap) + sizeof(*range); + dbitmap->flags = VFIO_IOMMU_DIRTY_PAGES_FLAG_GET_BITMAP; + range = (struct vfio_iommu_type1_dirty_bitmap_get *)&dbitmap->data; + range->iova = iova; + range->size = size; + + /* + * cpu_physical_memory_set_dirty_lebitmap() expects pages in bitmap of + * TARGET_PAGE_SIZE to mark those dirty. Hence set bitmap's pgsize to + * TARGET_PAGE_SIZE. + */ + range->bitmap.pgsize = TARGET_PAGE_SIZE; + + pages = TARGET_PAGE_ALIGN(range->size) >> TARGET_PAGE_BITS; + range->bitmap.size = ROUND_UP(pages, sizeof(__u64) * BITS_PER_BYTE) / + BITS_PER_BYTE; + range->bitmap.data = g_try_malloc0(range->bitmap.size); + if (!range->bitmap.data) { + ret = -ENOMEM; + goto err_out; + } + + ret = ioctl(container->fd, VFIO_IOMMU_DIRTY_PAGES, dbitmap); + if (ret) { + error_report("Failed to get dirty bitmap for iova: 0x%llx " + "size: 0x%llx err: %d", + range->iova, range->size, errno); + goto err_out; + } + + cpu_physical_memory_set_dirty_lebitmap((uint64_t *)range->bitmap.data, + ram_addr, pages); + + trace_vfio_get_dirty_bitmap(container->fd, range->iova, range->size, + range->bitmap.size, ram_addr); +err_out: + g_free(range->bitmap.data); + g_free(dbitmap); + + return ret; +} + +static int vfio_sync_dirty_bitmap(VFIOContainer *container, + MemoryRegionSection *section) +{ + ram_addr_t ram_addr; + + ram_addr = memory_region_get_ram_addr(section->mr) + + section->offset_within_region; + + return vfio_get_dirty_bitmap(container, + TARGET_PAGE_ALIGN(section->offset_within_address_space), + int128_get64(section->size), ram_addr); +} + +static void vfio_listerner_log_sync(MemoryListener *listener, + MemoryRegionSection *section) +{ + VFIOContainer *container = container_of(listener, VFIOContainer, listener); + + if (vfio_listener_skipped_section(section) || + !container->dirty_pages_supported) { + return; + } + + if (vfio_devices_all_stopped_and_saving(container)) { + vfio_sync_dirty_bitmap(container, section); + } +} + static const MemoryListener vfio_memory_listener = { .region_add = vfio_listener_region_add, .region_del = vfio_listener_region_del, + .log_sync = vfio_listerner_log_sync, }; static void vfio_listener_release(VFIOContainer *container) diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events index a75b5208818c..dd991bd8f265 100644 --- a/hw/vfio/trace-events +++ b/hw/vfio/trace-events @@ -163,3 +163,4 @@ vfio_load_device_config_state(const char *name) " (%s)" vfio_load_state(const char *name, uint64_t data) " (%s) data 0x%"PRIx64 vfio_load_state_device_data(const char *name, uint64_t data_offset, uint64_t data_size) " (%s) Offset 0x%"PRIx64" size 0x%"PRIx64 vfio_load_cleanup(const char *name) " (%s)" +vfio_get_dirty_bitmap(int fd, uint64_t iova, uint64_t size, uint64_t bitmap_size, uint64_t start) "container fd=%d, iova=0x%"PRIx64" size= 0x%"PRIx64" bitmap_size=0x%"PRIx64" start=0x%"PRIx64
next prev parent reply index Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-10-26 19:32 [PULL 00/32] VFIO updates 2020-10-26 (for QEMU 5.2 soft-freeze) Alex Williamson 2020-10-26 19:32 ` [PULL 01/32] vfio: Add function to unmap VFIO region Alex Williamson 2020-10-26 19:32 ` [PULL 02/32] vfio: Add vfio_get_object callback to VFIODeviceOps Alex Williamson 2020-10-26 19:32 ` [PULL 03/32] vfio: Add save and load functions for VFIO PCI devices Alex Williamson 2020-10-26 19:32 ` [PULL 04/32] vfio: Add migration region initialization and finalize function Alex Williamson 2020-10-26 19:33 ` [PULL 05/32] vfio: Add VM state change handler to know state of VM Alex Williamson 2020-10-26 19:33 ` [PULL 06/32] vfio: Add migration state change notifier Alex Williamson 2020-10-26 19:33 ` [PULL 07/32] vfio: Register SaveVMHandlers for VFIO device Alex Williamson 2020-10-26 19:33 ` [PULL 08/32] vfio: Add save state functions to SaveVMHandlers Alex Williamson 2020-10-26 19:33 ` [PULL 09/32] vfio: Add load " Alex Williamson 2020-10-26 19:33 ` [PULL 10/32] memory: Set DIRTY_MEMORY_MIGRATION when IOMMU is enabled Alex Williamson 2020-10-26 19:34 ` [PULL 11/32] vfio: Get migration capability flags for container Alex Williamson 2020-10-26 19:34 ` [PULL 12/32] vfio: Add function to start and stop dirty pages tracking Alex Williamson 2020-10-26 19:34 ` Alex Williamson [this message] 2020-10-26 19:34 ` [PULL 14/32] vfio: Dirty page tracking when vIOMMU is enabled Alex Williamson 2020-10-26 19:34 ` [PULL 15/32] vfio: Add ioctl to get dirty pages bitmap during dma unmap Alex Williamson 2020-10-26 19:34 ` [PULL 16/32] vfio: Make vfio-pci device migration capable Alex Williamson 2020-10-26 19:34 ` [PULL 17/32] qapi: Add VFIO devices migration stats in Migration stats Alex Williamson 2020-10-26 19:35 ` [PULL 18/32] update-linux-headers: Add vfio_zdev.h Alex Williamson 2020-10-26 19:35 ` [PULL 19/32] linux-headers: update against 5.10-rc1 Alex Williamson 2020-10-26 19:35 ` [PULL 20/32] s390x/pci: Move header files to include/hw/s390x Alex Williamson 2020-10-26 19:35 ` [PULL 21/32] vfio: Create shared routine for scanning info capabilities Alex Williamson 2020-10-26 19:35 ` [PULL 22/32] vfio: Find DMA available capability Alex Williamson 2020-10-26 19:35 ` [PULL 23/32] s390x/pci: Add routine to get the vfio dma available count Alex Williamson 2020-10-26 19:35 ` [PULL 24/32] s390x/pci: Honor DMA limits set by vfio Alex Williamson 2020-10-26 19:35 ` [PULL 25/32] s390x/pci: create a header dedicated to PCI CLP Alex Williamson 2020-10-26 19:36 ` [PULL 26/32] s390x/pci: use a PCI Group structure Alex Williamson 2020-10-26 19:36 ` [PULL 27/32] s390x/pci: clean up s390 PCI groups Alex Williamson 2020-10-26 19:36 ` [PULL 28/32] s390x/pci: use a PCI Function structure Alex Williamson 2020-10-26 19:36 ` [PULL 29/32] vfio: Add routine for finding VFIO_DEVICE_GET_INFO capabilities Alex Williamson 2020-10-26 19:36 ` [PULL 30/32] s390x/pci: get zPCI function info from host Alex Williamson 2020-10-26 19:36 ` [PULL 31/32] hw/vfio: Use lock guard macros Alex Williamson 2020-10-26 19:36 ` [PULL 32/32] vfio: fix incorrect print type Alex Williamson 2020-10-27 23:42 ` [PULL 00/32] VFIO updates 2020-10-26 (for QEMU 5.2 soft-freeze) Peter Maydell 2020-10-28 2:00 ` Alex Williamson 2020-10-28 9:18 ` Dr. David Alan Gilbert 2020-10-28 15:23 ` Miklos Szeredi 2020-10-28 9:21 ` Max Reitz 2020-10-28 8:11 ` Cornelia Huck 2020-10-28 9:28 ` Max Reitz 2020-10-28 9:41 ` Max Reitz 2020-10-28 10:12 ` Cornelia Huck 2020-10-28 15:07 ` Peter Maydell 2020-10-28 15:20 ` Matthew Rosato 2020-10-28 15:41 ` Alex Williamson
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=160374085615.22414.9118278258571519417.stgit@gimli.home \ --to=alex.williamson@redhat.com \ --cc=cjia@nvidia.com \ --cc=kwankhede@nvidia.com \ --cc=qemu-devel@nongnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
QEMU-Devel Archive on lore.kernel.org Archives are clonable: git clone --mirror https://lore.kernel.org/qemu-devel/0 qemu-devel/git/0.git git clone --mirror https://lore.kernel.org/qemu-devel/1 qemu-devel/git/1.git git clone --mirror https://lore.kernel.org/qemu-devel/2 qemu-devel/git/2.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 qemu-devel qemu-devel/ https://lore.kernel.org/qemu-devel \ qemu-devel@nongnu.org public-inbox-index qemu-devel Example config snippet for mirrors Newsgroup available over NNTP: nntp://nntp.lore.kernel.org/org.nongnu.qemu-devel AGPL code for this site: git clone https://public-inbox.org/public-inbox.git