- kvm-rbd-Run-co-BH-CB-in-the-coroutine-s-AioContext.patch [RHEL-79118] - kvm-curl-Fix-coroutine-waking.patch [RHEL-79118] - kvm-block-io-Take-reqs_lock-for-tracked_requests.patch [RHEL-79118] - kvm-qcow2-Re-initialize-lock-in-invalidate_cache.patch [RHEL-79118] - kvm-qcow2-Fix-cache_clean_timer.patch [RHEL-79118] - kvm-net-bundle-all-offloads-in-a-single-struct.patch [RHEL-143785] - kvm-linux-headers-deal-with-counted_by-annotation.patch [RHEL-143785] - kvm-linux-headers-Update-to-Linux-v6.17-rc1.patch [RHEL-143785] - kvm-virtio-introduce-extended-features-type.patch [RHEL-143785] - kvm-virtio-serialize-extended-features-state.patch [RHEL-143785] - kvm-virtio-add-support-for-negotiating-extended-features.patch [RHEL-143785] - kvm-virtio-pci-implement-support-for-extended-features.patch [RHEL-143785] - kvm-vhost-add-support-for-negotiating-extended-features.patch [RHEL-143785] - kvm-qmp-update-virtio-features-map-to-support-extended-f.patch [RHEL-143785] - kvm-vhost-backend-implement-extended-features-support.patch [RHEL-143785] - kvm-vhost-net-implement-extended-features-support.patch [RHEL-143785] - kvm-virtio-net-implement-extended-features-support.patch [RHEL-143785] - kvm-net-implement-tunnel-probing.patch [RHEL-143785] - kvm-net-implement-UDP-tunnel-features-offloading.patch [RHEL-143785] - Resolves: RHEL-79118 ([network-storage][rbd][core-dump]installation of guest failed sometimes with multiqueue enabled [rhel10]) - Resolves: RHEL-143785 (backport support for GSO over UDP tunnel offload)
197 lines
7.1 KiB
Diff
197 lines
7.1 KiB
Diff
From 71096da8a19183bbe11f28d5dfe6cf6cc38d9585 Mon Sep 17 00:00:00 2001
|
|
From: Paolo Abeni <pabeni@redhat.com>
|
|
Date: Mon, 22 Sep 2025 16:18:21 +0200
|
|
Subject: [PATCH 12/19] virtio-pci: implement support for extended features
|
|
|
|
RH-Author: Laurent Vivier <lvivier@redhat.com>
|
|
RH-MergeRequest: 456: backport support for GSO over UDP tunnel offload
|
|
RH-Jira: RHEL-143785
|
|
RH-Acked-by: Cindy Lu <lulu@redhat.com>
|
|
RH-Acked-by: MST <mst@redhat.com>
|
|
RH-Commit: [7/14] 7d5683a98169722acb250f9e01344ec3d56faad4 (lvivier/qemu-kvm-centos)
|
|
|
|
JIRA: https://issues.redhat.com/browse/RHEL-143785
|
|
|
|
Extend the features configuration space to 128 bits. If the virtio
|
|
device supports any extended features, allow the common read/write
|
|
operation to access all of it, otherwise keep exposing only the
|
|
lower 64 bits.
|
|
|
|
On migration, save the 128 bit version of the features only if the
|
|
upper bits are non zero. Relay on reset to clear all the feature
|
|
space before load.
|
|
|
|
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
|
|
Acked-by: Jason Wang <jasowang@redhat.com>
|
|
Acked-by: Stefano Garzarella <sgarzare@redhat.com>
|
|
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
|
Tested-by: Lei Yang <leiyang@redhat.com>
|
|
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
|
Message-ID: <c0b81601f65b41ca8310eba8f05e2dcf3702de89.1758549625.git.pabeni@redhat.com>
|
|
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
|
(cherry picked from commit 712c79d6d374e7abe94599de5ba2d155d5a79955)
|
|
Signed-off-by: Laurent Vivier <lvivier@redhat.com>
|
|
---
|
|
hw/virtio/virtio-pci.c | 76 ++++++++++++++++++++++++++++++----
|
|
include/hw/virtio/virtio-pci.h | 2 +-
|
|
2 files changed, 68 insertions(+), 10 deletions(-)
|
|
|
|
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
|
|
index 0cdc16217f..d38d0a5e9a 100644
|
|
--- a/hw/virtio/virtio-pci.c
|
|
+++ b/hw/virtio/virtio-pci.c
|
|
@@ -110,6 +110,29 @@ static const VMStateDescription vmstate_virtio_pci_modern_queue_state = {
|
|
}
|
|
};
|
|
|
|
+static bool virtio_pci_modern_state_features128_needed(void *opaque)
|
|
+{
|
|
+ VirtIOPCIProxy *proxy = opaque;
|
|
+ uint32_t features = 0;
|
|
+ int i;
|
|
+
|
|
+ for (i = 2; i < ARRAY_SIZE(proxy->guest_features); ++i) {
|
|
+ features |= proxy->guest_features[i];
|
|
+ }
|
|
+ return features;
|
|
+}
|
|
+
|
|
+static const VMStateDescription vmstate_virtio_pci_modern_state_features128 = {
|
|
+ .name = "virtio_pci/modern_state/features128",
|
|
+ .version_id = 1,
|
|
+ .minimum_version_id = 1,
|
|
+ .needed = &virtio_pci_modern_state_features128_needed,
|
|
+ .fields = (const VMStateField[]) {
|
|
+ VMSTATE_UINT32_SUB_ARRAY(guest_features, VirtIOPCIProxy, 2, 2),
|
|
+ VMSTATE_END_OF_LIST()
|
|
+ }
|
|
+};
|
|
+
|
|
static bool virtio_pci_modern_state_needed(void *opaque)
|
|
{
|
|
VirtIOPCIProxy *proxy = opaque;
|
|
@@ -117,6 +140,12 @@ static bool virtio_pci_modern_state_needed(void *opaque)
|
|
return virtio_pci_modern(proxy);
|
|
}
|
|
|
|
+/*
|
|
+ * Avoid silently breaking migration should the feature space increase
|
|
+ * even more in the (far away) future
|
|
+ */
|
|
+QEMU_BUILD_BUG_ON(VIRTIO_FEATURES_NU32S != 4);
|
|
+
|
|
static const VMStateDescription vmstate_virtio_pci_modern_state_sub = {
|
|
.name = "virtio_pci/modern_state",
|
|
.version_id = 1,
|
|
@@ -125,11 +154,15 @@ static const VMStateDescription vmstate_virtio_pci_modern_state_sub = {
|
|
.fields = (const VMStateField[]) {
|
|
VMSTATE_UINT32(dfselect, VirtIOPCIProxy),
|
|
VMSTATE_UINT32(gfselect, VirtIOPCIProxy),
|
|
- VMSTATE_UINT32_ARRAY(guest_features, VirtIOPCIProxy, 2),
|
|
+ VMSTATE_UINT32_SUB_ARRAY(guest_features, VirtIOPCIProxy, 0, 2),
|
|
VMSTATE_STRUCT_ARRAY(vqs, VirtIOPCIProxy, VIRTIO_QUEUE_MAX, 0,
|
|
vmstate_virtio_pci_modern_queue_state,
|
|
VirtIOPCIQueue),
|
|
VMSTATE_END_OF_LIST()
|
|
+ },
|
|
+ .subsections = (const VMStateDescription * const []) {
|
|
+ &vmstate_virtio_pci_modern_state_features128,
|
|
+ NULL
|
|
}
|
|
};
|
|
|
|
@@ -1478,6 +1511,19 @@ int virtio_pci_add_shm_cap(VirtIOPCIProxy *proxy,
|
|
return virtio_pci_add_mem_cap(proxy, &cap.cap);
|
|
}
|
|
|
|
+static int virtio_pci_select_max(const VirtIODevice *vdev)
|
|
+{
|
|
+ int i;
|
|
+
|
|
+ for (i = VIRTIO_FEATURES_NU64S - 1; i > 0; i--) {
|
|
+ if (vdev->host_features_ex[i]) {
|
|
+ return (i + 1) * 2;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return 2;
|
|
+}
|
|
+
|
|
static uint64_t virtio_pci_common_read(void *opaque, hwaddr addr,
|
|
unsigned size)
|
|
{
|
|
@@ -1495,18 +1541,21 @@ static uint64_t virtio_pci_common_read(void *opaque, hwaddr addr,
|
|
val = proxy->dfselect;
|
|
break;
|
|
case VIRTIO_PCI_COMMON_DF:
|
|
- if (proxy->dfselect <= 1) {
|
|
+ if (proxy->dfselect < virtio_pci_select_max(vdev)) {
|
|
VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
|
|
|
|
- val = (vdev->host_features & ~vdc->legacy_features) >>
|
|
- (32 * proxy->dfselect);
|
|
+ val = vdev->host_features_ex[proxy->dfselect >> 1] >>
|
|
+ (32 * (proxy->dfselect & 1));
|
|
+ if (proxy->dfselect <= 1) {
|
|
+ val &= (~vdc->legacy_features) >> (32 * proxy->dfselect);
|
|
+ }
|
|
}
|
|
break;
|
|
case VIRTIO_PCI_COMMON_GFSELECT:
|
|
val = proxy->gfselect;
|
|
break;
|
|
case VIRTIO_PCI_COMMON_GF:
|
|
- if (proxy->gfselect < ARRAY_SIZE(proxy->guest_features)) {
|
|
+ if (proxy->gfselect < virtio_pci_select_max(vdev)) {
|
|
val = proxy->guest_features[proxy->gfselect];
|
|
}
|
|
break;
|
|
@@ -1589,11 +1638,18 @@ static void virtio_pci_common_write(void *opaque, hwaddr addr,
|
|
proxy->gfselect = val;
|
|
break;
|
|
case VIRTIO_PCI_COMMON_GF:
|
|
- if (proxy->gfselect < ARRAY_SIZE(proxy->guest_features)) {
|
|
+ if (proxy->gfselect < virtio_pci_select_max(vdev)) {
|
|
+ uint64_t features[VIRTIO_FEATURES_NU64S];
|
|
+ int i;
|
|
+
|
|
proxy->guest_features[proxy->gfselect] = val;
|
|
- virtio_set_features(vdev,
|
|
- (((uint64_t)proxy->guest_features[1]) << 32) |
|
|
- proxy->guest_features[0]);
|
|
+ virtio_features_clear(features);
|
|
+ for (i = 0; i < ARRAY_SIZE(proxy->guest_features); ++i) {
|
|
+ uint64_t cur = proxy->guest_features[i];
|
|
+
|
|
+ features[i >> 1] |= cur << ((i & 1) * 32);
|
|
+ }
|
|
+ virtio_set_features_ex(vdev, features);
|
|
}
|
|
break;
|
|
case VIRTIO_PCI_COMMON_MSIX:
|
|
@@ -2312,6 +2368,8 @@ static void virtio_pci_reset(DeviceState *qdev)
|
|
virtio_bus_reset(bus);
|
|
msix_unuse_all_vectors(&proxy->pci_dev);
|
|
|
|
+ memset(proxy->guest_features, 0, sizeof(proxy->guest_features));
|
|
+
|
|
for (i = 0; i < VIRTIO_QUEUE_MAX; i++) {
|
|
proxy->vqs[i].enabled = 0;
|
|
proxy->vqs[i].reset = 0;
|
|
diff --git a/include/hw/virtio/virtio-pci.h b/include/hw/virtio/virtio-pci.h
|
|
index eab5394898..639752977e 100644
|
|
--- a/include/hw/virtio/virtio-pci.h
|
|
+++ b/include/hw/virtio/virtio-pci.h
|
|
@@ -158,7 +158,7 @@ struct VirtIOPCIProxy {
|
|
uint32_t nvectors;
|
|
uint32_t dfselect;
|
|
uint32_t gfselect;
|
|
- uint32_t guest_features[2];
|
|
+ uint32_t guest_features[VIRTIO_FEATURES_NU32S];
|
|
VirtIOPCIQueue vqs[VIRTIO_QUEUE_MAX];
|
|
|
|
VirtIOIRQFD *vector_irqfd;
|
|
--
|
|
2.47.3
|
|
|