All Virtuozzo development lists (kernel + QEMU)
 help / color / mirror / Atom feed
From: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
To: svt-core@virtuozzo.com
Cc: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
Subject: [PATCH QEMU HCI-8.1 v4 27/31] VZ: migration/cpr-exec: take the vhost-net devices back if exec fails
Date: Tue, 20 Oct 2026 19:31:07 +0300	[thread overview]
Message-ID: <20261020-vfio_v1-v4-27-83a5668230e5@virtuozzo.com> (raw)
In-Reply-To: <20261020-vfio_v1-v4-0-83a5668230e5@virtuozzo.com>

Right before execve(), cpr_exec_cb() releases the kernel vhost-net
devices with VHOST_RESET_OWNER, so that the new QEMU can take them.  If
execve() fails, the VM goes on in the old QEMU, but nobody takes the
devices back: the kernel refuses the ioctls of the next
vhost_net_start(), and the guest is left without network.

Take them back with VHOST_SET_OWNER when the exec fails, and set the
vring call and err fds again: VHOST_RESET_OWNER dropped them too, and
vhost_dev_init() registers them only once.  The devices are stopped at
that point, and vhost_net_start() sets up the rest again when the VM
resumes.  Only the devices that were actually released are taken back:
vhost_net_cpr_reset_owners() marks them.  vhost-vsock does the same in
its CPR notifier.

Signed-off-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
---
 hw/net/vhost_net.c        | 49 +++++++++++++++++++++++++++++++++++++++++++++++
 include/hw/virtio/vhost.h |  2 ++
 include/net/vhost_net.h   |  1 +
 migration/cpr-exec.c      |  2 ++
 4 files changed, 54 insertions(+)

diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index 56c697f4bcd..fae6b060c6f 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -594,6 +594,55 @@ void vhost_net_cpr_reset_owners(void)
             if (r < 0 && r != -ENOSYS) {
                 warn_report("cpr: failed to reset vhost-net owner for %s: %s",
                             nc->name, strerror(-r));
+            } else if (r == 0) {
+                net->cpr_owner_reset = true;
+            }
+        }
+    }
+}
+
+/*
+ * Take the ownership back when the exec fails and the VM goes on in the
+ * old QEMU.  VHOST_RESET_OWNER has reset the kernel device, but the devices
+ * are stopped, and vhost_net_start() sets everything up again when the VM
+ * resumes.
+ */
+void vhost_net_cpr_set_owners(void)
+{
+    NetClientState *nc;
+
+    QTAILQ_FOREACH(nc, &net_clients, next) {
+        VHostNetState *net = get_vhost_net(nc);
+
+        if (net && net->cpr_owner_reset) {
+            struct vhost_dev *dev = &net->dev;
+            int i, r = vhost_dev_set_owner(dev);
+
+            if (r < 0) {
+                warn_report("cpr: failed to set vhost-net owner for %s: %s",
+                            nc->name, strerror(-r));
+                continue;
+            }
+            net->cpr_owner_reset = false;
+
+            /* RESET_OWNER also dropped the vring fds set by vhost_dev_init() */
+            for (i = 0; i < dev->nvqs; i++) {
+                const VhostOps *ops = dev->vhost_ops;
+                struct vhost_virtqueue *vq = &dev->vqs[i];
+                struct vhost_vring_file file = {
+                    .index = ops->vhost_get_vq_index(dev, dev->vq_index + i),
+                    .fd = event_notifier_get_wfd(&vq->masked_notifier),
+                };
+
+                r = ops->vhost_set_vring_call(dev, &file);
+                if (r == 0 && ops->vhost_set_vring_err) {
+                    file.fd = event_notifier_get_fd(&vq->error_notifier);
+                    r = ops->vhost_set_vring_err(dev, &file);
+                }
+                if (r < 0) {
+                    warn_report("cpr: failed to set vring fds of %s: %s",
+                                nc->name, strerror(-r));
+                }
             }
         }
     }
diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
index a92439d3443..421f7139cfb 100644
--- a/include/hw/virtio/vhost.h
+++ b/include/hw/virtio/vhost.h
@@ -151,6 +151,8 @@ struct vhost_net {
     SaveAcketFeatures *save_acked_features;
     bool is_vhost_user;
     NetClientState *nc;
+    /* released for cpr-exec, take back if it fails */
+    bool cpr_owner_reset;
 };
 
 /**
diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h
index 39ce7ad0e3d..cdfefa81500 100644
--- a/include/net/vhost_net.h
+++ b/include/net/vhost_net.h
@@ -90,4 +90,5 @@ int vhost_net_virtqueue_restart(VirtIODevice *vdev, NetClientState *nc,
 void vhost_net_save_acked_features(NetClientState *nc);
 
 void vhost_net_cpr_reset_owners(void);
+void vhost_net_cpr_set_owners(void);
 #endif
diff --git a/migration/cpr-exec.c b/migration/cpr-exec.c
index dd2ff9b26ff..21caa614a13 100644
--- a/migration/cpr-exec.c
+++ b/migration/cpr-exec.c
@@ -251,6 +251,8 @@ fail:
     if (cpr_ram_rdonly) {
         cpr_ram_restore_rw();
     }
+    /* Still the same mm, take back the vhost-net devices we released */
+    vhost_net_cpr_set_owners();
 
     /* Note, we can go from state COMPLETED to FAILED */
     migration_call_notifiers(MIG_EVENT_PRECOPY_FAILED, NULL);

-- 
2.47.1


  parent reply	other threads:[~2026-10-20 16:31 UTC|newest]

Thread overview: 63+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-20 16:30 [PATCH QEMU HCI-8.1 v4 00/31] vfio: support qemu-update with passed through GPU's and vGPU's #VSTOR-103860 Andrey Drobyshev
2026-10-20 16:30 ` [PATCH QEMU HCI-8.1 v4 01/31] VZ: migration/cpr-exec: fix Error leak in preserve_ram() Andrey Drobyshev
2026-10-20 16:34   ` no-reply
2026-10-20 16:30 ` [PATCH QEMU HCI-8.1 v4 02/31] migration/cpr-exec: restore RAM write access if exec fails Andrey Drobyshev
2026-10-20 16:34   ` no-reply
2026-10-20 16:30 ` [PATCH QEMU HCI-8.1 v4 03/31] vfio/region: create BAR dma-bufs with O_CLOEXEC Andrey Drobyshev
2026-10-20 16:35   ` no-reply
2026-10-20 16:30 ` [PATCH QEMU HCI-8.1 v4 04/31] migration/cpr-exec: require a file or exec migration URI Andrey Drobyshev
2026-10-20 16:37   ` no-reply
2026-10-20 16:30 ` [PATCH QEMU HCI-8.1 v4 05/31] migration: close the CPR state if the outgoing channel fails to open Andrey Drobyshev
2026-10-20 16:38   ` no-reply
2026-10-20 16:30 ` [PATCH QEMU HCI-8.1 v4 06/31] migration: Plug memory leaks after migrate_set_error() Andrey Drobyshev
2026-10-20 16:38   ` no-reply
2026-10-20 16:30 ` [PATCH QEMU HCI-8.1 v4 07/31] hw/vfio: Fix liveness check in vfio_connect_kvm_msi_virq() Andrey Drobyshev
2026-10-20 16:38   ` no-reply
2026-10-20 16:30 ` [PATCH QEMU HCI-8.1 v4 08/31] vfio/pci: Reject invalid MSI-X Table and PBA BIR values Andrey Drobyshev
2026-10-20 16:38   ` no-reply
2026-10-20 16:30 ` [PATCH QEMU HCI-8.1 v4 09/31] vfio/pci: Fix information leak in vfio_rom_read() Andrey Drobyshev
2026-10-20 16:39   ` no-reply
2026-10-20 16:30 ` [PATCH QEMU HCI-8.1 v4 10/31] vfio/pci: Initialize rom_read_failed in vfio_pci_load_rom() Andrey Drobyshev
2026-10-20 16:40   ` no-reply
2026-10-20 16:30 ` [PATCH QEMU HCI-8.1 v4 11/31] vfio/pci: Grow buffer in vfio_pci_host_match() Andrey Drobyshev
2026-10-20 16:39   ` no-reply
2026-10-20 16:30 ` [PATCH QEMU HCI-8.1 v4 12/31] q35: Fix migration of SMRAM state Andrey Drobyshev
2026-10-20 16:41   ` no-reply
2026-10-20 16:30 ` [PATCH QEMU HCI-8.1 v4 13/31] migration: ensure APIC is loaded prior to VFIO PCI devices Andrey Drobyshev
2026-10-20 16:40   ` no-reply
2026-10-20 16:30 ` [PATCH QEMU HCI-8.1 v4 14/31] migration: Fix regression of passing error_fatal into vmstate_load_state() Andrey Drobyshev
2026-10-20 16:43   ` no-reply
2026-10-20 16:30 ` [PATCH QEMU HCI-8.1 v4 15/31] migration: vmstate_save_state_v: fix double error_setg Andrey Drobyshev
2026-10-20 16:45   ` no-reply
2026-10-20 16:30 ` [PATCH QEMU HCI-8.1 v4 16/31] migration: yank: Move register instance earlier Andrey Drobyshev
2026-10-20 16:47   ` no-reply
2026-10-20 16:30 ` [PATCH QEMU HCI-8.1 v4 17/31] migration: Free cpr-transfer MigrationAddress along with gsource Andrey Drobyshev
2026-10-20 16:47   ` no-reply
2026-10-20 16:30 ` [PATCH QEMU HCI-8.1 v4 18/31] migration: Move CPR HUP watch to cpr-transfer.c Andrey Drobyshev
2026-10-20 16:48   ` no-reply
2026-10-20 16:30 ` [PATCH QEMU HCI-8.1 v4 19/31] migration: Fix crash on second migration when cancel early Andrey Drobyshev
2026-10-20 16:52   ` no-reply
2026-10-20 16:31 ` [PATCH QEMU HCI-8.1 v4 20/31] kvm: tolerate ioctls after kvm_close() Andrey Drobyshev
2026-10-20 16:52   ` no-reply
2026-10-20 16:31 ` [PATCH QEMU HCI-8.1 v4 21/31] kvm: fix coalesced MMIO flush racing with kvm_close() Andrey Drobyshev
2026-10-20 16:54   ` no-reply
2026-10-20 16:31 ` [PATCH QEMU HCI-8.1 v4 22/31] migration/cpr: add cpr_is_in_progress() Andrey Drobyshev
2026-10-20 16:54   ` no-reply
2026-10-20 16:31 ` [PATCH QEMU HCI-8.1 v4 23/31] vfio/migration: don't migrate device state during CPR Andrey Drobyshev
2026-10-20 17:00   ` no-reply
2026-10-20 16:31 ` [PATCH QEMU HCI-8.1 v4 24/31] vfio/listener: skip dirty page tracking " Andrey Drobyshev
2026-10-20 16:59   ` no-reply
2026-10-20 16:31 ` [PATCH QEMU HCI-8.1 v4 25/31] VZ: vfio/cpr: don't close KVM on cpr-exec Andrey Drobyshev
2026-10-20 17:01   ` no-reply
2026-10-20 16:31 ` [PATCH QEMU HCI-8.1 v4 26/31] VZ: migration/cpr-exec: abort cpr-exec if memory can't be preserved Andrey Drobyshev
2026-10-20 17:02   ` no-reply
2026-10-20 16:31 ` Andrey Drobyshev [this message]
2026-10-20 17:03   ` [PATCH QEMU HCI-8.1 v4 27/31] VZ: migration/cpr-exec: take the vhost-net devices back if exec fails no-reply
2026-10-20 16:31 ` [PATCH QEMU HCI-8.1 v4 28/31] VZ: migration/cpr-exec: don't exec if a vhost-net device can't be released Andrey Drobyshev
2026-10-20 17:03   ` no-reply
2026-10-20 16:31 ` [PATCH QEMU HCI-8.1 v4 29/31] VZ: vfio/region: preserve BAR mappings across cpr-exec #VSTOR-103860 Andrey Drobyshev
2026-10-20 17:08   ` no-reply
2026-10-20 16:31 ` [PATCH QEMU HCI-8.1 v4 30/31] VZ: migration/cpr-exec: allow cpr-exec with VFIO devices #VSTOR-103860 Andrey Drobyshev
2026-10-20 17:04   ` no-reply
2026-10-20 16:31 ` [PATCH QEMU HCI-8.1 v4 31/31] VZ: vfio/container: lift the CPR blocker for mdev " Andrey Drobyshev
2026-10-20 17:06   ` 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=20261020-vfio_v1-v4-27-83a5668230e5@virtuozzo.com \
    --to=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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.