summary refs log tree commit diff stats
path: root/hw/net/virtio-net.c
diff options
context:
space:
mode:
authorStefan Hajnoczi <stefanha@redhat.com>2025-01-16 09:02:17 -0500
committerStefan Hajnoczi <stefanha@redhat.com>2025-01-16 09:02:18 -0500
commit0e3327b690b76b7c3966b028110ee053cc16a385 (patch)
tree1bf1c254a5589f5e9f595a55eaa2a6e93bb4c2be /hw/net/virtio-net.c
parent7433709a147706ad7d1956b15669279933d0f82b (diff)
parent3634039b93cc51816263e0cb5ba32e1b61142d5d (diff)
downloadfocaccia-qemu-0e3327b690b76b7c3966b028110ee053cc16a385.tar.gz
focaccia-qemu-0e3327b690b76b7c3966b028110ee053cc16a385.zip
Merge tag 'for_upstream' of https://git.kernel.org/pub/scm/virt/kvm/mst/qemu into staging
virtio,pc,pci: features, fixes, cleanups

The big thing here are:
stage-1 translation in vtd
internal migration in vhost-user
ghes driver preparation for error injection
new resource uuid feature in virtio gpu
new vmclock device

And as usual, fixes and cleanups.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

# -----BEGIN PGP SIGNATURE-----
#
# iQFDBAABCAAtFiEEXQn9CHHI+FuUyooNKB8NuNKNVGkFAmeIOiIPHG1zdEByZWRo
# YXQuY29tAAoJECgfDbjSjVRpORgIAL0clwZxQL7PIPJ91FwXc1bo6Do/HYquAzvH
# eA+ryCG5S5ewh/e2R8SdIUG7nYesEMWJGVL1gb3BFu7wgGh1aLaaTxQ1LIo5HpRF
# P0Ak3QO7TKIsSEcZIz9h3eMEpg6X9d8i2h7llp7H3qqXBbduO+cGfeNH/fZD5IEl
# 7DFvXuJUgUtZb38I+qtcO+9EQFKGHjgdQAN5P/I4vawWJdxN9sBfT4YVEgpVhiq/
# ALxdSeaEiXA4EXexdHVZhXiQzEBsCQ78RZIIDiRE8I34cVY7rolTodKRfr4bip3P
# 6Llu11yvzNi1gppOzkny3QFsRza3hV0RisWYjAMTwLhNCdi/mHQ=
# =GjDq
# -----END PGP SIGNATURE-----
# gpg: Signature made Wed 15 Jan 2025 17:43:46 EST
# gpg:                using RSA key 5D09FD0871C8F85B94CA8A0D281F0DB8D28D5469
# gpg:                issuer "mst@redhat.com"
# gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>" [full]
# gpg:                 aka "Michael S. Tsirkin <mst@redhat.com>" [full]
# Primary key fingerprint: 0270 606B 6F3C DF3D 0B17  0970 C350 3912 AFBE 8E67
#      Subkey fingerprint: 5D09 FD08 71C8 F85B 94CA  8A0D 281F 0DB8 D28D 5469

* tag 'for_upstream' of https://git.kernel.org/pub/scm/virt/kvm/mst/qemu: (49 commits)
  hw/acpi: Add vmclock device
  virtio-net: vhost-user: Implement internal migration
  vhost: Add stubs for the migration state transfer interface
  hw/cxl: Fix msix_notify: Assertion `vector < dev->msix_entries_nr`
  tests: acpi: update expected blobs
  pci: acpi: Windows 'PCI Label Id' bug workaround
  tests: acpi: whitelist expected blobs
  docs: acpi_hest_ghes: fix documentation for CPER size
  acpi/ghes: Change ghes fill logic to work with only one source
  acpi/ghes: move offset calculus to a separate function
  acpi/ghes: better name the offset of the hardware error firmware
  acpi/ghes: rename etc/hardware_error file macros
  acpi/ghes: don't crash QEMU if ghes GED is not found
  acpi/ghes: better name GHES memory error function
  acpi/ghes: make the GHES record generation more generic
  acpi/ghes: don't check if physical_address is not zero
  acpi/ghes: Change the type for source_id
  acpi/ghes: Remove a duplicated out of bounds check
  acpi/ghes: Fix acpi_ghes_record_errors() argument
  acpi/ghes: better handle source_id and notification
  ...

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'hw/net/virtio-net.c')
-rw-r--r--hw/net/virtio-net.c135
1 files changed, 112 insertions, 23 deletions
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 06f096abf6..85e14b788c 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -3337,6 +3337,117 @@ static const VMStateDescription vmstate_virtio_net_rss = {
     },
 };
 
+static struct vhost_dev *virtio_net_get_vhost(VirtIODevice *vdev)
+{
+    VirtIONet *n = VIRTIO_NET(vdev);
+    NetClientState *nc;
+    struct vhost_net *net;
+
+    if (!n->nic) {
+        return NULL;
+    }
+
+    nc = qemu_get_queue(n->nic);
+    if (!nc) {
+        return NULL;
+    }
+
+    net = get_vhost_net(nc->peer);
+    if (!net) {
+        return NULL;
+    }
+
+    return &net->dev;
+}
+
+static int vhost_user_net_save_state(QEMUFile *f, void *pv, size_t size,
+                                     const VMStateField *field,
+                                     JSONWriter *vmdesc)
+{
+    VirtIONet *n = pv;
+    VirtIODevice *vdev = VIRTIO_DEVICE(n);
+    struct vhost_dev *vhdev;
+    Error *local_error = NULL;
+    int ret;
+
+    vhdev = virtio_net_get_vhost(vdev);
+    if (vhdev == NULL) {
+        error_reportf_err(local_error,
+                          "Error getting vhost back-end of %s device %s: ",
+                          vdev->name, vdev->parent_obj.canonical_path);
+        return -1;
+    }
+
+    ret = vhost_save_backend_state(vhdev, f, &local_error);
+    if (ret < 0) {
+        error_reportf_err(local_error,
+                          "Error saving back-end state of %s device %s: ",
+                          vdev->name, vdev->parent_obj.canonical_path);
+        return ret;
+    }
+
+    return 0;
+}
+
+static int vhost_user_net_load_state(QEMUFile *f, void *pv, size_t size,
+                                     const VMStateField *field)
+{
+    VirtIONet *n = pv;
+    VirtIODevice *vdev = VIRTIO_DEVICE(n);
+    struct vhost_dev *vhdev;
+    Error *local_error = NULL;
+    int ret;
+
+    vhdev = virtio_net_get_vhost(vdev);
+    if (vhdev == NULL) {
+        error_reportf_err(local_error,
+                          "Error getting vhost back-end of %s device %s: ",
+                          vdev->name, vdev->parent_obj.canonical_path);
+        return -1;
+    }
+
+    ret = vhost_load_backend_state(vhdev, f, &local_error);
+    if (ret < 0) {
+        error_reportf_err(local_error,
+                          "Error loading  back-end state of %s device %s: ",
+                          vdev->name, vdev->parent_obj.canonical_path);
+        return ret;
+    }
+
+    return 0;
+}
+
+static bool vhost_user_net_is_internal_migration(void *opaque)
+{
+    VirtIONet *n = opaque;
+    VirtIODevice *vdev = VIRTIO_DEVICE(n);
+    struct vhost_dev *vhdev;
+
+    vhdev = virtio_net_get_vhost(vdev);
+    if (vhdev == NULL) {
+        return false;
+    }
+
+    return vhost_supports_device_state(vhdev);
+}
+
+static const VMStateDescription vhost_user_net_backend_state = {
+    .name = "virtio-net-device/backend",
+    .version_id = 0,
+    .needed = vhost_user_net_is_internal_migration,
+    .fields = (const VMStateField[]) {
+        {
+            .name = "backend",
+            .info = &(const VMStateInfo) {
+                .name = "virtio-net vhost-user backend state",
+                .get = vhost_user_net_load_state,
+                .put = vhost_user_net_save_state,
+            },
+         },
+         VMSTATE_END_OF_LIST()
+    }
+};
+
 static const VMStateDescription vmstate_virtio_net_device = {
     .name = "virtio-net-device",
     .version_id = VIRTIO_NET_VM_VERSION,
@@ -3389,6 +3500,7 @@ static const VMStateDescription vmstate_virtio_net_device = {
     },
     .subsections = (const VMStateDescription * const []) {
         &vmstate_virtio_net_rss,
+        &vhost_user_net_backend_state,
         NULL
     }
 };
@@ -3950,29 +4062,6 @@ static bool dev_unplug_pending(void *opaque)
     return vdc->primary_unplug_pending(dev);
 }
 
-static struct vhost_dev *virtio_net_get_vhost(VirtIODevice *vdev)
-{
-    VirtIONet *n = VIRTIO_NET(vdev);
-    NetClientState *nc;
-    struct vhost_net *net;
-
-    if (!n->nic) {
-        return NULL;
-    }
-
-    nc = qemu_get_queue(n->nic);
-    if (!nc) {
-        return NULL;
-    }
-
-    net = get_vhost_net(nc->peer);
-    if (!net) {
-        return NULL;
-    }
-
-    return &net->dev;
-}
-
 static const VMStateDescription vmstate_virtio_net = {
     .name = "virtio-net",
     .minimum_version_id = VIRTIO_NET_VM_VERSION,