Virtuozzo QEMU development (svt-core@virtuozzo.com)
 help / color / mirror / Atom feed
From: no-reply@sashiko.virtuozzo.com
To: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>,
	 svt-core@virtuozzo.com
Subject: Re: [PATCH QEMU HCI-8.1 v6 32/34] VZ: vfio/region: preserve BAR mappings across cpr-exec #VSTOR-103860
Date: Mon, 2 Nov 2026 11:16:43 +0000	[thread overview]
Message-ID: <010701a19bf9d28e-a958f0e8-613e-4e5d-b829-ef9a7739c1af-000000@eu-central-1.amazonses.com> (raw)
In-Reply-To: <20261102-vfio_v1-v6-32-9bc7cabc850d@virtuozzo.com>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [Medium] vfio: unconditional cpr-transfer blocker added in vfio_device_attach() regresses working mode
- [Medium] vfio: cpr-transfer blocker is skipped for vfio-user devices
- [Low] vfio: BAR mappings in CPR ramblock list lose PROT_READ-only protection under -cpr-ram-rdonly
--

commit 6269c4e3bb1402af4f2335050cc5373497aec6be
Author: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>

VZ: vfio/region: preserve BAR mappings across cpr-exec #VSTOR-103860

This patch saves each VFIO BAR mapping in the CPR ramblock list, so cpr-exec
carries it over with MADV_DOEXEC and the new QEMU reuses it instead of
calling mmap() again. It also adds a cpr-transfer migration blocker to VFIO
devices in vfio_device_attach().

> diff --git a/hw/vfio/device.c b/hw/vfio/device.c
> --- a/hw/vfio/device.c
> +++ b/hw/vfio/device.c

[ ... ]

> @@ -464,12 +464,32 @@ bool vfio_device_attach(char *name, VFIODevice *vbasedev,
>                               TYPE_VFIO_IOMMU_IOMMUFD :
>                               TYPE_VFIO_IOMMU_LEGACY;
>  
> -    return vfio_device_attach_by_iommu_type(iommu_type, name, vbasedev,
> -                                            as, errp);
> +    /*
> +     * Only cpr-exec keeps the address space and so the region mappings,
> +     * see vfio_region_mmap().  A cpr-transfer target would have to map the
> +     * regions anew, which some drivers (NVIDIA vGPU) refuse.
> +     */
> +    error_setg(&vbasedev->cpr.mmap_blocker,
> +               "cpr-transfer is not supported with VFIO devices; "
> +               "use the cpr-exec mode");
> +    if (migrate_add_blocker_modes(&vbasedev->cpr.mmap_blocker, errp,
> +                                  MIG_MODE_CPR_TRANSFER, -1)) {
> +        return false;
> +    }

[Severity: Medium]
Is this blocker too broad?

It is added in vfio_device_attach() for every VFIO device and every iommu
backend, whether or not a BAR is mmapped. At the base commit, cpr-transfer
with VFIO was not blocked. The vfio_devices_present() check was only
reached under:

    if (migrate_mode() == MIG_MODE_CPR_EXEC && migrate_cpr_is_blocked(errp))

The existing cpr-transfer notifier registration in
vfio_cpr_pci_register_device() and the cpr-legacy and cpr-iommufd transfer
blockers and notifiers also become unreachable for VFIO.

Can this regress cpr-transfer for vfio-pci devices that do not need the BAR
reuse path? Would it be better to add the blocker only when a BAR is
actually mapped?

migrate_add_blocker_modes() can also return -EBUSY here, for example during
savevm or an active cpr-transfer migration. Is it intended that a device
attach or hotplug now fails in those cases?

Also, docs/devel/migration/CPR.rst is not updated to mention the new
restriction.

> +
> +    if (!vfio_device_attach_by_iommu_type(iommu_type, name, vbasedev,
> +                                          as, errp)) {
> +        migrate_del_blocker(&vbasedev->cpr.mmap_blocker);
> +        return false;
> +    }
> +
> +    return true;
>  }

[ ... ]

> diff --git a/hw/vfio/region.c b/hw/vfio/region.c
> --- a/hw/vfio/region.c
> +++ b/hw/vfio/region.c

[ ... ]

> +static void vfio_region_cpr_save(VFIORegion *region, int index)
> +{
> +    g_autofree char *name = vfio_region_cpr_name(region, index);
> +    void *addr = region->mmaps[index].mmap;
> +    size_t size = region->mmaps[index].size;
> +
> +    cpr_save_ramblock(name, (cpr_ramblock_t) { (uintptr_t)addr, size });
> +}

[Severity: Low]
Can the BAR mapping lose its original protection here?

vfio_region_mmap() derives prot from VFIO_REGION_INFO_FLAG_READ and
VFIO_REGION_INFO_FLAG_WRITE, so a region with READ but not WRITE is mapped
PROT_READ. This function records only the address and length in the generic
ramblock list.

With -cpr-ram-rdonly, cpr_exec_cb() runs mark_ram_rdonly() over every entry
including the BARs. mark_ram_rw() then calls qemu_mprotect_rw() on every
entry, both in cpr_ram_restore_rw() and in the new QEMU path.

Could a read-only BAR mapping become writable after cpr-exec, or after a
failed cpr-exec rollback, when this debug option is used?

[ ... ]

> @@ -347,7 +392,9 @@ int vfio_region_mmap(VFIORegion *region)
>              ret = -errno;
>              goto no_mmap;
>          }
> +        vfio_region_cpr_save(region, i);

[Severity: Medium]
Is the cpr-transfer blocker skipped for vfio-user devices?

The blocker is added only in the vfio_device_attach() wrapper.
vfio_user_pci_realize() calls the lower-level function directly:

    if (!vfio_device_attach_by_iommu_type(TYPE_VFIO_IOMMU_USER,
                                          vbasedev->name, vbasedev,
                                          as, errp)) {

It can still reach vfio_bars_register() and then vfio_region_mmap(), and
vfio_user_get_region_info() shows that vfio-user regions can be mmappable.
So vfio_region_cpr_save() records the BAR address in cpr_state.ramblocks
for those devices too.

With cpr-transfer, can vfio_region_cpr_find() in the target process then
return an address that belongs to the source process? That address would be
passed to memory_region_init_ram_device_ptr(). I did not find any cpr or
blocker code under hw/vfio-user/ that would prevent this.

>  
> +mapped:
>          name = g_strdup_printf("%s mmaps[%d]",

[ ... ]

-- 
Sashiko AI review · https://sashiko.vzint.dev/#/patchset/20261102-vfio_v1-v6-0-9bc7cabc850d@virtuozzo.com?part=32

  reply	other threads:[~2026-11-02 11:16 UTC|newest]

Thread overview: 70+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-02 10:36 [PATCH QEMU HCI-8.1 v6 00/34] vfio: support qemu-update with passed through GPU's and vGPU's #VSTOR-103860 Andrey Drobyshev
2026-11-02 10:36 ` [PATCH QEMU HCI-8.1 v6 01/34] VZ: migration/cpr-exec: fix Error leak in preserve_ram() Andrey Drobyshev
2026-11-02 10:39   ` no-reply
2026-11-02 10:36 ` [PATCH QEMU HCI-8.1 v6 02/34] migration/cpr-exec: restore RAM write access if exec fails Andrey Drobyshev
2026-11-02 10:40   ` no-reply
2026-11-02 10:36 ` [PATCH QEMU HCI-8.1 v6 03/34] vfio/region: create BAR dma-bufs with O_CLOEXEC Andrey Drobyshev
2026-11-02 10:40   ` no-reply
2026-11-02 10:36 ` [PATCH QEMU HCI-8.1 v6 04/34] migration/cpr-exec: require a file or exec migration URI Andrey Drobyshev
2026-11-02 10:42   ` no-reply
2026-11-02 10:36 ` [PATCH QEMU HCI-8.1 v6 05/34] migration: close the CPR state if the outgoing channel fails to open Andrey Drobyshev
2026-11-02 10:42   ` no-reply
2026-11-02 10:36 ` [PATCH QEMU HCI-8.1 v6 06/34] migration/cpr-exec: close the persisted state if the " Andrey Drobyshev
2026-11-02 10:44   ` no-reply
2026-11-02 10:36 ` [PATCH QEMU HCI-8.1 v6 07/34] migration: don't refuse a blocker over a migration of another mode Andrey Drobyshev
2026-11-02 10:44   ` no-reply
2026-11-02 10:36 ` [PATCH QEMU HCI-8.1 v6 08/34] migration: Plug memory leaks after migrate_set_error() Andrey Drobyshev
2026-11-02 10:44   ` no-reply
2026-11-02 10:36 ` [PATCH QEMU HCI-8.1 v6 09/34] hw/vfio: Fix liveness check in vfio_connect_kvm_msi_virq() Andrey Drobyshev
2026-11-02 10:45   ` no-reply
2026-11-02 10:36 ` [PATCH QEMU HCI-8.1 v6 10/34] vfio/pci: Reject invalid MSI-X Table and PBA BIR values Andrey Drobyshev
2026-11-02 10:45   ` no-reply
2026-11-02 10:36 ` [PATCH QEMU HCI-8.1 v6 11/34] vfio/pci: Fix information leak in vfio_rom_read() Andrey Drobyshev
2026-11-02 10:45   ` no-reply
2026-11-02 10:36 ` [PATCH QEMU HCI-8.1 v6 12/34] vfio/pci: Initialize rom_read_failed in vfio_pci_load_rom() Andrey Drobyshev
2026-11-02 10:46   ` no-reply
2026-11-02 10:36 ` [PATCH QEMU HCI-8.1 v6 13/34] vfio/pci: Grow buffer in vfio_pci_host_match() Andrey Drobyshev
2026-11-02 10:46   ` no-reply
2026-11-02 10:36 ` [PATCH QEMU HCI-8.1 v6 14/34] q35: Fix migration of SMRAM state Andrey Drobyshev
2026-11-02 10:48   ` no-reply
2026-11-02 10:36 ` [PATCH QEMU HCI-8.1 v6 15/34] migration: ensure APIC is loaded prior to VFIO PCI devices Andrey Drobyshev
2026-11-02 10:47   ` no-reply
2026-11-02 10:36 ` [PATCH QEMU HCI-8.1 v6 16/34] migration: Fix regression of passing error_fatal into vmstate_load_state() Andrey Drobyshev
2026-11-02 10:51   ` no-reply
2026-11-02 10:36 ` [PATCH QEMU HCI-8.1 v6 17/34] migration: vmstate_save_state_v: fix double error_setg Andrey Drobyshev
2026-11-02 10:51   ` no-reply
2026-11-02 10:36 ` [PATCH QEMU HCI-8.1 v6 18/34] migration: yank: Move register instance earlier Andrey Drobyshev
2026-11-02 10:55   ` no-reply
2026-11-02 10:36 ` [PATCH QEMU HCI-8.1 v6 19/34] migration: Free cpr-transfer MigrationAddress along with gsource Andrey Drobyshev
2026-11-02 10:53   ` no-reply
2026-11-02 10:36 ` [PATCH QEMU HCI-8.1 v6 20/34] migration: Move CPR HUP watch to cpr-transfer.c Andrey Drobyshev
2026-11-02 10:54   ` no-reply
2026-11-02 10:36 ` [PATCH QEMU HCI-8.1 v6 21/34] migration: Fix crash on second migration when cancel early Andrey Drobyshev
2026-11-02 10:57   ` no-reply
2026-11-02 10:36 ` [PATCH QEMU HCI-8.1 v6 22/34] kvm: tolerate ioctls after kvm_close() Andrey Drobyshev
2026-11-02 11:01   ` no-reply
2026-11-02 10:36 ` [PATCH QEMU HCI-8.1 v6 23/34] kvm: fix coalesced MMIO flush racing with kvm_close() Andrey Drobyshev
2026-11-02 11:00   ` no-reply
2026-11-02 10:36 ` [PATCH QEMU HCI-8.1 v6 24/34] migration/cpr: add cpr_is_in_progress() Andrey Drobyshev
2026-11-02 11:01   ` no-reply
2026-11-02 10:36 ` [PATCH QEMU HCI-8.1 v6 25/34] vfio/migration: don't migrate device state during CPR Andrey Drobyshev
2026-11-02 11:07   ` no-reply
2026-11-02 10:36 ` [PATCH QEMU HCI-8.1 v6 26/34] vfio/migration: don't assume the device is running on CPR incoming Andrey Drobyshev
2026-11-02 11:06   ` no-reply
2026-11-02 10:36 ` [PATCH QEMU HCI-8.1 v6 27/34] migration/ram: don't start dirty logging in CPR modes Andrey Drobyshev
2026-11-02 11:07   ` no-reply
2026-11-02 10:36 ` [PATCH QEMU HCI-8.1 v6 28/34] VZ: vfio/cpr: don't close KVM on cpr-exec Andrey Drobyshev
2026-11-02 11:09   ` no-reply
2026-11-02 10:36 ` [PATCH QEMU HCI-8.1 v6 29/34] VZ: migration/cpr-exec: abort cpr-exec if memory can't be preserved Andrey Drobyshev
2026-11-02 11:09   ` no-reply
2026-11-02 10:36 ` [PATCH QEMU HCI-8.1 v6 30/34] VZ: migration/cpr-exec: take the vhost-net devices back if exec fails Andrey Drobyshev
2026-11-02 11:11   ` no-reply
2026-11-02 10:36 ` [PATCH QEMU HCI-8.1 v6 31/34] VZ: migration/cpr-exec: don't exec if a vhost-net device can't be released Andrey Drobyshev
2026-11-02 11:10   ` no-reply
2026-11-02 10:36 ` [PATCH QEMU HCI-8.1 v6 32/34] VZ: vfio/region: preserve BAR mappings across cpr-exec #VSTOR-103860 Andrey Drobyshev
2026-11-02 11:16   ` no-reply [this message]
2026-11-02 10:36 ` [PATCH QEMU HCI-8.1 v6 33/34] VZ: migration/cpr-exec: allow cpr-exec with VFIO devices #VSTOR-103860 Andrey Drobyshev
2026-11-02 11:12   ` no-reply
2026-11-02 10:36 ` [PATCH QEMU HCI-8.1 v6 34/34] VZ: vfio/migration: don't wait for stop-copy-only device state #VSTOR-141821 Andrey Drobyshev
2026-11-02 11:15   ` no-reply
  -- strict thread matches above, loose matches on Subject: below --
2026-10-30 14:45 [PATCH QEMU HCI-8.1 v6 00/34] vfio: support qemu-update with passed through GPU's and vGPU's #VSTOR-103860 Andrey Drobyshev
2026-10-30 14:46 ` [PATCH QEMU HCI-8.1 v6 32/34] VZ: vfio/region: preserve BAR mappings across cpr-exec #VSTOR-103860 Andrey Drobyshev

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=010701a19bf9d28e-a958f0e8-613e-4e5d-b829-ef9a7739c1af-000000@eu-central-1.amazonses.com \
    --to=no-reply@sashiko.virtuozzo.com \
    --cc=andrey.drobyshev@virtuozzo.com \
    --cc=svt-core@virtuozzo.com \
    /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
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox