From: no-reply@sashiko.virtuozzo.com
To: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>,
svt-core@virtuozzo.com
Subject: Re: [PATCH QEMU HCI-8.1 v5 32/36] VZ: vfio/region: preserve BAR mappings across cpr-exec #VSTOR-103860
Date: Fri, 23 Oct 2026 17:36:52 +0000 [thread overview]
Message-ID: <010701a169d6442c-24c92fe0-8b4d-4478-9fe1-1edaffabdecf-000000@eu-central-1.amazonses.com> (raw)
In-Reply-To: <20261023-vfio_v1-v5-32-ba0bf3c6d122@virtuozzo.com>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Low] vfio: unclaimed CPR BAR mmap entries are never reconciled after cpr-exec
- [Low] vfio: BAR mmaps in the CPR ramblock list get RAM-only mprotect in cpr-ram-rdonly
--
commit a087f4249b17de71aa8260f7340069a28fcc6353
Author: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
VZ: vfio/region: preserve BAR mappings across cpr-exec #VSTOR-103860
This patch saves each VFIO BAR mmap in the CPR ramblock list so that
cpr_exec_cb() preserves it with MADV_DOEXEC. After cpr-exec, new QEMU finds
the saved mapping and reuses it instead of calling mmap() again. It also
blocks cpr-transfer for VFIO devices.
> diff --git a/hw/vfio/region.c b/hw/vfio/region.c
> --- a/hw/vfio/region.c
> +++ b/hw/vfio/region.c
[ ... ]
> +/*
> + * A saved mapping is one preserved by cpr-exec, reuse it. None means old
> + * QEMU didn't map the region, e.g. its mmap failed or it's mapped lazily,
> + * so map it afresh.
> + */
> +static void *vfio_region_cpr_find(VFIORegion *region, int index)
> +{
> + g_autofree char *name = vfio_region_cpr_name(region, index);
> + cpr_ramblock_t ram = cpr_find_ramblock(name);
> +
> + if (ram.addr && ram.length != region->mmaps[index].size) {
> + error_report("CPR mode=exec is requested, but the mapping of %s "
> + "can't be reused: addr=%p length=%zu, expected "
> + "length=%zu. Aborting", name, (void *)ram.addr,
> + ram.length, region->mmaps[index].size);
> + exit(1);
> + }
> +
> + return (void *)(uintptr_t)ram.addr;
> +}
[Severity: Low]
Is there a path that removes an unclaimed entry after cpr-exec?
vfio_region_cpr_find() only reads the entry with cpr_find_ramblock(). It
never consumes it or marks it as claimed. The entry is removed only by
vfio_subregion_unmap() and vfio_region_finalize().
Suppose new QEMU never calls vfio_region_mmap() for a region that old QEMU
had saved. Examples are a different device configuration, a no-mmap
configuration, or a region that new QEMU maps lazily. The entry then stays
in cpr_state.ramblocks.
cpr_exec_cb() calls cpr_walk_ramblock(preserve_ram), which walks every
entry in the list. A stale BAR entry would be marked MADV_DOEXEC again at
the next cpr-exec.
If a stale entry is later found by name with a different length, this code
calls exit(1) instead of falling back to a fresh mmap.
I could not find any code in the series that reconciles unclaimed entries.
Should unclaimed entries be dropped after the new QEMU finishes device
setup, and should a size mismatch fall back to a fresh mmap?
> +
> +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 putting device BAR mappings into the generic CPR ramblock list
interfere with the -cpr-ram-rdonly debug option?
vfio_region_cpr_save() adds each BAR mmap to the same list that
migration/cpr-exec.c treats as guest RAM. When cpr_ram_rdonly is set,
cpr_exec_cb() runs cpr_walk_ramblock(mark_ram_rdonly) over this list, and
that now includes the BAR mappings.
mark_ram_rw() runs on the exec-failure path and in the new QEMU. It calls
qemu_mprotect_rw() with PROT_READ|PROT_WRITE on every entry, and it calls
abort() on failure:
migration/cpr-exec.c:mark_ram_rw() {
if (qemu_mprotect_rw((void *) ram.addr, ram.length)) {
...
abort();
}
}
vfio_region_mmap() derives prot from region->flags (READ and WRITE). A BAR
mapped read-only or with no access would be widened to read-write. If the
kernel or a driver rejects the mprotect(), QEMU aborts.
Typical vfio-pci BARs are read-write, and the option is debug-only. Should
BAR entries be excluded from the mark_ram_rdonly and mark_ram_rw walks?
[ ... ]
> @@ -427,6 +474,8 @@ void vfio_region_finalize(VFIORegion *region)
>
> for (i = 0; i < region->nr_mmaps; i++) {
> if (region->mmaps[i].mmap) {
> + g_autofree char *cpr_name = vfio_region_cpr_name(region, i);
> + cpr_delete_ramblock(cpr_name);
> munmap(region->mmaps[i].mmap, region->mmaps[i].size);
> }
> }
This is the second of only two places that delete a BAR entry, as noted in
the vfio_region_cpr_find() comment above.
--
Sashiko AI review · https://sashiko.vzint.dev/#/patchset/20261023-vfio_v1-v5-0-ba0bf3c6d122@virtuozzo.com?part=32
next prev parent reply other threads:[~2026-10-23 17:36 UTC|newest]
Thread overview: 73+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-23 16:53 [PATCH QEMU HCI-8.1 v5 00/36] vfio: support qemu-update with passed through GPU's and vGPU's #VSTOR-103860 Andrey Drobyshev
2026-10-23 16:53 ` [PATCH QEMU HCI-8.1 v5 01/36] VZ: migration/cpr-exec: fix Error leak in preserve_ram() Andrey Drobyshev
2026-10-23 16:58 ` no-reply
2026-10-23 16:53 ` [PATCH QEMU HCI-8.1 v5 02/36] migration/cpr-exec: restore RAM write access if exec fails Andrey Drobyshev
2026-10-23 16:58 ` no-reply
2026-10-23 16:53 ` [PATCH QEMU HCI-8.1 v5 03/36] vfio/region: create BAR dma-bufs with O_CLOEXEC Andrey Drobyshev
2026-10-23 17:00 ` no-reply
2026-10-23 16:53 ` [PATCH QEMU HCI-8.1 v5 04/36] migration/cpr-exec: require a file or exec migration URI Andrey Drobyshev
2026-10-23 17:00 ` no-reply
2026-10-23 16:53 ` [PATCH QEMU HCI-8.1 v5 05/36] migration: close the CPR state if the outgoing channel fails to open Andrey Drobyshev
2026-10-23 17:01 ` no-reply
2026-10-23 16:53 ` [PATCH QEMU HCI-8.1 v5 06/36] migration/cpr-exec: close the persisted state if the " Andrey Drobyshev
2026-10-23 17:01 ` no-reply
2026-10-23 16:53 ` [PATCH QEMU HCI-8.1 v5 07/36] migration: don't refuse a blocker over a migration of another mode Andrey Drobyshev
2026-10-23 17:03 ` no-reply
2026-10-23 16:53 ` [PATCH QEMU HCI-8.1 v5 08/36] migration: Plug memory leaks after migrate_set_error() Andrey Drobyshev
2026-10-23 17:02 ` no-reply
2026-10-23 16:53 ` [PATCH QEMU HCI-8.1 v5 09/36] hw/vfio: Fix liveness check in vfio_connect_kvm_msi_virq() Andrey Drobyshev
2026-10-23 17:04 ` no-reply
2026-10-23 16:53 ` [PATCH QEMU HCI-8.1 v5 10/36] vfio/pci: Reject invalid MSI-X Table and PBA BIR values Andrey Drobyshev
2026-10-23 17:03 ` no-reply
2026-10-23 16:53 ` [PATCH QEMU HCI-8.1 v5 11/36] vfio/pci: Fix information leak in vfio_rom_read() Andrey Drobyshev
2026-10-23 17:04 ` no-reply
2026-10-23 16:53 ` [PATCH QEMU HCI-8.1 v5 12/36] vfio/pci: Initialize rom_read_failed in vfio_pci_load_rom() Andrey Drobyshev
2026-10-23 17:05 ` no-reply
2026-10-23 16:53 ` [PATCH QEMU HCI-8.1 v5 13/36] vfio/pci: Grow buffer in vfio_pci_host_match() Andrey Drobyshev
2026-10-23 17:05 ` no-reply
2026-10-23 16:53 ` [PATCH QEMU HCI-8.1 v5 14/36] q35: Fix migration of SMRAM state Andrey Drobyshev
2026-10-23 17:07 ` no-reply
2026-10-23 16:53 ` [PATCH QEMU HCI-8.1 v5 15/36] migration: ensure APIC is loaded prior to VFIO PCI devices Andrey Drobyshev
2026-10-23 17:06 ` no-reply
2026-10-23 16:53 ` [PATCH QEMU HCI-8.1 v5 16/36] migration: Fix regression of passing error_fatal into vmstate_load_state() Andrey Drobyshev
2026-10-23 17:09 ` no-reply
2026-10-23 16:53 ` [PATCH QEMU HCI-8.1 v5 17/36] migration: vmstate_save_state_v: fix double error_setg Andrey Drobyshev
2026-10-23 17:11 ` no-reply
2026-10-23 16:53 ` [PATCH QEMU HCI-8.1 v5 18/36] migration: yank: Move register instance earlier Andrey Drobyshev
2026-10-23 17:13 ` no-reply
2026-10-23 16:53 ` [PATCH QEMU HCI-8.1 v5 19/36] migration: Free cpr-transfer MigrationAddress along with gsource Andrey Drobyshev
2026-10-23 17:12 ` no-reply
2026-10-23 16:53 ` [PATCH QEMU HCI-8.1 v5 20/36] migration: Move CPR HUP watch to cpr-transfer.c Andrey Drobyshev
2026-10-23 17:12 ` no-reply
2026-10-23 16:53 ` [PATCH QEMU HCI-8.1 v5 21/36] migration: Fix crash on second migration when cancel early Andrey Drobyshev
2026-10-23 17:17 ` no-reply
2026-10-23 16:53 ` [PATCH QEMU HCI-8.1 v5 22/36] kvm: tolerate ioctls after kvm_close() Andrey Drobyshev
2026-10-23 17:17 ` no-reply
2026-10-23 16:54 ` [PATCH QEMU HCI-8.1 v5 23/36] kvm: fix coalesced MMIO flush racing with kvm_close() Andrey Drobyshev
2026-10-23 17:19 ` no-reply
2026-10-23 16:54 ` [PATCH QEMU HCI-8.1 v5 24/36] migration/cpr: add cpr_is_in_progress() Andrey Drobyshev
2026-10-23 17:19 ` no-reply
2026-10-23 16:54 ` [PATCH QEMU HCI-8.1 v5 25/36] vfio/migration: don't migrate device state during CPR Andrey Drobyshev
2026-10-23 17:26 ` no-reply
2026-10-23 16:54 ` [PATCH QEMU HCI-8.1 v5 26/36] vfio/migration: don't assume the device is running on CPR incoming Andrey Drobyshev
2026-10-23 17:23 ` no-reply
2026-10-23 16:54 ` [PATCH QEMU HCI-8.1 v5 27/36] vfio/listener: skip dirty page tracking during CPR Andrey Drobyshev
2026-10-23 17:27 ` no-reply
2026-10-23 16:54 ` [PATCH QEMU HCI-8.1 v5 28/36] VZ: vfio/cpr: don't close KVM on cpr-exec Andrey Drobyshev
2026-10-23 17:29 ` no-reply
2026-10-23 16:54 ` [PATCH QEMU HCI-8.1 v5 29/36] VZ: migration/cpr-exec: abort cpr-exec if memory can't be preserved Andrey Drobyshev
2026-10-23 17:29 ` no-reply
2026-10-23 16:54 ` [PATCH QEMU HCI-8.1 v5 30/36] VZ: migration/cpr-exec: take the vhost-net devices back if exec fails Andrey Drobyshev
2026-10-23 17:31 ` no-reply
2026-10-23 16:54 ` [PATCH QEMU HCI-8.1 v5 31/36] VZ: migration/cpr-exec: don't exec if a vhost-net device can't be released Andrey Drobyshev
2026-10-23 17:30 ` no-reply
2026-10-23 16:54 ` [PATCH QEMU HCI-8.1 v5 32/36] VZ: vfio/region: preserve BAR mappings across cpr-exec #VSTOR-103860 Andrey Drobyshev
2026-10-23 17:36 ` no-reply [this message]
2026-10-23 16:54 ` [PATCH QEMU HCI-8.1 v5 33/36] VZ: migration/cpr-exec: allow cpr-exec with VFIO devices #VSTOR-103860 Andrey Drobyshev
2026-10-23 17:32 ` no-reply
2026-10-23 16:54 ` [PATCH QEMU HCI-8.1 v5 34/36] VZ: vfio/container: lift the CPR blocker for mdev " Andrey Drobyshev
2026-10-23 17:34 ` no-reply
2026-10-23 16:54 ` [PATCH QEMU HCI-8.1 v5 35/36] VZ: migration: keep the estimate and wait over starved windows #VSTOR-150595 Andrey Drobyshev
2026-10-23 17:38 ` no-reply
2026-10-23 16:54 ` [PATCH QEMU HCI-8.1 v5 36/36] VZ: migration: don't wait for stop-copy-only device state #VSTOR-150595 Andrey Drobyshev
2026-10-23 17:40 ` no-reply
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=010701a169d6442c-24c92fe0-8b4d-4478-9fe1-1edaffabdecf-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