!846 QEMU update to version 6.2.0-84(master)

From: @JiaboFeng 
Reviewed-by: @aven6 
Signed-off-by: @aven6
This commit is contained in:
openeuler-ci-bot 2023-11-29 10:48:10 +00:00 committed by Gitee
commit 037bfea747
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
187 changed files with 20388 additions and 1 deletions

View File

@ -0,0 +1,163 @@
From 529074fd45a543a9259441e02652c3ac60673d07 Mon Sep 17 00:00:00 2001
From: fangyi <eric.fangyi@huawei.com>
Date: Wed, 22 Nov 2023 09:53:34 +0800
Subject: [PATCH] Revert "vhost: add support for configure interrupt"
This reverts commit f7220a7ce21604a4bc6260ccca4dc9068c1f27f2.
Fixes: f7220a7ce2 ("vhost: add support for configure interrupt")
Cc: "Cindy Lu" <lulu@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
hw/virtio/vhost.c | 76 ---------------------------------------
include/hw/virtio/vhost.h | 4 ---
2 files changed, 80 deletions(-)
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index caa53443ab..2f9bb96d63 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -1581,67 +1581,6 @@ void vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n,
}
}
-bool vhost_config_pending(struct vhost_dev *hdev)
-{
- assert(hdev->vhost_ops);
- if ((hdev->started == false) ||
- (hdev->vhost_ops->vhost_set_config_call == NULL)) {
- return false;
- }
-
- EventNotifier *notifier =
- &hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier;
- return event_notifier_test_and_clear(notifier);
-}
-
-void vhost_config_mask(struct vhost_dev *hdev, VirtIODevice *vdev, bool mask)
-{
- int fd;
- int r;
- EventNotifier *notifier =
- &hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier;
- EventNotifier *config_notifier = &vdev->config_notifier;
- assert(hdev->vhost_ops);
-
- if ((hdev->started == false) ||
- (hdev->vhost_ops->vhost_set_config_call == NULL)) {
- return;
- }
- if (mask) {
- assert(vdev->use_guest_notifier_mask);
- fd = event_notifier_get_fd(notifier);
- } else {
- fd = event_notifier_get_fd(config_notifier);
- }
- r = hdev->vhost_ops->vhost_set_config_call(hdev, fd);
- if (r < 0) {
- VHOST_OPS_DEBUG(r, "vhost_set_config_call failed");
- }
-}
-
-static void vhost_stop_config_intr(struct vhost_dev *dev)
-{
- int fd = -1;
- assert(dev->vhost_ops);
- if (dev->vhost_ops->vhost_set_config_call) {
- dev->vhost_ops->vhost_set_config_call(dev, fd);
- }
-}
-
-static void vhost_start_config_intr(struct vhost_dev *dev)
-{
- int r;
-
- assert(dev->vhost_ops);
- int fd = event_notifier_get_fd(&dev->vdev->config_notifier);
- if (dev->vhost_ops->vhost_set_config_call) {
- r = dev->vhost_ops->vhost_set_config_call(dev, fd);
- if (!r) {
- event_notifier_set(&dev->vdev->config_notifier);
- }
- }
-}
-
uint64_t vhost_get_features(struct vhost_dev *hdev, const int *feature_bits,
uint64_t features)
{
@@ -1854,16 +1793,6 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
}
}
- r = event_notifier_init(
- &hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier, 0);
- if (r < 0) {
- return r;
- }
- event_notifier_test_and_clear(
- &hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier);
- if (!vdev->use_guest_notifier_mask) {
- vhost_config_mask(hdev, vdev, true);
- }
if (hdev->log_enabled) {
uint64_t log_base;
@@ -1896,7 +1825,6 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
vhost_device_iotlb_miss(hdev, vq->used_phys, true);
}
}
- vhost_start_config_intr(hdev);
return 0;
fail_log:
vhost_log_put(hdev, false);
@@ -1922,9 +1850,6 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev)
/* should only be called after backend is connected */
assert(hdev->vhost_ops);
- event_notifier_test_and_clear(
- &hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier);
- event_notifier_test_and_clear(&vdev->config_notifier);
if (hdev->vhost_ops->vhost_dev_start) {
hdev->vhost_ops->vhost_dev_start(hdev, false);
@@ -1942,7 +1867,6 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev)
}
memory_listener_unregister(&hdev->iommu_listener);
}
- vhost_stop_config_intr(hdev);
vhost_log_put(hdev, true);
hdev->started = false;
hdev->vdev = NULL;
diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
index 2ae5c3bfd8..86f36f0106 100644
--- a/include/hw/virtio/vhost.h
+++ b/include/hw/virtio/vhost.h
@@ -29,7 +29,6 @@ struct vhost_virtqueue {
unsigned long long used_phys;
unsigned used_size;
EventNotifier masked_notifier;
- EventNotifier masked_config_notifier;
struct vhost_dev *dev;
};
@@ -38,7 +37,6 @@ typedef unsigned long vhost_log_chunk_t;
#define VHOST_LOG_BITS (8 * sizeof(vhost_log_chunk_t))
#define VHOST_LOG_CHUNK (VHOST_LOG_PAGE * VHOST_LOG_BITS)
#define VHOST_INVALID_FEATURE_BIT (0xff)
-#define VHOST_QUEUE_NUM_CONFIG_INR 0
struct vhost_log {
unsigned long long size;
@@ -118,8 +116,6 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev);
void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev);
int vhost_dev_enable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev);
void vhost_dev_disable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev);
-bool vhost_config_pending(struct vhost_dev *hdev);
-void vhost_config_mask(struct vhost_dev *hdev, VirtIODevice *vdev, bool mask);
/* Test and clear masked event pending status.
* Should be called after unmask to avoid losing events.
--
2.27.0

View File

@ -0,0 +1,36 @@
From 0ad1ce1ff54a4d654c00e4a3b95361b519f4fd37 Mon Sep 17 00:00:00 2001
From: fangyi <eric.fangyi@huawei.com>
Date: Wed, 22 Nov 2023 09:43:37 +0800
Subject: [PATCH] Revert "vhost: introduce new VhostOps vhost_set_config_call"
This reverts commit af8377d0e9437401ad30d80a27ab1fcf8252fad1.
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
include/hw/virtio/vhost-backend.h | 3 ---
1 file changed, 3 deletions(-)
diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
index bd1c7dfe4f..a64708f456 100644
--- a/include/hw/virtio/vhost-backend.h
+++ b/include/hw/virtio/vhost-backend.h
@@ -125,8 +125,6 @@ typedef int (*vhost_vq_get_addr_op)(struct vhost_dev *dev,
typedef int (*vhost_get_device_id_op)(struct vhost_dev *dev, uint32_t *dev_id);
typedef bool (*vhost_force_iommu_op)(struct vhost_dev *dev);
-typedef int (*vhost_set_config_call_op)(struct vhost_dev *dev,
- int fd);
typedef void (*vhost_set_used_memslots_op)(struct vhost_dev *dev);
typedef unsigned int (*vhost_get_used_memslots_op)(void);
@@ -175,7 +173,6 @@ typedef struct VhostOps {
vhost_vq_get_addr_op vhost_vq_get_addr;
vhost_get_device_id_op vhost_get_device_id;
vhost_force_iommu_op vhost_force_iommu;
- vhost_set_config_call_op vhost_set_config_call;
vhost_set_used_memslots_op vhost_set_used_memslots;
vhost_get_used_memslots_op vhost_get_used_memslots;
} VhostOps;
--
2.27.0

View File

@ -0,0 +1,56 @@
From 92df45517567838512512f093f418067c857e8dc Mon Sep 17 00:00:00 2001
From: fangyi <eric.fangyi@huawei.com>
Date: Wed, 22 Nov 2023 09:58:20 +0800
Subject: [PATCH] Revert "vhost-vdpa: add support for config interrupt"
This reverts commit 634f7c89fbd78f57d00d5d6b39c0ade9df1fe27f.
Fixes: 634f7c89fb ("vhost-vdpa: add support for config interrupt")
Cc: "Cindy Lu" <lulu@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
hw/virtio/trace-events | 1 -
hw/virtio/vhost-vdpa.c | 7 -------
2 files changed, 8 deletions(-)
diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
index 39c36ff7a6..650e521e35 100644
--- a/hw/virtio/trace-events
+++ b/hw/virtio/trace-events
@@ -53,7 +53,6 @@ vhost_vdpa_get_features(void *dev, uint64_t features) "dev: %p features: 0x%"PRI
vhost_vdpa_set_owner(void *dev) "dev: %p"
vhost_vdpa_vq_get_addr(void *dev, void *vq, uint64_t desc_user_addr, uint64_t avail_user_addr, uint64_t used_user_addr) "dev: %p vq: %p desc_user_addr: 0x%"PRIx64" avail_user_addr: 0x%"PRIx64" used_user_addr: 0x%"PRIx64
vhost_vdpa_get_iova_range(void *dev, uint64_t first, uint64_t last) "dev: %p first: 0x%"PRIx64" last: 0x%"PRIx64
-vhost_vdpa_set_config_call(void *dev, int fd)"dev: %p fd: %d"
# virtio.c
virtqueue_alloc_element(void *elem, size_t sz, unsigned in_num, unsigned out_num) "elem %p size %zd in_num %u out_num %u"
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index d8fba0b714..25a2f570a2 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -737,12 +737,6 @@ static int vhost_vdpa_set_vring_call(struct vhost_dev *dev,
trace_vhost_vdpa_set_vring_call(dev, file->index, file->fd);
return vhost_vdpa_call(dev, VHOST_SET_VRING_CALL, file);
}
-static int vhost_vdpa_set_config_call(struct vhost_dev *dev,
- int fd)
-{
- trace_vhost_vdpa_set_config_call(dev, fd);
- return vhost_vdpa_call(dev, VHOST_VDPA_SET_CONFIG_CALL, &fd);
-}
static int vhost_vdpa_get_features(struct vhost_dev *dev,
uint64_t *features)
@@ -823,7 +817,6 @@ const VhostOps vdpa_ops = {
.vhost_get_device_id = vhost_vdpa_get_device_id,
.vhost_vq_get_addr = vhost_vdpa_vq_get_addr,
.vhost_force_iommu = vhost_vdpa_force_iommu,
- .vhost_set_config_call = vhost_vdpa_set_config_call,
.vhost_set_used_memslots = vhost_vdpa_set_used_memslots,
.vhost_get_used_memslots = vhost_vdpa_get_used_memslots,
};
--
2.27.0

View File

@ -0,0 +1,101 @@
From 3ee9abc7cdd10ccb7057a523326fec21fb01a7bb Mon Sep 17 00:00:00 2001
From: fangyi <eric.fangyi@huawei.com>
Date: Wed, 22 Nov 2023 09:55:19 +0800
Subject: [PATCH] Revert "virtio: add support for configure interrupt"
This reverts commit 081f864f56307551f59c5e934e3f30a7290d0faa.
Fixes: 081f864f56 ("virtio: add support for configure interrupt")
Cc: "Cindy Lu" <lulu@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
hw/virtio/virtio.c | 29 -----------------------------
include/hw/virtio/virtio.h | 4 ----
2 files changed, 33 deletions(-)
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 05409b84d1..c1497f59aa 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -3547,14 +3547,7 @@ static void virtio_queue_guest_notifier_read(EventNotifier *n)
virtio_irq(vq);
}
}
-static void virtio_config_guest_notifier_read(EventNotifier *n)
-{
- VirtIODevice *vdev = container_of(n, VirtIODevice, config_notifier);
- if (event_notifier_test_and_clear(n)) {
- virtio_notify_config(vdev);
- }
-}
void virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign,
bool with_irqfd)
{
@@ -3571,23 +3564,6 @@ void virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign,
}
}
-void virtio_config_set_guest_notifier_fd_handler(VirtIODevice *vdev,
- bool assign, bool with_irqfd)
-{
- EventNotifier *n;
- n = &vdev->config_notifier;
- if (assign && !with_irqfd) {
- event_notifier_set_handler(n, virtio_config_guest_notifier_read);
- } else {
- event_notifier_set_handler(n, NULL);
- }
- if (!assign) {
- /* Test and clear notifier before closing it,*/
- /* in case poll callback didn't have time to run. */
- virtio_config_guest_notifier_read(n);
- }
-}
-
EventNotifier *virtio_queue_get_guest_notifier(VirtQueue *vq)
{
return &vq->guest_notifier;
@@ -3661,11 +3637,6 @@ EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq)
return &vq->host_notifier;
}
-EventNotifier *virtio_config_get_guest_notifier(VirtIODevice *vdev)
-{
- return &vdev->config_notifier;
-}
-
void virtio_queue_set_host_notifier_enabled(VirtQueue *vq, bool enabled)
{
vq->host_notifier_enabled = enabled;
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index 8788ccd1f3..c113a5b864 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -112,7 +112,6 @@ struct VirtIODevice
bool use_guest_notifier_mask;
AddressSpace *dma_as;
QLIST_HEAD(, VirtQueue) *vector_queues;
- EventNotifier config_notifier;
};
struct VirtioDeviceClass {
@@ -316,14 +315,11 @@ uint16_t virtio_get_queue_index(VirtQueue *vq);
EventNotifier *virtio_queue_get_guest_notifier(VirtQueue *vq);
void virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign,
bool with_irqfd);
-void virtio_config_set_guest_notifier_fd_handler(VirtIODevice *vdev,
- bool assign, bool with_irqfd);
int virtio_device_start_ioeventfd(VirtIODevice *vdev);
int virtio_device_grab_ioeventfd(VirtIODevice *vdev);
void virtio_device_release_ioeventfd(VirtIODevice *vdev);
bool virtio_device_ioeventfd_enabled(VirtIODevice *vdev);
EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq);
-EventNotifier *virtio_config_get_guest_notifier(VirtIODevice *vdev);
void virtio_queue_set_host_notifier_enabled(VirtQueue *vq, bool enabled);
void virtio_queue_host_notifier_read(EventNotifier *n);
void virtio_queue_aio_set_host_notifier_handler(VirtQueue *vq, AioContext *ctx,
--
2.27.0

View File

@ -0,0 +1,161 @@
From 01e4e3aa5f2e2e44b72e81e76a74821edf2debd3 Mon Sep 17 00:00:00 2001
From: fangyi <eric.fangyi@huawei.com>
Date: Wed, 22 Nov 2023 10:05:16 +0800
Subject: [PATCH] Revert "virtio: introduce macro IRTIO_CONFIG_IRQ_IDX"
This reverts commit bf1d85c166c19af95dbd27b1faba1d2909732323.
Fixes: bf1d85c166 ("virtio: introduce macro IRTIO_CONFIG_IRQ_IDX")
Cc: "Cindy Lu" <lulu@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
hw/display/vhost-user-gpu.c | 6 ------
hw/net/virtio-net.c | 10 ++--------
hw/virtio/vhost-user-fs.c | 6 ------
hw/virtio/vhost-vsock-common.c | 6 ------
hw/virtio/virtio-crypto.c | 6 ------
include/hw/virtio/virtio.h | 3 ---
6 files changed, 2 insertions(+), 35 deletions(-)
diff --git a/hw/display/vhost-user-gpu.c b/hw/display/vhost-user-gpu.c
index 73ad3d84c9..49df56cd14 100644
--- a/hw/display/vhost-user-gpu.c
+++ b/hw/display/vhost-user-gpu.c
@@ -485,9 +485,6 @@ vhost_user_gpu_guest_notifier_pending(VirtIODevice *vdev, int idx)
{
VhostUserGPU *g = VHOST_USER_GPU(vdev);
- if (idx == VIRTIO_CONFIG_IRQ_IDX) {
- return false;
- }
return vhost_virtqueue_pending(&g->vhost->dev, idx);
}
@@ -496,9 +493,6 @@ vhost_user_gpu_guest_notifier_mask(VirtIODevice *vdev, int idx, bool mask)
{
VhostUserGPU *g = VHOST_USER_GPU(vdev);
- if (idx == VIRTIO_CONFIG_IRQ_IDX) {
- return;
- }
vhost_virtqueue_mask(&g->vhost->dev, vdev, idx, mask);
}
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 7537f44d10..3bd786cc22 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -3195,9 +3195,6 @@ static bool virtio_net_guest_notifier_pending(VirtIODevice *vdev, int idx)
VirtIONet *n = VIRTIO_NET(vdev);
NetClientState *nc = qemu_get_subqueue(n->nic, vq2q(idx));
assert(n->vhost_started);
- if (idx == VIRTIO_CONFIG_IRQ_IDX) {
- return false;
- }
return vhost_net_virtqueue_pending(get_vhost_net(nc->peer), idx);
}
@@ -3207,11 +3204,8 @@ static void virtio_net_guest_notifier_mask(VirtIODevice *vdev, int idx,
VirtIONet *n = VIRTIO_NET(vdev);
NetClientState *nc = qemu_get_subqueue(n->nic, vq2q(idx));
assert(n->vhost_started);
- if (idx == VIRTIO_CONFIG_IRQ_IDX) {
- return;
- }
-
- vhost_net_virtqueue_mask(get_vhost_net(nc->peer), vdev, idx, mask);
+ vhost_net_virtqueue_mask(get_vhost_net(nc->peer),
+ vdev, idx, mask);
}
static void virtio_net_set_config_size(VirtIONet *n, uint64_t host_features)
diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c
index 90c2bc9c5d..fc7dcc96ef 100644
--- a/hw/virtio/vhost-user-fs.c
+++ b/hw/virtio/vhost-user-fs.c
@@ -161,9 +161,6 @@ static void vuf_guest_notifier_mask(VirtIODevice *vdev, int idx,
{
VHostUserFS *fs = VHOST_USER_FS(vdev);
- if (idx == VIRTIO_CONFIG_IRQ_IDX) {
- return;
- }
vhost_virtqueue_mask(&fs->vhost_dev, vdev, idx, mask);
}
@@ -171,9 +168,6 @@ static bool vuf_guest_notifier_pending(VirtIODevice *vdev, int idx)
{
VHostUserFS *fs = VHOST_USER_FS(vdev);
- if (idx == VIRTIO_CONFIG_IRQ_IDX) {
- return false;
- }
return vhost_virtqueue_pending(&fs->vhost_dev, idx);
}
diff --git a/hw/virtio/vhost-vsock-common.c b/hw/virtio/vhost-vsock-common.c
index b1f0d46209..ed706681ac 100644
--- a/hw/virtio/vhost-vsock-common.c
+++ b/hw/virtio/vhost-vsock-common.c
@@ -125,9 +125,6 @@ static void vhost_vsock_common_guest_notifier_mask(VirtIODevice *vdev, int idx,
{
VHostVSockCommon *vvc = VHOST_VSOCK_COMMON(vdev);
- if (idx == VIRTIO_CONFIG_IRQ_IDX) {
- return;
- }
vhost_virtqueue_mask(&vvc->vhost_dev, vdev, idx, mask);
}
@@ -136,9 +133,6 @@ static bool vhost_vsock_common_guest_notifier_pending(VirtIODevice *vdev,
{
VHostVSockCommon *vvc = VHOST_VSOCK_COMMON(vdev);
- if (idx == VIRTIO_CONFIG_IRQ_IDX) {
- return false;
- }
return vhost_virtqueue_pending(&vvc->vhost_dev, idx);
}
diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c
index 52ba34ef1e..274c7b4dea 100644
--- a/hw/virtio/virtio-crypto.c
+++ b/hw/virtio/virtio-crypto.c
@@ -953,9 +953,6 @@ static void virtio_crypto_guest_notifier_mask(VirtIODevice *vdev, int idx,
assert(vcrypto->vhost_started);
- if (idx == VIRTIO_CONFIG_IRQ_IDX) {
- return;
- }
cryptodev_vhost_virtqueue_mask(vdev, queue, idx, mask);
}
@@ -966,9 +963,6 @@ static bool virtio_crypto_guest_notifier_pending(VirtIODevice *vdev, int idx)
assert(vcrypto->vhost_started);
- if (idx == VIRTIO_CONFIG_IRQ_IDX) {
- return false;
- }
return cryptodev_vhost_virtqueue_pending(vdev, queue, idx);
}
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index c113a5b864..7472145821 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -68,9 +68,6 @@ typedef struct VirtQueueElement
#define VIRTIO_NO_VECTOR 0xffff
-/* special index value used internally for config irqs */
-#define VIRTIO_CONFIG_IRQ_IDX -1
-
#define TYPE_VIRTIO_DEVICE "virtio-device"
OBJECT_DECLARE_TYPE(VirtIODevice, VirtioDeviceClass, VIRTIO_DEVICE)
--
2.27.0

View File

@ -0,0 +1,64 @@
From 9633634fe4395000e88c8ab829ec756c7132d3bf Mon Sep 17 00:00:00 2001
From: fangyi <eric.fangyi@huawei.com>
Date: Wed, 22 Nov 2023 09:48:17 +0800
Subject: [PATCH] Revert "virtio-mmio: add support for configure interrupt"
This reverts commit d48185f1a40d4e4ed2fa2873a42b2a5eb8748256.
Fixes: d48185f1a4 ("virtio-mmio: add support for configure interrupt")
Cc: "Cindy Lu" <lulu@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
hw/virtio/virtio-mmio.c | 27 ---------------------------
1 file changed, 27 deletions(-)
diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
index 809132018b..72da12fea5 100644
--- a/hw/virtio/virtio-mmio.c
+++ b/hw/virtio/virtio-mmio.c
@@ -673,30 +673,7 @@ static int virtio_mmio_set_guest_notifier(DeviceState *d, int n, bool assign,
return 0;
}
-static int virtio_mmio_set_config_guest_notifier(DeviceState *d, bool assign)
-{
- VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d);
- VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
- VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
- bool with_irqfd = false;
- EventNotifier *notifier = virtio_config_get_guest_notifier(vdev);
- int r = 0;
- if (assign) {
- r = event_notifier_init(notifier, 0);
- if (r < 0) {
- return r;
- }
- virtio_config_set_guest_notifier_fd_handler(vdev, assign, with_irqfd);
- } else {
- virtio_config_set_guest_notifier_fd_handler(vdev, assign, with_irqfd);
- event_notifier_cleanup(notifier);
- }
- if (vdc->guest_notifier_mask && vdev->use_guest_notifier_mask) {
- vdc->guest_notifier_mask(vdev, VIRTIO_CONFIG_IRQ_IDX, !assign);
- }
- return r;
-}
static int virtio_mmio_set_guest_notifiers(DeviceState *d, int nvqs,
bool assign)
{
@@ -718,10 +695,6 @@ static int virtio_mmio_set_guest_notifiers(DeviceState *d, int nvqs,
goto assign_error;
}
}
- r = virtio_mmio_set_config_guest_notifier(d, assign);
- if (r < 0) {
- goto assign_error;
- }
return 0;
--
2.27.0

View File

@ -0,0 +1,52 @@
From 4f6f9e62214a008523b054c82d663d14d82a2c86 Mon Sep 17 00:00:00 2001
From: fangyi <eric.fangyi@huawei.com>
Date: Wed, 22 Nov 2023 09:50:43 +0800
Subject: [PATCH] Revert "virtio-net: add support for configure interrupt"
This reverts commit 497679d51087090d5a22fd265d1b96cf92d49d9d.
Fixes: 497679d510 ("virtio-net: add support for configure interrupt")
Cc: "Cindy Lu" <lulu@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
hw/net/vhost_net.c | 9 ---------
include/net/vhost_net.h | 2 --
2 files changed, 11 deletions(-)
diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index d5a92144bb..bea053a742 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -524,15 +524,6 @@ void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev,
vhost_virtqueue_mask(&net->dev, dev, idx, mask);
}
-bool vhost_net_config_pending(VHostNetState *net)
-{
- return vhost_config_pending(&net->dev);
-}
-
-void vhost_net_config_mask(VHostNetState *net, VirtIODevice *dev, bool mask)
-{
- vhost_config_mask(&net->dev, dev, mask);
-}
VHostNetState *get_vhost_net(NetClientState *nc)
{
VHostNetState *vhost_net = 0;
diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h
index 1844f0ed46..7bdbf484e4 100644
--- a/include/net/vhost_net.h
+++ b/include/net/vhost_net.h
@@ -39,8 +39,6 @@ int vhost_net_set_config(struct vhost_net *net, const uint8_t *data,
bool vhost_net_virtqueue_pending(VHostNetState *net, int n);
void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev,
int idx, bool mask);
-bool vhost_net_config_pending(VHostNetState *net);
-void vhost_net_config_mask(VHostNetState *net, VirtIODevice *dev, bool mask);
int vhost_net_notify_migration_done(VHostNetState *net, char* mac_addr);
VHostNetState *get_vhost_net(NetClientState *nc);
--
2.27.0

View File

@ -0,0 +1,215 @@
From b97597030e537248f3986589cfc4a32a3e7eb8f5 Mon Sep 17 00:00:00 2001
From: fangyi <eric.fangyi@huawei.com>
Date: Wed, 22 Nov 2023 09:46:06 +0800
Subject: [PATCH] Revert "virtio-pci: add support for configure interrupt"
This reverts commit d5d24d859c3957ea1674d0e102f96439cdbfe93a.
Fixes: d5d24d859c ("virtio-pci: add support for configure interrupt")
Cc: "Cindy Lu" <lulu@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
hw/virtio/virtio-pci.c | 92 ++++++------------------------------------
hw/virtio/virtio-pci.h | 4 +-
2 files changed, 13 insertions(+), 83 deletions(-)
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 90237f523e..75be770971 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -812,8 +812,7 @@ static int virtio_pci_get_notifier(VirtIOPCIProxy *proxy, int queue_no,
VirtQueue *vq;
if (queue_no == VIRTIO_CONFIG_IRQ_IDX) {
- *n = virtio_config_get_guest_notifier(vdev);
- *vector = vdev->config_vector;
+ return -1;
} else {
if (!virtio_queue_get_num(vdev, queue_no)) {
return -1;
@@ -888,10 +887,6 @@ static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs)
return ret;
}
-static int kvm_virtio_pci_vector_config_use(VirtIOPCIProxy *proxy)
-{
- return kvm_virtio_pci_vector_use_one(proxy, VIRTIO_CONFIG_IRQ_IDX);
-}
static void kvm_virtio_pci_vector_release_one(VirtIOPCIProxy *proxy,
int queue_no)
@@ -929,11 +924,6 @@ static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs)
}
}
-static void kvm_virtio_pci_vector_config_release(VirtIOPCIProxy *proxy)
-{
- kvm_virtio_pci_vector_release_one(proxy, VIRTIO_CONFIG_IRQ_IDX);
-}
-
static int virtio_pci_one_vector_unmask(VirtIOPCIProxy *proxy,
unsigned int queue_no,
unsigned int vector,
@@ -1015,17 +1005,9 @@ static int virtio_pci_vector_unmask(PCIDevice *dev, unsigned vector,
}
vq = virtio_vector_next_queue(vq);
}
- /* unmask config intr */
- n = virtio_config_get_guest_notifier(vdev);
- ret = virtio_pci_one_vector_unmask(proxy, VIRTIO_CONFIG_IRQ_IDX, vector,
- msg, n);
- if (ret < 0) {
- goto undo_config;
- }
+
return 0;
-undo_config:
- n = virtio_config_get_guest_notifier(vdev);
- virtio_pci_one_vector_mask(proxy, VIRTIO_CONFIG_IRQ_IDX, vector, n);
+
undo:
vq = virtio_vector_first_queue(vdev, vector);
while (vq && unmasked >= 0) {
@@ -1059,8 +1041,6 @@ static void virtio_pci_vector_mask(PCIDevice *dev, unsigned vector)
}
vq = virtio_vector_next_queue(vq);
}
- n = virtio_config_get_guest_notifier(vdev);
- virtio_pci_one_vector_mask(proxy, VIRTIO_CONFIG_IRQ_IDX, vector, n);
}
static void virtio_pci_vector_poll(PCIDevice *dev,
@@ -1092,34 +1072,6 @@ static void virtio_pci_vector_poll(PCIDevice *dev,
msix_set_pending(dev, vector);
}
}
- /* poll the config intr */
- ret = virtio_pci_get_notifier(proxy, VIRTIO_CONFIG_IRQ_IDX, &notifier,
- &vector);
- if (ret < 0) {
- return;
- }
- if (vector < vector_start || vector >= vector_end ||
- !msix_is_masked(dev, vector)) {
- return;
- }
- if (k->guest_notifier_pending) {
- if (k->guest_notifier_pending(vdev, VIRTIO_CONFIG_IRQ_IDX)) {
- msix_set_pending(dev, vector);
- }
- } else if (event_notifier_test_and_clear(notifier)) {
- msix_set_pending(dev, vector);
- }
-}
-
-void virtio_pci_set_guest_notifier_fd_handler(VirtIODevice *vdev, VirtQueue *vq,
- int n, bool assign,
- bool with_irqfd)
-{
- if (n == VIRTIO_CONFIG_IRQ_IDX) {
- virtio_config_set_guest_notifier_fd_handler(vdev, assign, with_irqfd);
- } else {
- virtio_queue_set_guest_notifier_fd_handler(vq, assign, with_irqfd);
- }
}
static int virtio_pci_set_guest_notifier(DeviceState *d, int n, bool assign,
@@ -1128,25 +1080,17 @@ static int virtio_pci_set_guest_notifier(DeviceState *d, int n, bool assign,
VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
- VirtQueue *vq = NULL;
- EventNotifier *notifier = NULL;
-
- if (n == VIRTIO_CONFIG_IRQ_IDX) {
- notifier = virtio_config_get_guest_notifier(vdev);
- } else {
- vq = virtio_get_queue(vdev, n);
- notifier = virtio_queue_get_guest_notifier(vq);
- }
+ VirtQueue *vq = virtio_get_queue(vdev, n);
+ EventNotifier *notifier = virtio_queue_get_guest_notifier(vq);
if (assign) {
int r = event_notifier_init(notifier, 0);
if (r < 0) {
return r;
}
- virtio_pci_set_guest_notifier_fd_handler(vdev, vq, n, true, with_irqfd);
+ virtio_queue_set_guest_notifier_fd_handler(vq, true, with_irqfd);
} else {
- virtio_pci_set_guest_notifier_fd_handler(vdev, vq, n, false,
- with_irqfd);
+ virtio_queue_set_guest_notifier_fd_handler(vq, false, with_irqfd);
event_notifier_cleanup(notifier);
}
@@ -1188,7 +1132,6 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign)
msix_unset_vector_notifiers(&proxy->pci_dev);
if (proxy->vector_irqfd) {
kvm_virtio_pci_vector_release(proxy, nvqs);
- kvm_virtio_pci_vector_config_release(proxy);
g_free(proxy->vector_irqfd);
proxy->vector_irqfd = NULL;
}
@@ -1204,11 +1147,7 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign)
goto assign_error;
}
}
- r = virtio_pci_set_guest_notifier(d, VIRTIO_CONFIG_IRQ_IDX, assign,
- with_irqfd);
- if (r < 0) {
- goto config_assign_error;
- }
+
/* Must set vector notifier after guest notifier has been assigned */
if ((with_irqfd || k->guest_notifier_mask) && assign) {
if (with_irqfd) {
@@ -1217,14 +1156,11 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign)
msix_nr_vectors_allocated(&proxy->pci_dev));
r = kvm_virtio_pci_vector_use(proxy, nvqs);
if (r < 0) {
- goto config_assign_error;
+ goto assign_error;
}
}
- r = kvm_virtio_pci_vector_config_use(proxy);
- if (r < 0) {
- goto config_error;
- }
- r = msix_set_vector_notifiers(&proxy->pci_dev, virtio_pci_vector_unmask,
+ r = msix_set_vector_notifiers(&proxy->pci_dev,
+ virtio_pci_vector_unmask,
virtio_pci_vector_mask,
virtio_pci_vector_poll);
if (r < 0) {
@@ -1239,11 +1175,7 @@ notifiers_error:
assert(assign);
kvm_virtio_pci_vector_release(proxy, nvqs);
}
-config_error:
- kvm_virtio_pci_vector_config_release(proxy);
-config_assign_error:
- virtio_pci_set_guest_notifier(d, VIRTIO_CONFIG_IRQ_IDX, !assign,
- with_irqfd);
+
assign_error:
/* We get here on assignment failure. Recover by undoing for VQs 0 .. n. */
assert(assign);
diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h
index 6d8e071d8d..d95b1a13a5 100644
--- a/hw/virtio/virtio-pci.h
+++ b/hw/virtio/virtio-pci.h
@@ -256,7 +256,5 @@ void virtio_pci_types_register(const VirtioPCIDeviceTypeInfo *t);
* @fixed_queues.
*/
unsigned virtio_pci_optimal_num_queues(unsigned fixed_queues);
-void virtio_pci_set_guest_notifier_fd_handler(VirtIODevice *vdev, VirtQueue *vq,
- int n, bool assign,
- bool with_irqfd);
+
#endif
--
2.27.0

View File

@ -0,0 +1,255 @@
From 38c0a07985c6616c43ee98caf7054ddd49dcd34e Mon Sep 17 00:00:00 2001
From: fangyi <eric.fangyi@huawei.com>
Date: Wed, 22 Nov 2023 10:02:59 +0800
Subject: [PATCH] Revert "virtio-pci: decouple notifier from interrupt process"
This reverts commit e3480ef81f6fb61cc9c04e3b5be8b7e84484fc05.
Fixes: e3480ef81f ("virtio-pci: decouple notifier from interrupt process")
Cc: "Cindy Lu" <lulu@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
hw/virtio/virtio-pci.c | 88 +++++++++++++++---------------------------
1 file changed, 31 insertions(+), 57 deletions(-)
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 85d7357f66..21c0ec3b1b 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -789,41 +789,29 @@ static void kvm_virtio_pci_vq_vector_release(VirtIOPCIProxy *proxy,
}
static int kvm_virtio_pci_irqfd_use(VirtIOPCIProxy *proxy,
- EventNotifier *n,
+ unsigned int queue_no,
unsigned int vector)
{
VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
+ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
+ VirtQueue *vq = virtio_get_queue(vdev, queue_no);
+ EventNotifier *n = virtio_queue_get_guest_notifier(vq);
return kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, n, NULL, irqfd->virq);
}
static void kvm_virtio_pci_irqfd_release(VirtIOPCIProxy *proxy,
- EventNotifier *n ,
+ unsigned int queue_no,
unsigned int vector)
{
+ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
+ VirtQueue *vq = virtio_get_queue(vdev, queue_no);
+ EventNotifier *n = virtio_queue_get_guest_notifier(vq);
VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
int ret;
ret = kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, n, irqfd->virq);
assert(ret == 0);
}
-static int virtio_pci_get_notifier(VirtIOPCIProxy *proxy, int queue_no,
- EventNotifier **n, unsigned int *vector)
-{
- VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
- VirtQueue *vq;
-
- if (queue_no == VIRTIO_CONFIG_IRQ_IDX) {
- return -1;
- } else {
- if (!virtio_queue_get_num(vdev, queue_no)) {
- return -1;
- }
- *vector = virtio_queue_vector(vdev, queue_no);
- vq = virtio_get_queue(vdev, queue_no);
- *n = virtio_queue_get_guest_notifier(vq);
- }
- return 0;
-}
static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs)
{
@@ -832,15 +820,12 @@ static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs)
VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
unsigned int vector;
int ret, queue_no;
- EventNotifier *n;
+
for (queue_no = 0; queue_no < nvqs; queue_no++) {
if (!virtio_queue_get_num(vdev, queue_no)) {
break;
}
- ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector);
- if (ret < 0) {
- break;
- }
+ vector = virtio_queue_vector(vdev, queue_no);
if (vector >= msix_nr_vectors_allocated(dev)) {
continue;
}
@@ -852,7 +837,7 @@ static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs)
* Otherwise, delay until unmasked in the frontend.
*/
if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
- ret = kvm_virtio_pci_irqfd_use(proxy, n, vector);
+ ret = kvm_virtio_pci_irqfd_use(proxy, queue_no, vector);
if (ret < 0) {
kvm_virtio_pci_vq_vector_release(proxy, vector);
goto undo;
@@ -868,11 +853,7 @@ undo:
continue;
}
if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
- ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector);
- if (ret < 0) {
- break;
- }
- kvm_virtio_pci_irqfd_release(proxy, n, vector);
+ kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
}
kvm_virtio_pci_vq_vector_release(proxy, vector);
}
@@ -886,16 +867,12 @@ static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs)
unsigned int vector;
int queue_no;
VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
- EventNotifier *n;
- int ret ;
+
for (queue_no = 0; queue_no < nvqs; queue_no++) {
if (!virtio_queue_get_num(vdev, queue_no)) {
break;
}
- ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector);
- if (ret < 0) {
- break;
- }
+ vector = virtio_queue_vector(vdev, queue_no);
if (vector >= msix_nr_vectors_allocated(dev)) {
continue;
}
@@ -903,20 +880,21 @@ static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs)
* Otherwise, it was cleaned when masked in the frontend.
*/
if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
- kvm_virtio_pci_irqfd_release(proxy, n, vector);
+ kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
}
kvm_virtio_pci_vq_vector_release(proxy, vector);
}
}
-static int virtio_pci_one_vector_unmask(VirtIOPCIProxy *proxy,
+static int virtio_pci_vq_vector_unmask(VirtIOPCIProxy *proxy,
unsigned int queue_no,
unsigned int vector,
- MSIMessage msg,
- EventNotifier *n)
+ MSIMessage msg)
{
VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
+ VirtQueue *vq = virtio_get_queue(vdev, queue_no);
+ EventNotifier *n = virtio_queue_get_guest_notifier(vq);
VirtIOIRQFD *irqfd;
int ret = 0;
@@ -943,15 +921,14 @@ static int virtio_pci_one_vector_unmask(VirtIOPCIProxy *proxy,
event_notifier_set(n);
}
} else {
- ret = kvm_virtio_pci_irqfd_use(proxy, n, vector);
+ ret = kvm_virtio_pci_irqfd_use(proxy, queue_no, vector);
}
return ret;
}
-static void virtio_pci_one_vector_mask(VirtIOPCIProxy *proxy,
+static void virtio_pci_vq_vector_mask(VirtIOPCIProxy *proxy,
unsigned int queue_no,
- unsigned int vector,
- EventNotifier *n)
+ unsigned int vector)
{
VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
@@ -962,7 +939,7 @@ static void virtio_pci_one_vector_mask(VirtIOPCIProxy *proxy,
if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
k->guest_notifier_mask(vdev, queue_no, true);
} else {
- kvm_virtio_pci_irqfd_release(proxy, n, vector);
+ kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
}
}
@@ -972,7 +949,6 @@ static int virtio_pci_vector_unmask(PCIDevice *dev, unsigned vector,
VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
VirtQueue *vq = virtio_vector_first_queue(vdev, vector);
- EventNotifier *n;
int ret, index, unmasked = 0;
while (vq) {
@@ -981,8 +957,7 @@ static int virtio_pci_vector_unmask(PCIDevice *dev, unsigned vector,
break;
}
if (index < proxy->nvqs_with_notifiers) {
- n = virtio_queue_get_guest_notifier(vq);
- ret = virtio_pci_one_vector_unmask(proxy, index, vector, msg, n);
+ ret = virtio_pci_vq_vector_unmask(proxy, index, vector, msg);
if (ret < 0) {
goto undo;
}
@@ -998,8 +973,7 @@ undo:
while (vq && unmasked >= 0) {
index = virtio_get_queue_index(vq);
if (index < proxy->nvqs_with_notifiers) {
- n = virtio_queue_get_guest_notifier(vq);
- virtio_pci_one_vector_mask(proxy, index, vector, n);
+ virtio_pci_vq_vector_mask(proxy, index, vector);
--unmasked;
}
vq = virtio_vector_next_queue(vq);
@@ -1012,17 +986,15 @@ static void virtio_pci_vector_mask(PCIDevice *dev, unsigned vector)
VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
VirtQueue *vq = virtio_vector_first_queue(vdev, vector);
- EventNotifier *n;
int index;
while (vq) {
index = virtio_get_queue_index(vq);
- n = virtio_queue_get_guest_notifier(vq);
if (!virtio_queue_get_num(vdev, index)) {
break;
}
if (index < proxy->nvqs_with_notifiers) {
- virtio_pci_one_vector_mask(proxy, index, vector, n);
+ virtio_pci_vq_vector_mask(proxy, index, vector);
}
vq = virtio_vector_next_queue(vq);
}
@@ -1038,17 +1010,19 @@ static void virtio_pci_vector_poll(PCIDevice *dev,
int queue_no;
unsigned int vector;
EventNotifier *notifier;
- int ret;
+ VirtQueue *vq;
for (queue_no = 0; queue_no < proxy->nvqs_with_notifiers; queue_no++) {
- ret = virtio_pci_get_notifier(proxy, queue_no, &notifier, &vector);
- if (ret < 0) {
+ if (!virtio_queue_get_num(vdev, queue_no)) {
break;
}
+ vector = virtio_queue_vector(vdev, queue_no);
if (vector < vector_start || vector >= vector_end ||
!msix_is_masked(dev, vector)) {
continue;
}
+ vq = virtio_get_queue(vdev, queue_no);
+ notifier = virtio_queue_get_guest_notifier(vq);
if (k->guest_notifier_pending) {
if (k->guest_notifier_pending(vdev, queue_no)) {
msix_set_pending(dev, vector);
--
2.27.0

View File

@ -0,0 +1,192 @@
From 074043d5d6c2610a320d2bc7d8649b7eff9c806e Mon Sep 17 00:00:00 2001
From: fangyi <eric.fangyi@huawei.com>
Date: Wed, 22 Nov 2023 10:01:17 +0800
Subject: [PATCH] Revert "virtio-pci: decouple the single vector from the
interrupt process"
This reverts commit 316011b8a74e777eb3ba03171cd701a291c28867.
Fixes: 316011b8a7 ("virtio-pci: decouple the single vector from the interrupt process")
Cc: "Cindy Lu" <lulu@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
hw/virtio/virtio-pci.c | 131 ++++++++++++++++++-----------------------
1 file changed, 58 insertions(+), 73 deletions(-)
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 75be770971..85d7357f66 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -762,6 +762,7 @@ static uint32_t virtio_read_config(PCIDevice *pci_dev,
}
static int kvm_virtio_pci_vq_vector_use(VirtIOPCIProxy *proxy,
+ unsigned int queue_no,
unsigned int vector)
{
VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
@@ -824,103 +825,87 @@ static int virtio_pci_get_notifier(VirtIOPCIProxy *proxy, int queue_no,
return 0;
}
-static int kvm_virtio_pci_vector_use_one(VirtIOPCIProxy *proxy, int queue_no)
+static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs)
{
- unsigned int vector;
- int ret;
- EventNotifier *n;
PCIDevice *dev = &proxy->pci_dev;
VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
-
- ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector);
- if (ret < 0) {
- return ret;
- }
- if (vector >= msix_nr_vectors_allocated(dev)) {
- return 0;
- }
- ret = kvm_virtio_pci_vq_vector_use(proxy, vector);
- if (ret < 0) {
- goto undo;
- }
- /*
- * If guest supports masking, set up irqfd now.
- * Otherwise, delay until unmasked in the frontend.
- */
- if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
- ret = kvm_virtio_pci_irqfd_use(proxy, n, vector);
+ unsigned int vector;
+ int ret, queue_no;
+ EventNotifier *n;
+ for (queue_no = 0; queue_no < nvqs; queue_no++) {
+ if (!virtio_queue_get_num(vdev, queue_no)) {
+ break;
+ }
+ ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector);
+ if (ret < 0) {
+ break;
+ }
+ if (vector >= msix_nr_vectors_allocated(dev)) {
+ continue;
+ }
+ ret = kvm_virtio_pci_vq_vector_use(proxy, queue_no, vector);
if (ret < 0) {
- kvm_virtio_pci_vq_vector_release(proxy, vector);
goto undo;
}
+ /* If guest supports masking, set up irqfd now.
+ * Otherwise, delay until unmasked in the frontend.
+ */
+ if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
+ ret = kvm_virtio_pci_irqfd_use(proxy, n, vector);
+ if (ret < 0) {
+ kvm_virtio_pci_vq_vector_release(proxy, vector);
+ goto undo;
+ }
+ }
}
-
return 0;
-undo:
- vector = virtio_queue_vector(vdev, queue_no);
- if (vector >= msix_nr_vectors_allocated(dev)) {
- return ret;
- }
- if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
- ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector);
- if (ret < 0) {
- return ret;
+undo:
+ while (--queue_no >= 0) {
+ vector = virtio_queue_vector(vdev, queue_no);
+ if (vector >= msix_nr_vectors_allocated(dev)) {
+ continue;
}
- kvm_virtio_pci_irqfd_release(proxy, n, vector);
- }
- return ret;
-}
-static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs)
-{
- int queue_no;
- int ret = 0;
- VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
-
- for (queue_no = 0; queue_no < nvqs; queue_no++) {
- if (!virtio_queue_get_num(vdev, queue_no)) {
- return -1;
+ if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
+ ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector);
+ if (ret < 0) {
+ break;
+ }
+ kvm_virtio_pci_irqfd_release(proxy, n, vector);
}
- ret = kvm_virtio_pci_vector_use_one(proxy, queue_no);
+ kvm_virtio_pci_vq_vector_release(proxy, vector);
}
return ret;
}
-
-static void kvm_virtio_pci_vector_release_one(VirtIOPCIProxy *proxy,
- int queue_no)
+static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs)
{
+ PCIDevice *dev = &proxy->pci_dev;
VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
unsigned int vector;
- EventNotifier *n;
- int ret;
- VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
- PCIDevice *dev = &proxy->pci_dev;
-
- ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector);
- if (ret < 0) {
- return;
- }
- if (vector >= msix_nr_vectors_allocated(dev)) {
- return;
- }
- if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
- kvm_virtio_pci_irqfd_release(proxy, n, vector);
- }
- kvm_virtio_pci_vq_vector_release(proxy, vector);
-}
-
-static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs)
-{
int queue_no;
- VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
-
+ VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
+ EventNotifier *n;
+ int ret ;
for (queue_no = 0; queue_no < nvqs; queue_no++) {
if (!virtio_queue_get_num(vdev, queue_no)) {
break;
}
- kvm_virtio_pci_vector_release_one(proxy, queue_no);
+ ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector);
+ if (ret < 0) {
+ break;
+ }
+ if (vector >= msix_nr_vectors_allocated(dev)) {
+ continue;
+ }
+ /* If guest supports masking, clean up irqfd now.
+ * Otherwise, it was cleaned when masked in the frontend.
+ */
+ if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
+ kvm_virtio_pci_irqfd_release(proxy, n, vector);
+ }
+ kvm_virtio_pci_vq_vector_release(proxy, vector);
}
}
--
2.27.0

View File

@ -0,0 +1,37 @@
From db2e1d340763e23180e4709e4ddf33390f2e49ea Mon Sep 17 00:00:00 2001
From: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
Date: Fri, 17 Nov 2023 09:00:01 +0000
Subject: [PATCH] artist: set memory region owners for buffers to the artist
device mainline inclusion commit 39fbaeca096a9bf6cbe2af88572c1cb2aa62aa8c
category: bugfix
---------------------------------------------------------------
This fixes the output of "info qom-tree" so that the buffers appear as children
of the artist device, rather than underneath the "unattached" container.
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Message-Id: <20220624160839.886649-1-mark.cave-ayland@ilande.co.uk>
Reviewed-by: Helge Deller <deller@gmx.de>
Signed-off-by: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
---
hw/display/artist.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/display/artist.c b/hw/display/artist.c
index 21b7fd1b44..1767203477 100644
--- a/hw/display/artist.c
+++ b/hw/display/artist.c
@@ -1359,7 +1359,7 @@ static void artist_create_buffer(ARTISTState *s, const char *name,
{
struct vram_buffer *buf = s->vram_buffer + idx;
- memory_region_init_ram(&buf->mr, NULL, name, width * height,
+ memory_region_init_ram(&buf->mr, OBJECT(s), name, width * height,
&error_fatal);
memory_region_add_subregion_overlap(&s->mem_as_root, *offset, &buf->mr, 0);
--
2.27.0

View File

@ -0,0 +1,89 @@
From dcebeb0f7acf549620faff1badf73baba04b2068 Mon Sep 17 00:00:00 2001
From: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
Date: Fri, 17 Nov 2023 10:15:09 +0000
Subject: [PATCH] e1000: set RX descriptor status in a separate operation
mainline inclusion commit 034d00d4858161e1d4cff82d8d230bce874a04d3 category:
bugfix
---------------------------------------------------------------
The code of setting RX descriptor status field maybe work fine in
previously, however with the update of glibc version, it shows two
issues when guest using dpdk receive packets:
1. The dpdk has a certain probability getting wrong buffer_addr
this impact may be not obvious, such as lost a packet once in
a while
2. The dpdk may consume a packet twice when scan the RX desc queue
over again
this impact will lead a infinite wait in Qemu, since the RDT
(tail pointer) be inscreased to equal to RDH by unexpected,
which regard as the RX desc queue is full
Write a whole of RX desc with DD flag on is not quite correct, because
when the underlying implementation of memcpy using XMM registers to
copy e1000_rx_desc (when AVX or something else CPU feature is usable),
the bytes order of desc writing to memory is indeterminacy
We can use full-scale test case to reproduce the issue-2 by
https://github.com/BASM/qemu_dpdk_e1000_test (thanks to Leonid Myravjev)
I also write a POC test case at https://github.com/cdkey/e1000_poc
which can reproduce both of them, and easy to verify the patch effect.
The hw watchpoint also shows that, when Qemu using XMM related instructions
writing 16 bytes e1000_rx_desc, concurrent with DPDK using movb
writing 1 byte status, the final result of writing to memory will be one
of them, if it made by Qemu which DD flag is on, DPDK will consume it
again.
Setting DD status in a separate operation, can prevent the impact of
disorder memory writing by memcpy, also avoid unexpected data when
concurrent writing status by qemu and guest dpdk.
Links: https://lore.kernel.org/qemu-devel/20200102110504.GG121208@stefanha-x1.localdomain/T/
Reported-by: Leonid Myravjev <asm@asm.pp.ru>
Cc: Stefan Hajnoczi <stefanha@gmail.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: qemu-stable@nongnu.org
Tested-by: Jing Zhang <zhangjing@sangfor.com.cn>
Reviewed-by: Frank Lee <lifan38153@sangfor.com.cn>
Signed-off-by: Ding Hui <dinghui@sangfor.com.cn>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
---
hw/net/e1000.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
index f5bc81296d..e26e0a64c1 100644
--- a/hw/net/e1000.c
+++ b/hw/net/e1000.c
@@ -979,7 +979,7 @@ e1000_receive_iov(NetClientState *nc, const struct iovec *iov, int iovcnt)
base = rx_desc_base(s) + sizeof(desc) * s->mac_reg[RDH];
pci_dma_read(d, base, &desc, sizeof(desc));
desc.special = vlan_special;
- desc.status |= (vlan_status | E1000_RXD_STAT_DD);
+ desc.status &= ~E1000_RXD_STAT_DD;
if (desc.buffer_addr) {
if (desc_offset < size) {
size_t iov_copy;
@@ -1013,6 +1013,9 @@ e1000_receive_iov(NetClientState *nc, const struct iovec *iov, int iovcnt)
DBGOUT(RX, "Null RX descriptor!!\n");
}
pci_dma_write(d, base, &desc, sizeof(desc));
+ desc.status |= (vlan_status | E1000_RXD_STAT_DD);
+ pci_dma_write(d, base + offsetof(struct e1000_rx_desc, status),
+ &desc.status, sizeof(desc.status));
if (++s->mac_reg[RDH] * sizeof(desc) >= s->mac_reg[RDLEN])
s->mac_reg[RDH] = 0;
--
2.27.0

View File

@ -0,0 +1,62 @@
From 81c2b665d9ea6670677f35aa1ab2ad68d6e73aa4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@linaro.org>
Date: Mon, 20 Nov 2023 12:51:15 +0100
Subject: [PATCH] hw/arm/fsl-imx: Do not ignore Error argument
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
mainline inclusion
commit 0cbb56c236a4a28f5149eed227d74bb737321cfc
category: bugfix
--------------------------------------------------------
Both i.MX25 and i.MX6 SoC models ignore the Error argument when
setting the PHY number. Pick &error_abort which is the error
used by the i.MX7 SoC (see commit 1f7197deb0 "ability to change
the FEC PHY on i.MX7 processor").
Fixes: 74c1330582 ("ability to change the FEC PHY on i.MX25 processor")
Fixes: a9c167a3c4 ("ability to change the FEC PHY on i.MX6 processor")
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20231120115116.76858-1-philmd@linaro.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: zhujun2 <zhujun2_yewu@cmss.chinamobile.com>
---
hw/arm/fsl-imx25.c | 3 ++-
hw/arm/fsl-imx6.c | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/hw/arm/fsl-imx25.c b/hw/arm/fsl-imx25.c
index 24c4374590..9aabbf7f58 100644
--- a/hw/arm/fsl-imx25.c
+++ b/hw/arm/fsl-imx25.c
@@ -169,7 +169,8 @@ static void fsl_imx25_realize(DeviceState *dev, Error **errp)
epit_table[i].irq));
}
- object_property_set_uint(OBJECT(&s->fec), "phy-num", s->phy_num, &err);
+ object_property_set_uint(OBJECT(&s->fec), "phy-num", s->phy_num,
+ &error_abort);
qdev_set_nic_properties(DEVICE(&s->fec), &nd_table[0]);
if (!sysbus_realize(SYS_BUS_DEVICE(&s->fec), errp)) {
diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c
index 00dafe3f62..c4b95dc7a7 100644
--- a/hw/arm/fsl-imx6.c
+++ b/hw/arm/fsl-imx6.c
@@ -377,7 +377,8 @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp)
spi_table[i].irq));
}
- object_property_set_uint(OBJECT(&s->eth), "phy-num", s->phy_num, &err);
+ object_property_set_uint(OBJECT(&s->eth), "phy-num", s->phy_num,
+ &error_abort);
qdev_set_nic_properties(DEVICE(&s->eth), &nd_table[0]);
if (!sysbus_realize(SYS_BUS_DEVICE(&s->eth), errp)) {
return;
--
2.27.0

View File

@ -0,0 +1,39 @@
From 2e37d6ac7713c9962cb006900d18e83df54e8e0f Mon Sep 17 00:00:00 2001
From: zhujun2 <zhujun2_yewu@cmss.chinamobile.com>
Date: Fri, 24 Nov 2023 00:21:31 -0800
Subject: [PATCH] hw/net/cadence_gem.c: spelling fixes: Octects
Signed-off-by: zhujun2 <zhujun2_yewu@cmss.chinamobile.com>
---
hw/net/cadence_gem.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
index 24b3a0ff66..21e1bd091f 100644
--- a/hw/net/cadence_gem.c
+++ b/hw/net/cadence_gem.c
@@ -81,8 +81,8 @@
#define GEM_IPGSTRETCH (0x000000BC / 4) /* IPG Stretch reg */
#define GEM_SVLAN (0x000000C0 / 4) /* Stacked VLAN reg */
#define GEM_MODID (0x000000FC / 4) /* Module ID reg */
-#define GEM_OCTTXLO (0x00000100 / 4) /* Octects transmitted Low reg */
-#define GEM_OCTTXHI (0x00000104 / 4) /* Octects transmitted High reg */
+#define GEM_OCTTXLO (0x00000100 / 4) /* Octets transmitted Low reg */
+#define GEM_OCTTXHI (0x00000104 / 4) /* Octets transmitted High reg */
#define GEM_TXCNT (0x00000108 / 4) /* Error-free Frames transmitted */
#define GEM_TXBCNT (0x0000010C / 4) /* Error-free Broadcast Frames */
#define GEM_TXMCNT (0x00000110 / 4) /* Error-free Multicast Frame */
@@ -101,8 +101,8 @@
#define GEM_LATECOLLCNT (0x00000144 / 4) /* Late Collision Frames */
#define GEM_DEFERTXCNT (0x00000148 / 4) /* Deferred Transmission Frames */
#define GEM_CSENSECNT (0x0000014C / 4) /* Carrier Sense Error Counter */
-#define GEM_OCTRXLO (0x00000150 / 4) /* Octects Received register Low */
-#define GEM_OCTRXHI (0x00000154 / 4) /* Octects Received register High */
+#define GEM_OCTRXLO (0x00000150 / 4) /* Octets Received register Low */
+#define GEM_OCTRXHI (0x00000154 / 4) /* Octets Received register High */
#define GEM_RXCNT (0x00000158 / 4) /* Error-free Frames Received */
#define GEM_RXBROADCNT (0x0000015C / 4) /* Error-free Broadcast Frames RX */
#define GEM_RXMULTICNT (0x00000160 / 4) /* Error-free Multicast Frames RX */
--
2.27.0

View File

@ -0,0 +1,65 @@
From 6532f02449e7a001bc74ea43690d6e1a87a7e3fc Mon Sep 17 00:00:00 2001
From: Yuval Shaia <yuval.shaia.ml@gmail.com>
Date: Wed, 1 Mar 2023 16:29:26 +0200
Subject: [PATCH] hw/pvrdma: Protect against buggy or malicious guest driver
Guest driver allocates and initialize page tables to be used as a ring
of descriptors for CQ and async events.
The page table that represents the ring, along with the number of pages
in the page table is passed to the device.
Currently our device supports only one page table for a ring.
Let's make sure that the number of page table entries the driver
reports, do not exceeds the one page table size.
Reported-by: Soul Chen <soulchen8650@gmail.com>
Signed-off-by: Yuval Shaia <yuval.shaia.ml@gmail.com>
Fixes: CVE-2023-1544
Message-ID: <20230301142926.18686-1-yuval.shaia.ml@gmail.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
hw/rdma/vmw/pvrdma_main.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/hw/rdma/vmw/pvrdma_main.c b/hw/rdma/vmw/pvrdma_main.c
index 91206dbb8e..f99b12a592 100644
--- a/hw/rdma/vmw/pvrdma_main.c
+++ b/hw/rdma/vmw/pvrdma_main.c
@@ -91,19 +91,33 @@ static int init_dev_ring(PvrdmaRing *ring, PvrdmaRingState **ring_state,
dma_addr_t dir_addr, uint32_t num_pages)
{
uint64_t *dir, *tbl;
- int rc = 0;
+ int max_pages, rc = 0;
if (!num_pages) {
rdma_error_report("Ring pages count must be strictly positive");
return -EINVAL;
}
+ /*
+ * Make sure we can satisfy the requested number of pages in a single
+ * TARGET_PAGE_SIZE sized page table (taking into account that first entry
+ * is reserved for ring-state)
+ */
+ max_pages = TARGET_PAGE_SIZE / sizeof(dma_addr_t) - 1;
+ if (num_pages > max_pages) {
+ rdma_error_report("Maximum pages on a single directory must not exceed %d\n",
+ max_pages);
+ return -EINVAL;
+ }
+
dir = rdma_pci_dma_map(pci_dev, dir_addr, TARGET_PAGE_SIZE);
if (!dir) {
rdma_error_report("Failed to map to page directory (ring %s)", name);
rc = -ENOMEM;
goto out;
}
+
+ /* We support only one page table for a ring */
tbl = rdma_pci_dma_map(pci_dev, dir[0], TARGET_PAGE_SIZE);
if (!tbl) {
rdma_error_report("Failed to map to page table (ring %s)", name);
--
2.27.0

View File

@ -0,0 +1,38 @@
From 7f5cf2958ee5d178d058470031b96a82d3002a5c Mon Sep 17 00:00:00 2001
From: qihao <qihao_yewu@cmss.chinamobile.com>
Date: Wed, 1 Nov 2023 19:00:34 +0800
Subject: [PATCH] hw/timer/npcm7xx_timer: Prevent timer from counting down past
zero
cheery-pick from 9ef2629712680e70cbf39d8b6cb1ec0e0e2e72fa
The counter register is only 24-bits and counts down. If the timer is
running but the qtimer to reset it hasn't fired off yet, there is a chance
the regster read can return an invalid result.
Signed-off-by: Chris Rauer <crauer@google.com>
Message-id: 20230922181411.2697135-1-crauer@google.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: qihao_yewu <qihao_yewu@cmss.chinamobile.com>
---
hw/timer/npcm7xx_timer.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/hw/timer/npcm7xx_timer.c b/hw/timer/npcm7xx_timer.c
index 32f5e021f8..a8bd93aeb2 100644
--- a/hw/timer/npcm7xx_timer.c
+++ b/hw/timer/npcm7xx_timer.c
@@ -138,6 +138,9 @@ static int64_t npcm7xx_timer_count_to_ns(NPCM7xxTimer *t, uint32_t count)
/* Convert a time interval in nanoseconds to a timer cycle count. */
static uint32_t npcm7xx_timer_ns_to_count(NPCM7xxTimer *t, int64_t ns)
{
+ if (ns < 0) {
+ return 0;
+ }
return clock_ns_to_ticks(t->ctrl->clock, ns) /
npcm7xx_tcsr_prescaler(t->tcsr);
}
--
2.27.0

View File

@ -0,0 +1,64 @@
From fc52088f7aa8a1be3b3c7d135a2aebd28ba4c673 Mon Sep 17 00:00:00 2001
From: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
Date: Mon, 6 Nov 2023 06:57:46 +0000
Subject: [PATCH] hw/usb/hcd-ehci: fix writeback order mainline inclusion
commit f471e8b060798f26a7fc339c6152f82f22a7b33d category: bugfix
---------------------------------------------------------------
The 'active' bit passes control over a qTD between the guest and the
controller: set to 1 by guest to enable execution by the controller,
and the controller sets it to '0' to hand back control to the guest.
ehci_state_writeback write two dwords to main memory using DMA:
the third dword of the qTD (containing dt, total bytes to transfer,
cpage, cerr and status) and the fourth dword of the qTD (containing
the offset).
This commit makes sure the fourth dword is written before the third,
avoiding a race condition where a new offset written into the qTD
by the guest after it observed the status going to go to '0' gets
overwritten by a 'late' DMA writeback of the previous offset.
This race condition could lead to 'cpage out of range (5)' errors,
and reproduced by:
./qemu-system-x86_64 -enable-kvm -bios $SEABIOS/bios.bin -m 4096 -device usb-ehci -blockdev driver=file,read-only=on,filename=/home/aengelen/Downloads/openSUSE-Tumbleweed-DVD-i586-Snapshot20220428-Media.iso,node-name=iso -device usb-storage,drive=iso,bootindex=0 -chardev pipe,id=shell,path=/tmp/pipe -device virtio-serial -device virtconsole,chardev=shell -device virtio-rng-pci -serial mon:stdio -nographic
(press a key, select 'Installation' (2), and accept the default
values. On my machine the 'cpage out of range' is reproduced while
loading the Linux Kernel about once per 7 attempts. With the fix in
this commit it no longer fails)
This problem was previously reported as a seabios problem in
https://mail.coreboot.org/hyperkitty/list/seabios@seabios.org/thread/OUTHT5ISSQJGXPNTUPY3O5E5EPZJCHM3/
and as a nixos CI build failure in
https://github.com/NixOS/nixpkgs/issues/170803
Signed-off-by: Arnout Engelen <arnout@bzzt.net>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
---
hw/usb/hcd-ehci.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index 0289b3696d..f9aa567f5d 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -2013,7 +2013,10 @@ static int ehci_state_writeback(EHCIQueue *q)
ehci_trace_qtd(q, NLPTR_GET(p->qtdaddr), (EHCIqtd *) &q->qh.next_qtd);
qtd = (uint32_t *) &q->qh.next_qtd;
addr = NLPTR_GET(p->qtdaddr);
- put_dwords(q->ehci, addr + 2 * sizeof(uint32_t), qtd + 2, 2);
+ /* First write back the offset */
+ put_dwords(q->ehci, addr + 3 * sizeof(uint32_t), qtd + 3, 1);
+ /* Then write back the token, clearing the 'active' bit */
+ put_dwords(q->ehci, addr + 2 * sizeof(uint32_t), qtd + 2, 1);
ehci_free_packet(p);
/*
--
2.27.0

View File

@ -0,0 +1,70 @@
From f5b5cba0b86caacdea334725bedcdfb689504b3a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alex=20Benn=C3=A9e?= <alex.bennee@linaro.org>
Date: Tue, 2 Aug 2022 10:49:57 +0100
Subject: [PATCH] hw/virtio: add some vhost-user trace events
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
These are useful for tracing the lifetime of vhost-user connections.
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20220802095010.3330793-10-alex.bennee@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
hw/virtio/trace-events | 4 ++++
hw/virtio/vhost.c | 6 ++++++
2 files changed, 10 insertions(+)
diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
index 63c7668e5b..b8a33b2a83 100644
--- a/hw/virtio/trace-events
+++ b/hw/virtio/trace-events
@@ -8,6 +8,10 @@ vhost_region_add_section_aligned(const char *name, uint64_t gpa, uint64_t size,
vhost_section(const char *name) "%s"
vhost_reject_section(const char *name, int d) "%s:%d"
vhost_iotlb_miss(void *dev, int step) "%p step %d"
+vhost_dev_cleanup(void *dev) "%p"
+vhost_dev_start(void *dev, const char *name) "%p:%s"
+vhost_dev_stop(void *dev, const char *name) "%p:%s"
+
# vhost-user.c
vhost_user_postcopy_end_entry(void) ""
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index c1f5cb5b91..86c727d2ab 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -1460,6 +1460,8 @@ void vhost_dev_cleanup(struct vhost_dev *hdev)
{
int i;
+ trace_vhost_dev_cleanup(hdev);
+
for (i = 0; i < hdev->nvqs; ++i) {
vhost_virtqueue_cleanup(hdev->vqs + i);
}
@@ -1766,6 +1768,8 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
/* should only be called after backend is connected */
assert(hdev->vhost_ops);
+ trace_vhost_dev_start(hdev, vdev->name);
+
vdev->vhost_started = true;
hdev->started = true;
hdev->vdev = vdev;
@@ -1852,6 +1856,8 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev)
/* should only be called after backend is connected */
assert(hdev->vhost_ops);
+ trace_vhost_dev_stop(hdev, vdev->name);
+
if (hdev->vhost_ops->vhost_dev_start) {
hdev->vhost_ops->vhost_dev_start(hdev, false);
}
--
2.27.0

View File

@ -0,0 +1,62 @@
From 57451ee8e278827ef0ab592d565c14076dd62fd0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alex=20Benn=C3=A9e?= <alex.bennee@linaro.org>
Date: Mon, 21 Mar 2022 15:30:27 +0000
Subject: [PATCH] hw/virtio: add vhost_user_[read|write] trace points
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
These are useful when trying to debug the initial vhost-user
negotiation, especially when it hard to get logging from the low level
library on the other side.
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20220321153037.3622127-4-alex.bennee@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
hw/virtio/trace-events | 2 ++
hw/virtio/vhost-user.c | 4 ++++
2 files changed, 6 insertions(+)
diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
index 37c1555330..63c7668e5b 100644
--- a/hw/virtio/trace-events
+++ b/hw/virtio/trace-events
@@ -21,6 +21,8 @@ vhost_user_set_mem_table_withfd(int index, const char *name, uint64_t memory_siz
vhost_user_postcopy_waker(const char *rb, uint64_t rb_offset) "%s + 0x%"PRIx64
vhost_user_postcopy_waker_found(uint64_t client_addr) "0x%"PRIx64
vhost_user_postcopy_waker_nomatch(const char *rb, uint64_t rb_offset) "%s + 0x%"PRIx64
+vhost_user_read(uint32_t req, uint32_t flags) "req:%d flags:0x%"PRIx32""
+vhost_user_write(uint32_t req, uint32_t flags) "req:%d flags:0x%"PRIx32""
# vhost-vdpa.c
vhost_vdpa_dma_map(void *vdpa, int fd, uint32_t msg_type, uint64_t iova, uint64_t size, uint64_t uaddr, uint8_t perm, uint8_t type) "vdpa:%p fd: %d msg_type: %"PRIu32" iova: 0x%"PRIx64" size: 0x%"PRIx64" uaddr: 0x%"PRIx64" perm: 0x%"PRIx8" type: %"PRIu8
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index 358dc82010..ea6d40eb5f 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -491,6 +491,8 @@ static int vhost_user_write(struct vhost_dev *dev, VhostUserMsg *msg,
return ret < 0 ? -saved_errno : -EIO;
}
+ trace_vhost_user_write(msg->hdr.request, msg->hdr.flags);
+
return 0;
}
@@ -544,6 +546,8 @@ static int vhost_user_set_log_base(struct vhost_dev *dev, uint64_t base,
}
}
+ trace_vhost_user_read(msg.hdr.request, msg.hdr.flags);
+
return 0;
}
--
2.27.0

View File

@ -0,0 +1,135 @@
From 6cbac9f34c67e2a2e28109152957f5eca35b6e73 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alex=20Benn=C3=A9e?= <alex.bennee@linaro.org>
Date: Mon, 10 Jul 2023 16:35:05 +0100
Subject: [PATCH] hw/virtio: fix typo in VIRTIO_CONFIG_IRQ_IDX comments
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Fixes: 544f0278af (virtio: introduce macro VIRTIO_CONFIG_IRQ_IDX)
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20230710153522.3469097-4-alex.bennee@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
hw/display/vhost-user-gpu.c | 4 ++--
hw/net/virtio-net.c | 4 ++--
hw/virtio/vhost-user-fs.c | 4 ++--
hw/virtio/vhost-vsock-common.c | 4 ++--
hw/virtio/virtio-crypto.c | 4 ++--
5 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/hw/display/vhost-user-gpu.c b/hw/display/vhost-user-gpu.c
index 1c78272a83..4363e34db1 100644
--- a/hw/display/vhost-user-gpu.c
+++ b/hw/display/vhost-user-gpu.c
@@ -487,7 +487,7 @@ vhost_user_gpu_guest_notifier_pending(VirtIODevice *vdev, int idx)
/*
* Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1
- * as the Marco of configure interrupt's IDX, If this driver does not
+ * as the macro of configure interrupt's IDX, If this driver does not
* support, the function will return
*/
@@ -504,7 +504,7 @@ vhost_user_gpu_guest_notifier_mask(VirtIODevice *vdev, int idx, bool mask)
/*
* Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1
- * as the Marco of configure interrupt's IDX, If this driver does not
+ * as the macro of configure interrupt's IDX, If this driver does not
* support, the function will return
*/
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index ae37b3461b..3e1fa6adf3 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -3249,7 +3249,7 @@ static bool virtio_net_guest_notifier_pending(VirtIODevice *vdev, int idx)
}
/*
* Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1
- * as the Marco of configure interrupt's IDX, If this driver does not
+ * as the macro of configure interrupt's IDX, If this driver does not
* support, the function will return false
*/
@@ -3281,7 +3281,7 @@ static void virtio_net_guest_notifier_mask(VirtIODevice *vdev, int idx,
}
/*
*Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1
- * as the Marco of configure interrupt's IDX, If this driver does not
+ * as the macro of configure interrupt's IDX, If this driver does not
* support, the function will return
*/
diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c
index 0c6ecd3b4f..5ac5dcce49 100644
--- a/hw/virtio/vhost-user-fs.c
+++ b/hw/virtio/vhost-user-fs.c
@@ -163,7 +163,7 @@ static void vuf_guest_notifier_mask(VirtIODevice *vdev, int idx,
/*
* Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1
- * as the Marco of configure interrupt's IDX, If this driver does not
+ * as the macro of configure interrupt's IDX, If this driver does not
* support, the function will return
*/
@@ -179,7 +179,7 @@ static bool vuf_guest_notifier_pending(VirtIODevice *vdev, int idx)
/*
* Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1
- * as the Marco of configure interrupt's IDX, If this driver does not
+ * as the macro of configure interrupt's IDX, If this driver does not
* support, the function will return
*/
diff --git a/hw/virtio/vhost-vsock-common.c b/hw/virtio/vhost-vsock-common.c
index e4a8d90f4c..b9cf5f3f29 100644
--- a/hw/virtio/vhost-vsock-common.c
+++ b/hw/virtio/vhost-vsock-common.c
@@ -127,7 +127,7 @@ static void vhost_vsock_common_guest_notifier_mask(VirtIODevice *vdev, int idx,
/*
* Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1
- * as the Marco of configure interrupt's IDX, If this driver does not
+ * as the macro of configure interrupt's IDX, If this driver does not
* support, the function will return
*/
@@ -144,7 +144,7 @@ static bool vhost_vsock_common_guest_notifier_pending(VirtIODevice *vdev,
/*
* Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1
- * as the Marco of configure interrupt's IDX, If this driver does not
+ * as the macro of configure interrupt's IDX, If this driver does not
* support, the function will return
*/
diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c
index 9f7dcc88ba..61b421aab3 100644
--- a/hw/virtio/virtio-crypto.c
+++ b/hw/virtio/virtio-crypto.c
@@ -960,7 +960,7 @@ static void virtio_crypto_guest_notifier_mask(VirtIODevice *vdev, int idx,
/*
* Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1
- * as the Marco of configure interrupt's IDX, If this driver does not
+ * as the macro of configure interrupt's IDX, If this driver does not
* support, the function will return
*/
@@ -979,7 +979,7 @@ static bool virtio_crypto_guest_notifier_pending(VirtIODevice *vdev, int idx)
/*
* Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1
- * as the Marco of configure interrupt's IDX, If this driver does not
+ * as the macro of configure interrupt's IDX, If this driver does not
* support, the function will return
*/
--
2.27.0

View File

@ -0,0 +1,48 @@
From 09081b494d4aad3137fd375f5f18edc63c7e5d10 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alex=20Benn=C3=A9e?= <alex.bennee@linaro.org>
Date: Thu, 28 Jul 2022 14:55:03 +0100
Subject: [PATCH] hw/virtio: fix vhost_user_read tracepoint
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
As reads happen in the callback we were never seeing them. We only
really care about the header so move the tracepoint to when the header
is complete.
Fixes: 6ca6d8ee9d (hw/virtio: add vhost_user_[read|write] trace points)
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Acked-by: Jason Wang <jasowang@redhat.com>
Message-Id: <20220728135503.1060062-5-alex.bennee@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
hw/virtio/vhost-user.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index ea6d40eb5f..937b3021e9 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -297,6 +297,8 @@ static int vhost_user_read_header(struct vhost_dev *dev, VhostUserMsg *msg)
return -EPROTO;
}
+ trace_vhost_user_read(msg->hdr.request, msg->hdr.flags);
+
return 0;
}
@@ -546,8 +548,6 @@ static int vhost_user_set_log_base(struct vhost_dev *dev, uint64_t base,
}
}
- trace_vhost_user_read(msg.hdr.request, msg.hdr.flags);
-
return 0;
}
--
2.27.0

View File

@ -0,0 +1,52 @@
From edbbc82bdf7cdb21604bb1c8b4a222691b3c3665 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alex=20Benn=C3=A9e?= <alex.bennee@linaro.org>
Date: Thu, 28 Jul 2022 14:55:01 +0100
Subject: [PATCH] hw/virtio: gracefully handle unset vhost_dev vdev
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
I've noticed asserts firing because we query the status of vdev after
a vhost connection is closed down. Rather than faulting on the NULL
indirect just quietly reply false.
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20220728135503.1060062-3-alex.bennee@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
hw/virtio/vhost.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 2f0ddd35d6..8e8657fb0d 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -310,7 +310,7 @@ static inline void vhost_dev_log_resize(struct vhost_dev *dev, uint64_t size)
dev->log_size = size;
}
-static int vhost_dev_has_iommu(struct vhost_dev *dev)
+static bool vhost_dev_has_iommu(struct vhost_dev *dev)
{
VirtIODevice *vdev = dev->vdev;
@@ -320,8 +320,12 @@ static int vhost_dev_has_iommu(struct vhost_dev *dev)
* does not have IOMMU, there's no need to enable this feature
* which may cause unnecessary IOTLB miss/update transactions.
*/
- return virtio_bus_device_iommu_enabled(vdev) &&
- virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM);
+ if (vdev) {
+ return virtio_bus_device_iommu_enabled(vdev) &&
+ virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM);
+ } else {
+ return false;
+ }
}
static void *vhost_memory_map(struct vhost_dev *dev, hwaddr addr,
--
2.27.0

View File

@ -0,0 +1,34 @@
From 7c0b752e2bfd9c6e12570d7a9229a6f733d9ca59 Mon Sep 17 00:00:00 2001
From: Leonardo Garcia <lagarcia@br.ibm.com>
Date: Tue, 23 Nov 2021 08:48:31 -0300
Subject: [PATCH] hw/virtio/vhost: Fix typo in comment.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Leonardo Garcia <lagarcia@br.ibm.com>
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <a10a0ddab65b474ebea1e1141abe0f4aa463909b.1637668012.git.lagarcia@br.ibm.com>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
hw/virtio/vhost.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 22ec9e1ef7..2f0ddd35d6 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -318,7 +318,7 @@ static int vhost_dev_has_iommu(struct vhost_dev *dev)
* For vhost, VIRTIO_F_IOMMU_PLATFORM means the backend support
* incremental memory mapping API via IOTLB API. For platform that
* does not have IOMMU, there's no need to enable this feature
- * which may cause unnecessary IOTLB miss/update trnasactions.
+ * which may cause unnecessary IOTLB miss/update transactions.
*/
return virtio_bus_device_iommu_enabled(vdev) &&
virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM);
--
2.27.0

View File

@ -0,0 +1,192 @@
From 6e43246f43753030a247c23cd6082792a588817b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alex=20Benn=C3=A9e?= <alex.bennee@linaro.org>
Date: Mon, 21 Mar 2022 15:30:34 +0000
Subject: [PATCH] include/hw: start documenting the vhost API
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
While trying to get my head around the nest of interactions for vhost
devices I though I could start by documenting the key API functions.
This patch documents the main API hooks for creating and starting a
vhost device as well as how the configuration changes are handled.
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Stefan Hajnoczi <stefanha@redhat.com>
Cc: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20220321153037.3622127-11-alex.bennee@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
include/hw/virtio/vhost.h | 132 +++++++++++++++++++++++++++++++++++---
1 file changed, 122 insertions(+), 10 deletions(-)
diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
index 86f36f0106..d7ab2579ff 100644
--- a/include/hw/virtio/vhost.h
+++ b/include/hw/virtio/vhost.h
@@ -61,6 +61,12 @@ typedef struct VhostDevConfigOps {
} VhostDevConfigOps;
struct vhost_memory;
+
+/**
+ * struct vhost_dev - common vhost_dev structure
+ * @vhost_ops: backend specific ops
+ * @config_ops: ops for config changes (see @vhost_dev_set_config_notifier)
+ */
struct vhost_dev {
VirtIODevice *vdev;
MemoryListener memory_listener;
@@ -108,15 +114,129 @@ struct vhost_net {
NetClientState *nc;
};
+/**
+ * vhost_dev_init() - initialise the vhost interface
+ * @hdev: the common vhost_dev structure
+ * @opaque: opaque ptr passed to backend (vhost/vhost-user/vdpa)
+ * @backend_type: type of backend
+ * @busyloop_timeout: timeout for polling virtqueue
+ * @errp: error handle
+ *
+ * The initialisation of the vhost device will trigger the
+ * initialisation of the backend and potentially capability
+ * negotiation of backend interface. Configuration of the VirtIO
+ * itself won't happen until the interface is started.
+ *
+ * Return: 0 on success, non-zero on error while setting errp.
+ */
int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
VhostBackendType backend_type,
uint32_t busyloop_timeout, Error **errp);
+
+/**
+ * vhost_dev_cleanup() - tear down and cleanup vhost interface
+ * @hdev: the common vhost_dev structure
+ */
void vhost_dev_cleanup(struct vhost_dev *hdev);
-int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev);
-void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev);
+
+/**
+ * vhost_dev_enable_notifiers() - enable event notifiers
+ * @hdev: common vhost_dev structure
+ * @vdev: the VirtIODevice structure
+ *
+ * Enable notifications directly to the vhost device rather than being
+ * triggered by QEMU itself. Notifications should be enabled before
+ * the vhost device is started via @vhost_dev_start.
+ *
+ * Return: 0 on success, < 0 on error.
+ */
int vhost_dev_enable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev);
+
+/**
+ * vhost_dev_disable_notifiers - disable event notifications
+ * @hdev: common vhost_dev structure
+ * @vdev: the VirtIODevice structure
+ *
+ * Disable direct notifications to vhost device.
+ */
void vhost_dev_disable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev);
+/**
+ * vhost_dev_start() - start the vhost device
+ * @hdev: common vhost_dev structure
+ * @vdev: the VirtIODevice structure
+ *
+ * Starts the vhost device. From this point VirtIO feature negotiation
+ * can start and the device can start processing VirtIO transactions.
+ *
+ * Return: 0 on success, < 0 on error.
+ */
+int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev);
+
+/**
+ * vhost_dev_stop() - stop the vhost device
+ * @hdev: common vhost_dev structure
+ * @vdev: the VirtIODevice structure
+ *
+ * Stop the vhost device. After the device is stopped the notifiers
+ * can be disabled (@vhost_dev_disable_notifiers) and the device can
+ * be torn down (@vhost_dev_cleanup).
+ */
+void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev);
+
+/**
+ * DOC: vhost device configuration handling
+ *
+ * The VirtIO device configuration space is used for rarely changing
+ * or initialisation time parameters. The configuration can be updated
+ * by either the guest driver or the device itself. If the device can
+ * change the configuration over time the vhost handler should
+ * register a @VhostDevConfigOps structure with
+ * @vhost_dev_set_config_notifier so the guest can be notified. Some
+ * devices register a handler anyway and will signal an error if an
+ * unexpected config change happens.
+ */
+
+/**
+ * vhost_dev_get_config() - fetch device configuration
+ * @hdev: common vhost_dev_structure
+ * @config: pointer to device appropriate config structure
+ * @config_len: size of device appropriate config structure
+ *
+ * Return: 0 on success, < 0 on error while setting errp
+ */
+int vhost_dev_get_config(struct vhost_dev *hdev, uint8_t *config,
+ uint32_t config_len, Error **errp);
+
+/**
+ * vhost_dev_set_config() - set device configuration
+ * @hdev: common vhost_dev_structure
+ * @data: pointer to data to set
+ * @offset: offset into configuration space
+ * @size: length of set
+ * @flags: @VhostSetConfigType flags
+ *
+ * By use of @offset/@size a subset of the configuration space can be
+ * written to. The @flags are used to indicate if it is a normal
+ * transaction or related to migration.
+ *
+ * Return: 0 on success, non-zero on error
+ */
+int vhost_dev_set_config(struct vhost_dev *dev, const uint8_t *data,
+ uint32_t offset, uint32_t size, uint32_t flags);
+
+/**
+ * vhost_dev_set_config_notifier() - register VhostDevConfigOps
+ * @hdev: common vhost_dev_structure
+ * @ops: notifier ops
+ *
+ * If the device is expected to change configuration a notifier can be
+ * setup to handle the case.
+ */
+void vhost_dev_set_config_notifier(struct vhost_dev *dev,
+ const VhostDevConfigOps *ops);
+
+
/* Test and clear masked event pending status.
* Should be called after unmask to avoid losing events.
*/
@@ -136,14 +256,6 @@ int vhost_net_set_backend(struct vhost_dev *hdev,
struct vhost_vring_file *file);
int vhost_device_iotlb_miss(struct vhost_dev *dev, uint64_t iova, int write);
-int vhost_dev_get_config(struct vhost_dev *hdev, uint8_t *config,
- uint32_t config_len, Error **errp);
-int vhost_dev_set_config(struct vhost_dev *dev, const uint8_t *data,
- uint32_t offset, uint32_t size, uint32_t flags);
-/* notifier callback in case vhost device config space changed
- */
-void vhost_dev_set_config_notifier(struct vhost_dev *dev,
- const VhostDevConfigOps *ops);
void vhost_dev_reset_inflight(struct vhost_inflight *inflight);
void vhost_dev_free_inflight(struct vhost_inflight *inflight);
--
2.27.0

View File

@ -0,0 +1,55 @@
From 78cb2c9c218155d048e566c5ac6d59961703b5d3 Mon Sep 17 00:00:00 2001
From: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
Date: Tue, 21 Nov 2023 06:14:40 +0000
Subject: [PATCH] io_uring: fix short read slow path mainline inclusion commit
c06fc7ce147e57ab493bad9263f1601b8298484b category: bugfix
---------------------------------------------------------------
sqeq.off here is the offset to read within the disk image, so obviously
not 'nread' (the amount we just read), but as the author meant to write
its current value incremented by the amount we just read.
Normally recent versions of linux will not issue short reads,
but it can happen so we should fix this.
This lead to weird image corruptions when short read happened
Fixes: 6663a0a33764 ("block/io_uring: implements interfaces for io_uring")
Link: https://lkml.kernel.org/r/YrrFGO4A1jS0GI0G@atmark-techno.com
Signed-off-by: Dominique Martinet <dominique.martinet@atmark-techno.com>
Message-Id: <20220630010137.2518851-1-dominique.martinet@atmark-techno.com>
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
---
block/io_uring.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/block/io_uring.c b/block/io_uring.c
index dfa475cc87..e88d75d462 100644
--- a/block/io_uring.c
+++ b/block/io_uring.c
@@ -89,7 +89,7 @@ static void luring_resubmit_short_read(LuringState *s, LuringAIOCB *luringcb,
trace_luring_resubmit_short_read(s, luringcb, nread);
/* Update read position */
- luringcb->total_read = nread;
+ luringcb->total_read += nread;
remaining = luringcb->qiov->size - luringcb->total_read;
/* Shorten qiov */
@@ -103,7 +103,7 @@ static void luring_resubmit_short_read(LuringState *s, LuringAIOCB *luringcb,
remaining);
/* Update sqe */
- luringcb->sqeq.off = nread;
+ luringcb->sqeq.off += nread;
luringcb->sqeq.addr = (__u64)(uintptr_t)luringcb->resubmit_qiov.iov;
luringcb->sqeq.len = luringcb->resubmit_qiov.niov;
--
2.27.0

View File

@ -0,0 +1,48 @@
From c2353941d94a5aeb8364dc5204c29a4fbb09437f Mon Sep 17 00:00:00 2001
From: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
Date: Tue, 21 Nov 2023 06:47:43 +0000
Subject: [PATCH] libvhost-user: Fix VHOST_USER_ADD_MEM_REG reply mainline
inclusion commit 7f27d20ded2f480f3e66d03f90ea71507b834276 category: bugfix
---------------------------------------------------------------
With REPLY_NEEDED, libvhost-user sends both the acutal result and an
additional ACK reply for VHOST_USER_ADD_MEM_REG. This is incorrect, the
spec mandates that it behave the same with and without REPLY_NEEDED
because it always sends a reply.
Fixes: ec94c8e621de96c50c2d381c8c9ec94f5beec7c1
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20220627134500.94842-4-kwolf@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
---
subprojects/libvhost-user/libvhost-user.c | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/subprojects/libvhost-user/libvhost-user.c b/subprojects/libvhost-user/libvhost-user.c
index 787f4d2d4f..8ab20138f4 100644
--- a/subprojects/libvhost-user/libvhost-user.c
+++ b/subprojects/libvhost-user/libvhost-user.c
@@ -756,15 +756,9 @@ vu_add_mem_reg(VuDev *dev, VhostUserMsg *vmsg) {
/* Send the message back to qemu with the addresses filled in. */
vmsg->fd_num = 0;
- if (!vu_send_reply(dev, dev->sock, vmsg)) {
- vu_panic(dev, "failed to respond to add-mem-region for postcopy");
- return false;
- }
-
DPRINT("Successfully added new region in postcopy\n");
dev->nregions++;
- return false;
-
+ return true;
} else {
for (i = 0; i < dev->max_queues; i++) {
if (dev->vq[i].vring.desc) {
--
2.27.0

View File

@ -0,0 +1,53 @@
From 3e2df0133efdf3e3aea63f413b42e37bc6c87112 Mon Sep 17 00:00:00 2001
From: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
Date: Tue, 21 Nov 2023 06:36:05 +0000
Subject: [PATCH] libvhost-user: Fix VHOST_USER_GET_MAX_MEM_SLOTS reply
mainline inclusion commit 69a5daec06f423843ce1bb9be5fb049314996f78 category:
bugfix
---------------------------------------------------------------
With REPLY_NEEDED, libvhost-user sends both the acutal result and an
additional ACK reply for VHOST_USER_GET_MAX_MEM_SLOTS. This is
incorrect, the spec mandates that it behave the same with and without
REPLY_NEEDED because it always sends a reply.
Fixes: 6fb2e173d20c9bbb5466183d33a3ad7dcd0375fa
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20220627134500.94842-3-kwolf@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
---
subprojects/libvhost-user/libvhost-user.c | 11 ++---------
1 file changed, 2 insertions(+), 9 deletions(-)
diff --git a/subprojects/libvhost-user/libvhost-user.c b/subprojects/libvhost-user/libvhost-user.c
index 787f4d2d4f..27e7799262 100644
--- a/subprojects/libvhost-user/libvhost-user.c
+++ b/subprojects/libvhost-user/libvhost-user.c
@@ -1788,18 +1788,11 @@ vu_handle_vring_kick(VuDev *dev, VhostUserMsg *vmsg)
static bool vu_handle_get_max_memslots(VuDev *dev, VhostUserMsg *vmsg)
{
- vmsg->flags = VHOST_USER_REPLY_MASK | VHOST_USER_VERSION;
- vmsg->size = sizeof(vmsg->payload.u64);
- vmsg->payload.u64 = VHOST_USER_MAX_RAM_SLOTS;
- vmsg->fd_num = 0;
-
- if (!vu_message_write(dev, dev->sock, vmsg)) {
- vu_panic(dev, "Failed to send max ram slots: %s\n", strerror(errno));
- }
+ vmsg_set_reply_u64(vmsg, VHOST_USER_MAX_RAM_SLOTS);
DPRINT("u64: 0x%016"PRIx64"\n", (uint64_t) VHOST_USER_MAX_RAM_SLOTS);
- return false;
+ return true;
}
static bool
--
2.27.0

View File

@ -0,0 +1,50 @@
From 1cc7783df04674ff375905cc9a8ec23f71617408 Mon Sep 17 00:00:00 2001
From: qihao <qihao_yewu@cmss.chinamobile.com>
Date: Tue, 21 Nov 2023 20:40:24 +0800
Subject: [PATCH] net: Fix a misleading error message
cheery-pick from 0a4a1512e01228fc59b00d68e86f7099b6439773
The error message
$ qemu-system-x86_64 -netdev user,id=net0,ipv6-net=fec0::0/
qemu-system-x86_64: -netdev user,id=net0,ipv6-net=fec0::0/: Parameter 'ipv6-prefixlen' expects a number
points to ipv6-prefixlen instead of ipv6-net. Fix:
qemu-system-x86_64: -netdev user,id=net0,ipv6-net=fec0::0/: parameter 'ipv6-net' expects a number after '/'
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-ID: <20231031111059.3407803-6-armbru@redhat.com>
Signed-off-by: qihao_yewu <qihao_yewu@cmss.chinamobile.com>
---
net/net.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/net.c b/net/net.c
index ed4b1c1740..daad8784ec 100644
--- a/net/net.c
+++ b/net/net.c
@@ -1122,7 +1122,7 @@ static int net_client_init(QemuOpts *opts, bool is_netdev, Error **errp)
int ret = -1;
Visitor *v = opts_visitor_new(opts);
- /* Parse convenience option format ip6-net=fec0::0[/64] */
+ /* Parse convenience option format ipv6-net=fec0::0[/64] */
const char *ip6_net = qemu_opt_get(opts, "ipv6-net");
if (ip6_net) {
@@ -1142,8 +1142,8 @@ static int net_client_init(QemuOpts *opts, bool is_netdev, Error **errp)
if (substrings[1] &&
qemu_strtoul(substrings[1], NULL, 10, &prefix_len))
{
- error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
- "ipv6-prefixlen", "a number");
+ error_setg(errp,
+ "parameter 'ipv6-net' expects a number after '/'");
goto out;
}
--
2.27.0

View File

@ -0,0 +1,62 @@
From 02c67ab8c1f1e29bf8274d9b460dc2f07b8e195b Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Mon, 31 Oct 2022 13:29:01 +0000
Subject: [PATCH] net/vhost-vdpa.c: Fix clang compilation failure
Commit 8801ccd0500437 introduced a compilation failure with clang
version 10.0.0-4ubuntu1:
../../net/vhost-vdpa.c:654:16: error: variable 'vdpa_device_fd' is
used uninitialized whenever 'if' condition is false
[-Werror,-Wsometimes-uninitialized]
} else if (opts->has_vhostfd) {
^~~~~~~~~~~~~~~~~
../../net/vhost-vdpa.c:662:33: note: uninitialized use occurs here
r = vhost_vdpa_get_features(vdpa_device_fd, &features, errp);
^~~~~~~~~~~~~~
../../net/vhost-vdpa.c:654:12: note: remove the 'if' if its condition
is always true
} else if (opts->has_vhostfd) {
^~~~~~~~~~~~~~~~~~~~~~~
../../net/vhost-vdpa.c:629:23: note: initialize the variable
'vdpa_device_fd' to silence this warning
int vdpa_device_fd;
^
= 0
1 error generated.
It's a false positive -- the compiler doesn't manage to figure out
that the error checks further up mean that there's no code path where
vdpa_device_fd isn't initialized. Put another way, the problem is
that we check "if (opts->has_vhostfd)" when in fact that condition
must always be true. A cleverer static analyser would probably warn
that we were checking an always-true condition.
Fix the compilation failure by removing the unnecessary if().
Fixes: 8801ccd0500437 ("vhost-vdpa: allow passing opened vhostfd to vhost-vdpa")
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-Id: <20221031132901.1277150-1-peter.maydell@linaro.org>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
net/vhost-vdpa.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index 58225649f9..c89f9d1243 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -659,7 +659,8 @@ int net_init_vhost_vdpa(const Netdev *netdev, const char *name,
if (vdpa_device_fd == -1) {
return -errno;
}
- } else if (opts->has_vhostfd) {
+ } else {
+ /* has_vhostfd */
vdpa_device_fd = monitor_fd_param(monitor_cur(), opts->vhostfd, errp);
if (vdpa_device_fd == -1) {
error_prepend(errp, "vhost-vdpa: unable to parse vhostfd: ");
--
2.27.0

View File

@ -0,0 +1,53 @@
From d81bf8c86e2b024f85d90e199181ae048134d4ee Mon Sep 17 00:00:00 2001
From: Guoyi Tu <tugy@chinatelecom.cn>
Date: Fri, 11 Aug 2023 22:46:51 +0800
Subject: [PATCH] pci: Fix the update of interrupt disable bit in PCI_COMMAND
register
The PCI_COMMAND register is located at offset 4 within
the PCI configuration space and occupies 2 bytes. The
interrupt disable bit is at the 10th bit, which corresponds
to the byte at offset 5 in the PCI configuration space.
In our testing environment, the guest driver may directly
updates the byte at offset 5 in the PCI configuration space.
The backtrace looks like as following:
at hw/pci/pci.c:1442
at hw/virtio/virtio-pci.c:605
val=5, len=1) at hw/pci/pci_host.c:81
In this situation, the range_covers_byte function called
by the pci_default_write_config function will return false,
resulting in the inability to handle the interrupt disable
update event.
To fix this issue, we can use the ranges_overlap function
instead of range_covers_byte to determine whether the interrupt
bit has been updated.
Signed-off-by: Guoyi Tu <tugy@chinatelecom.cn>
Signed-off-by: yuanminghao <yuanmh12@chinatelecom.cn>
Message-Id: <ce2d0437-8faa-4d61-b536-4668f645a959@chinatelecom.cn>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Fixes: b6981cb57be5 ("pci: interrupt disable bit support")
---
hw/pci/pci.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 3e6805d54a..3a4619e2a5 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -1471,7 +1471,7 @@ void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val_in, int
range_covers_byte(addr, l, PCI_COMMAND))
pci_update_mappings(d);
- if (range_covers_byte(addr, l, PCI_COMMAND)) {
+ if (ranges_overlap(addr, l, PCI_COMMAND, 2)) {
pci_update_irq_disabled(d, was_irq_disabled);
memory_region_set_enabled(&d->bus_master_enable_region,
(pci_get_word(d->config + PCI_COMMAND)
--
2.27.0

View File

@ -0,0 +1,106 @@
From b2d665abb4dbd3c91c0ceceebe537cf411f6c650 Mon Sep 17 00:00:00 2001
From: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
Date: Mon, 6 Nov 2023 06:35:28 +0000
Subject: [PATCH] pci: fix overflow in snprintf string formatting mainline
inclusion commit 36f18c6989a3d1ff1d7a0e50b0868ef3958299b4 category: bugfix
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---------------------------------------------------------------
the code in pcibus_get_fw_dev_path contained the potential for a
stack buffer overflow of 1 byte, potentially writing to the stack an
extra NUL byte.
This overflow could happen if the PCI slot is >= 0x10000000,
and the PCI function is >= 0x10000000, due to the size parameter
of snprintf being incorrectly calculated in the call:
if (PCI_FUNC(d->devfn))
snprintf(path + off, sizeof(path) + off, ",%x", PCI_FUNC(d->devfn));
since the off obtained from a previous call to snprintf is added
instead of subtracted from the total available size of the buffer.
Without the accurate size guard from snprintf, we end up writing in the
worst case:
name (32) + "@" (1) + SLOT (8) + "," (1) + FUNC (8) + term NUL (1) = 51 bytes
In order to provide something more robust, replace all of the code in
pcibus_get_fw_dev_path with a single call to g_strdup_printf,
so there is no need to rely on manual calculations.
Found by compiling QEMU with FORTIFY_SOURCE=3 as the error:
*** buffer overflow detected ***: terminated
Thread 1 "qemu-system-x86" received signal SIGABRT, Aborted.
[Switching to Thread 0x7ffff642c380 (LWP 121307)]
0x00007ffff71ff55c in __pthread_kill_implementation () from /lib64/libc.so.6
(gdb) bt
#0 0x00007ffff71ff55c in __pthread_kill_implementation () at /lib64/libc.so.6
#1 0x00007ffff71ac6f6 in raise () at /lib64/libc.so.6
#2 0x00007ffff7195814 in abort () at /lib64/libc.so.6
#3 0x00007ffff71f279e in __libc_message () at /lib64/libc.so.6
#4 0x00007ffff729767a in __fortify_fail () at /lib64/libc.so.6
#5 0x00007ffff7295c36 in () at /lib64/libc.so.6
#6 0x00007ffff72957f5 in __snprintf_chk () at /lib64/libc.so.6
#7 0x0000555555b1c1fd in pcibus_get_fw_dev_path ()
#8 0x0000555555f2bde4 in qdev_get_fw_dev_path_helper.constprop ()
#9 0x0000555555f2bd86 in qdev_get_fw_dev_path_helper.constprop ()
#10 0x00005555559a6e5d in get_boot_device_path ()
#11 0x00005555559a712c in get_boot_devices_list ()
#12 0x0000555555b1a3d0 in fw_cfg_machine_reset ()
#13 0x0000555555bf4c2d in pc_machine_reset ()
#14 0x0000555555c66988 in qemu_system_reset ()
#15 0x0000555555a6dff6 in qdev_machine_creation_done ()
#16 0x0000555555c79186 in qmp_x_exit_preconfig.part ()
#17 0x0000555555c7b459 in qemu_init ()
#18 0x0000555555960a29 in main ()
Found-by: Dario Faggioli <Dario Faggioli <dfaggioli@suse.com>
Found-by: Martin Liška <martin.liska@suse.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Claudio Fontana <cfontana@suse.de>
Message-Id: <20220531114707.18830-1-cfontana@suse.de>
Reviewed-by: Ani Sinha <ani@anisinha.ca>
Signed-off-by: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
---
hw/pci/pci.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 3e6805d54a..6a5e8a3654 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -2588,15 +2588,15 @@ static char *pci_dev_fw_name(DeviceState *dev, char *buf, int len)
static char *pcibus_get_fw_dev_path(DeviceState *dev)
{
PCIDevice *d = (PCIDevice *)dev;
- char path[50], name[33];
- int off;
-
- off = snprintf(path, sizeof(path), "%s@%x",
- pci_dev_fw_name(dev, name, sizeof name),
- PCI_SLOT(d->devfn));
- if (PCI_FUNC(d->devfn))
- snprintf(path + off, sizeof(path) + off, ",%x", PCI_FUNC(d->devfn));
- return g_strdup(path);
+ char name[33];
+ int has_func = !!PCI_FUNC(d->devfn);
+
+ return g_strdup_printf("%s@%x%s%.*x",
+ pci_dev_fw_name(dev, name, sizeof(name)),
+ PCI_SLOT(d->devfn),
+ has_func ? "," : "",
+ has_func,
+ PCI_FUNC(d->devfn));
}
static char *pcibus_get_dev_path(DeviceState *dev)
--
2.27.0

View File

@ -0,0 +1,39 @@
From 274dd10230eef97714a2a283ecd8a8ce2ecbf687 Mon Sep 17 00:00:00 2001
From: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
Date: Mon, 6 Nov 2023 07:28:31 +0000
Subject: [PATCH] qemu-timer: Skip empty timer lists before locking in
qemu_clock_deadline_ns_all mainline inclusion commit
3f42906c9ab2c777a895b48b87b8107167e4a275 category: bugfix
---------------------------------------------------------------
This decreases qemu_clock_deadline_ns_all's share from 23.2% to 13% in a
profile of icount-enabled aarch64-softmmu.
Signed-off-by: Idan Horowitz <idan.horowitz@gmail.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20220114004358.299534-2-idan.horowitz@gmail.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
---
util/qemu-timer.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/util/qemu-timer.c b/util/qemu-timer.c
index 40e8c83722..c5b6dc987c 100644
--- a/util/qemu-timer.c
+++ b/util/qemu-timer.c
@@ -330,6 +330,9 @@ int64_t qemu_clock_deadline_ns_all(QEMUClockType type, int attr_mask)
}
QLIST_FOREACH(timer_list, &clock->timerlists, list) {
+ if (!qatomic_read(&timer_list->active_timers)) {
+ continue;
+ }
qemu_mutex_lock(&timer_list->active_timers_lock);
ts = timer_list->active_timers;
/* Skip all external timers */
--
2.27.0

376
qemu.spec
View File

@ -3,7 +3,7 @@
Name: qemu Name: qemu
Version: 6.2.0 Version: 6.2.0
Release: 83 Release: 84
Epoch: 10 Epoch: 10
Summary: QEMU is a generic and open source machine emulator and virtualizer Summary: QEMU is a generic and open source machine emulator and virtualizer
License: GPLv2 and BSD and MIT and CC-BY-SA-4.0 License: GPLv2 and BSD and MIT and CC-BY-SA-4.0
@ -599,6 +599,192 @@ Patch0584: disas-riscv-Fix-the-typo-of-inverted-order-of-pmpadd.patch
Patch0585: softmmu-dirtylimit-Add-parameter-check-for-hmp-set_v.patch Patch0585: softmmu-dirtylimit-Add-parameter-check-for-hmp-set_v.patch
Patch0586: tests-Fix-printf-format-string-in-acpi-utils.c.patch Patch0586: tests-Fix-printf-format-string-in-acpi-utils.c.patch
Patch0587: hw-virtio-virtio-pmem-Replace-impossible-check-by-as.patch Patch0587: hw-virtio-virtio-pmem-Replace-impossible-check-by-as.patch
Patch0588: target-i386-Export-GDS_NO-bit-to-guests.patch
Patch0589: semihosting-fix-memleak-at-semihosting_arg_fallback.patch
Patch0590: semihosting-config-Merge-semihosting-config-option-g.patch
Patch0591: qemu-timer-Skip-empty-timer-lists-before-locking-in-.patch
Patch0592: hw-usb-hcd-ehci-fix-writeback-order.patch
Patch0593: pci-fix-overflow-in-snprintf-string-formatting.patch
Patch0594: tpm_crb-mark-command-buffer-as-dirty-on-request-comp.patch
Patch0595: hw-timer-npcm7xx_timer-Prevent-timer-from-counting-d.patch
Patch0596: pci-Fix-the-update-of-interrupt-disable-bit-in-PCI_C.patch
Patch0597: virtio-introduce-macro-IRTIO_CONFIG_IRQ_IDX.patch
Patch0598: virtio-pci-decouple-notifier-from-interrupt-process.patch
Patch0599: virtio-pci-decouple-the-single-vector-from-the-inter.patch
Patch0600: vhost-vdpa-add-support-for-config-interrupt.patch
Patch0601: virtio-add-support-for-configure-interrupt.patch
Patch0602: vhost-add-support-for-configure-interrupt.patch
Patch0603: virtio-net-add-support-for-configure-interrupt.patch
Patch0604: virtio-mmio-add-support-for-configure-interrupt.patch
Patch0605: virtio-pci-add-support-for-configure-interrupt.patch
Patch0606: vhost-vdpa-stick-to-errno-error-return-convention.patch
Patch0607: vhost-user-stick-to-errno-error-return-convention.patch
Patch0608: vhost-stick-to-errno-error-return-convention.patch
Patch0609: vhost-introduce-new-VhostOps-vhost_set_config_call.patch
Patch0610: e1000-set-RX-descriptor-status-in-a-separate-operati.patch
Patch0611: virtio-iommu-Fix-the-partial-copy-of-probe-request.patch
Patch0612: artist-set-memory-region-owners-for-buffers-to-the-a.patch
Patch0613: qom-object-Remove-circular-include-dependency.patch
Patch0614: vga-avoid-crash-if-no-default-vga-card.patch
Patch0615: hw-pvrdma-Protect-against-buggy-or-malicious-guest-driver.patch
Patch0616: tracetool-avoid-invalid-escape-in-Python-string.patch
Patch0617: target-i386-Add-support-for-CMPCCXADD-in-CPUID-enume.patch
Patch0618: target-i386-Add-support-for-AMX-FP16-in-CPUID-enumer.patch
Patch0619: target-i386-Add-support-for-AVX-IFMA-in-CPUID-enumer.patch
Patch0620: target-i386-Add-support-for-AVX-VNNI-INT8-in-CPUID-e.patch
Patch0621: target-i386-Add-support-for-AVX-NE-CONVERT-in-CPUID-.patch
Patch0622: target-i386-Add-support-for-PREFETCHIT0-1-in-CPUID-e.patch
Patch0623: target-i386-Add-new-CPU-model-GraniteRapids.patch
Patch0624: target-i386-Adjust-feature-level-according-to-FEAT_7.patch
Patch0625: virtio-signal-after-wrapping-packed-used_idx.patch
Patch0626: Revert-vhost-introduce-new-VhostOps-vhost_set_config.patch
Patch0627: Revert-virtio-pci-add-support-for-configure-interrup.patch
Patch0628: Revert-virtio-mmio-add-support-for-configure-interru.patch
Patch0629: Revert-virtio-net-add-support-for-configure-interrup.patch
Patch0630: Revert-vhost-add-support-for-configure-interrupt.patch
Patch0631: Revert-virtio-add-support-for-configure-interrupt.patch
Patch0632: Revert-vhost-vdpa-add-support-for-config-interrupt.patch
Patch0633: Revert-virtio-pci-decouple-the-single-vector-from-th.patch
Patch0634: Revert-virtio-pci-decouple-notifier-from-interrupt-p.patch
Patch0635: Revert-virtio-introduce-macro-IRTIO_CONFIG_IRQ_IDX.patch
Patch0636: vdpa-Make-ncs-autofree.patch
Patch0637: vhost-Add-VhostShadowVirtqueue.patch
Patch0638: vhost-Add-Shadow-VirtQueue-kick-forwarding-capabilit.patch
Patch0639: vhost-Add-Shadow-VirtQueue-call-forwarding-capabilit.patch
Patch0640: vhost-Add-vhost_svq_valid_features-to-shadow-vq.patch
Patch0641: virtio-Add-vhost_svq_get_vring_addr.patch
Patch0642: vdpa-adapt-vhost_ops-callbacks-to-svq.patch
Patch0643: vhost-Shadow-virtqueue-buffers-forwarding.patch
Patch0644: util-Add-iova_tree_alloc_map.patch
Patch0645: util-add-iova_tree_find_iova.patch
Patch0646: vhost-Add-VhostIOVATree.patch
Patch0647: vdpa-Add-custom-IOTLB-translations-to-SVQ.patch
Patch0648: vdpa-Adapt-vhost_vdpa_get_vring_base-to-SVQ.patch
Patch0649: vdpa-Never-set-log_base-addr-if-SVQ-is-enabled.patch
Patch0650: vdpa-Expose-VHOST_F_LOG_ALL-on-SVQ.patch
Patch0651: virtio-fix-enable-vhost-user-build-on-non-Linux.patch
Patch0652: vhost-vdpa-fix-typo-in-a-comment.patch
Patch0653: vdpa-Add-missing-tracing-to-batch-mapping-functions.patch
Patch0654: vhost-Track-descriptor-chain-in-private-at-SVQ.patch
Patch0655: vhost-Fix-device-s-used-descriptor-dequeue.patch
Patch0656: vdpa-Fix-bad-index-calculus-at-vhost_vdpa_get_vring_.patch
Patch0657: vdpa-Fix-index-calculus-at-vhost_vdpa_svqs_start.patch
Patch0658: vhost-Fix-element-in-vhost_svq_add-failure.patch
Patch0659: hw-virtio-add-vhost_user_-read-write-trace-points.patch
Patch0660: include-hw-start-documenting-the-vhost-API.patch
Patch0661: virtio-add-vhost-support-for-virtio-devices.patch
Patch0662: virtio-net-align-ctrl_vq-index-for-non-mq-guest-for-.patch
Patch0663: vhost-vdpa-fix-improper-cleanup-in-net_init_vhost_vd.patch
Patch0664: vhost-vdpa-backend-feature-should-set-only-once.patch
Patch0665: vhost-vdpa-change-name-and-polarity-for-vhost_vdpa_o.patch
Patch0666: virtio-net-don-t-handle-mq-request-in-userspace-hand.patch
Patch0667: util-Return-void-on-iova_tree_remove.patch
Patch0668: vhost-move-descriptor-translation-to-vhost_svq_vring.patch
Patch0669: virtio-net-Expose-MAC_TABLE_ENTRIES.patch
Patch0670: virtio-net-Expose-ctrl-virtqueue-logic.patch
Patch0671: vdpa-Avoid-compiler-to-squash-reads-to-used-idx.patch
Patch0672: vhost-Reorder-vhost_svq_kick.patch
Patch0673: vhost-Move-vhost_svq_kick-call-to-vhost_svq_add.patch
Patch0674: vhost-Check-for-queue-full-at-vhost_svq_add.patch
Patch0675: vhost-Decouple-vhost_svq_add-from-VirtQueueElement.patch
Patch0676: vhost-Add-SVQDescState.patch
Patch0677: vhost-Track-number-of-descs-in-SVQDescState.patch
Patch0678: vhost-add-vhost_svq_push_elem.patch
Patch0679: vhost-Expose-vhost_svq_add.patch
Patch0680: vhost-add-vhost_svq_poll.patch
Patch0681: vhost-Add-svq-avail_handler-callback.patch
Patch0682: vdpa-Export-vhost_vdpa_dma_map-and-unmap-calls.patch
Patch0683: vdpa-manual-forward-CVQ-buffers.patch
Patch0684: vdpa-Buffer-CVQ-support-on-shadow-virtqueue.patch
Patch0685: vdpa-Extract-get-features-part-from-vhost_vdpa_get_m.patch
Patch0686: vdpa-Add-device-migration-blocker.patch
Patch0687: vdpa-Add-x-svq-to-NetdevVhostVDPAOptions.patch
Patch0688: vhost-Get-vring-base-from-vq-not-svq.patch
Patch0689: vdpa-Fix-memory-listener-deletions-of-iova-tree.patch
Patch0690: vdpa-Fix-file-descriptor-leak-on-get-features-error.patch
Patch0691: vdpa-Skip-the-maps-not-in-the-iova-tree.patch
Patch0692: vdpa-do-not-save-failed-dma-maps-in-SVQ-iova-tree.patch
Patch0693: util-accept-iova_tree_remove_parameter-by-value.patch
Patch0694: vdpa-Remove-SVQ-vring-from-iova_tree-at-shutdown.patch
Patch0695: vdpa-Make-SVQ-vring-unmapping-return-void.patch
Patch0696: vdpa-Use-ring-hwaddr-at-vhost_vdpa_svq_unmap_ring.patch
Patch0697: vhost_net-Add-NetClientInfo-start-callback.patch
Patch0698: vhost_net-Add-NetClientInfo-stop-callback.patch
Patch0699: vdpa-add-net_vhost_vdpa_cvq_info-NetClientInfo.patch
Patch0700: vdpa-Move-command-buffers-map-to-start-of-net-device.patch
Patch0701: vdpa-extract-vhost_vdpa_net_cvq_add-from-vhost_vdpa_.patch
Patch0702: vhost_net-add-NetClientState-load-callback.patch
Patch0703: vdpa-Add-virtio-net-mac-address-via-CVQ-at-start.patch
Patch0704: vdpa-Delete-CVQ-migration-blocker.patch
Patch0705: vdpa-Make-VhostVDPAState-cvq_cmd_in_buffer-control-a.patch
Patch0706: vdpa-extract-vhost_vdpa_net_load_mac-from-vhost_vdpa.patch
Patch0707: vdpa-Add-vhost_vdpa_net_load_mq.patch
Patch0708: vdpa-validate-MQ-CVQ-commands.patch
Patch0709: virtio-net-Update-virtio-net-curr_queue_pairs-in-vdp.patch
Patch0710: vdpa-Allow-MQ-feature-in-SVQ.patch
Patch0711: hw-virtio-add-some-vhost-user-trace-events.patch
Patch0712: vdpa-Delete-duplicated-vdpa_feature_bits-entry.patch
Patch0713: vdpa-Remove-shadow-CVQ-command-check.patch
Patch0714: vhost-vdpa-allow-passing-opened-vhostfd-to-vhost-vdp.patch
Patch0715: net-vhost-vdpa.c-Fix-clang-compilation-failure.patch
Patch0716: vhost-vdpa-fix-assert-virtio_net_get_subqueue-nc-asy.patch
Patch0717: vhost-enable-vrings-in-vhost_dev_start-for-vhost-use.patch
Patch0718: vdpa-use-v-shadow_vqs_enabled-in-vhost_vdpa_svqs_sta.patch
Patch0719: vhost-set-SVQ-device-call-handler-at-SVQ-start.patch
Patch0720: vhost-allocate-SVQ-device-file-descriptors-at-device.patch
Patch0721: vdpa-add-vhost_vdpa_net_valid_svq_features.patch
Patch0722: vdpa-request-iova_range-only-once.patch
Patch0723: vdpa-move-SVQ-vring-features-check-to-net.patch
Patch0724: vdpa-allocate-SVQ-array-unconditionally.patch
Patch0725: vdpa-add-asid-parameter-to-vhost_vdpa_dma_map-unmap.patch
Patch0726: vdpa-store-x-svq-parameter-in-VhostVDPAState.patch
Patch0727: vdpa-add-shadow_data-to-vhost_vdpa.patch
Patch0728: vdpa-always-start-CVQ-in-SVQ-mode-if-possible.patch
Patch0729: hw-virtio-vhost-Fix-typo-in-comment.patch
Patch0730: hw-virtio-gracefully-handle-unset-vhost_dev-vdev.patch
Patch0731: vhost-fix-vq-dirty-bitmap-syncing-when-vIOMMU-is-ena.patch
Patch0732: vdpa-handle-VIRTIO_NET_CTRL_ANNOUNCE-in-vhost_vdpa_n.patch
Patch0733: vdpa-do-not-handle-VIRTIO_NET_F_GUEST_ANNOUNCE-in-vh.patch
Patch0734: virtio-introduce-macro-VIRTIO_CONFIG_IRQ_IDX.patch
Patch0735: virtio-pci-decouple-notifier-from-interrupt-process-new.patch
Patch0736: virtio-pci-decouple-the-single-vector-from-the-inter-new.patch
Patch0737: vhost-introduce-new-VhostOps-vhost_set_config_call-new.patch
Patch0738: vhost-vdpa-add-support-for-config-interrupt-new.patch
Patch0739: virtio-add-support-for-configure-interrupt-new.patch
Patch0740: vhost-add-support-for-configure-interrupt-new.patch
Patch0741: virtio-net-add-support-for-configure-interrupt-new.patch
Patch0742: virtio-mmio-add-support-for-configure-interrupt-new.patch
Patch0743: virtio-pci-add-support-for-configure-interrupt-new.patch
Patch0744: vdpa-dev-get-iova-range-explicitly.patch
Patch0745: vdpa-harden-the-error-path-if-get_iova_range-failed.patch
Patch0746: vdpa-commit-all-host-notifier-MRs-in-a-single-MR-tra.patch
Patch0747: virtio-crypto-verify-src-dst-buffer-length-for-sym-request.patch
Patch0748: vhost-Always-store-new-kick-fd-on-vhost_svq_set_svq_.patch
Patch0749: vhost-move-iova_tree-set-to-vhost_svq_start.patch
Patch0750: vhost-fix-possible-wrap-in-SVQ-descriptor-ring.patch
Patch0751: vhost-Fix-false-positive-out-of-bounds.patch
Patch0752: hw-virtio-fix-vhost_user_read-tracepoint.patch
Patch0753: vdpa-Fix-possible-use-after-free-for-VirtQueueElemen.patch
Patch0754: vdpa-fix-not-using-CVQ-buffer-in-case-of-error.patch
Patch0755: vdpa-Return-EIO-if-device-ack-is-VIRTIO_NET_ERR-in-_.patch
Patch0756: vdpa-Return-EIO-if-device-ack-is-VIRTIO_NET_ERR-in-_-new.patch
Patch0757: vdpa-net-block-migration-if-the-device-has-CVQ.patch
Patch0758: vdpa-do-not-block-migration-if-device-has-cvq-and-x-.patch
Patch0759: vdpa-fix-VHOST_BACKEND_F_IOTLB_ASID-flag-check.patch
Patch0760: virtio-net-clear-guest_announce-feature-if-no-cvq-ba.patch
Patch0761: hw-virtio-fix-typo-in-VIRTIO_CONFIG_IRQ_IDX-comments.patch
Patch0762: virtio-i2c-Check-notifier-helpers-for-VIRTIO_CONFIG_.patch
Patch0763: vhost-fix-the-fd-leak.patch
Patch0764: vhost-release-virtqueue-objects-in-error-path.patch
Patch0765: vdpa-stop-all-svq-on-device-deletion.patch
Patch0766: net-Fix-a-misleading-error-message.patch
Patch0767: qsd-Unlink-absolute-PID-file-path.patch
Patch0768: libvhost-user-Fix-VHOST_USER_ADD_MEM_REG-reply.patch
Patch0769: io_uring-fix-short-read-slow-path.patch
Patch0770: libvhost-user-Fix-VHOST_USER_GET_MAX_MEM_SLOTS-reply.patch
Patch0771: tests-qtest-check-the-return-value.patch
Patch0772: hw-net-cadence_gem.c-spelling-fixes-Octects.patch
Patch0773: hw-arm-fsl-imx-Do-not-ignore-Error-argument.patch
BuildRequires: flex BuildRequires: flex
BuildRequires: gcc BuildRequires: gcc
@ -1172,6 +1358,194 @@ getent passwd qemu >/dev/null || \
%endif %endif
%changelog %changelog
* Tue Nov 28 2023 <fengjiabo1@huawei.com> - 10:6.2.0-84
- hw/arm/fsl-imx: Do not ignore Error argument
- hw/net/cadence_gem.c: spelling fixes: Octects
- tests/qtest: check the return value
- libvhost-user: Fix VHOST_USER_GET_MAX_MEM_SLOTS reply mainline inclusion commit 69a5daec06f423843ce1bb9be5fb049314996f78 category: bugfix
- io_uring: fix short read slow path mainline inclusion commit c06fc7ce147e57ab493bad9263f1601b8298484b category: bugfix
- libvhost-user: Fix VHOST_USER_ADD_MEM_REG reply mainline inclusion commit 7f27d20ded2f480f3e66d03f90ea71507b834276 category: bugfix
- qsd: Unlink absolute PID file path mainline inclusion commit 9d8f8233b9fa525a7e37350fbc18877051128c5d category: bugfix
- net: Fix a misleading error message
- vdpa: stop all svq on device deletion
- vhost: release virtqueue objects in error path
- vhost: fix the fd leak
- virtio: i2c: Check notifier helpers for VIRTIO_CONFIG_IRQ_IDX
- hw/virtio: fix typo in VIRTIO_CONFIG_IRQ_IDX comments
- virtio-net: clear guest_announce feature if no cvq backend
- vdpa: fix VHOST_BACKEND_F_IOTLB_ASID flag check
- vdpa: do not block migration if device has cvq and x-svq=on
- vdpa net: block migration if the device has CVQ
- vdpa: Return -EIO if device ack is VIRTIO_NET_ERR in _load_mq()
- vdpa: Return -EIO if device ack is VIRTIO_NET_ERR in _load_mac()
- vdpa: fix not using CVQ buffer in case of error
- vdpa: Fix possible use-after-free for VirtQueueElement
- hw/virtio: fix vhost_user_read tracepoint
- vhost: Fix false positive out-of-bounds
- vhost: fix possible wrap in SVQ descriptor ring
- vhost: move iova_tree set to vhost_svq_start
- vhost: Always store new kick fd on vhost_svq_set_svq_kick_fd
- virtio-crypto: verify src&dst buffer length for sym request
- vdpa: commit all host notifier MRs in a single MR transaction
- vdpa: harden the error path if get_iova_range failed
- vdpa-dev: get iova range explicitly
- virtio-pci: add support for configure interrupt
- virtio-mmio: add support for configure interrupt
- virtio-net: add support for configure interrupt
- vhost: add support for configure interrupt
- virtio: add support for configure interrupt
- vhost-vdpa: add support for config interrupt
- vhost: introduce new VhostOps vhost_set_config_call
- virtio-pci: decouple the single vector from the interrupt process
- virtio-pci: decouple notifier from interrupt process
- virtio: introduce macro VIRTIO_CONFIG_IRQ_IDX
- vdpa: do not handle VIRTIO_NET_F_GUEST_ANNOUNCE in vhost-vdpa
- vdpa: handle VIRTIO_NET_CTRL_ANNOUNCE in vhost_vdpa_net_handle_ctrl_avail
- vhost: fix vq dirty bitmap syncing when vIOMMU is enabled
- hw/virtio: gracefully handle unset vhost_dev vdev
- hw/virtio/vhost: Fix typo in comment.
- vdpa: always start CVQ in SVQ mode if possible
- vdpa: add shadow_data to vhost_vdpa
- vdpa: store x-svq parameter in VhostVDPAState
- vdpa: add asid parameter to vhost_vdpa_dma_map/unmap
- vdpa: allocate SVQ array unconditionally
- vdpa: move SVQ vring features check to net/
- vdpa: request iova_range only once
- vdpa: add vhost_vdpa_net_valid_svq_features
- vhost: allocate SVQ device file descriptors at device start
- vhost: set SVQ device call handler at SVQ start
- vdpa: use v->shadow_vqs_enabled in vhost_vdpa_svqs_start & stop
- vhost: enable vrings in vhost_dev_start() for vhost-user devices
- vhost-vdpa: fix assert !virtio_net_get_subqueue(nc)->async_tx.elem in virtio_net_reset
- net/vhost-vdpa.c: Fix clang compilation failure
- vhost-vdpa: allow passing opened vhostfd to vhost-vdpa
- vdpa: Remove shadow CVQ command check
- vdpa: Delete duplicated vdpa_feature_bits entry
- hw/virtio: add some vhost-user trace events
- vdpa: Allow MQ feature in SVQ
- virtio-net: Update virtio-net curr_queue_pairs in vdpa backends
- vdpa: validate MQ CVQ commands
- vdpa: Add vhost_vdpa_net_load_mq
- vdpa: extract vhost_vdpa_net_load_mac from vhost_vdpa_net_load
- vdpa: Make VhostVDPAState cvq_cmd_in_buffer control ack type
- vdpa: Delete CVQ migration blocker
- vdpa: Add virtio-net mac address via CVQ at start
- vhost_net: add NetClientState->load() callback
- vdpa: extract vhost_vdpa_net_cvq_add from vhost_vdpa_net_handle_ctrl_avail
- vdpa: Move command buffers map to start of net device
- vdpa: add net_vhost_vdpa_cvq_info NetClientInfo
- vhost_net: Add NetClientInfo stop callback
- vhost_net: Add NetClientInfo start callback
- vdpa: Use ring hwaddr at vhost_vdpa_svq_unmap_ring
- vdpa: Make SVQ vring unmapping return void
- vdpa: Remove SVQ vring from iova_tree at shutdown
- util: accept iova_tree_remove_parameter by value
- vdpa: do not save failed dma maps in SVQ iova tree
- vdpa: Skip the maps not in the iova tree
- vdpa: Fix file descriptor leak on get features error
- vdpa: Fix memory listener deletions of iova tree
- vhost: Get vring base from vq, not svq
- vdpa: Add x-svq to NetdevVhostVDPAOptions
- vdpa: Add device migration blocker
- vdpa: Extract get features part from vhost_vdpa_get_max_queue_pairs
- vdpa: Buffer CVQ support on shadow virtqueue
- vdpa: manual forward CVQ buffers
- vdpa: Export vhost_vdpa_dma_map and unmap calls
- vhost: Add svq avail_handler callback
- vhost: add vhost_svq_poll
- vhost: Expose vhost_svq_add
- vhost: add vhost_svq_push_elem
- vhost: Track number of descs in SVQDescState
- vhost: Add SVQDescState
- vhost: Decouple vhost_svq_add from VirtQueueElement
- vhost: Check for queue full at vhost_svq_add
- vhost: Move vhost_svq_kick call to vhost_svq_add
- vhost: Reorder vhost_svq_kick
- vdpa: Avoid compiler to squash reads to used idx
- virtio-net: Expose ctrl virtqueue logic
- virtio-net: Expose MAC_TABLE_ENTRIES
- vhost: move descriptor translation to vhost_svq_vring_write_descs
- util: Return void on iova_tree_remove
- virtio-net: don't handle mq request in userspace handler for vhost-vdpa
- vhost-vdpa: change name and polarity for vhost_vdpa_one_time_request()
- vhost-vdpa: backend feature should set only once
- vhost-vdpa: fix improper cleanup in net_init_vhost_vdpa
- virtio-net: align ctrl_vq index for non-mq guest for vhost_vdpa
- virtio: add vhost support for virtio devices
- include/hw: start documenting the vhost API
- hw/virtio: add vhost_user_[read|write] trace points
- vhost: Fix element in vhost_svq_add failure
- vdpa: Fix index calculus at vhost_vdpa_svqs_start
- vdpa: Fix bad index calculus at vhost_vdpa_get_vring_base
- vhost: Fix device's used descriptor dequeue
- vhost: Track descriptor chain in private at SVQ
- vdpa: Add missing tracing to batch mapping functions
- vhost-vdpa: fix typo in a comment
- virtio: fix --enable-vhost-user build on non-Linux
- vdpa: Expose VHOST_F_LOG_ALL on SVQ
- vdpa: Never set log_base addr if SVQ is enabled
- vdpa: Adapt vhost_vdpa_get_vring_base to SVQ
- vdpa: Add custom IOTLB translations to SVQ
- vhost: Add VhostIOVATree
- util: add iova_tree_find_iova
- util: Add iova_tree_alloc_map
- vhost: Shadow virtqueue buffers forwarding
- vdpa: adapt vhost_ops callbacks to svq
- virtio: Add vhost_svq_get_vring_addr
- vhost: Add vhost_svq_valid_features to shadow vq
- vhost: Add Shadow VirtQueue call forwarding capabilities
- vhost: Add Shadow VirtQueue kick forwarding capabilities
- vhost: Add VhostShadowVirtqueue
- vdpa: Make ncs autofree
- Revert "virtio: introduce macro IRTIO_CONFIG_IRQ_IDX"
- Revert "virtio-pci: decouple notifier from interrupt process"
- Revert "virtio-pci: decouple the single vector from the interrupt process"
- Revert "vhost-vdpa: add support for config interrupt"
- Revert "virtio: add support for configure interrupt"
- Revert "vhost: add support for configure interrupt"
- Revert "virtio-net: add support for configure interrupt"
- Revert "virtio-mmio: add support for configure interrupt"
- Revert "virtio-pci: add support for configure interrupt"
- Revert "vhost: introduce new VhostOps vhost_set_config_call"
- virtio: signal after wrapping packed used_idx
- target/i386: Adjust feature level according to FEAT_7_1_EDX
- target/i386: Add new CPU model GraniteRapids
- target/i386: Add support for PREFETCHIT0/1 in CPUID enumeration
- target/i386: Add support for AVX-NE-CONVERT in CPUID enumeration
- target/i386: Add support for AVX-VNNI-INT8 in CPUID enumeration
- target/i386: Add support for AVX-IFMA in CPUID enumeration
- target/i386: Add support for AMX-FP16 in CPUID enumeration
- target/i386: Add support for CMPCCXADD in CPUID enumeration
- tracetool: avoid invalid escape in Python string
- hw/pvrdma: Protect against buggy or malicious guest driver
- vga: avoid crash if no default vga card mainline inclusion commit 6985d8ede92494f3b791de01e8ee9306eb6d5e4a category: bugfix
- qom/object: Remove circular include dependency mainline inclusion commit 5bba9bcfbb42e7c016626420e148a1bf1b080835 category: bugfix
- artist: set memory region owners for buffers to the artist device mainline inclusion commit 39fbaeca096a9bf6cbe2af88572c1cb2aa62aa8c category: bugfix
- virtio-iommu: Fix the partial copy of probe request mainline inclusion commit 45461aace83d961e933b27519b81d17b4c690514 category: bugfix
- e1000: set RX descriptor status in a separate operation mainline inclusion commit 034d00d4858161e1d4cff82d8d230bce874a04d3 category: bugfix
- vhost: introduce new VhostOps vhost_set_config_call
- vhost: stick to -errno error return convention
- vhost-user: stick to -errno error return convention
- vhost-vdpa: stick to -errno error return convention
- virtio-pci: add support for configure interrupt
- virtio-mmio: add support for configure interrupt
- virtio-net: add support for configure interrupt
- vhost: add support for configure interrupt
- virtio: add support for configure interrupt
- vhost-vdpa: add support for config interrupt
- virtio-pci: decouple the single vector from the interrupt process
- virtio-pci: decouple notifier from interrupt process
- virtio: introduce macro IRTIO_CONFIG_IRQ_IDX
- pci: Fix the update of interrupt disable bit in PCI_COMMAND register
- hw/timer/npcm7xx_timer: Prevent timer from counting down past zero
- tpm_crb: mark command buffer as dirty on request completion mainline inclusion commit e37a0ef4605e5d2041785ff3fc89ca6021faf7a0 category: bugfix
- pci: fix overflow in snprintf string formatting mainline inclusion commit 36f18c6989a3d1ff1d7a0e50b0868ef3958299b4 category: bugfix
- hw/usb/hcd-ehci: fix writeback order mainline inclusion commit f471e8b060798f26a7fc339c6152f82f22a7b33d category: bugfix
- qemu-timer: Skip empty timer lists before locking in qemu_clock_deadline_ns_all mainline inclusion commit 3f42906c9ab2c777a895b48b87b8107167e4a275 category: bugfix
- semihosting/config: Merge --semihosting-config option groups mainline inclusion commit 90c072e063737e9e8f431489bbd334452f89056e category: bugfix
- semihosting: fix memleak at semihosting_arg_fallback
- target/i386: Export GDS_NO bit to guests
* Mon Oct 30 2023 <fengjiabo1@huawei.com> - 10:6.2.0-83 * Mon Oct 30 2023 <fengjiabo1@huawei.com> - 10:6.2.0-83
- hw/virtio/virtio-pmem: Replace impossible check by assertion - hw/virtio/virtio-pmem: Replace impossible check by assertion
- tests: Fix printf format string in acpi-utils.c - tests: Fix printf format string in acpi-utils.c

View File

@ -0,0 +1,41 @@
From e4393667e45bdcf04150ada3840a6d87e3188d36 Mon Sep 17 00:00:00 2001
From: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
Date: Fri, 17 Nov 2023 09:13:07 +0000
Subject: [PATCH] qom/object: Remove circular include dependency mainline
inclusion commit 5bba9bcfbb42e7c016626420e148a1bf1b080835 category: bugfix
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---------------------------------------------------------------
"qom/object.h" doesn't need to include itself.
Fixes: db1015e92e04 ("Move QOM typedefs and add missing includes")
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Damien Hedde <damien.hedde@greensocs.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <20220509084659.52076-1-philippe.mathieu.daude@gmail.com>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
---
include/qom/object.h | 1 -
1 file changed, 1 deletion(-)
diff --git a/include/qom/object.h b/include/qom/object.h
index fae096f51c..f658e1e0a0 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -16,7 +16,6 @@
#include "qapi/qapi-builtin-types.h"
#include "qemu/module.h"
-#include "qom/object.h"
struct TypeImpl;
typedef struct TypeImpl *Type;
--
2.27.0

View File

@ -0,0 +1,81 @@
From 43668bdb7ebaa64536277d4b5b47875e58a3452a Mon Sep 17 00:00:00 2001
From: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
Date: Tue, 21 Nov 2023 07:00:39 +0000
Subject: [PATCH] qsd: Unlink absolute PID file path mainline inclusion commit
9d8f8233b9fa525a7e37350fbc18877051128c5d category: bugfix
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---------------------------------------------------------------
After writing the PID file, we register an atexit() handler to unlink it
when the process terminates. However, if the process has changed its
working directory in the meantime (e.g. in os_setup_post() when
daemonizing), this will not work when the PID file path was relative.
Therefore, pass the absolute path (created with realpath()) to the
unlink() call in the atexit() handler.
(realpath() needs a path pointing to an existing file, so we cannot use
it before qemu_write_pidfile().)
Reproducer:
$ cd /tmp
$ qemu-storage-daemon --daemonize --pidfile qsd.pid
$ file qsd.pid
qsd.pid: ASCII text
$ kill $(cat qsd.pid)
$ file qsd.pid
qsd.pid: ASCII text
(qsd.pid should be gone after the process has terminated.)
Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=2092322
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
Message-Id: <20220609122701.17172-2-hreitz@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
---
storage-daemon/qemu-storage-daemon.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/storage-daemon/qemu-storage-daemon.c b/storage-daemon/qemu-storage-daemon.c
index 52cf17e8ac..f3d8c4ca11 100644
--- a/storage-daemon/qemu-storage-daemon.c
+++ b/storage-daemon/qemu-storage-daemon.c
@@ -60,6 +60,7 @@
#include "trace/control.h"
static const char *pid_file;
+static char *pid_file_realpath;
static volatile bool exit_requested = false;
void qemu_system_killed(int signal, pid_t pid)
@@ -292,7 +293,7 @@ static void process_options(int argc, char *argv[])
static void pid_file_cleanup(void)
{
- unlink(pid_file);
+ unlink(pid_file_realpath);
}
static void pid_file_init(void)
@@ -308,6 +309,14 @@ static void pid_file_init(void)
exit(EXIT_FAILURE);
}
+ pid_file_realpath = g_malloc(PATH_MAX);
+ if (!realpath(pid_file, pid_file_realpath)) {
+ error_report("cannot resolve PID file path: %s: %s",
+ pid_file, strerror(errno));
+ unlink(pid_file);
+ exit(EXIT_FAILURE);
+ }
+
atexit(pid_file_cleanup);
}
--
2.27.0

View File

@ -0,0 +1,54 @@
From ff7918646e3c696d13732fb22f032d7d78c34fe1 Mon Sep 17 00:00:00 2001
From: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
Date: Mon, 6 Nov 2023 08:15:13 +0000
Subject: [PATCH] semihosting/config: Merge --semihosting-config option groups
mainline inclusion commit 90c072e063737e9e8f431489bbd334452f89056e category:
bugfix
---------------------------------------------------------------
Currently we mishandle the --semihosting-config option if the
user specifies it on the command line more than once. For
example with:
--semihosting-config target=gdb --semihosting-config arg=foo,arg=bar
the function qemu_semihosting_config_options() is called twice, once
for each argument. But that function expects to be called only once,
and it always unconditionally sets the semihosting.enabled,
semihost_chardev and semihosting.target variables. This means that
if any of those options were set anywhere except the last
--semihosting-config option on the command line, those settings are
ignored. In the example above, 'target=gdb' in the first option is
overridden by an implied default 'target=auto' in the second.
The QemuOptsList machinery has a flag for handling this kind of
"option group is setting global state": by setting
.merge_lists = true;
we make the machinery merge all the --semihosting-config arguments
the user passes into a single set of options and call our
qemu_semihosting_config_options() just once.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Luc Michel <luc@lmichel.fr>
Message-id: 20220526190053.521505-3-peter.maydell@linaro.org
Signed-off-by: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
---
semihosting/config.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/semihosting/config.c b/semihosting/config.c
index 137171b717..ba3e310a61 100644
--- a/semihosting/config.c
+++ b/semihosting/config.c
@@ -27,6 +27,7 @@
QemuOptsList qemu_semihosting_config_opts = {
.name = "semihosting-config",
+ .merge_lists = true,
.implied_opt_name = "enable",
.head = QTAILQ_HEAD_INITIALIZER(qemu_semihosting_config_opts.head),
.desc = {
--
2.27.0

View File

@ -0,0 +1,47 @@
From 47a24e233e335025ed37ab0ba4a4e728719a2ad3 Mon Sep 17 00:00:00 2001
From: qihao <qihao_yewu@cmss.chinamobile.com>
Date: Mon, 6 Nov 2023 18:14:06 +0800
Subject: [PATCH] semihosting: fix memleak at semihosting_arg_fallback
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
cheery-pick from 2eb71a0c20a6a77be128a76c1ef8fb5dc7028a8b
We duplicate "cmd" as strtok may modify its argument, but we forgot
to free it later. Furthermore, add_semihosting_arg doesn't take
responsibility for this memory either (it strdup's the argument).
Signed-off-by: Matheus Tavares Bernardino <quic_mathbern@quicinc.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-Id: <03d81c56bfc3d08224e4106efca5949d8894cfa5.1697801632.git.quic_mathbern@quicinc.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20231029145033.592566-18-alex.bennee@linaro.org>
Signed-off-by: qihao_yewu <qihao_yewu@cmss.chinamobile.com>
---
semihosting/config.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/semihosting/config.c b/semihosting/config.c
index 137171b717..303338f647 100644
--- a/semihosting/config.c
+++ b/semihosting/config.c
@@ -109,12 +109,13 @@ static int add_semihosting_arg(void *opaque,
void semihosting_arg_fallback(const char *file, const char *cmd)
{
char *cmd_token;
+ g_autofree char *cmd_dup = g_strdup(cmd);
/* argv[0] */
add_semihosting_arg(&semihosting, "arg", file, NULL);
/* split -append and initialize argv[1..n] */
- cmd_token = strtok(g_strdup(cmd), " ");
+ cmd_token = strtok(cmd_dup, " ");
while (cmd_token) {
add_semihosting_arg(&semihosting, "arg", cmd_token, NULL);
cmd_token = strtok(NULL, " ");
--
2.27.0

View File

@ -0,0 +1,183 @@
From 7ebcbfb9ac1d53ea46bfd86fa7f0a90a4012412e Mon Sep 17 00:00:00 2001
From: Tao Su <tao1.su@linux.intel.com>
Date: Thu, 6 Jul 2023 13:49:49 +0800
Subject: [PATCH] target/i386: Add new CPU model GraniteRapids
commit 6d5e9694ef374159072984c0958c3eaab6dd1d52 upstream.
The GraniteRapids CPU model mainly adds the following new features
based on SapphireRapids:
- PREFETCHITI CPUID.(EAX=7,ECX=1):EDX[bit 14]
- AMX-FP16 CPUID.(EAX=7,ECX=1):EAX[bit 21]
And adds the following security fix for corresponding vulnerabilities:
- MCDT_NO CPUID.(EAX=7,ECX=2):EDX[bit 5]
- SBDR_SSDP_NO MSR_IA32_ARCH_CAPABILITIES[bit 13]
- FBSDP_NO MSR_IA32_ARCH_CAPABILITIES[bit 14]
- PSDP_NO MSR_IA32_ARCH_CAPABILITIES[bit 15]
- PBRSB_NO MSR_IA32_ARCH_CAPABILITIES[bit 24]
Intel-SIG: commit 6d5e9694ef37 target/i386: Add new CPU model GraniteRapids.
Backport GNR and SRF ISA into QEMU-6.2
Signed-off-by: Tao Su <tao1.su@linux.intel.com>
Tested-by: Xuelian Guo <xuelian.guo@intel.com>
Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
Message-ID: <20230706054949.66556-7-tao1.su@linux.intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
[ Quanxian Wang: amend commit log ]
Signed-off-by: Quanxian Wang <quanxian.wang@intel.com>
---
target/i386/cpu.c | 136 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 136 insertions(+)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index ee243693e3..efe0c2b46c 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -3707,6 +3707,142 @@ static const X86CPUDefinition builtin_x86_defs[] = {
{ /* end of list */ }
}
},
+ {
+ .name = "GraniteRapids",
+ .level = 0x20,
+ .vendor = CPUID_VENDOR_INTEL,
+ .family = 6,
+ .model = 173,
+ .stepping = 0,
+ /*
+ * please keep the ascending order so that we can have a clear view of
+ * bit position of each feature.
+ */
+ .features[FEAT_1_EDX] =
+ CPUID_FP87 | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC |
+ CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC |
+ CPUID_SEP | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV |
+ CPUID_PAT | CPUID_PSE36 | CPUID_CLFLUSH | CPUID_MMX | CPUID_FXSR |
+ CPUID_SSE | CPUID_SSE2,
+ .features[FEAT_1_ECX] =
+ CPUID_EXT_SSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSSE3 |
+ CPUID_EXT_FMA | CPUID_EXT_CX16 | CPUID_EXT_PCID | CPUID_EXT_SSE41 |
+ CPUID_EXT_SSE42 | CPUID_EXT_X2APIC | CPUID_EXT_MOVBE |
+ CPUID_EXT_POPCNT | CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_AES |
+ CPUID_EXT_XSAVE | CPUID_EXT_AVX | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
+ .features[FEAT_8000_0001_EDX] =
+ CPUID_EXT2_SYSCALL | CPUID_EXT2_NX | CPUID_EXT2_PDPE1GB |
+ CPUID_EXT2_RDTSCP | CPUID_EXT2_LM,
+ .features[FEAT_8000_0001_ECX] =
+ CPUID_EXT3_LAHF_LM | CPUID_EXT3_ABM | CPUID_EXT3_3DNOWPREFETCH,
+ .features[FEAT_8000_0008_EBX] =
+ CPUID_8000_0008_EBX_WBNOINVD,
+ .features[FEAT_7_0_EBX] =
+ CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_HLE |
+ CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 |
+ CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID | CPUID_7_0_EBX_RTM |
+ CPUID_7_0_EBX_AVX512F | CPUID_7_0_EBX_AVX512DQ |
+ CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX | CPUID_7_0_EBX_SMAP |
+ CPUID_7_0_EBX_AVX512IFMA | CPUID_7_0_EBX_CLFLUSHOPT |
+ CPUID_7_0_EBX_CLWB | CPUID_7_0_EBX_AVX512CD | CPUID_7_0_EBX_SHA_NI |
+ CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512VL,
+ .features[FEAT_7_0_ECX] =
+ CPUID_7_0_ECX_AVX512_VBMI | CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_PKU |
+ CPUID_7_0_ECX_AVX512_VBMI2 | CPUID_7_0_ECX_GFNI |
+ CPUID_7_0_ECX_VAES | CPUID_7_0_ECX_VPCLMULQDQ |
+ CPUID_7_0_ECX_AVX512VNNI | CPUID_7_0_ECX_AVX512BITALG |
+ CPUID_7_0_ECX_AVX512_VPOPCNTDQ | CPUID_7_0_ECX_LA57 |
+ CPUID_7_0_ECX_RDPID | CPUID_7_0_ECX_BUS_LOCK_DETECT,
+ .features[FEAT_7_0_EDX] =
+ CPUID_7_0_EDX_FSRM | CPUID_7_0_EDX_SERIALIZE |
+ CPUID_7_0_EDX_TSX_LDTRK | CPUID_7_0_EDX_AMX_BF16 |
+ CPUID_7_0_EDX_AVX512_FP16 | CPUID_7_0_EDX_AMX_TILE |
+ CPUID_7_0_EDX_AMX_INT8 | CPUID_7_0_EDX_SPEC_CTRL |
+ CPUID_7_0_EDX_ARCH_CAPABILITIES | CPUID_7_0_EDX_SPEC_CTRL_SSBD,
+ .features[FEAT_ARCH_CAPABILITIES] =
+ MSR_ARCH_CAP_RDCL_NO | MSR_ARCH_CAP_IBRS_ALL |
+ MSR_ARCH_CAP_SKIP_L1DFL_VMENTRY | MSR_ARCH_CAP_MDS_NO |
+ MSR_ARCH_CAP_PSCHANGE_MC_NO | MSR_ARCH_CAP_TAA_NO |
+ MSR_ARCH_CAP_SBDR_SSDP_NO | MSR_ARCH_CAP_FBSDP_NO |
+ MSR_ARCH_CAP_PSDP_NO | MSR_ARCH_CAP_PBRSB_NO,
+ .features[FEAT_XSAVE] =
+ CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
+ CPUID_XSAVE_XGETBV1 | CPUID_XSAVE_XSAVES | CPUID_D_1_EAX_XFD,
+ .features[FEAT_6_EAX] =
+ CPUID_6_EAX_ARAT,
+ .features[FEAT_7_1_EAX] =
+ CPUID_7_1_EAX_AVX_VNNI | CPUID_7_1_EAX_AVX512_BF16 |
+ CPUID_7_1_EAX_FZRM | CPUID_7_1_EAX_FSRS | CPUID_7_1_EAX_FSRC |
+ CPUID_7_1_EAX_AMX_FP16,
+ .features[FEAT_7_1_EDX] =
+ CPUID_7_1_EDX_PREFETCHITI,
+ .features[FEAT_7_2_EDX] =
+ CPUID_7_2_EDX_MCDT_NO,
+ .features[FEAT_VMX_BASIC] =
+ MSR_VMX_BASIC_INS_OUTS | MSR_VMX_BASIC_TRUE_CTLS,
+ .features[FEAT_VMX_ENTRY_CTLS] =
+ VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_IA32E_MODE |
+ VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL |
+ VMX_VM_ENTRY_LOAD_IA32_PAT | VMX_VM_ENTRY_LOAD_IA32_EFER,
+ .features[FEAT_VMX_EPT_VPID_CAPS] =
+ MSR_VMX_EPT_EXECONLY |
+ MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_PAGE_WALK_LENGTH_5 |
+ MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB | MSR_VMX_EPT_1GB |
+ MSR_VMX_EPT_INVEPT | MSR_VMX_EPT_AD_BITS |
+ MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT |
+ MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR |
+ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT |
+ MSR_VMX_EPT_INVVPID_ALL_CONTEXT |
+ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS,
+ .features[FEAT_VMX_EXIT_CTLS] =
+ VMX_VM_EXIT_SAVE_DEBUG_CONTROLS |
+ VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |
+ VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_IA32_PAT |
+ VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER |
+ VMX_VM_EXIT_LOAD_IA32_EFER | VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER,
+ .features[FEAT_VMX_MISC] =
+ MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_ACTIVITY_HLT |
+ MSR_VMX_MISC_VMWRITE_VMEXIT,
+ .features[FEAT_VMX_PINBASED_CTLS] =
+ VMX_PIN_BASED_EXT_INTR_MASK | VMX_PIN_BASED_NMI_EXITING |
+ VMX_PIN_BASED_VIRTUAL_NMIS | VMX_PIN_BASED_VMX_PREEMPTION_TIMER |
+ VMX_PIN_BASED_POSTED_INTR,
+ .features[FEAT_VMX_PROCBASED_CTLS] =
+ VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
+ VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
+ VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
+ VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
+ VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING |
+ VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
+ VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_VIRTUAL_NMI_PENDING |
+ VMX_CPU_BASED_MOV_DR_EXITING | VMX_CPU_BASED_UNCOND_IO_EXITING |
+ VMX_CPU_BASED_USE_IO_BITMAPS | VMX_CPU_BASED_MONITOR_TRAP_FLAG |
+ VMX_CPU_BASED_USE_MSR_BITMAPS | VMX_CPU_BASED_MONITOR_EXITING |
+ VMX_CPU_BASED_PAUSE_EXITING |
+ VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
+ .features[FEAT_VMX_SECONDARY_CTLS] =
+ VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
+ VMX_SECONDARY_EXEC_ENABLE_EPT | VMX_SECONDARY_EXEC_DESC |
+ VMX_SECONDARY_EXEC_RDTSCP |
+ VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
+ VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_WBINVD_EXITING |
+ VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST |
+ VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT |
+ VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
+ VMX_SECONDARY_EXEC_RDRAND_EXITING |
+ VMX_SECONDARY_EXEC_ENABLE_INVPCID |
+ VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS |
+ VMX_SECONDARY_EXEC_RDSEED_EXITING | VMX_SECONDARY_EXEC_ENABLE_PML |
+ VMX_SECONDARY_EXEC_XSAVES,
+ .features[FEAT_VMX_VMFUNC] =
+ MSR_VMX_VMFUNC_EPT_SWITCHING,
+ .xlevel = 0x80000008,
+ .model_id = "Intel Xeon Processor (GraniteRapids)",
+ .versions = (X86CPUVersionDefinition[]) {
+ { .version = 1 },
+ { /* end of list */ },
+ },
+ },
{
.name = "Denverton",
.level = 21,
--
2.27.0

View File

@ -0,0 +1,62 @@
From c362956eb88558991bee59e43d7db52c8bc7e5f5 Mon Sep 17 00:00:00 2001
From: Jiaxi Chen <jiaxi.chen@linux.intel.com>
Date: Fri, 3 Mar 2023 14:59:09 +0800
Subject: [PATCH] target/i386: Add support for AMX-FP16 in CPUID enumeration
commit 99ed8445ea27742a4df40f51a3a5fbd6f8e76fa5 upstream.
Latest Intel platform Granite Rapids has introduced a new instruction -
AMX-FP16, which performs dot-products of two FP16 tiles and accumulates
the results into a packed single precision tile. AMX-FP16 adds FP16
capability and allows a FP16 GPU trained model to run faster without
loss of accuracy or added SW overhead.
The bit definition:
CPUID.(EAX=7,ECX=1):EAX[bit 21]
Add CPUID definition for AMX-FP16.
Intel-SIG: commit 99ed8445ea27 target/i386: Add support for AMX-FP16 in CPUID enumeration.
Backport GNR and SRF ISA into QEMU-6.2
Signed-off-by: Jiaxi Chen <jiaxi.chen@linux.intel.com>
Signed-off-by: Tao Su <tao1.su@linux.intel.com>
Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
Message-Id: <20230303065913.1246327-3-tao1.su@linux.intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
[ Quanxian Wang: amend commit log ]
Signed-off-by: Quanxian Wang <quanxian.wang@intel.com>
---
target/i386/cpu.c | 2 +-
target/i386/cpu.h | 2 ++
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 47c2d9da80..3fc3b8041a 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -876,7 +876,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
NULL, NULL, "fzrm", "fsrs",
"fsrc", NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
+ NULL, "amx-fp16", NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
},
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 4a7362ee07..c747e68a7a 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -891,6 +891,8 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
#define CPUID_7_1_EAX_FSRS (1U << 11)
/* Fast Short REP CMPS/SCAS */
#define CPUID_7_1_EAX_FSRC (1U << 12)
+/* Support Tile Computational Operations on FP16 Numbers */
+#define CPUID_7_1_EAX_AMX_FP16 (1U << 21)
/* Do not exhibit MXCSR Configuration Dependent Timing (MCDT) behavior */
#define CPUID_7_2_EDX_MCDT_NO (1U << 5)
--
2.27.0

View File

@ -0,0 +1,60 @@
From 8fe9899c39d86f9e0baf832744a7cfe19642a3fd Mon Sep 17 00:00:00 2001
From: Jiaxi Chen <jiaxi.chen@linux.intel.com>
Date: Fri, 3 Mar 2023 14:59:10 +0800
Subject: [PATCH] target/i386: Add support for AVX-IFMA in CPUID enumeration
commit a957a88416ecbec51e147cba9fe89b93f6646b3b upstream.
AVX-IFMA is a new instruction in the latest Intel platform Sierra
Forest. This instruction packed multiplies unsigned 52-bit integers and
adds the low/high 52-bit products to Qword Accumulators.
The bit definition:
CPUID.(EAX=7,ECX=1):EAX[bit 23]
Add CPUID definition for AVX-IFMA.
Intel-SIG: commit a957a88416ec target/i386: Add support for AVX-IFMA in CPUID enumeration.
Backport GNR and SRF ISA into QEMU-6.2
Signed-off-by: Jiaxi Chen <jiaxi.chen@linux.intel.com>
Signed-off-by: Tao Su <tao1.su@linux.intel.com>
Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
Message-Id: <20230303065913.1246327-4-tao1.su@linux.intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
[ Quanxian Wang: amend commit log ]
Signed-off-by: Quanxian Wang <quanxian.wang@intel.com>
---
target/i386/cpu.c | 2 +-
target/i386/cpu.h | 2 ++
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 3fc3b8041a..b19fb0cf87 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -876,7 +876,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
NULL, NULL, "fzrm", "fsrs",
"fsrc", NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
- NULL, "amx-fp16", NULL, NULL,
+ NULL, "amx-fp16", NULL, "avx-ifma",
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
},
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index c747e68a7a..2bcc127fac 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -893,6 +893,8 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
#define CPUID_7_1_EAX_FSRC (1U << 12)
/* Support Tile Computational Operations on FP16 Numbers */
#define CPUID_7_1_EAX_AMX_FP16 (1U << 21)
+/* Support for VPMADD52[H,L]UQ */
+#define CPUID_7_1_EAX_AVX_IFMA (1U << 23)
/* Do not exhibit MXCSR Configuration Dependent Timing (MCDT) behavior */
#define CPUID_7_2_EDX_MCDT_NO (1U << 5)
--
2.27.0

View File

@ -0,0 +1,62 @@
From 165d587b52f7c8459d9a9deca389610f9165b33a Mon Sep 17 00:00:00 2001
From: Quanxian Wang <quanxian.wang@intel.com>
Date: Wed, 8 Nov 2023 12:44:56 +0800
Subject: [PATCH] target/i386: Add support for AVX-NE-CONVERT in CPUID
enumeration
commit ecd2e6ca037d7bf3673c5478590d686d5cd6135a upstream.
AVX-NE-CONVERT is a new set of instructions which can convert low
precision floating point like BF16/FP16 to high precision floating point
FP32, as well as convert FP32 elements to BF16. This instruction allows
the platform to have improved AI capabilities and better compatibility.
The bit definition:
CPUID.(EAX=7,ECX=1):EDX[bit 5]
Add CPUID definition for AVX-NE-CONVERT.
Intel-SIG: commit ecd2e6ca037d target/i386: Add support for AVX-NE-CONVERT in CPUID enumeration.
Backport GNR and SRF ISA into QEMU-6.2
Signed-off-by: Jiaxi Chen <jiaxi.chen@linux.intel.com>
Signed-off-by: Tao Su <tao1.su@linux.intel.com>
Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
Message-Id: <20230303065913.1246327-6-tao1.su@linux.intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
[ Quanxian Wang: amend commit log ]
Signed-off-by: Quanxian Wang <quanxian.wang@intel.com>
---
target/i386/cpu.c | 2 +-
target/i386/cpu.h | 2 ++
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index a14284a81b..d36174d689 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -911,7 +911,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
.type = CPUID_FEATURE_WORD,
.feat_names = {
NULL, NULL, NULL, NULL,
- "avx-vnni-int8", NULL, NULL, NULL,
+ "avx-vnni-int8", "avx-ne-convert", NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index b81d77084c..93c8bd6a13 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -898,6 +898,8 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
#define CPUID_7_1_EAX_AVX_IFMA (1U << 23)
/* Support for VPDPB[SU,UU,SS]D[,S] */
#define CPUID_7_1_EDX_AVX_VNNI_INT8 (1U << 4)
+/* AVX NE CONVERT Instructions */
+#define CPUID_7_1_EDX_AVX_NE_CONVERT (1U << 5)
/* Do not exhibit MXCSR Configuration Dependent Timing (MCDT) behavior */
#define CPUID_7_2_EDX_MCDT_NO (1U << 5)
--
2.27.0

View File

@ -0,0 +1,110 @@
From 71b820dc04fbe04342d5a05be3d774c704b682ec Mon Sep 17 00:00:00 2001
From: Quanxian Wang <quanxian.wang@intel.com>
Date: Wed, 8 Nov 2023 12:43:11 +0800
Subject: [PATCH] target/i386: Add support for AVX-VNNI-INT8 in CPUID
enumeration
commit eaaa197d5b112ea2758b54df58881a2626de3af5 upstream.
AVX-VNNI-INT8 is a new set of instructions in the latest Intel platform
Sierra Forest, aims for the platform to have superior AI capabilities.
This instruction multiplies the individual bytes of two unsigned or
unsigned source operands, then adds and accumulates the results into the
destination dword element size operand.
The bit definition:
CPUID.(EAX=7,ECX=1):EDX[bit 4]
AVX-VNNI-INT8 is on a new feature bits leaf. Add a CPUID feature word
FEAT_7_1_EDX for this leaf.
Add CPUID definition for AVX-VNNI-INT8.
Intel-SIG: commit eaaa197d5b11 target/i386: Add support for AVX-VNNI-INT8 in CPUID enumeration.
Backport GNR and SRF ISA into QEMU-6.2
Signed-off-by: Jiaxi Chen <jiaxi.chen@linux.intel.com>
Signed-off-by: Tao Su <tao1.su@linux.intel.com>
Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
Message-Id: <20230303065913.1246327-5-tao1.su@linux.intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
[ Quanxian Wang: amend commit log ]
Signed-off-by: Quanxian Wang <quanxian.wang@intel.com>
---
target/i386/cpu.c | 22 +++++++++++++++++++++-
target/i386/cpu.h | 3 +++
2 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index b19fb0cf87..a14284a81b 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -663,6 +663,7 @@ void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
#define TCG_7_0_EDX_FEATURES CPUID_7_0_EDX_FSRM
#define TCG_7_1_EAX_FEATURES (CPUID_7_1_EAX_FZRM | CPUID_7_1_EAX_FSRS | \
CPUID_7_1_EAX_FSRC)
+#define TCG_7_1_EDX_FEATURES 0
#define TCG_7_2_EDX_FEATURES 0
#define TCG_APM_FEATURES 0
#define TCG_6_EAX_FEATURES CPUID_6_EAX_ARAT
@@ -906,6 +907,25 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
},
.tcg_features = TCG_7_2_EDX_FEATURES,
},
+ [FEAT_7_1_EDX] = {
+ .type = CPUID_FEATURE_WORD,
+ .feat_names = {
+ NULL, NULL, NULL, NULL,
+ "avx-vnni-int8", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ },
+ .cpuid = {
+ .eax = 7,
+ .needs_ecx = true, .ecx = 1,
+ .reg = R_EDX,
+ },
+ .tcg_features = TCG_7_1_EDX_FEATURES,
+ },
[FEAT_8000_0007_EDX] = {
.type = CPUID_FEATURE_WORD,
.feat_names = {
@@ -5557,9 +5577,9 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
}
} else if (count == 1) {
*eax = env->features[FEAT_7_1_EAX];
+ *edx = env->features[FEAT_7_1_EDX];
*ebx = 0;
*ecx = 0;
- *edx = 0;
} else if (count == 2) {
*edx = env->features[FEAT_7_2_EDX];
*eax = 0;
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 2bcc127fac..b81d77084c 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -601,6 +601,7 @@ typedef enum FeatureWord {
FEAT_SGX_12_0_EAX, /* CPUID[EAX=0x12,ECX=0].EAX (SGX) */
FEAT_SGX_12_0_EBX, /* CPUID[EAX=0x12,ECX=0].EBX (SGX MISCSELECT[31:0]) */
FEAT_SGX_12_1_EAX, /* CPUID[EAX=0x12,ECX=1].EAX (SGX ATTRIBUTES[31:0]) */
+ FEAT_7_1_EDX, /* CPUID[EAX=7,ECX=1].EDX */
FEAT_7_2_EDX, /* CPUID[EAX=7,ECX=2].EDX */
FEATURE_WORDS,
} FeatureWord;
@@ -895,6 +896,8 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
#define CPUID_7_1_EAX_AMX_FP16 (1U << 21)
/* Support for VPMADD52[H,L]UQ */
#define CPUID_7_1_EAX_AVX_IFMA (1U << 23)
+/* Support for VPDPB[SU,UU,SS]D[,S] */
+#define CPUID_7_1_EDX_AVX_VNNI_INT8 (1U << 4)
/* Do not exhibit MXCSR Configuration Dependent Timing (MCDT) behavior */
#define CPUID_7_2_EDX_MCDT_NO (1U << 5)
--
2.27.0

View File

@ -0,0 +1,61 @@
From 25d08629eab566f5a47bf915a86e20318ee1cf08 Mon Sep 17 00:00:00 2001
From: Jiaxi Chen <jiaxi.chen@linux.intel.com>
Date: Fri, 3 Mar 2023 14:59:08 +0800
Subject: [PATCH] target/i386: Add support for CMPCCXADD in CPUID enumeration
commit a9ce107fd0f2017af84255a9cf6542fa3eb3e214 upstream.
CMPccXADD is a new set of instructions in the latest Intel platform
Sierra Forest. This new instruction set includes a semaphore operation
that can compare and add the operands if condition is met, which can
improve database performance.
The bit definition:
CPUID.(EAX=7,ECX=1):EAX[bit 7]
Add CPUID definition for CMPCCXADD.
Intel-SIG: commit a9ce107fd0f2 target/i386: Add support for CMPCCXADD in CPUID enumeration.
Backport GNR and SRF ISA into QEMU-6.2
Signed-off-by: Jiaxi Chen <jiaxi.chen@linux.intel.com>
Signed-off-by: Tao Su <tao1.su@linux.intel.com>
Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
Message-Id: <20230303065913.1246327-2-tao1.su@linux.intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
[ Quanxian Wang: amend commit log ]
Signed-off-by: Quanxian Wang <quanxian.wang@intel.com>
---
target/i386/cpu.c | 2 +-
target/i386/cpu.h | 2 ++
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 58124071da..47c2d9da80 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -872,7 +872,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
.type = CPUID_FEATURE_WORD,
.feat_names = {
NULL, NULL, NULL, NULL,
- "avx-vnni", "avx512-bf16", NULL, NULL,
+ "avx-vnni", "avx512-bf16", NULL, "cmpccxadd",
NULL, NULL, "fzrm", "fsrs",
"fsrc", NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 37c687d4d8..4a7362ee07 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -883,6 +883,8 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
#define CPUID_7_1_EAX_AVX_VNNI (1U << 4)
/* AVX512 BFloat16 Instruction */
#define CPUID_7_1_EAX_AVX512_BF16 (1U << 5)
+/* CMPCCXADD Instructions */
+#define CPUID_7_1_EAX_CMPCCXADD (1U << 7)
/* Fast Zero REP MOVS */
#define CPUID_7_1_EAX_FZRM (1U << 10)
/* Fast Short REP STOS */
--
2.27.0

View File

@ -0,0 +1,61 @@
From 9a56c714caaf3bf31430a769befdf92e79388dda Mon Sep 17 00:00:00 2001
From: Quanxian Wang <quanxian.wang@intel.com>
Date: Wed, 8 Nov 2023 12:46:00 +0800
Subject: [PATCH] target/i386: Add support for PREFETCHIT0/1 in CPUID
enumeration
commit d1a1111514333e46a98b136235f71eef90d610fa upstream.
Latest Intel platform Granite Rapids has introduced a new instruction -
PREFETCHIT0/1, which moves code to memory (cache) closer to the
processor depending on specific hints.
The bit definition:
CPUID.(EAX=7,ECX=1):EDX[bit 14]
Add CPUID definition for PREFETCHIT0/1.
Intel-SIG: commit d1a111151433 target/i386: Add support for PREFETCHIT0/1 in CPUID enumeration.
Backport GNR and SRF ISA into QEMU-6.2
Signed-off-by: Jiaxi Chen <jiaxi.chen@linux.intel.com>
Signed-off-by: Tao Su <tao1.su@linux.intel.com>
Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
Message-Id: <20230303065913.1246327-7-tao1.su@linux.intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
[ Quanxian Wang: amend commit log ]
Signed-off-by: Quanxian Wang <quanxian.wang@intel.com>
---
target/i386/cpu.c | 2 +-
target/i386/cpu.h | 2 ++
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index d36174d689..ee243693e3 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -913,7 +913,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
NULL, NULL, NULL, NULL,
"avx-vnni-int8", "avx-ne-convert", NULL, NULL,
NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
+ NULL, NULL, "prefetchiti", NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 93c8bd6a13..32ecec5fa7 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -900,6 +900,8 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
#define CPUID_7_1_EDX_AVX_VNNI_INT8 (1U << 4)
/* AVX NE CONVERT Instructions */
#define CPUID_7_1_EDX_AVX_NE_CONVERT (1U << 5)
+/* PREFETCHIT0/1 Instructions */
+#define CPUID_7_1_EDX_PREFETCHITI (1U << 14)
/* Do not exhibit MXCSR Configuration Dependent Timing (MCDT) behavior */
#define CPUID_7_2_EDX_MCDT_NO (1U << 5)
--
2.27.0

View File

@ -0,0 +1,46 @@
From 52d000a4043f3000f880bb5c75a298f57b8e0fe0 Mon Sep 17 00:00:00 2001
From: Tao Su <tao1.su@linux.intel.com>
Date: Thu, 6 Jul 2023 13:49:44 +0800
Subject: [PATCH] target/i386: Adjust feature level according to FEAT_7_1_EDX
commit 8731336e90dea3dd04948127e775c9f087f97a4c upstream.
If FEAT_7_1_EAX is 0 and FEAT_7_1_EDX is non-zero, as is the case
with a Granite Rapids host and
'-cpu host,-avx-vnni,-avx512-bf16,-fzrm,-fsrs,-fsrc,-amx-fp16', we can't
get CPUID_7_1 leaf even though CPUID_7_1_EDX has non-zero value.
Update cpuid_level_func7 according to CPUID_7_1_EDX, otherwise
guest may report wrong maximum number sub-leaves in leaf 07H.
Fixes: eaaa197d5b11 ("target/i386: Add support for AVX-VNNI-INT8 in CPUID enumeration")
Intel-SIG: commit 8731336e90de target/i386: Adjust feature level according to FEAT_7_1_EDX.
Backport GNR and SRF ISA into QEMU-6.2
Cc: qemu-stable@nongnu.org
Signed-off-by: Tao Su <tao1.su@linux.intel.com>
Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
Message-ID: <20230706054949.66556-2-tao1.su@linux.intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
[ Quanxian Wang: amend commit log ]
Signed-off-by: Quanxian Wang <quanxian.wang@intel.com>
---
target/i386/cpu.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index efe0c2b46c..6aaa730a0d 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -6551,6 +6551,7 @@ void x86_cpu_expand_features(X86CPU *cpu, Error **errp)
x86_cpu_adjust_feat_level(cpu, FEAT_6_EAX);
x86_cpu_adjust_feat_level(cpu, FEAT_7_0_ECX);
x86_cpu_adjust_feat_level(cpu, FEAT_7_1_EAX);
+ x86_cpu_adjust_feat_level(cpu, FEAT_7_1_EDX);
x86_cpu_adjust_feat_level(cpu, FEAT_7_2_EDX);
x86_cpu_adjust_feat_level(cpu, FEAT_8000_0001_EDX);
x86_cpu_adjust_feat_level(cpu, FEAT_8000_0001_ECX);
--
2.27.0

View File

@ -0,0 +1,46 @@
From 3cea2c36571b39a6fa956abe66507c04283ad614 Mon Sep 17 00:00:00 2001
From: Pawan Gupta <pawan.kumar.gupta@linux.intel.com>
Date: Mon, 14 Aug 2023 21:54:27 -0700
Subject: [PATCH] target/i386: Export GDS_NO bit to guests
commit 3a2a1f97ea349745094e789e6b0768dbd92d0dcd upstream.
Gather Data Sampling (GDS) is a side-channel attack using Gather
instructions. Some Intel processors will set ARCH_CAP_GDS_NO bit in
MSR IA32_ARCH_CAPABILITIES to report that they are not vulnerable to
GDS.
Make this bit available to guests.
Intel-SIG: commit 3a2a1f97ea34 ("target/i386: Export GDS_NO bit to guests")
Backport to export GDS_NO bit to guests(CVE-2022-40982).
Closes: https://lore.kernel.org/qemu-devel/CAMGffEmG6TNq0n3+4OJAgXc8J0OevY60KHZekXCBs3LoK9vehA@mail.gmail.com/
Reported-by: Jack Wang <jinpu.wang@ionos.com>
Signed-off-by: Pawan Gupta <pawan.kumar.gupta@linux.intel.com>
Tested-by: Jack Wang <jinpu.wang@ionos.com>
Tested-by: Daniel Sneddon <daniel.sneddon@linux.intel.com>
Message-ID: <fde42d81ce454477ca8e27d5429a190b7366fe86.1692074650.git.pawan.kumar.gupta@linux.intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
[ Aichun Shi: amend commit log ]
Signed-off-by: Aichun Shi <aichun.shi@intel.com>
---
target/i386/cpu.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index eb911b12fa..58124071da 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1004,7 +1004,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
NULL, "sbdr-ssdp-no", "fbsdp-no", "psdp-no",
NULL, "fb-clear", NULL, NULL,
NULL, NULL, NULL, NULL,
- "pbrsb-no", NULL, NULL, NULL,
+ "pbrsb-no", NULL, "gds-no", NULL,
NULL, NULL, NULL, NULL,
},
.msr = {
--
2.27.0

View File

@ -0,0 +1,62 @@
From 53e0242318e838013504688307af44e80ab36c70 Mon Sep 17 00:00:00 2001
From: zhujun2 <zhujun2_yewu@cmss.chinamobile.com>
Date: Tue, 21 Nov 2023 18:03:25 -0800
Subject: [PATCH] tests/qtest: check the return value
These variables "ret" are never referenced in the code, thus
add check logic for the "ret"
Signed-off-by: zhujun2 <zhujun2_yewu@cmss.chinamobile.com>
---
tests/qtest/test-filter-mirror.c | 1 +
tests/qtest/test-filter-redirector.c | 2 ++
tests/qtest/virtio-net-test.c | 1 +
3 files changed, 4 insertions(+)
diff --git a/tests/qtest/test-filter-mirror.c b/tests/qtest/test-filter-mirror.c
index bc0dee64dd..40f736734a 100644
--- a/tests/qtest/test-filter-mirror.c
+++ b/tests/qtest/test-filter-mirror.c
@@ -71,6 +71,7 @@ static void test_mirror(void)
g_assert_cmpint(len, ==, sizeof(send_buf));
recv_buf = g_malloc(len);
ret = qemu_recv(recv_sock[0], recv_buf, len, 0);
+ g_assert_cmpint(ret, ==, len);
g_assert_cmpstr(recv_buf, ==, send_buf);
g_free(recv_buf);
diff --git a/tests/qtest/test-filter-redirector.c b/tests/qtest/test-filter-redirector.c
index 4269b2cdd9..f802c94f54 100644
--- a/tests/qtest/test-filter-redirector.c
+++ b/tests/qtest/test-filter-redirector.c
@@ -133,6 +133,7 @@ static void test_redirector_tx(void)
g_assert_cmpint(len, ==, sizeof(send_buf));
recv_buf = g_malloc(len);
ret = qemu_recv(recv_sock, recv_buf, len, 0);
+ g_assert_cmpint(ret, ==, len);
g_assert_cmpstr(recv_buf, ==, send_buf);
g_free(recv_buf);
@@ -201,6 +202,7 @@ static void test_redirector_rx(void)
g_assert_cmpint(len, ==, sizeof(send_buf));
recv_buf = g_malloc(len);
ret = qemu_recv(backend_sock[0], recv_buf, len, 0);
+ g_assert_cmpint(ret, ==, len);
g_assert_cmpstr(recv_buf, ==, send_buf);
close(send_sock);
diff --git a/tests/qtest/virtio-net-test.c b/tests/qtest/virtio-net-test.c
index 8bf74e516c..aab4480fb0 100644
--- a/tests/qtest/virtio-net-test.c
+++ b/tests/qtest/virtio-net-test.c
@@ -92,6 +92,7 @@ static void tx_test(QVirtioDevice *dev,
len = ntohl(len);
ret = qemu_recv(socket, buffer, len, 0);
+ g_assert_cmpint(ret, ==, len);
g_assert_cmpstr(buffer, ==, "TEST");
}
--
2.27.0

View File

@ -0,0 +1,43 @@
From 1e32685272ff1932b9ca022db8717720fc901d0e Mon Sep 17 00:00:00 2001
From: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
Date: Mon, 6 Nov 2023 06:17:47 +0000
Subject: [PATCH] tpm_crb: mark command buffer as dirty on request completion
mainline inclusion commit e37a0ef4605e5d2041785ff3fc89ca6021faf7a0 category:
bugfix
---------------------------------------------------------------
At the moment, there doesn't seems to be any way to know that QEMU
made modification to the command buffer. This is potentially an issue
on Xen while migrating a guest, as modification to the buffer after
the migration as started could be ignored and not transfered to the
destination.
Mark the memory region of the command buffer as dirty once a request
is completed.
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Message-id: 20220411144749.47185-1-anthony.perard@citrix.com
Signed-off-by: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
---
hw/tpm/tpm_crb.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/hw/tpm/tpm_crb.c b/hw/tpm/tpm_crb.c
index 58ebd1469c..c05972736a 100644
--- a/hw/tpm/tpm_crb.c
+++ b/hw/tpm/tpm_crb.c
@@ -196,6 +196,7 @@ static void tpm_crb_request_completed(TPMIf *ti, int ret)
ARRAY_FIELD_DP32(s->regs, CRB_CTRL_STS,
tpmSts, 1); /* fatal error */
}
+ memory_region_set_dirty(&s->cmdmem, 0, CRB_CTRL_CMD_SIZE);
}
static enum TPMVersion tpm_crb_get_version(TPMIf *ti)
--
2.27.0

View File

@ -0,0 +1,38 @@
From cb5e4e55c489462a2ff11143a5768b5c096bf1ad Mon Sep 17 00:00:00 2001
From: qihao <qihao_yewu@cmss.chinamobile.com>
Date: Wed, 15 Nov 2023 14:49:44 +0800
Subject: [PATCH] tracetool: avoid invalid escape in Python string
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
cheery-pick from 4d96307c5b4fac40c6ca25f38318b4b65d315de0
This is an error in Python 3.12; fix it by using a raw string literal.
Cc: <qemu-stable@nongnu.org>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20231108105649.60453-1-marcandre.lureau@redhat.com>
Signed-off-by: qihao_yewu <qihao_yewu@cmss.chinamobile.com>
---
scripts/tracetool/__init__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py
index 5bc94d95cf..630e85a5d6 100644
--- a/scripts/tracetool/__init__.py
+++ b/scripts/tracetool/__init__.py
@@ -94,7 +94,7 @@ def out(*lines, **kwargs):
def validate_type(name):
bits = name.split(" ")
for bit in bits:
- bit = re.sub("\*", "", bit)
+ bit = re.sub(r"\*", "", bit)
if bit == "":
continue
if bit == "const":
--
2.27.0

View File

@ -0,0 +1,219 @@
From 6dac473fb3f4f98ef67c63a38b00465299519132 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Mon, 14 Mar 2022 18:34:48 +0100
Subject: [PATCH] util: Add iova_tree_alloc_map
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This iova tree function allows it to look for a hole in allocated
regions and return a totally new translation for a given translated
address.
It's usage is mainly to allow devices to access qemu address space,
remapping guest's one into a new iova space where qemu can add chunks of
addresses.
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
include/qemu/iova-tree.h | 18 ++++++
util/iova-tree.c | 136 +++++++++++++++++++++++++++++++++++++++
2 files changed, 154 insertions(+)
diff --git a/include/qemu/iova-tree.h b/include/qemu/iova-tree.h
index 8249edd764..d066400f09 100644
--- a/include/qemu/iova-tree.h
+++ b/include/qemu/iova-tree.h
@@ -29,6 +29,7 @@
#define IOVA_OK (0)
#define IOVA_ERR_INVALID (-1) /* Invalid parameters */
#define IOVA_ERR_OVERLAP (-2) /* IOVA range overlapped */
+#define IOVA_ERR_NOMEM (-3) /* Cannot allocate */
typedef struct IOVATree IOVATree;
typedef struct DMAMap {
@@ -119,6 +120,23 @@ const DMAMap *iova_tree_find_address(const IOVATree *tree, hwaddr iova);
*/
void iova_tree_foreach(IOVATree *tree, iova_tree_iterator iterator);
+/**
+ * iova_tree_alloc_map:
+ *
+ * @tree: the iova tree to allocate from
+ * @map: the new map (as translated addr & size) to allocate in the iova region
+ * @iova_begin: the minimum address of the allocation
+ * @iova_end: the maximum addressable direction of the allocation
+ *
+ * Allocates a new region of a given size, between iova_min and iova_max.
+ *
+ * Return: Same as iova_tree_insert, but cannot overlap and can return error if
+ * iova tree is out of free contiguous range. The caller gets the assigned iova
+ * in map->iova.
+ */
+int iova_tree_alloc_map(IOVATree *tree, DMAMap *map, hwaddr iova_begin,
+ hwaddr iova_end);
+
/**
* iova_tree_destroy:
*
diff --git a/util/iova-tree.c b/util/iova-tree.c
index 23ea35b7a4..139626b46f 100644
--- a/util/iova-tree.c
+++ b/util/iova-tree.c
@@ -16,6 +16,40 @@ struct IOVATree {
GTree *tree;
};
+/* Args to pass to iova_tree_alloc foreach function. */
+struct IOVATreeAllocArgs {
+ /* Size of the desired allocation */
+ size_t new_size;
+
+ /* The minimum address allowed in the allocation */
+ hwaddr iova_begin;
+
+ /* Map at the left of the hole, can be NULL if "this" is first one */
+ const DMAMap *prev;
+
+ /* Map at the right of the hole, can be NULL if "prev" is the last one */
+ const DMAMap *this;
+
+ /* If found, we fill in the IOVA here */
+ hwaddr iova_result;
+
+ /* Whether have we found a valid IOVA */
+ bool iova_found;
+};
+
+/**
+ * Iterate args to the next hole
+ *
+ * @args: The alloc arguments
+ * @next: The next mapping in the tree. Can be NULL to signal the last one
+ */
+static void iova_tree_alloc_args_iterate(struct IOVATreeAllocArgs *args,
+ const DMAMap *next)
+{
+ args->prev = args->this;
+ args->this = next;
+}
+
static int iova_tree_compare(gconstpointer a, gconstpointer b, gpointer data)
{
const DMAMap *m1 = a, *m2 = b;
@@ -107,6 +141,108 @@ int iova_tree_remove(IOVATree *tree, const DMAMap *map)
return IOVA_OK;
}
+/**
+ * Try to find an unallocated IOVA range between prev and this elements.
+ *
+ * @args: Arguments to allocation
+ *
+ * Cases:
+ *
+ * (1) !prev, !this: No entries allocated, always succeed
+ *
+ * (2) !prev, this: We're iterating at the 1st element.
+ *
+ * (3) prev, !this: We're iterating at the last element.
+ *
+ * (4) prev, this: this is the most common case, we'll try to find a hole
+ * between "prev" and "this" mapping.
+ *
+ * Note that this function assumes the last valid iova is HWADDR_MAX, but it
+ * searches linearly so it's easy to discard the result if it's not the case.
+ */
+static void iova_tree_alloc_map_in_hole(struct IOVATreeAllocArgs *args)
+{
+ const DMAMap *prev = args->prev, *this = args->this;
+ uint64_t hole_start, hole_last;
+
+ if (this && this->iova + this->size < args->iova_begin) {
+ return;
+ }
+
+ hole_start = MAX(prev ? prev->iova + prev->size + 1 : 0, args->iova_begin);
+ hole_last = this ? this->iova : HWADDR_MAX;
+
+ if (hole_last - hole_start > args->new_size) {
+ args->iova_result = hole_start;
+ args->iova_found = true;
+ }
+}
+
+/**
+ * Foreach dma node in the tree, compare if there is a hole with its previous
+ * node (or minimum iova address allowed) and the node.
+ *
+ * @key: Node iterating
+ * @value: Node iterating
+ * @pargs: Struct to communicate with the outside world
+ *
+ * Return: false to keep iterating, true if needs break.
+ */
+static gboolean iova_tree_alloc_traverse(gpointer key, gpointer value,
+ gpointer pargs)
+{
+ struct IOVATreeAllocArgs *args = pargs;
+ DMAMap *node = value;
+
+ assert(key == value);
+
+ iova_tree_alloc_args_iterate(args, node);
+ iova_tree_alloc_map_in_hole(args);
+ return args->iova_found;
+}
+
+int iova_tree_alloc_map(IOVATree *tree, DMAMap *map, hwaddr iova_begin,
+ hwaddr iova_last)
+{
+ struct IOVATreeAllocArgs args = {
+ .new_size = map->size,
+ .iova_begin = iova_begin,
+ };
+
+ if (unlikely(iova_last < iova_begin)) {
+ return IOVA_ERR_INVALID;
+ }
+
+ /*
+ * Find a valid hole for the mapping
+ *
+ * Assuming low iova_begin, so no need to do a binary search to
+ * locate the first node.
+ *
+ * TODO: Replace all this with g_tree_node_first/next/last when available
+ * (from glib since 2.68). To do it with g_tree_foreach complicates the
+ * code a lot.
+ *
+ */
+ g_tree_foreach(tree->tree, iova_tree_alloc_traverse, &args);
+ if (!args.iova_found) {
+ /*
+ * Either tree is empty or the last hole is still not checked.
+ * g_tree_foreach does not compare (last, iova_last] range, so we check
+ * it here.
+ */
+ iova_tree_alloc_args_iterate(&args, NULL);
+ iova_tree_alloc_map_in_hole(&args);
+ }
+
+ if (!args.iova_found || args.iova_result + map->size > iova_last) {
+ return IOVA_ERR_NOMEM;
+ }
+
+ map->iova = args.iova_result;
+ return iova_tree_insert(tree, map);
+}
+
void iova_tree_destroy(IOVATree *tree)
{
g_tree_destroy(tree->tree);
--
2.27.0

View File

@ -0,0 +1,61 @@
From b4c0eb3ad95c5c9a32cf87d30647d63ec9c193a9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Wed, 27 Apr 2022 17:49:31 +0200
Subject: [PATCH] util: Return void on iova_tree_remove
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
It always returns IOVA_OK so nobody uses it.
Acked-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Message-Id: <20220427154931.3166388-1-eperezma@redhat.com>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
include/qemu/iova-tree.h | 4 +---
util/iova-tree.c | 4 +---
2 files changed, 2 insertions(+), 6 deletions(-)
diff --git a/include/qemu/iova-tree.h b/include/qemu/iova-tree.h
index c938fb0793..16bbfdf5f8 100644
--- a/include/qemu/iova-tree.h
+++ b/include/qemu/iova-tree.h
@@ -72,10 +72,8 @@ int iova_tree_insert(IOVATree *tree, const DMAMap *map);
* provided. The range does not need to be exactly what has inserted,
* all the mappings that are included in the provided range will be
* removed from the tree. Here map->translated_addr is meaningless.
- *
- * Return: 0 if succeeded, or <0 if error.
*/
-int iova_tree_remove(IOVATree *tree, const DMAMap *map);
+void iova_tree_remove(IOVATree *tree, const DMAMap *map);
/**
* iova_tree_find:
diff --git a/util/iova-tree.c b/util/iova-tree.c
index 6dff29c1f6..fee530a579 100644
--- a/util/iova-tree.c
+++ b/util/iova-tree.c
@@ -164,15 +164,13 @@ void iova_tree_foreach(IOVATree *tree, iova_tree_iterator iterator)
g_tree_foreach(tree->tree, iova_tree_traverse, iterator);
}
-int iova_tree_remove(IOVATree *tree, const DMAMap *map)
+void iova_tree_remove(IOVATree *tree, const DMAMap *map)
{
const DMAMap *overlap;
while ((overlap = iova_tree_find(tree, map))) {
g_tree_remove(tree->tree, overlap);
}
-
- return IOVA_OK;
}
/**
--
2.27.0

View File

@ -0,0 +1,173 @@
From 4ac2c0c847ffee0fb6aa92a9735be9448c62c107 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Tue, 23 Aug 2022 20:20:04 +0200
Subject: [PATCH] util: accept iova_tree_remove_parameter by value
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
It's convenient to call iova_tree_remove from a map returned from
iova_tree_find or iova_tree_find_iova. With the current code this is not
possible, since we will free it, and then we will try to search for it
again.
Fix it making accepting the map by value, forcing a copy of the
argument. Not applying a fixes tag, since there is no use like that at
the moment.
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
hw/i386/intel_iommu.c | 6 +++---
hw/virtio/vhost-iova-tree.c | 2 +-
hw/virtio/vhost-iova-tree.h | 2 +-
hw/virtio/vhost-vdpa.c | 6 +++---
include/qemu/iova-tree.h | 2 +-
net/vhost-vdpa.c | 4 ++--
util/iova-tree.c | 4 ++--
7 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 5b865ac08c..2d5ad84149 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -1157,7 +1157,7 @@ static int vtd_page_walk_one(IOMMUTLBEvent *event, vtd_page_walk_info *info)
return ret;
}
/* Drop any existing mapping */
- iova_tree_remove(as->iova_tree, &target);
+ iova_tree_remove(as->iova_tree, target);
/* Recover the correct type */
event->type = IOMMU_NOTIFIER_MAP;
entry->perm = cache_perm;
@@ -1170,7 +1170,7 @@ static int vtd_page_walk_one(IOMMUTLBEvent *event, vtd_page_walk_info *info)
trace_vtd_page_walk_one_skip_unmap(entry->iova, entry->addr_mask);
return 0;
}
- iova_tree_remove(as->iova_tree, &target);
+ iova_tree_remove(as->iova_tree, target);
}
trace_vtd_page_walk_one(info->domain_id, entry->iova,
@@ -3516,7 +3516,7 @@ static void vtd_address_space_unmap(VTDAddressSpace *as, IOMMUNotifier *n)
map.iova = n->start;
map.size = size;
- iova_tree_remove(as->iova_tree, &map);
+ iova_tree_remove(as->iova_tree, map);
}
static void vtd_address_space_unmap_all(IntelIOMMUState *s)
diff --git a/hw/virtio/vhost-iova-tree.c b/hw/virtio/vhost-iova-tree.c
index 55fed1fefb..1339a4de8b 100644
--- a/hw/virtio/vhost-iova-tree.c
+++ b/hw/virtio/vhost-iova-tree.c
@@ -104,7 +104,7 @@ int vhost_iova_tree_map_alloc(VhostIOVATree *tree, DMAMap *map)
* @iova_tree: The vhost iova tree
* @map: The map to remove
*/
-void vhost_iova_tree_remove(VhostIOVATree *iova_tree, const DMAMap *map)
+void vhost_iova_tree_remove(VhostIOVATree *iova_tree, DMAMap map)
{
iova_tree_remove(iova_tree->iova_taddr_map, map);
}
diff --git a/hw/virtio/vhost-iova-tree.h b/hw/virtio/vhost-iova-tree.h
index 6a4f24e0f9..4adfd79ff0 100644
--- a/hw/virtio/vhost-iova-tree.h
+++ b/hw/virtio/vhost-iova-tree.h
@@ -22,6 +22,6 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(VhostIOVATree, vhost_iova_tree_delete);
const DMAMap *vhost_iova_tree_find_iova(const VhostIOVATree *iova_tree,
const DMAMap *map);
int vhost_iova_tree_map_alloc(VhostIOVATree *iova_tree, DMAMap *map);
-void vhost_iova_tree_remove(VhostIOVATree *iova_tree, const DMAMap *map);
+void vhost_iova_tree_remove(VhostIOVATree *iova_tree, DMAMap map);
#endif
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index 02dab41c42..0f640f670b 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -242,7 +242,7 @@ static void vhost_vdpa_listener_region_add(MemoryListener *listener,
fail_map:
if (v->shadow_vqs_enabled) {
- vhost_iova_tree_remove(v->iova_tree, &mem_region);
+ vhost_iova_tree_remove(v->iova_tree, mem_region);
}
fail:
@@ -302,7 +302,7 @@ static void vhost_vdpa_listener_region_del(MemoryListener *listener,
return;
}
iova = result->iova;
- vhost_iova_tree_remove(v->iova_tree, result);
+ vhost_iova_tree_remove(v->iova_tree, *result);
}
vhost_vdpa_iotlb_batch_begin_once(v);
ret = vhost_vdpa_dma_unmap(v, iova, int128_get64(llsize));
@@ -946,7 +946,7 @@ static bool vhost_vdpa_svq_map_ring(struct vhost_vdpa *v, DMAMap *needle,
needle->perm == IOMMU_RO);
if (unlikely(r != 0)) {
error_setg_errno(errp, -r, "Cannot map region to device");
- vhost_iova_tree_remove(v->iova_tree, needle);
+ vhost_iova_tree_remove(v->iova_tree, *needle);
}
return r == 0;
diff --git a/include/qemu/iova-tree.h b/include/qemu/iova-tree.h
index 16bbfdf5f8..8528e5c98f 100644
--- a/include/qemu/iova-tree.h
+++ b/include/qemu/iova-tree.h
@@ -73,7 +73,7 @@ int iova_tree_insert(IOVATree *tree, const DMAMap *map);
* all the mappings that are included in the provided range will be
* removed from the tree. Here map->translated_addr is meaningless.
*/
-void iova_tree_remove(IOVATree *tree, const DMAMap *map);
+void iova_tree_remove(IOVATree *tree, DMAMap map);
/**
* iova_tree_find:
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index 0f75aa6080..8cfd086639 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -252,7 +252,7 @@ static void vhost_vdpa_cvq_unmap_buf(struct vhost_vdpa *v, void *addr)
error_report("Device cannot unmap: %s(%d)", g_strerror(r), r);
}
- vhost_iova_tree_remove(tree, map);
+ vhost_iova_tree_remove(tree, *map);
}
static size_t vhost_vdpa_net_cvq_cmd_len(void)
@@ -305,7 +305,7 @@ static bool vhost_vdpa_cvq_map_buf(struct vhost_vdpa *v,
return true;
dma_map_err:
- vhost_iova_tree_remove(v->iova_tree, &map);
+ vhost_iova_tree_remove(v->iova_tree, map);
return false;
}
diff --git a/util/iova-tree.c b/util/iova-tree.c
index fee530a579..536789797e 100644
--- a/util/iova-tree.c
+++ b/util/iova-tree.c
@@ -164,11 +164,11 @@ void iova_tree_foreach(IOVATree *tree, iova_tree_iterator iterator)
g_tree_foreach(tree->tree, iova_tree_traverse, iterator);
}
-void iova_tree_remove(IOVATree *tree, const DMAMap *map)
+void iova_tree_remove(IOVATree *tree, DMAMap map)
{
const DMAMap *overlap;
- while ((overlap = iova_tree_find(tree, map))) {
+ while ((overlap = iova_tree_find(tree, &map))) {
g_tree_remove(tree->tree, overlap);
}
}
--
2.27.0

View File

@ -0,0 +1,116 @@
From 087ef4f1cfef58eadcb157585b70cf716c567305 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Mon, 14 Mar 2022 18:34:49 +0100
Subject: [PATCH] util: add iova_tree_find_iova
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This function does the reverse operation of iova_tree_find: To look for
a mapping that match a translated address so we can do the reverse.
This have linear complexity instead of logarithmic, but it supports
overlapping HVA. Future developments could reduce it.
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
include/qemu/iova-tree.h | 20 +++++++++++++++++++-
util/iova-tree.c | 34 ++++++++++++++++++++++++++++++++++
2 files changed, 53 insertions(+), 1 deletion(-)
diff --git a/include/qemu/iova-tree.h b/include/qemu/iova-tree.h
index d066400f09..c938fb0793 100644
--- a/include/qemu/iova-tree.h
+++ b/include/qemu/iova-tree.h
@@ -83,7 +83,7 @@ int iova_tree_remove(IOVATree *tree, const DMAMap *map);
* @tree: the iova tree to search from
* @map: the mapping to search
*
- * Search for a mapping in the iova tree that overlaps with the
+ * Search for a mapping in the iova tree that iova overlaps with the
* mapping range specified. Only the first found mapping will be
* returned.
*
@@ -95,6 +95,24 @@ int iova_tree_remove(IOVATree *tree, const DMAMap *map);
*/
const DMAMap *iova_tree_find(const IOVATree *tree, const DMAMap *map);
+/**
+ * iova_tree_find_iova:
+ *
+ * @tree: the iova tree to search from
+ * @map: the mapping to search
+ *
+ * Search for a mapping in the iova tree that translated_addr overlaps with the
+ * mapping range specified. Only the first found mapping will be
+ * returned.
+ *
+ * Return: DMAMap pointer if found, or NULL if not found. Note that
+ * the returned DMAMap pointer is maintained internally. User should
+ * only read the content but never modify or free the content. Also,
+ * user is responsible to make sure the pointer is valid (say, no
+ * concurrent deletion in progress).
+ */
+const DMAMap *iova_tree_find_iova(const IOVATree *tree, const DMAMap *map);
+
/**
* iova_tree_find_address:
*
diff --git a/util/iova-tree.c b/util/iova-tree.c
index 139626b46f..6dff29c1f6 100644
--- a/util/iova-tree.c
+++ b/util/iova-tree.c
@@ -37,6 +37,11 @@ struct IOVATreeAllocArgs {
bool iova_found;
};
+typedef struct IOVATreeFindIOVAArgs {
+ const DMAMap *needle;
+ const DMAMap *result;
+} IOVATreeFindIOVAArgs;
+
/**
* Iterate args to the next hole
*
@@ -81,6 +86,35 @@ const DMAMap *iova_tree_find(const IOVATree *tree, const DMAMap *map)
return g_tree_lookup(tree->tree, map);
}
+static gboolean iova_tree_find_address_iterator(gpointer key, gpointer value,
+ gpointer data)
+{
+ const DMAMap *map = key;
+ IOVATreeFindIOVAArgs *args = data;
+ const DMAMap *needle;
+
+ g_assert(key == value);
+
+ needle = args->needle;
+ if (map->translated_addr + map->size < needle->translated_addr ||
+ needle->translated_addr + needle->size < map->translated_addr) {
+ return false;
+ }
+
+ args->result = map;
+ return true;
+}
+
+const DMAMap *iova_tree_find_iova(const IOVATree *tree, const DMAMap *map)
+{
+ IOVATreeFindIOVAArgs args = {
+ .needle = map,
+ };
+
+ g_tree_foreach(tree->tree, iova_tree_find_address_iterator, &args);
+ return args.result;
+}
+
const DMAMap *iova_tree_find_address(const IOVATree *tree, hwaddr iova)
{
const DMAMap map = { .iova = iova, .size = 0 };
--
2.27.0

View File

@ -0,0 +1,59 @@
From d42fea8a40c4a5d8909103910d86da8e674d1fb2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Mon, 14 Mar 2022 18:34:52 +0100
Subject: [PATCH] vdpa: Adapt vhost_vdpa_get_vring_base to SVQ
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This is needed to achieve migration, so the destination can restore its
index.
Setting base as last used idx, so destination will see as available all
the entries that the device did not use, including the in-flight
processing ones.
This is ok for networking, but other kinds of devices might have
problems with these retransmissions.
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
hw/virtio/vhost-vdpa.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index 8245345bcd..428137f654 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -1143,8 +1143,25 @@ static int vhost_vdpa_set_vring_base(struct vhost_dev *dev,
static int vhost_vdpa_get_vring_base(struct vhost_dev *dev,
struct vhost_vring_state *ring)
{
+ struct vhost_vdpa *v = dev->opaque;
int ret;
+ if (v->shadow_vqs_enabled) {
+ VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs,
+ ring->index);
+
+ /*
+ * Setting base as last used idx, so destination will see as available
+ * all the entries that the device did not use, including the in-flight
+ * processing ones.
+ *
+ * TODO: This is ok for networking, but other kinds of devices might
+ * have problems with these retransmissions.
+ */
+ ring->num = svq->last_used_idx;
+ return 0;
+ }
+
ret = vhost_vdpa_call(dev, VHOST_GET_VRING_BASE, ring);
trace_vhost_vdpa_get_vring_base(dev, ring->index, ring->num);
return ret;
--
2.27.0

View File

@ -0,0 +1,415 @@
From 649e277b6ec0d2cd798f6d43776ea38b00450db9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Mon, 14 Mar 2022 18:34:51 +0100
Subject: [PATCH] vdpa: Add custom IOTLB translations to SVQ
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Use translations added in VhostIOVATree in SVQ.
Only introduce usage here, not allocation and deallocation. As with
previous patches, we use the dead code paths of shadow_vqs_enabled to
avoid commiting too many changes at once. These are impossible to take
at the moment.
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
hw/virtio/vhost-shadow-virtqueue.c | 86 +++++++++++++++++---
hw/virtio/vhost-shadow-virtqueue.h | 6 +-
hw/virtio/vhost-vdpa.c | 122 ++++++++++++++++++++++++-----
include/hw/virtio/vhost-vdpa.h | 3 +
4 files changed, 187 insertions(+), 30 deletions(-)
diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c
index 46e94f0861..c38b6b6ab5 100644
--- a/hw/virtio/vhost-shadow-virtqueue.c
+++ b/hw/virtio/vhost-shadow-virtqueue.c
@@ -69,7 +69,59 @@ static uint16_t vhost_svq_available_slots(const VhostShadowVirtqueue *svq)
return svq->vring.num - (svq->shadow_avail_idx - svq->shadow_used_idx);
}
-static void vhost_vring_write_descs(VhostShadowVirtqueue *svq,
+/**
+ * Translate addresses between the qemu's virtual address and the SVQ IOVA
+ *
+ * @svq: Shadow VirtQueue
+ * @vaddr: Translated IOVA addresses
+ * @iovec: Source qemu's VA addresses
+ * @num: Length of iovec and minimum length of vaddr
+ */
+static bool vhost_svq_translate_addr(const VhostShadowVirtqueue *svq,
+ hwaddr *addrs, const struct iovec *iovec,
+ size_t num)
+{
+ if (num == 0) {
+ return true;
+ }
+
+ for (size_t i = 0; i < num; ++i) {
+ DMAMap needle = {
+ .translated_addr = (hwaddr)(uintptr_t)iovec[i].iov_base,
+ .size = iovec[i].iov_len,
+ };
+ Int128 needle_last, map_last;
+ size_t off;
+
+ const DMAMap *map = vhost_iova_tree_find_iova(svq->iova_tree, &needle);
+ /*
+ * Map cannot be NULL since iova map contains all guest space and
+ * qemu already has a physical address mapped
+ */
+ if (unlikely(!map)) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "Invalid address 0x%"HWADDR_PRIx" given by guest",
+ needle.translated_addr);
+ return false;
+ }
+
+ off = needle.translated_addr - map->translated_addr;
+ addrs[i] = map->iova + off;
+
+ needle_last = int128_add(int128_make64(needle.translated_addr),
+ int128_make64(iovec[i].iov_len));
+ map_last = int128_make64(map->translated_addr + map->size);
+ if (unlikely(int128_gt(needle_last, map_last))) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "Guest buffer expands over iova range");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static void vhost_vring_write_descs(VhostShadowVirtqueue *svq, hwaddr *sg,
const struct iovec *iovec, size_t num,
bool more_descs, bool write)
{
@@ -88,7 +140,7 @@ static void vhost_vring_write_descs(VhostShadowVirtqueue *svq,
} else {
descs[i].flags = flags;
}
- descs[i].addr = cpu_to_le64((hwaddr)(intptr_t)iovec[n].iov_base);
+ descs[i].addr = cpu_to_le64(sg[n]);
descs[i].len = cpu_to_le32(iovec[n].iov_len);
last = i;
@@ -103,6 +155,8 @@ static bool vhost_svq_add_split(VhostShadowVirtqueue *svq,
{
unsigned avail_idx;
vring_avail_t *avail = svq->vring.avail;
+ bool ok;
+ g_autofree hwaddr *sgs = g_new(hwaddr, MAX(elem->out_num, elem->in_num));
*head = svq->free_head;
@@ -113,9 +167,20 @@ static bool vhost_svq_add_split(VhostShadowVirtqueue *svq,
return false;
}
- vhost_vring_write_descs(svq, elem->out_sg, elem->out_num, elem->in_num > 0,
- false);
- vhost_vring_write_descs(svq, elem->in_sg, elem->in_num, false, true);
+ ok = vhost_svq_translate_addr(svq, sgs, elem->out_sg, elem->out_num);
+ if (unlikely(!ok)) {
+ return false;
+ }
+ vhost_vring_write_descs(svq, sgs, elem->out_sg, elem->out_num,
+ elem->in_num > 0, false);
+
+
+ ok = vhost_svq_translate_addr(svq, sgs, elem->in_sg, elem->in_num);
+ if (unlikely(!ok)) {
+ return false;
+ }
+
+ vhost_vring_write_descs(svq, sgs, elem->in_sg, elem->in_num, false, true);
/*
* Put the entry in the available array (but don't update avail->idx until
@@ -394,9 +459,9 @@ void vhost_svq_set_svq_call_fd(VhostShadowVirtqueue *svq, int call_fd)
void vhost_svq_get_vring_addr(const VhostShadowVirtqueue *svq,
struct vhost_vring_addr *addr)
{
- addr->desc_user_addr = (uint64_t)(intptr_t)svq->vring.desc;
- addr->avail_user_addr = (uint64_t)(intptr_t)svq->vring.avail;
- addr->used_user_addr = (uint64_t)(intptr_t)svq->vring.used;
+ addr->desc_user_addr = (uint64_t)(uintptr_t)svq->vring.desc;
+ addr->avail_user_addr = (uint64_t)(uintptr_t)svq->vring.avail;
+ addr->used_user_addr = (uint64_t)(uintptr_t)svq->vring.used;
}
size_t vhost_svq_driver_area_size(const VhostShadowVirtqueue *svq)
@@ -517,11 +582,13 @@ void vhost_svq_stop(VhostShadowVirtqueue *svq)
* Creates vhost shadow virtqueue, and instructs the vhost device to use the
* shadow methods and file descriptors.
*
+ * @iova_tree: Tree to perform descriptors translations
+ *
* Returns the new virtqueue or NULL.
*
* In case of error, reason is reported through error_report.
*/
-VhostShadowVirtqueue *vhost_svq_new(void)
+VhostShadowVirtqueue *vhost_svq_new(VhostIOVATree *iova_tree)
{
g_autofree VhostShadowVirtqueue *svq = g_new0(VhostShadowVirtqueue, 1);
int r;
@@ -542,6 +609,7 @@ VhostShadowVirtqueue *vhost_svq_new(void)
event_notifier_init_fd(&svq->svq_kick, VHOST_FILE_UNBIND);
event_notifier_set_handler(&svq->hdev_call, vhost_svq_handle_call);
+ svq->iova_tree = iova_tree;
return g_steal_pointer(&svq);
err_init_hdev_call:
diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h
index 38b3b91ca7..e5e24c536d 100644
--- a/hw/virtio/vhost-shadow-virtqueue.h
+++ b/hw/virtio/vhost-shadow-virtqueue.h
@@ -13,6 +13,7 @@
#include "qemu/event_notifier.h"
#include "hw/virtio/virtio.h"
#include "standard-headers/linux/vhost_types.h"
+#include "hw/virtio/vhost-iova-tree.h"
/* Shadow virtqueue to relay notifications */
typedef struct VhostShadowVirtqueue {
@@ -43,6 +44,9 @@ typedef struct VhostShadowVirtqueue {
/* Virtio device */
VirtIODevice *vdev;
+ /* IOVA mapping */
+ VhostIOVATree *iova_tree;
+
/* Map for use the guest's descriptors */
VirtQueueElement **ring_id_maps;
@@ -75,7 +79,7 @@ void vhost_svq_start(VhostShadowVirtqueue *svq, VirtIODevice *vdev,
VirtQueue *vq);
void vhost_svq_stop(VhostShadowVirtqueue *svq);
-VhostShadowVirtqueue *vhost_svq_new(void);
+VhostShadowVirtqueue *vhost_svq_new(VhostIOVATree *iova_tree);
void vhost_svq_free(gpointer vq);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(VhostShadowVirtqueue, vhost_svq_free);
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index db34f26246..8245345bcd 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -211,6 +211,21 @@ static void vhost_vdpa_listener_region_add(MemoryListener *listener,
vaddr, section->readonly);
llsize = int128_sub(llend, int128_make64(iova));
+ if (v->shadow_vqs_enabled) {
+ DMAMap mem_region = {
+ .translated_addr = (hwaddr)(uintptr_t)vaddr,
+ .size = int128_get64(llsize) - 1,
+ .perm = IOMMU_ACCESS_FLAG(true, section->readonly),
+ };
+
+ int r = vhost_iova_tree_map_alloc(v->iova_tree, &mem_region);
+ if (unlikely(r != IOVA_OK)) {
+ error_report("Can't allocate a mapping (%d)", r);
+ goto fail;
+ }
+
+ iova = mem_region.iova;
+ }
vhost_vdpa_iotlb_batch_begin_once(v);
ret = vhost_vdpa_dma_map(v, iova, int128_get64(llsize),
@@ -263,6 +278,20 @@ static void vhost_vdpa_listener_region_del(MemoryListener *listener,
llsize = int128_sub(llend, int128_make64(iova));
+ if (v->shadow_vqs_enabled) {
+ const DMAMap *result;
+ const void *vaddr = memory_region_get_ram_ptr(section->mr) +
+ section->offset_within_region +
+ (iova - section->offset_within_address_space);
+ DMAMap mem_region = {
+ .translated_addr = (hwaddr)(uintptr_t)vaddr,
+ .size = int128_get64(llsize) - 1,
+ };
+
+ result = vhost_iova_tree_find_iova(v->iova_tree, &mem_region);
+ iova = result->iova;
+ vhost_iova_tree_remove(v->iova_tree, &mem_region);
+ }
vhost_vdpa_iotlb_batch_begin_once(v);
ret = vhost_vdpa_dma_unmap(v, iova, int128_get64(llsize));
if (ret) {
@@ -372,7 +401,7 @@ static int vhost_vdpa_init_svq(struct vhost_dev *hdev, struct vhost_vdpa *v,
shadow_vqs = g_ptr_array_new_full(hdev->nvqs, vhost_svq_free);
for (unsigned n = 0; n < hdev->nvqs; ++n) {
- g_autoptr(VhostShadowVirtqueue) svq = vhost_svq_new();
+ g_autoptr(VhostShadowVirtqueue) svq = vhost_svq_new(v->iova_tree);
if (unlikely(!svq)) {
error_setg(errp, "Cannot create svq %u", n);
@@ -809,33 +838,70 @@ static int vhost_vdpa_svq_set_fds(struct vhost_dev *dev,
/**
* Unmap a SVQ area in the device
*/
-static bool vhost_vdpa_svq_unmap_ring(struct vhost_vdpa *v, hwaddr iova,
- hwaddr size)
+static bool vhost_vdpa_svq_unmap_ring(struct vhost_vdpa *v,
+ const DMAMap *needle)
{
+ const DMAMap *result = vhost_iova_tree_find_iova(v->iova_tree, needle);
+ hwaddr size;
int r;
- size = ROUND_UP(size, qemu_real_host_page_size);
- r = vhost_vdpa_dma_unmap(v, iova, size);
+ if (unlikely(!result)) {
+ error_report("Unable to find SVQ address to unmap");
+ return false;
+ }
+
+ size = ROUND_UP(result->size, qemu_real_host_page_size);
+ r = vhost_vdpa_dma_unmap(v, result->iova, size);
return r == 0;
}
static bool vhost_vdpa_svq_unmap_rings(struct vhost_dev *dev,
const VhostShadowVirtqueue *svq)
{
+ DMAMap needle = {};
struct vhost_vdpa *v = dev->opaque;
struct vhost_vring_addr svq_addr;
- size_t device_size = vhost_svq_device_area_size(svq);
- size_t driver_size = vhost_svq_driver_area_size(svq);
bool ok;
vhost_svq_get_vring_addr(svq, &svq_addr);
- ok = vhost_vdpa_svq_unmap_ring(v, svq_addr.desc_user_addr, driver_size);
+ needle.translated_addr = svq_addr.desc_user_addr;
+ ok = vhost_vdpa_svq_unmap_ring(v, &needle);
if (unlikely(!ok)) {
return false;
}
- return vhost_vdpa_svq_unmap_ring(v, svq_addr.used_user_addr, device_size);
+ needle.translated_addr = svq_addr.used_user_addr;
+ return vhost_vdpa_svq_unmap_ring(v, &needle);
+}
+
+/**
+ * Map the SVQ area in the device
+ *
+ * @v: Vhost-vdpa device
+ * @needle: The area to search iova
+ * @errorp: Error pointer
+ */
+static bool vhost_vdpa_svq_map_ring(struct vhost_vdpa *v, DMAMap *needle,
+ Error **errp)
+{
+ int r;
+
+ r = vhost_iova_tree_map_alloc(v->iova_tree, needle);
+ if (unlikely(r != IOVA_OK)) {
+ error_setg(errp, "Cannot allocate iova (%d)", r);
+ return false;
+ }
+
+ r = vhost_vdpa_dma_map(v, needle->iova, needle->size + 1,
+ (void *)(uintptr_t)needle->translated_addr,
+ needle->perm == IOMMU_RO);
+ if (unlikely(r != 0)) {
+ error_setg_errno(errp, -r, "Cannot map region to device");
+ vhost_iova_tree_remove(v->iova_tree, needle);
+ }
+
+ return r == 0;
}
/**
@@ -851,28 +917,44 @@ static bool vhost_vdpa_svq_map_rings(struct vhost_dev *dev,
struct vhost_vring_addr *addr,
Error **errp)
{
+ DMAMap device_region, driver_region;
+ struct vhost_vring_addr svq_addr;
struct vhost_vdpa *v = dev->opaque;
size_t device_size = vhost_svq_device_area_size(svq);
size_t driver_size = vhost_svq_driver_area_size(svq);
- int r;
+ size_t avail_offset;
+ bool ok;
ERRP_GUARD();
- vhost_svq_get_vring_addr(svq, addr);
+ vhost_svq_get_vring_addr(svq, &svq_addr);
- r = vhost_vdpa_dma_map(v, addr->desc_user_addr, driver_size,
- (void *)(uintptr_t)addr->desc_user_addr, true);
- if (unlikely(r != 0)) {
- error_setg_errno(errp, -r, "Cannot create vq driver region: ");
+ driver_region = (DMAMap) {
+ .translated_addr = svq_addr.desc_user_addr,
+ .size = driver_size - 1,
+ .perm = IOMMU_RO,
+ };
+ ok = vhost_vdpa_svq_map_ring(v, &driver_region, errp);
+ if (unlikely(!ok)) {
+ error_prepend(errp, "Cannot create vq driver region: ");
return false;
}
+ addr->desc_user_addr = driver_region.iova;
+ avail_offset = svq_addr.avail_user_addr - svq_addr.desc_user_addr;
+ addr->avail_user_addr = driver_region.iova + avail_offset;
- r = vhost_vdpa_dma_map(v, addr->used_user_addr, device_size,
- (void *)(intptr_t)addr->used_user_addr, false);
- if (unlikely(r != 0)) {
- error_setg_errno(errp, -r, "Cannot create vq device region: ");
+ device_region = (DMAMap) {
+ .translated_addr = svq_addr.used_user_addr,
+ .size = device_size - 1,
+ .perm = IOMMU_RW,
+ };
+ ok = vhost_vdpa_svq_map_ring(v, &device_region, errp);
+ if (unlikely(!ok)) {
+ error_prepend(errp, "Cannot create vq device region: ");
+ vhost_vdpa_svq_unmap_ring(v, &driver_region);
}
+ addr->used_user_addr = device_region.iova;
- return r == 0;
+ return ok;
}
static bool vhost_vdpa_svq_setup(struct vhost_dev *dev,
diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h
index 009a9f3b6b..ee8e939ad0 100644
--- a/include/hw/virtio/vhost-vdpa.h
+++ b/include/hw/virtio/vhost-vdpa.h
@@ -14,6 +14,7 @@
#include <gmodule.h>
+#include "hw/virtio/vhost-iova-tree.h"
#include "hw/virtio/virtio.h"
#include "standard-headers/linux/vhost_types.h"
@@ -30,6 +31,8 @@ typedef struct vhost_vdpa {
MemoryListener listener;
struct vhost_vdpa_iova_range iova_range;
bool shadow_vqs_enabled;
+ /* IOVA mapping used by the Shadow Virtqueue */
+ VhostIOVATree *iova_tree;
GPtrArray *shadow_vqs;
struct vhost_dev *dev;
VhostVDPAHostNotifier notifier[VIRTIO_QUEUE_MAX];
--
2.27.0

View File

@ -0,0 +1,87 @@
From 3f0eafe9e86bac9cf99176bf65a22d2dab154617 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Wed, 20 Jul 2022 08:59:45 +0200
Subject: [PATCH] vdpa: Add device migration blocker
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Since the vhost-vdpa device is exposing _F_LOG, adding a migration blocker if
it uses CVQ.
However, qemu is able to migrate simple devices with no CVQ as long as
they use SVQ. To allow it, add a placeholder error to vhost_vdpa, and
only add to vhost_dev when used. vhost_dev machinery place the migration
blocker if needed.
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
hw/virtio/vhost-vdpa.c | 15 +++++++++++++++
include/hw/virtio/vhost-vdpa.h | 1 +
2 files changed, 16 insertions(+)
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index 31b58aec59..5956ff4660 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -20,6 +20,7 @@
#include "hw/virtio/vhost-shadow-virtqueue.h"
#include "hw/virtio/vhost-vdpa.h"
#include "exec/address-spaces.h"
+#include "migration/blocker.h"
#include "qemu/main-loop.h"
#include "cpu.h"
#include "trace.h"
@@ -1024,6 +1025,13 @@ static bool vhost_vdpa_svqs_start(struct vhost_dev *dev)
return true;
}
+ if (v->migration_blocker) {
+ int r = migrate_add_blocker(v->migration_blocker, &err);
+ if (unlikely(r < 0)) {
+ return false;
+ }
+ }
+
for (i = 0; i < v->shadow_vqs->len; ++i) {
VirtQueue *vq = virtio_get_queue(dev->vdev, dev->vq_index + i);
VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, i);
@@ -1066,6 +1074,10 @@ err:
vhost_svq_stop(svq);
}
+ if (v->migration_blocker) {
+ migrate_del_blocker(v->migration_blocker);
+ }
+
return false;
}
@@ -1085,6 +1097,9 @@ static bool vhost_vdpa_svqs_stop(struct vhost_dev *dev)
}
}
+ if (v->migration_blocker) {
+ migrate_del_blocker(v->migration_blocker);
+ }
return true;
}
diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h
index 1111d85643..d10a89303e 100644
--- a/include/hw/virtio/vhost-vdpa.h
+++ b/include/hw/virtio/vhost-vdpa.h
@@ -35,6 +35,7 @@ typedef struct vhost_vdpa {
bool shadow_vqs_enabled;
/* IOVA mapping used by the Shadow Virtqueue */
VhostIOVATree *iova_tree;
+ Error *migration_blocker;
GPtrArray *shadow_vqs;
const VhostShadowVirtqueueOps *shadow_vq_ops;
void *shadow_vq_ops_opaque;
--
2.27.0

View File

@ -0,0 +1,58 @@
From d3aa8e2f948c0b3cd2cd723364fe968fd6befca9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Tue, 5 Apr 2022 08:36:28 +0200
Subject: [PATCH] vdpa: Add missing tracing to batch mapping functions
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
These functions were not traced properly.
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Message-Id: <20220405063628.853745-1-eperezma@redhat.com>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
hw/virtio/trace-events | 2 ++
hw/virtio/vhost-vdpa.c | 2 ++
2 files changed, 4 insertions(+)
diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
index 650e521e35..37c1555330 100644
--- a/hw/virtio/trace-events
+++ b/hw/virtio/trace-events
@@ -25,6 +25,8 @@ vhost_user_postcopy_waker_nomatch(const char *rb, uint64_t rb_offset) "%s + 0x%"
# vhost-vdpa.c
vhost_vdpa_dma_map(void *vdpa, int fd, uint32_t msg_type, uint64_t iova, uint64_t size, uint64_t uaddr, uint8_t perm, uint8_t type) "vdpa:%p fd: %d msg_type: %"PRIu32" iova: 0x%"PRIx64" size: 0x%"PRIx64" uaddr: 0x%"PRIx64" perm: 0x%"PRIx8" type: %"PRIu8
vhost_vdpa_dma_unmap(void *vdpa, int fd, uint32_t msg_type, uint64_t iova, uint64_t size, uint8_t type) "vdpa:%p fd: %d msg_type: %"PRIu32" iova: 0x%"PRIx64" size: 0x%"PRIx64" type: %"PRIu8
+vhost_vdpa_listener_begin_batch(void *v, int fd, uint32_t msg_type, uint8_t type) "vdpa:%p fd: %d msg_type: %"PRIu32" type: %"PRIu8
+vhost_vdpa_listener_commit(void *v, int fd, uint32_t msg_type, uint8_t type) "vdpa:%p fd: %d msg_type: %"PRIu32" type: %"PRIu8
vhost_vdpa_listener_region_add(void *vdpa, uint64_t iova, uint64_t llend, void *vaddr, bool readonly) "vdpa: %p iova 0x%"PRIx64" llend 0x%"PRIx64" vaddr: %p read-only: %d"
vhost_vdpa_listener_region_del(void *vdpa, uint64_t iova, uint64_t llend) "vdpa: %p iova 0x%"PRIx64" llend 0x%"PRIx64
vhost_vdpa_add_status(void *dev, uint8_t status) "dev: %p status: 0x%"PRIx8
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index b66697da6e..022d70aefb 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -131,6 +131,7 @@ static void vhost_vdpa_listener_begin_batch(struct vhost_vdpa *v)
.iotlb.type = VHOST_IOTLB_BATCH_BEGIN,
};
+ trace_vhost_vdpa_listener_begin_batch(v, fd, msg.type, msg.iotlb.type);
if (write(fd, &msg, sizeof(msg)) != sizeof(msg)) {
error_report("failed to write, fd=%d, errno=%d (%s)",
fd, errno, strerror(errno));
@@ -165,6 +166,7 @@ static void vhost_vdpa_listener_commit(MemoryListener *listener)
msg.type = v->msg_type;
msg.iotlb.type = VHOST_IOTLB_BATCH_END;
+ trace_vhost_vdpa_listener_commit(v, fd, msg.type, msg.iotlb.type);
if (write(fd, &msg, sizeof(msg)) != sizeof(msg)) {
error_report("failed to write, fd=%d, errno=%d (%s)",
fd, errno, strerror(errno));
--
2.27.0

View File

@ -0,0 +1,65 @@
From 6dc398327ebe7fcfe78b3df4fe9c1386bafef552 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Tue, 6 Sep 2022 17:07:16 +0200
Subject: [PATCH] vdpa: Add vhost_vdpa_net_load_mq
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Same way as with the MAC, restore the expected number of queues at
device's start.
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
net/vhost-vdpa.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index 15cd38b52e..b32fe5e68a 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -408,6 +408,28 @@ static int vhost_vdpa_net_load_mac(VhostVDPAState *s, const VirtIONet *n)
return 0;
}
+static int vhost_vdpa_net_load_mq(VhostVDPAState *s,
+ const VirtIONet *n)
+{
+ struct virtio_net_ctrl_mq mq;
+ uint64_t features = n->parent_obj.guest_features;
+ ssize_t dev_written;
+
+ if (!(features & BIT_ULL(VIRTIO_NET_F_MQ))) {
+ return 0;
+ }
+
+ mq.virtqueue_pairs = cpu_to_le16(n->curr_queue_pairs);
+ dev_written = vhost_vdpa_net_load_cmd(s, VIRTIO_NET_CTRL_MQ,
+ VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET, &mq,
+ sizeof(mq));
+ if (unlikely(dev_written < 0)) {
+ return dev_written;
+ }
+
+ return *s->status != VIRTIO_NET_OK;
+}
+
static int vhost_vdpa_net_load(NetClientState *nc)
{
VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
@@ -426,6 +448,10 @@ static int vhost_vdpa_net_load(NetClientState *nc)
if (unlikely(r < 0)) {
return r;
}
+ r = vhost_vdpa_net_load_mq(s, n);
+ if (unlikely(r)) {
+ return r;
+ }
return 0;
}
--
2.27.0

View File

@ -0,0 +1,78 @@
From 8df992cbd90fb742e14ea1a90211cf535f20fbaa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Tue, 23 Aug 2022 20:30:36 +0200
Subject: [PATCH] vdpa: Add virtio-net mac address via CVQ at start
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This is needed so the destination vdpa device see the same state a the
guest set in the source.
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
net/vhost-vdpa.c | 40 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index b24e0919d0..561e43fa92 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -371,11 +371,51 @@ static ssize_t vhost_vdpa_net_cvq_add(VhostVDPAState *s, size_t out_len,
return vhost_svq_poll(svq);
}
+static int vhost_vdpa_net_load(NetClientState *nc)
+{
+ VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
+ const struct vhost_vdpa *v = &s->vhost_vdpa;
+ const VirtIONet *n;
+ uint64_t features;
+
+ assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);
+
+ if (!v->shadow_vqs_enabled) {
+ return 0;
+ }
+
+ n = VIRTIO_NET(v->dev->vdev);
+ features = n->parent_obj.guest_features;
+ if (features & BIT_ULL(VIRTIO_NET_F_CTRL_MAC_ADDR)) {
+ const struct virtio_net_ctrl_hdr ctrl = {
+ .class = VIRTIO_NET_CTRL_MAC,
+ .cmd = VIRTIO_NET_CTRL_MAC_ADDR_SET,
+ };
+ char *cursor = s->cvq_cmd_out_buffer;
+ ssize_t dev_written;
+
+ memcpy(cursor, &ctrl, sizeof(ctrl));
+ cursor += sizeof(ctrl);
+ memcpy(cursor, n->mac, sizeof(n->mac));
+
+ dev_written = vhost_vdpa_net_cvq_add(s, sizeof(ctrl) + sizeof(n->mac),
+ sizeof(virtio_net_ctrl_ack));
+ if (unlikely(dev_written < 0)) {
+ return dev_written;
+ }
+
+ return *((virtio_net_ctrl_ack *)s->cvq_cmd_in_buffer) != VIRTIO_NET_OK;
+ }
+
+ return 0;
+}
+
static NetClientInfo net_vhost_vdpa_cvq_info = {
.type = NET_CLIENT_DRIVER_VHOST_VDPA,
.size = sizeof(VhostVDPAState),
.receive = vhost_vdpa_receive,
.start = vhost_vdpa_net_cvq_start,
+ .load = vhost_vdpa_net_load,
.stop = vhost_vdpa_net_cvq_stop,
.cleanup = vhost_vdpa_cleanup,
.has_vnet_hdr = vhost_vdpa_has_vnet_hdr,
--
2.27.0

View File

@ -0,0 +1,208 @@
From 3f278509424df64a731f69f4599460eda9a8d133 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Wed, 20 Jul 2022 08:59:46 +0200
Subject: [PATCH] vdpa: Add x-svq to NetdevVhostVDPAOptions
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Finally offering the possibility to enable SVQ from the command line.
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Acked-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
net/vhost-vdpa.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++--
qapi/net.json | 9 +++++-
2 files changed, 77 insertions(+), 4 deletions(-)
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index 6a0fcab443..460f9674d7 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -74,6 +74,28 @@ const int vdpa_feature_bits[] = {
VHOST_INVALID_FEATURE_BIT
};
+/** Supported device specific feature bits with SVQ */
+static const uint64_t vdpa_svq_device_features =
+ BIT_ULL(VIRTIO_NET_F_CSUM) |
+ BIT_ULL(VIRTIO_NET_F_GUEST_CSUM) |
+ BIT_ULL(VIRTIO_NET_F_MTU) |
+ BIT_ULL(VIRTIO_NET_F_MAC) |
+ BIT_ULL(VIRTIO_NET_F_GUEST_TSO4) |
+ BIT_ULL(VIRTIO_NET_F_GUEST_TSO6) |
+ BIT_ULL(VIRTIO_NET_F_GUEST_ECN) |
+ BIT_ULL(VIRTIO_NET_F_GUEST_UFO) |
+ BIT_ULL(VIRTIO_NET_F_HOST_TSO4) |
+ BIT_ULL(VIRTIO_NET_F_HOST_TSO6) |
+ BIT_ULL(VIRTIO_NET_F_HOST_ECN) |
+ BIT_ULL(VIRTIO_NET_F_HOST_UFO) |
+ BIT_ULL(VIRTIO_NET_F_MRG_RXBUF) |
+ BIT_ULL(VIRTIO_NET_F_STATUS) |
+ BIT_ULL(VIRTIO_NET_F_CTRL_VQ) |
+ BIT_ULL(VIRTIO_F_ANY_LAYOUT) |
+ BIT_ULL(VIRTIO_NET_F_CTRL_MAC_ADDR) |
+ BIT_ULL(VIRTIO_NET_F_RSC_EXT) |
+ BIT_ULL(VIRTIO_NET_F_STANDBY);
+
VHostNetState *vhost_vdpa_get_vhost_net(NetClientState *nc)
{
VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
@@ -132,6 +154,7 @@ err_init:
static void vhost_vdpa_cleanup(NetClientState *nc)
{
VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
+ struct vhost_dev *dev = &s->vhost_net->dev;
/*
* If a peer NIC is attached, do not cleanup anything.
@@ -144,6 +167,9 @@ static void vhost_vdpa_cleanup(NetClientState *nc)
qemu_vfree(s->cvq_cmd_out_buffer);
qemu_vfree(s->cvq_cmd_in_buffer);
+ if (dev->vq_index + dev->nvqs == dev->vq_index_end) {
+ g_clear_pointer(&s->vhost_vdpa.iova_tree, vhost_iova_tree_delete);
+ }
if (s->vhost_net) {
vhost_net_cleanup(s->vhost_net);
g_free(s->vhost_net);
@@ -445,7 +471,9 @@ static NetClientState *net_vhost_vdpa_init(NetClientState *peer,
int vdpa_device_fd,
int queue_pair_index,
int nvqs,
- bool is_datapath)
+ bool is_datapath,
+ bool svq,
+ VhostIOVATree *iova_tree)
{
NetClientState *nc = NULL;
VhostVDPAState *s;
@@ -463,6 +491,8 @@ static NetClientState *net_vhost_vdpa_init(NetClientState *peer,
s->vhost_vdpa.device_fd = vdpa_device_fd;
s->vhost_vdpa.index = queue_pair_index;
+ s->vhost_vdpa.shadow_vqs_enabled = svq;
+ s->vhost_vdpa.iova_tree = iova_tree;
if (!is_datapath) {
s->cvq_cmd_out_buffer = qemu_memalign(qemu_real_host_page_size,
vhost_vdpa_net_cvq_cmd_page_len());
@@ -473,6 +503,8 @@ static NetClientState *net_vhost_vdpa_init(NetClientState *peer,
s->vhost_vdpa.shadow_vq_ops = &vhost_vdpa_net_svq_ops;
s->vhost_vdpa.shadow_vq_ops_opaque = s;
+ error_setg(&s->vhost_vdpa.migration_blocker,
+ "Migration disabled: vhost-vdpa uses CVQ.");
}
ret = vhost_vdpa_add(nc, (void *)&s->vhost_vdpa, queue_pair_index, nvqs);
if (ret) {
@@ -482,6 +514,14 @@ static NetClientState *net_vhost_vdpa_init(NetClientState *peer,
return nc;
}
+static int vhost_vdpa_get_iova_range(int fd,
+ struct vhost_vdpa_iova_range *iova_range)
+{
+ int ret = ioctl(fd, VHOST_VDPA_GET_IOVA_RANGE, iova_range);
+
+ return ret < 0 ? -errno : 0;
+}
+
static int vhost_vdpa_get_features(int fd, uint64_t *features, Error **errp)
{
int ret = ioctl(fd, VHOST_GET_FEATURES, features);
@@ -532,6 +572,7 @@ int net_init_vhost_vdpa(const Netdev *netdev, const char *name,
uint64_t features;
int vdpa_device_fd;
g_autofree NetClientState **ncs = NULL;
+ g_autoptr(VhostIOVATree) iova_tree = NULL;
NetClientState *nc;
int queue_pairs, r, i, has_cvq = 0;
@@ -559,22 +600,45 @@ int net_init_vhost_vdpa(const Netdev *netdev, const char *name,
return queue_pairs;
}
+ if (opts->x_svq) {
+ struct vhost_vdpa_iova_range iova_range;
+
+ uint64_t invalid_dev_features =
+ features & ~vdpa_svq_device_features &
+ /* Transport are all accepted at this point */
+ ~MAKE_64BIT_MASK(VIRTIO_TRANSPORT_F_START,
+ VIRTIO_TRANSPORT_F_END - VIRTIO_TRANSPORT_F_START);
+
+ if (invalid_dev_features) {
+ error_setg(errp, "vdpa svq does not work with features 0x%" PRIx64,
+ invalid_dev_features);
+ goto err_svq;
+ }
+
+ vhost_vdpa_get_iova_range(vdpa_device_fd, &iova_range);
+ iova_tree = vhost_iova_tree_new(iova_range.first, iova_range.last);
+ }
+
ncs = g_malloc0(sizeof(*ncs) * queue_pairs);
for (i = 0; i < queue_pairs; i++) {
ncs[i] = net_vhost_vdpa_init(peer, TYPE_VHOST_VDPA, name,
- vdpa_device_fd, i, 2, true);
+ vdpa_device_fd, i, 2, true, opts->x_svq,
+ iova_tree);
if (!ncs[i])
goto err;
}
if (has_cvq) {
nc = net_vhost_vdpa_init(peer, TYPE_VHOST_VDPA, name,
- vdpa_device_fd, i, 1, false);
+ vdpa_device_fd, i, 1, false,
+ opts->x_svq, iova_tree);
if (!nc)
goto err;
}
+ /* iova_tree ownership belongs to last NetClientState */
+ g_steal_pointer(&iova_tree);
return 0;
err:
@@ -583,6 +647,8 @@ err:
qemu_del_net_client(ncs[i]);
}
}
+
+err_svq:
qemu_close(vdpa_device_fd);
return -1;
diff --git a/qapi/net.json b/qapi/net.json
index 7fab2e7cd8..6a5460ce56 100644
--- a/qapi/net.json
+++ b/qapi/net.json
@@ -445,12 +445,19 @@
# @queues: number of queues to be created for multiqueue vhost-vdpa
# (default: 1)
#
+# @x-svq: Start device with (experimental) shadow virtqueue. (Since 7.1)
+# (default: false)
+#
+# Features:
+# @unstable: Member @x-svq is experimental.
+#
# Since: 5.1
##
{ 'struct': 'NetdevVhostVDPAOptions',
'data': {
'*vhostdev': 'str',
- '*queues': 'int' } }
+ '*queues': 'int',
+ '*x-svq': {'type': 'bool', 'features' : [ 'unstable'] } } }
##
# @NetClientDriver:
--
2.27.0

View File

@ -0,0 +1,32 @@
From 275135fcfb7e7c22ec84a79297ffc9c96fb82639 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Tue, 6 Sep 2022 17:07:19 +0200
Subject: [PATCH] vdpa: Allow MQ feature in SVQ
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Finally enable SVQ with MQ feature.
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
net/vhost-vdpa.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index 831709a270..479abf97a7 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -93,6 +93,7 @@ static const uint64_t vdpa_svq_device_features =
BIT_ULL(VIRTIO_NET_F_MRG_RXBUF) |
BIT_ULL(VIRTIO_NET_F_STATUS) |
BIT_ULL(VIRTIO_NET_F_CTRL_VQ) |
+ BIT_ULL(VIRTIO_NET_F_MQ) |
BIT_ULL(VIRTIO_F_ANY_LAYOUT) |
BIT_ULL(VIRTIO_NET_F_CTRL_MAC_ADDR) |
BIT_ULL(VIRTIO_NET_F_RSC_EXT) |
--
2.27.0

View File

@ -0,0 +1,46 @@
From 853f14a29c9a31ca132647770f7d6886103b2b77 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Wed, 20 Jul 2022 08:59:29 +0200
Subject: [PATCH] vdpa: Avoid compiler to squash reads to used idx
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
In the next patch we will allow busypolling of this value. The compiler
have a running path where shadow_used_idx, last_used_idx, and vring used
idx are not modified within the same thread busypolling.
This was not an issue before since we always cleared device event
notifier before checking it, and that could act as memory barrier.
However, the busypoll needs something similar to kernel READ_ONCE.
Let's add it here, sepparated from the polling.
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
hw/virtio/vhost-shadow-virtqueue.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c
index da1e1ce3c7..acf50a9a0b 100644
--- a/hw/virtio/vhost-shadow-virtqueue.c
+++ b/hw/virtio/vhost-shadow-virtqueue.c
@@ -326,11 +326,12 @@ static void vhost_handle_guest_kick_notifier(EventNotifier *n)
static bool vhost_svq_more_used(VhostShadowVirtqueue *svq)
{
+ uint16_t *used_idx = &svq->vring.used->idx;
if (svq->last_used_idx != svq->shadow_used_idx) {
return true;
}
- svq->shadow_used_idx = cpu_to_le16(svq->vring.used->idx);
+ svq->shadow_used_idx = cpu_to_le16(*(volatile uint16_t *)used_idx);
return svq->last_used_idx != svq->shadow_used_idx;
}
--
2.27.0

View File

@ -0,0 +1,305 @@
From 31bf37b3097c1ece48b915137167bbd4bd7340aa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Wed, 20 Jul 2022 08:59:43 +0200
Subject: [PATCH] vdpa: Buffer CVQ support on shadow virtqueue
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Introduce the control virtqueue support for vDPA shadow virtqueue. This
is needed for advanced networking features like rx filtering.
Virtio-net control VQ copies the descriptors to qemu's VA, so we avoid
TOCTOU with the guest's or device's memory every time there is a device
model change. Otherwise, the guest could change the memory content in
the time between qemu and the device read it.
To demonstrate command handling, VIRTIO_NET_F_CTRL_MACADDR is
implemented. If the virtio-net driver changes MAC the virtio-net device
model will be updated with the new one, and a rx filtering change event
will be raised.
More cvq commands could be added here straightforwardly but they have
not been tested.
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
net/vhost-vdpa.c | 214 +++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 206 insertions(+), 8 deletions(-)
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index 53a14bc756..2d928feefb 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -32,6 +32,9 @@ typedef struct VhostVDPAState {
NetClientState nc;
struct vhost_vdpa vhost_vdpa;
VHostNetState *vhost_net;
+
+ /* Control commands shadow buffers */
+ void *cvq_cmd_out_buffer, *cvq_cmd_in_buffer;
bool started;
} VhostVDPAState;
@@ -138,6 +141,9 @@ static void vhost_vdpa_cleanup(NetClientState *nc)
if (nc->peer && nc->peer->info->type == NET_CLIENT_DRIVER_NIC) {
return;
}
+
+ qemu_vfree(s->cvq_cmd_out_buffer);
+ qemu_vfree(s->cvq_cmd_in_buffer);
if (s->vhost_net) {
vhost_net_cleanup(s->vhost_net);
g_free(s->vhost_net);
@@ -197,24 +203,191 @@ static NetClientInfo net_vhost_vdpa_info = {
.check_peer_type = vhost_vdpa_check_peer_type,
};
+static void vhost_vdpa_cvq_unmap_buf(struct vhost_vdpa *v, void *addr)
+{
+ VhostIOVATree *tree = v->iova_tree;
+ DMAMap needle = {
+ /*
+ * No need to specify size or to look for more translations since
+ * this contiguous chunk was allocated by us.
+ */
+ .translated_addr = (hwaddr)(uintptr_t)addr,
+ };
+ const DMAMap *map = vhost_iova_tree_find_iova(tree, &needle);
+ int r;
+
+ if (unlikely(!map)) {
+ error_report("Cannot locate expected map");
+ return;
+ }
+
+ r = vhost_vdpa_dma_unmap(v, map->iova, map->size + 1);
+ if (unlikely(r != 0)) {
+ error_report("Device cannot unmap: %s(%d)", g_strerror(r), r);
+ }
+
+ vhost_iova_tree_remove(tree, map);
+}
+
+static size_t vhost_vdpa_net_cvq_cmd_len(void)
+{
+ /*
+ * MAC_TABLE_SET is the ctrl command that produces the longer out buffer.
+ * In buffer is always 1 byte, so it should fit here
+ */
+ return sizeof(struct virtio_net_ctrl_hdr) +
+ 2 * sizeof(struct virtio_net_ctrl_mac) +
+ MAC_TABLE_ENTRIES * ETH_ALEN;
+}
+
+static size_t vhost_vdpa_net_cvq_cmd_page_len(void)
+{
+ return ROUND_UP(vhost_vdpa_net_cvq_cmd_len(), qemu_real_host_page_size);
+}
+
+/** Copy and map a guest buffer. */
+static bool vhost_vdpa_cvq_map_buf(struct vhost_vdpa *v,
+ const struct iovec *out_data,
+ size_t out_num, size_t data_len, void *buf,
+ size_t *written, bool write)
+{
+ DMAMap map = {};
+ int r;
+
+ if (unlikely(!data_len)) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid legnth of %s buffer\n",
+ __func__, write ? "in" : "out");
+ return false;
+ }
+
+ *written = iov_to_buf(out_data, out_num, 0, buf, data_len);
+ map.translated_addr = (hwaddr)(uintptr_t)buf;
+ map.size = vhost_vdpa_net_cvq_cmd_page_len() - 1;
+ map.perm = write ? IOMMU_RW : IOMMU_RO,
+ r = vhost_iova_tree_map_alloc(v->iova_tree, &map);
+ if (unlikely(r != IOVA_OK)) {
+ error_report("Cannot map injected element");
+ return false;
+ }
+
+ r = vhost_vdpa_dma_map(v, map.iova, vhost_vdpa_net_cvq_cmd_page_len(), buf,
+ !write);
+ if (unlikely(r < 0)) {
+ goto dma_map_err;
+ }
+
+ return true;
+
+dma_map_err:
+ vhost_iova_tree_remove(v->iova_tree, &map);
+ return false;
+}
+
/**
- * Forward buffer for the moment.
+ * Copy the guest element into a dedicated buffer suitable to be sent to NIC
+ *
+ * @iov: [0] is the out buffer, [1] is the in one
+ */
+static bool vhost_vdpa_net_cvq_map_elem(VhostVDPAState *s,
+ VirtQueueElement *elem,
+ struct iovec *iov)
+{
+ size_t in_copied;
+ bool ok;
+
+ iov[0].iov_base = s->cvq_cmd_out_buffer;
+ ok = vhost_vdpa_cvq_map_buf(&s->vhost_vdpa, elem->out_sg, elem->out_num,
+ vhost_vdpa_net_cvq_cmd_len(), iov[0].iov_base,
+ &iov[0].iov_len, false);
+ if (unlikely(!ok)) {
+ return false;
+ }
+
+ iov[1].iov_base = s->cvq_cmd_in_buffer;
+ ok = vhost_vdpa_cvq_map_buf(&s->vhost_vdpa, NULL, 0,
+ sizeof(virtio_net_ctrl_ack), iov[1].iov_base,
+ &in_copied, true);
+ if (unlikely(!ok)) {
+ vhost_vdpa_cvq_unmap_buf(&s->vhost_vdpa, s->cvq_cmd_out_buffer);
+ return false;
+ }
+
+ iov[1].iov_len = sizeof(virtio_net_ctrl_ack);
+ return true;
+}
+
+/**
+ * Do not forward commands not supported by SVQ. Otherwise, the device could
+ * accept it and qemu would not know how to update the device model.
+ */
+static bool vhost_vdpa_net_cvq_validate_cmd(const struct iovec *out,
+ size_t out_num)
+{
+ struct virtio_net_ctrl_hdr ctrl;
+ size_t n;
+
+ n = iov_to_buf(out, out_num, 0, &ctrl, sizeof(ctrl));
+ if (unlikely(n < sizeof(ctrl))) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: invalid legnth of out buffer %zu\n", __func__, n);
+ return false;
+ }
+
+ switch (ctrl.class) {
+ case VIRTIO_NET_CTRL_MAC:
+ switch (ctrl.cmd) {
+ case VIRTIO_NET_CTRL_MAC_ADDR_SET:
+ return true;
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid mac cmd %u\n",
+ __func__, ctrl.cmd);
+ };
+ break;
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid control class %u\n",
+ __func__, ctrl.class);
+ };
+
+ return false;
+}
+
+/**
+ * Validate and copy control virtqueue commands.
+ *
+ * Following QEMU guidelines, we offer a copy of the buffers to the device to
+ * prevent TOCTOU bugs.
*/
static int vhost_vdpa_net_handle_ctrl_avail(VhostShadowVirtqueue *svq,
VirtQueueElement *elem,
void *opaque)
{
- unsigned int n = elem->out_num + elem->in_num;
- g_autofree struct iovec *dev_buffers = g_new(struct iovec, n);
+ VhostVDPAState *s = opaque;
size_t in_len, dev_written;
virtio_net_ctrl_ack status = VIRTIO_NET_ERR;
- int r;
+ /* out and in buffers sent to the device */
+ struct iovec dev_buffers[2] = {
+ { .iov_base = s->cvq_cmd_out_buffer },
+ { .iov_base = s->cvq_cmd_in_buffer },
+ };
+ /* in buffer used for device model */
+ const struct iovec in = {
+ .iov_base = &status,
+ .iov_len = sizeof(status),
+ };
+ int r = -EINVAL;
+ bool ok;
+
+ ok = vhost_vdpa_net_cvq_map_elem(s, elem, dev_buffers);
+ if (unlikely(!ok)) {
+ goto out;
+ }
- memcpy(dev_buffers, elem->out_sg, elem->out_num);
- memcpy(dev_buffers + elem->out_num, elem->in_sg, elem->in_num);
+ ok = vhost_vdpa_net_cvq_validate_cmd(&dev_buffers[0], 1);
+ if (unlikely(!ok)) {
+ goto out;
+ }
- r = vhost_svq_add(svq, &dev_buffers[0], elem->out_num, &dev_buffers[1],
- elem->in_num, elem);
+ r = vhost_svq_add(svq, &dev_buffers[0], 1, &dev_buffers[1], 1, elem);
if (unlikely(r != 0)) {
if (unlikely(r == -ENOSPC)) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: No space on device queue\n",
@@ -231,6 +404,18 @@ static int vhost_vdpa_net_handle_ctrl_avail(VhostShadowVirtqueue *svq,
dev_written = vhost_svq_poll(svq);
if (unlikely(dev_written < sizeof(status))) {
error_report("Insufficient written data (%zu)", dev_written);
+ goto out;
+ }
+
+ memcpy(&status, dev_buffers[1].iov_base, sizeof(status));
+ if (status != VIRTIO_NET_OK) {
+ goto out;
+ }
+
+ status = VIRTIO_NET_ERR;
+ virtio_net_handle_ctrl_iov(svq->vdev, &in, 1, dev_buffers, 1);
+ if (status != VIRTIO_NET_OK) {
+ error_report("Bad CVQ processing in model");
}
out:
@@ -241,6 +426,12 @@ out:
}
vhost_svq_push_elem(svq, elem, MIN(in_len, sizeof(status)));
g_free(elem);
+ if (dev_buffers[0].iov_base) {
+ vhost_vdpa_cvq_unmap_buf(&s->vhost_vdpa, dev_buffers[0].iov_base);
+ }
+ if (dev_buffers[1].iov_base) {
+ vhost_vdpa_cvq_unmap_buf(&s->vhost_vdpa, dev_buffers[1].iov_base);
+ }
return r;
}
@@ -273,6 +464,13 @@ static NetClientState *net_vhost_vdpa_init(NetClientState *peer,
s->vhost_vdpa.device_fd = vdpa_device_fd;
s->vhost_vdpa.index = queue_pair_index;
if (!is_datapath) {
+ s->cvq_cmd_out_buffer = qemu_memalign(qemu_real_host_page_size,
+ vhost_vdpa_net_cvq_cmd_page_len());
+ memset(s->cvq_cmd_out_buffer, 0, vhost_vdpa_net_cvq_cmd_page_len());
+ s->cvq_cmd_in_buffer = qemu_memalign(qemu_real_host_page_size,
+ vhost_vdpa_net_cvq_cmd_page_len());
+ memset(s->cvq_cmd_in_buffer, 0, vhost_vdpa_net_cvq_cmd_page_len());
+
s->vhost_vdpa.shadow_vq_ops = &vhost_vdpa_net_svq_ops;
s->vhost_vdpa.shadow_vq_ops_opaque = s;
}
--
2.27.0

View File

@ -0,0 +1,89 @@
From cdc1b97f133a2b79318cc10aa6d1a9b69abac78f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Tue, 23 Aug 2022 20:30:37 +0200
Subject: [PATCH] vdpa: Delete CVQ migration blocker
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
We can restore the device state in the destination via CVQ now. Remove
the migration blocker.
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
hw/virtio/vhost-vdpa.c | 15 ---------------
include/hw/virtio/vhost-vdpa.h | 1 -
net/vhost-vdpa.c | 2 --
3 files changed, 18 deletions(-)
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index d7bdc0f37c..0f07c85b91 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -1035,13 +1035,6 @@ static bool vhost_vdpa_svqs_start(struct vhost_dev *dev)
return true;
}
- if (v->migration_blocker) {
- int r = migrate_add_blocker(v->migration_blocker, &err);
- if (unlikely(r < 0)) {
- return false;
- }
- }
-
for (i = 0; i < v->shadow_vqs->len; ++i) {
VirtQueue *vq = virtio_get_queue(dev->vdev, dev->vq_index + i);
VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, i);
@@ -1084,10 +1077,6 @@ err:
vhost_svq_stop(svq);
}
- if (v->migration_blocker) {
- migrate_del_blocker(v->migration_blocker);
- }
-
return false;
}
@@ -1103,10 +1092,6 @@ static void vhost_vdpa_svqs_stop(struct vhost_dev *dev)
VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, i);
vhost_vdpa_svq_unmap_rings(dev, svq);
}
-
- if (v->migration_blocker) {
- migrate_del_blocker(v->migration_blocker);
- }
}
static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started)
diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h
index d10a89303e..1111d85643 100644
--- a/include/hw/virtio/vhost-vdpa.h
+++ b/include/hw/virtio/vhost-vdpa.h
@@ -35,7 +35,6 @@ typedef struct vhost_vdpa {
bool shadow_vqs_enabled;
/* IOVA mapping used by the Shadow Virtqueue */
VhostIOVATree *iova_tree;
- Error *migration_blocker;
GPtrArray *shadow_vqs;
const VhostShadowVirtqueueOps *shadow_vq_ops;
void *shadow_vq_ops_opaque;
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index 561e43fa92..b10a18aeb4 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -563,8 +563,6 @@ static NetClientState *net_vhost_vdpa_init(NetClientState *peer,
s->vhost_vdpa.shadow_vq_ops = &vhost_vdpa_net_svq_ops;
s->vhost_vdpa.shadow_vq_ops_opaque = s;
- error_setg(&s->vhost_vdpa.migration_blocker,
- "Migration disabled: vhost-vdpa uses CVQ.");
}
ret = vhost_vdpa_add(nc, (void *)&s->vhost_vdpa, queue_pair_index, nvqs);
if (ret) {
--
2.27.0

View File

@ -0,0 +1,34 @@
From e316083c41f99c424879622c6e79452a6878b32f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Thu, 20 Oct 2022 10:00:58 +0200
Subject: [PATCH] vdpa: Delete duplicated vdpa_feature_bits entry
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This entry was duplicated on referenced commit. Removing it.
Fixes: 402378407dbd ("vhost-vdpa: multiqueue support")
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
net/vhost-vdpa.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index 479abf97a7..f4f6b8587f 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -62,7 +62,6 @@ const int vdpa_feature_bits[] = {
VIRTIO_NET_F_CTRL_RX,
VIRTIO_NET_F_CTRL_RX_EXTRA,
VIRTIO_NET_F_CTRL_VLAN,
- VIRTIO_NET_F_GUEST_ANNOUNCE,
VIRTIO_NET_F_CTRL_MAC_ADDR,
VIRTIO_NET_F_RSS,
VIRTIO_NET_F_MQ,
--
2.27.0

View File

@ -0,0 +1,65 @@
From 4054b1e42fde8f22703d5fc9bc84a9179ee8f9f7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Wed, 20 Jul 2022 08:59:40 +0200
Subject: [PATCH] vdpa: Export vhost_vdpa_dma_map and unmap calls
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Shadow CVQ will copy buffers on qemu VA, so we avoid TOCTOU attacks from
the guest that could set a different state in qemu device model and vdpa
device.
To do so, it needs to be able to map these new buffers to the device.
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
hw/virtio/vhost-vdpa.c | 7 +++----
include/hw/virtio/vhost-vdpa.h | 4 ++++
2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index a8d42655f0..8e962f511d 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -73,8 +73,8 @@ static bool vhost_vdpa_listener_skipped_section(MemoryRegionSection *section,
return false;
}
-static int vhost_vdpa_dma_map(struct vhost_vdpa *v, hwaddr iova, hwaddr size,
- void *vaddr, bool readonly)
+int vhost_vdpa_dma_map(struct vhost_vdpa *v, hwaddr iova, hwaddr size,
+ void *vaddr, bool readonly)
{
struct vhost_msg_v2 msg = {};
int fd = v->device_fd;
@@ -99,8 +99,7 @@ static int vhost_vdpa_dma_map(struct vhost_vdpa *v, hwaddr iova, hwaddr size,
return ret;
}
-static int vhost_vdpa_dma_unmap(struct vhost_vdpa *v, hwaddr iova,
- hwaddr size)
+int vhost_vdpa_dma_unmap(struct vhost_vdpa *v, hwaddr iova, hwaddr size)
{
struct vhost_msg_v2 msg = {};
int fd = v->device_fd;
diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h
index a29dbb3f53..7214eb47dc 100644
--- a/include/hw/virtio/vhost-vdpa.h
+++ b/include/hw/virtio/vhost-vdpa.h
@@ -39,4 +39,8 @@ typedef struct vhost_vdpa {
VhostVDPAHostNotifier notifier[VIRTIO_QUEUE_MAX];
} VhostVDPA;
+int vhost_vdpa_dma_map(struct vhost_vdpa *v, hwaddr iova, hwaddr size,
+ void *vaddr, bool readonly);
+int vhost_vdpa_dma_unmap(struct vhost_vdpa *v, hwaddr iova, hwaddr size);
+
#endif
--
2.27.0

View File

@ -0,0 +1,120 @@
From a531a56bddf997f559f67fe9d3dc6d4258c82eb1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Mon, 14 Mar 2022 18:34:54 +0100
Subject: [PATCH] vdpa: Expose VHOST_F_LOG_ALL on SVQ
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
SVQ is able to log the dirty bits by itself, so let's use it to not
block migration.
Also, ignore set and clear of VHOST_F_LOG_ALL on set_features if SVQ is
enabled. Even if the device supports it, the reports would be nonsense
because SVQ memory is in the qemu region.
The log region is still allocated. Future changes might skip that, but
this series is already long enough.
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
hw/virtio/vhost-vdpa.c | 39 ++++++++++++++++++++++++++++++----
include/hw/virtio/vhost-vdpa.h | 1 +
2 files changed, 36 insertions(+), 4 deletions(-)
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index 840141321a..3b5456cc0e 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -375,6 +375,16 @@ static bool vhost_vdpa_one_time_request(struct vhost_dev *dev)
return v->index != 0;
}
+static int vhost_vdpa_get_dev_features(struct vhost_dev *dev,
+ uint64_t *features)
+{
+ int ret;
+
+ ret = vhost_vdpa_call(dev, VHOST_GET_FEATURES, features);
+ trace_vhost_vdpa_get_features(dev, *features);
+ return ret;
+}
+
static int vhost_vdpa_init_svq(struct vhost_dev *hdev, struct vhost_vdpa *v,
Error **errp)
{
@@ -387,7 +397,7 @@ static int vhost_vdpa_init_svq(struct vhost_dev *hdev, struct vhost_vdpa *v,
return 0;
}
- r = hdev->vhost_ops->vhost_get_features(hdev, &dev_features);
+ r = vhost_vdpa_get_dev_features(hdev, &dev_features);
if (r != 0) {
error_setg_errno(errp, -r, "Can't get vdpa device features");
return r;
@@ -612,12 +622,29 @@ static int vhost_vdpa_set_mem_table(struct vhost_dev *dev,
static int vhost_vdpa_set_features(struct vhost_dev *dev,
uint64_t features)
{
+ struct vhost_vdpa *v = dev->opaque;
int ret;
if (vhost_vdpa_one_time_request(dev)) {
return 0;
}
+ if (v->shadow_vqs_enabled) {
+ if ((v->acked_features ^ features) == BIT_ULL(VHOST_F_LOG_ALL)) {
+ /*
+ * QEMU is just trying to enable or disable logging. SVQ handles
+ * this sepparately, so no need to forward this.
+ */
+ v->acked_features = features;
+ return 0;
+ }
+
+ v->acked_features = features;
+
+ /* We must not ack _F_LOG if SVQ is enabled */
+ features &= ~BIT_ULL(VHOST_F_LOG_ALL);
+ }
+
trace_vhost_vdpa_set_features(dev, features);
ret = vhost_vdpa_call(dev, VHOST_SET_FEATURES, &features);
if (ret) {
@@ -1202,10 +1229,14 @@ static int vhost_vdpa_set_vring_call(struct vhost_dev *dev,
static int vhost_vdpa_get_features(struct vhost_dev *dev,
uint64_t *features)
{
- int ret;
+ struct vhost_vdpa *v = dev->opaque;
+ int ret = vhost_vdpa_get_dev_features(dev, features);
+
+ if (ret == 0 && v->shadow_vqs_enabled) {
+ /* Add SVQ logging capabilities */
+ *features |= BIT_ULL(VHOST_F_LOG_ALL);
+ }
- ret = vhost_vdpa_call(dev, VHOST_GET_FEATURES, features);
- trace_vhost_vdpa_get_features(dev, *features);
return ret;
}
diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h
index ee8e939ad0..a29dbb3f53 100644
--- a/include/hw/virtio/vhost-vdpa.h
+++ b/include/hw/virtio/vhost-vdpa.h
@@ -30,6 +30,7 @@ typedef struct vhost_vdpa {
bool iotlb_batch_begin_sent;
MemoryListener listener;
struct vhost_vdpa_iova_range iova_range;
+ uint64_t acked_features;
bool shadow_vqs_enabled;
/* IOVA mapping used by the Shadow Virtqueue */
VhostIOVATree *iova_tree;
--
2.27.0

View File

@ -0,0 +1,89 @@
From 29048bdf8848d527b39a383c7f0c4f8c60870f71 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Wed, 20 Jul 2022 08:59:44 +0200
Subject: [PATCH] vdpa: Extract get features part from
vhost_vdpa_get_max_queue_pairs
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
To know the device features is needed for CVQ SVQ, so SVQ knows if it
can handle all commands or not. Extract from
vhost_vdpa_get_max_queue_pairs so we can reuse it.
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
net/vhost-vdpa.c | 30 ++++++++++++++++++++----------
1 file changed, 20 insertions(+), 10 deletions(-)
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index 2d928feefb..6a0fcab443 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -482,20 +482,24 @@ static NetClientState *net_vhost_vdpa_init(NetClientState *peer,
return nc;
}
-static int vhost_vdpa_get_max_queue_pairs(int fd, int *has_cvq, Error **errp)
+static int vhost_vdpa_get_features(int fd, uint64_t *features, Error **errp)
+{
+ int ret = ioctl(fd, VHOST_GET_FEATURES, features);
+ if (unlikely(ret < 0)) {
+ error_setg_errno(errp, errno,
+ "Fail to query features from vhost-vDPA device");
+ }
+ return ret;
+}
+
+static int vhost_vdpa_get_max_queue_pairs(int fd, uint64_t features,
+ int *has_cvq, Error **errp)
{
unsigned long config_size = offsetof(struct vhost_vdpa_config, buf);
g_autofree struct vhost_vdpa_config *config = NULL;
__virtio16 *max_queue_pairs;
- uint64_t features;
int ret;
- ret = ioctl(fd, VHOST_GET_FEATURES, &features);
- if (ret) {
- error_setg(errp, "Fail to query features from vhost-vDPA device");
- return ret;
- }
-
if (features & (1 << VIRTIO_NET_F_CTRL_VQ)) {
*has_cvq = 1;
} else {
@@ -525,10 +529,11 @@ int net_init_vhost_vdpa(const Netdev *netdev, const char *name,
NetClientState *peer, Error **errp)
{
const NetdevVhostVDPAOptions *opts;
+ uint64_t features;
int vdpa_device_fd;
g_autofree NetClientState **ncs = NULL;
NetClientState *nc;
- int queue_pairs, i, has_cvq = 0;
+ int queue_pairs, r, i, has_cvq = 0;
assert(netdev->type == NET_CLIENT_DRIVER_VHOST_VDPA);
opts = &netdev->u.vhost_vdpa;
@@ -542,7 +547,12 @@ int net_init_vhost_vdpa(const Netdev *netdev, const char *name,
return -errno;
}
- queue_pairs = vhost_vdpa_get_max_queue_pairs(vdpa_device_fd,
+ r = vhost_vdpa_get_features(vdpa_device_fd, &features, errp);
+ if (unlikely(r < 0)) {
+ return r;
+ }
+
+ queue_pairs = vhost_vdpa_get_max_queue_pairs(vdpa_device_fd, features,
&has_cvq, errp);
if (queue_pairs < 0) {
qemu_close(vdpa_device_fd);
--
2.27.0

View File

@ -0,0 +1,41 @@
From b37494d53478957b9e126e97f03d9501888a4d83 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Thu, 12 May 2022 19:57:44 +0200
Subject: [PATCH] vdpa: Fix bad index calculus at vhost_vdpa_get_vring_base
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Fixes: 6d0b222666 ("vdpa: Adapt vhost_vdpa_get_vring_base to SVQ")
Acked-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Message-Id: <20220512175747.142058-4-eperezma@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
hw/virtio/vhost-vdpa.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index 022d70aefb..3b67c9fd12 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -1174,11 +1174,11 @@ static int vhost_vdpa_get_vring_base(struct vhost_dev *dev,
struct vhost_vring_state *ring)
{
struct vhost_vdpa *v = dev->opaque;
+ int vdpa_idx = ring->index - dev->vq_index;
int ret;
if (v->shadow_vqs_enabled) {
- VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs,
- ring->index);
+ VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, vdpa_idx);
/*
* Setting base as last used idx, so destination will see as available
--
2.27.0

View File

@ -0,0 +1,50 @@
From 4077ce7f2d21dc67d18dc444165859b8496a185e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Tue, 2 Aug 2022 13:24:46 +0200
Subject: [PATCH] vdpa: Fix file descriptor leak on get features error
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
File descriptor vdpa_device_fd is not free in the case of returning
error from vhost_vdpa_get_features. Fixing it by making all errors go to
the same error path.
Resolves: Coverity CID 1490785
Fixes: 8170ab3f43 ("vdpa: Extract get features part from vhost_vdpa_get_max_queue_pairs")
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20220802112447.249436-2-eperezma@redhat.com>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
net/vhost-vdpa.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index 460f9674d7..0f75aa6080 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -574,7 +574,7 @@ int net_init_vhost_vdpa(const Netdev *netdev, const char *name,
g_autofree NetClientState **ncs = NULL;
g_autoptr(VhostIOVATree) iova_tree = NULL;
NetClientState *nc;
- int queue_pairs, r, i, has_cvq = 0;
+ int queue_pairs, r, i = 0, has_cvq = 0;
assert(netdev->type == NET_CLIENT_DRIVER_VHOST_VDPA);
opts = &netdev->u.vhost_vdpa;
@@ -590,7 +590,7 @@ int net_init_vhost_vdpa(const Netdev *netdev, const char *name,
r = vhost_vdpa_get_features(vdpa_device_fd, &features, errp);
if (unlikely(r < 0)) {
- return r;
+ goto err;
}
queue_pairs = vhost_vdpa_get_max_queue_pairs(vdpa_device_fd, features,
--
2.27.0

View File

@ -0,0 +1,37 @@
From 2f19a3fd1fbaca215906199ab7da7cd961b68d65 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Thu, 12 May 2022 19:57:45 +0200
Subject: [PATCH] vdpa: Fix index calculus at vhost_vdpa_svqs_start
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
With the introduction of MQ the index of the vq needs to be calculated
with the device model vq_index.
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Message-Id: <20220512175747.142058-5-eperezma@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
hw/virtio/vhost-vdpa.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index 3b67c9fd12..1360f2eaf7 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -1020,7 +1020,7 @@ static bool vhost_vdpa_svqs_start(struct vhost_dev *dev)
VirtQueue *vq = virtio_get_queue(dev->vdev, dev->vq_index + i);
VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, i);
struct vhost_vring_addr addr = {
- .index = i,
+ .index = dev->vq_index + i,
};
int r;
bool ok = vhost_vdpa_svq_setup(dev, svq, i, &err);
--
2.27.0

View File

@ -0,0 +1,53 @@
From de9a72905ad70e256a73608c92f50c3862b8eb8e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Fri, 22 Jul 2022 10:26:30 +0200
Subject: [PATCH] vdpa: Fix memory listener deletions of iova tree
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
vhost_vdpa_listener_region_del is always deleting the first iova entry
of the tree, since it's using the needle iova instead of the result's
one.
This was detected using a vga virtual device in the VM using vdpa SVQ.
It makes some extra memory adding and deleting, so the wrong one was
mapped / unmapped. This was undetected before since all the memory was
mappend and unmapped totally without that device, but other conditions
could trigger it too:
* mem_region was with .iova = 0, .translated_addr = (correct GPA).
* iova_tree_find_iova returned right result, but does not update
mem_region.
* iova_tree_remove always removed region with .iova = 0. Right iova were
sent to the device.
* Next map will fill the first region with .iova = 0, causing a mapping
with the same iova and device complains, if the next action is a map.
* Next unmap will cause to try to unmap again iova = 0, causing the
device to complain that no region was mapped at iova = 0.
Fixes: 34e3c94edaef ("vdpa: Add custom IOTLB translations to SVQ")
Reported-by: Lei Yang <leiyang@redhat.com>
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
hw/virtio/vhost-vdpa.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index 6304f174c2..d0cf7a0745 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -292,7 +292,7 @@ static void vhost_vdpa_listener_region_del(MemoryListener *listener,
result = vhost_iova_tree_find_iova(v->iova_tree, &mem_region);
iova = result->iova;
- vhost_iova_tree_remove(v->iova_tree, &mem_region);
+ vhost_iova_tree_remove(v->iova_tree, result);
}
vhost_vdpa_iotlb_batch_begin_once(v);
ret = vhost_vdpa_dma_unmap(v, iova, int128_get64(llsize));
--
2.27.0

View File

@ -0,0 +1,63 @@
From c8d132a62f026e51c2fb1f87dbf40aad8080fa9a Mon Sep 17 00:00:00 2001
From: Hawkins Jiawei <yin31149@gmail.com>
Date: Sat, 8 Jul 2023 00:44:42 +0800
Subject: [PATCH] vdpa: Fix possible use-after-free for VirtQueueElement
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
QEMU uses vhost_handle_guest_kick() to forward guest's available
buffers to the vdpa device in SVQ avail ring.
In vhost_handle_guest_kick(), a `g_autofree` `elem` is used to
iterate through the available VirtQueueElements. This `elem` is
then passed to `svq->ops->avail_handler`, specifically to the
vhost_vdpa_net_handle_ctrl_avail(). If this handler fails to
process the CVQ command, vhost_handle_guest_kick() regains
ownership of the `elem`, and either frees it or requeues it.
Yet the problem is that, vhost_vdpa_net_handle_ctrl_avail()
mistakenly frees the `elem`, even if it fails to forward the
CVQ command to vdpa device. This can result in a use-after-free
for the `elem` in vhost_handle_guest_kick().
This patch solves this problem by refactoring
vhost_vdpa_net_handle_ctrl_avail() to only freeing the `elem` if
it owns it.
Fixes: bd907ae4b0 ("vdpa: manual forward CVQ buffers")
Signed-off-by: Hawkins Jiawei <yin31149@gmail.com>
Message-Id: <e3f2d7db477734afe5c6a5ab3fa8b8317514ea34.1688746840.git.yin31149@gmail.com>
Reviewed-by: Eugenio Pérez <eperezma@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
net/vhost-vdpa.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index fd5dc8c6aa..94f74b54ae 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -658,7 +658,16 @@ out:
error_report("Bad device CVQ written length");
}
vhost_svq_push_elem(svq, elem, MIN(in_len, sizeof(status)));
- g_free(elem);
+ /*
+ * `elem` belongs to vhost_vdpa_net_handle_ctrl_avail() only when
+ * the function successfully forwards the CVQ command, indicated
+ * by a non-negative value of `dev_written`. Otherwise, it still
+ * belongs to SVQ.
+ * This function should only free the `elem` when it owns.
+ */
+ if (dev_written >= 0) {
+ g_free(elem);
+ }
return dev_written < 0 ? dev_written : 0;
}
--
2.27.0

View File

@ -0,0 +1,124 @@
From 39de24fc2b1cd16e8810b9e26cd23bb3896982a4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Tue, 23 Aug 2022 20:20:06 +0200
Subject: [PATCH] vdpa: Make SVQ vring unmapping return void
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Nothing actually reads the return value, but an error in cleaning some
entries could cause device stop to abort, making a restart impossible.
Better ignore explicitely the return value.
Reported-by: Lei Yang <leiyang@redhat.com>
Fixes: 34e3c94eda ("vdpa: Add custom IOTLB translations to SVQ")
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
hw/virtio/vhost-vdpa.c | 32 ++++++++++----------------------
1 file changed, 10 insertions(+), 22 deletions(-)
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index 3be6988e9c..31c1b71498 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -886,7 +886,7 @@ static int vhost_vdpa_svq_set_fds(struct vhost_dev *dev,
/**
* Unmap a SVQ area in the device
*/
-static bool vhost_vdpa_svq_unmap_ring(struct vhost_vdpa *v,
+static void vhost_vdpa_svq_unmap_ring(struct vhost_vdpa *v,
const DMAMap *needle)
{
const DMAMap *result = vhost_iova_tree_find_iova(v->iova_tree, needle);
@@ -895,38 +895,33 @@ static bool vhost_vdpa_svq_unmap_ring(struct vhost_vdpa *v,
if (unlikely(!result)) {
error_report("Unable to find SVQ address to unmap");
- return false;
+ return;
}
size = ROUND_UP(result->size, qemu_real_host_page_size);
r = vhost_vdpa_dma_unmap(v, result->iova, size);
if (unlikely(r < 0)) {
error_report("Unable to unmap SVQ vring: %s (%d)", g_strerror(-r), -r);
- return false;
+ return;
}
vhost_iova_tree_remove(v->iova_tree, *result);
- return r == 0;
}
-static bool vhost_vdpa_svq_unmap_rings(struct vhost_dev *dev,
+static void vhost_vdpa_svq_unmap_rings(struct vhost_dev *dev,
const VhostShadowVirtqueue *svq)
{
DMAMap needle = {};
struct vhost_vdpa *v = dev->opaque;
struct vhost_vring_addr svq_addr;
- bool ok;
vhost_svq_get_vring_addr(svq, &svq_addr);
needle.translated_addr = svq_addr.desc_user_addr;
- ok = vhost_vdpa_svq_unmap_ring(v, &needle);
- if (unlikely(!ok)) {
- return false;
- }
+ vhost_vdpa_svq_unmap_ring(v, &needle);
needle.translated_addr = svq_addr.used_user_addr;
- return vhost_vdpa_svq_unmap_ring(v, &needle);
+ vhost_vdpa_svq_unmap_ring(v, &needle);
}
/**
@@ -1097,26 +1092,22 @@ err:
return false;
}
-static bool vhost_vdpa_svqs_stop(struct vhost_dev *dev)
+static void vhost_vdpa_svqs_stop(struct vhost_dev *dev)
{
struct vhost_vdpa *v = dev->opaque;
if (!v->shadow_vqs) {
- return true;
+ return;
}
for (unsigned i = 0; i < v->shadow_vqs->len; ++i) {
VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, i);
- bool ok = vhost_vdpa_svq_unmap_rings(dev, svq);
- if (unlikely(!ok)) {
- return false;
- }
+ vhost_vdpa_svq_unmap_rings(dev, svq);
}
if (v->migration_blocker) {
migrate_del_blocker(v->migration_blocker);
}
- return true;
}
static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started)
@@ -1133,10 +1124,7 @@ static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started)
}
vhost_vdpa_set_vring_ready(dev);
} else {
- ok = vhost_vdpa_svqs_stop(dev);
- if (unlikely(!ok)) {
- return -1;
- }
+ vhost_vdpa_svqs_stop(dev);
vhost_vdpa_host_notifiers_uninit(dev, dev->nvqs);
}
--
2.27.0

View File

@ -0,0 +1,103 @@
From fdb55acf1833e6a35171b4e7e1c357f4b133e26f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Tue, 6 Sep 2022 17:07:14 +0200
Subject: [PATCH] vdpa: Make VhostVDPAState cvq_cmd_in_buffer control ack type
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This allows to simplify the code. Rename to status while we're at it.
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
net/vhost-vdpa.c | 23 ++++++++++++-----------
1 file changed, 12 insertions(+), 11 deletions(-)
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index b10a18aeb4..2700ef656f 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -34,7 +34,9 @@ typedef struct VhostVDPAState {
VHostNetState *vhost_net;
/* Control commands shadow buffers */
- void *cvq_cmd_out_buffer, *cvq_cmd_in_buffer;
+ void *cvq_cmd_out_buffer;
+ virtio_net_ctrl_ack *status;
+
bool started;
} VhostVDPAState;
@@ -166,7 +168,7 @@ static void vhost_vdpa_cleanup(NetClientState *nc)
}
qemu_vfree(s->cvq_cmd_out_buffer);
- qemu_vfree(s->cvq_cmd_in_buffer);
+ qemu_vfree(s->status);
if (dev->vq_index + dev->nvqs == dev->vq_index_end) {
g_clear_pointer(&s->vhost_vdpa.iova_tree, vhost_iova_tree_delete);
}
@@ -318,7 +320,7 @@ static int vhost_vdpa_net_cvq_start(NetClientState *nc)
return r;
}
- r = vhost_vdpa_cvq_map_buf(&s->vhost_vdpa, s->cvq_cmd_in_buffer,
+ r = vhost_vdpa_cvq_map_buf(&s->vhost_vdpa, s->status,
vhost_vdpa_net_cvq_cmd_page_len(), true);
if (unlikely(r < 0)) {
vhost_vdpa_cvq_unmap_buf(&s->vhost_vdpa, s->cvq_cmd_out_buffer);
@@ -335,7 +337,7 @@ static void vhost_vdpa_net_cvq_stop(NetClientState *nc)
if (s->vhost_vdpa.shadow_vqs_enabled) {
vhost_vdpa_cvq_unmap_buf(&s->vhost_vdpa, s->cvq_cmd_out_buffer);
- vhost_vdpa_cvq_unmap_buf(&s->vhost_vdpa, s->cvq_cmd_in_buffer);
+ vhost_vdpa_cvq_unmap_buf(&s->vhost_vdpa, s->status);
}
}
@@ -348,7 +350,7 @@ static ssize_t vhost_vdpa_net_cvq_add(VhostVDPAState *s, size_t out_len,
.iov_len = out_len,
};
const struct iovec in = {
- .iov_base = s->cvq_cmd_in_buffer,
+ .iov_base = s->status,
.iov_len = sizeof(virtio_net_ctrl_ack),
};
VhostShadowVirtqueue *svq = g_ptr_array_index(s->vhost_vdpa.shadow_vqs, 0);
@@ -404,7 +406,7 @@ static int vhost_vdpa_net_load(NetClientState *nc)
return dev_written;
}
- return *((virtio_net_ctrl_ack *)s->cvq_cmd_in_buffer) != VIRTIO_NET_OK;
+ return *s->status != VIRTIO_NET_OK;
}
return 0;
@@ -499,8 +501,7 @@ static int vhost_vdpa_net_handle_ctrl_avail(VhostShadowVirtqueue *svq,
goto out;
}
- memcpy(&status, s->cvq_cmd_in_buffer, sizeof(status));
- if (status != VIRTIO_NET_OK) {
+ if (*s->status != VIRTIO_NET_OK) {
return VIRTIO_NET_ERR;
}
@@ -557,9 +558,9 @@ static NetClientState *net_vhost_vdpa_init(NetClientState *peer,
s->cvq_cmd_out_buffer = qemu_memalign(qemu_real_host_page_size,
vhost_vdpa_net_cvq_cmd_page_len());
memset(s->cvq_cmd_out_buffer, 0, vhost_vdpa_net_cvq_cmd_page_len());
- s->cvq_cmd_in_buffer = qemu_memalign(qemu_real_host_page_size,
- vhost_vdpa_net_cvq_cmd_page_len());
- memset(s->cvq_cmd_in_buffer, 0, vhost_vdpa_net_cvq_cmd_page_len());
+ s->status = qemu_memalign(qemu_real_host_page_size,
+ vhost_vdpa_net_cvq_cmd_page_len());
+ memset(s->status, 0, vhost_vdpa_net_cvq_cmd_page_len());
s->vhost_vdpa.shadow_vq_ops = &vhost_vdpa_net_svq_ops;
s->vhost_vdpa.shadow_vq_ops_opaque = s;
--
2.27.0

View File

@ -0,0 +1,54 @@
From 1f1c2f74668cd1250cbd00b397dd59be92121314 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Mon, 14 Feb 2022 20:34:15 +0100
Subject: [PATCH] vdpa: Make ncs autofree
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Simplifying memory management.
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-Id: <20220214193415.1606752-2-eperezma@redhat.com>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
net/vhost-vdpa.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index 60b715aef1..9ba0f7bfca 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -271,7 +271,8 @@ int net_init_vhost_vdpa(const Netdev *netdev, const char *name,
{
const NetdevVhostVDPAOptions *opts;
int vdpa_device_fd;
- NetClientState **ncs, *nc;
+ g_autofree NetClientState **ncs = NULL;
+ NetClientState *nc;
int queue_pairs, i, has_cvq = 0;
assert(netdev->type == NET_CLIENT_DRIVER_VHOST_VDPA);
@@ -309,7 +310,6 @@ int net_init_vhost_vdpa(const Netdev *netdev, const char *name,
goto err;
}
- g_free(ncs);
return 0;
err:
@@ -317,7 +317,6 @@ err:
qemu_del_net_client(ncs[0]);
}
qemu_close(vdpa_device_fd);
- g_free(ncs);
return -1;
}
--
2.27.0

View File

@ -0,0 +1,242 @@
From 811a2e0b40724cc505141d4caf322030b83f86a3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Tue, 23 Aug 2022 20:30:33 +0200
Subject: [PATCH] vdpa: Move command buffers map to start of net device
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
As this series will reuse them to restore the device state at the end of
a migration (or a device start), let's allocate only once at the device
start so we don't duplicate their map and unmap.
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
net/vhost-vdpa.c | 123 ++++++++++++++++++++++-------------------------
1 file changed, 58 insertions(+), 65 deletions(-)
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index 04cb08d418..882f5ee89c 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -271,29 +271,20 @@ static size_t vhost_vdpa_net_cvq_cmd_page_len(void)
return ROUND_UP(vhost_vdpa_net_cvq_cmd_len(), qemu_real_host_page_size);
}
-/** Copy and map a guest buffer. */
-static bool vhost_vdpa_cvq_map_buf(struct vhost_vdpa *v,
- const struct iovec *out_data,
- size_t out_num, size_t data_len, void *buf,
- size_t *written, bool write)
+/** Map CVQ buffer. */
+static int vhost_vdpa_cvq_map_buf(struct vhost_vdpa *v, void *buf, size_t size,
+ bool write)
{
DMAMap map = {};
int r;
- if (unlikely(!data_len)) {
- qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid legnth of %s buffer\n",
- __func__, write ? "in" : "out");
- return false;
- }
-
- *written = iov_to_buf(out_data, out_num, 0, buf, data_len);
map.translated_addr = (hwaddr)(uintptr_t)buf;
- map.size = vhost_vdpa_net_cvq_cmd_page_len() - 1;
+ map.size = size - 1;
map.perm = write ? IOMMU_RW : IOMMU_RO,
r = vhost_iova_tree_map_alloc(v->iova_tree, &map);
if (unlikely(r != IOVA_OK)) {
error_report("Cannot map injected element");
- return false;
+ return r;
}
r = vhost_vdpa_dma_map(v, map.iova, vhost_vdpa_net_cvq_cmd_page_len(), buf,
@@ -302,50 +293,58 @@ static bool vhost_vdpa_cvq_map_buf(struct vhost_vdpa *v,
goto dma_map_err;
}
- return true;
+ return 0;
dma_map_err:
vhost_iova_tree_remove(v->iova_tree, map);
- return false;
+ return r;
}
-/**
- * Copy the guest element into a dedicated buffer suitable to be sent to NIC
- *
- * @iov: [0] is the out buffer, [1] is the in one
- */
-static bool vhost_vdpa_net_cvq_map_elem(VhostVDPAState *s,
- VirtQueueElement *elem,
- struct iovec *iov)
+static int vhost_vdpa_net_cvq_start(NetClientState *nc)
{
- size_t in_copied;
- bool ok;
+ VhostVDPAState *s;
+ int r;
- iov[0].iov_base = s->cvq_cmd_out_buffer;
- ok = vhost_vdpa_cvq_map_buf(&s->vhost_vdpa, elem->out_sg, elem->out_num,
- vhost_vdpa_net_cvq_cmd_len(), iov[0].iov_base,
- &iov[0].iov_len, false);
- if (unlikely(!ok)) {
- return false;
+ assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);
+
+ s = DO_UPCAST(VhostVDPAState, nc, nc);
+ if (!s->vhost_vdpa.shadow_vqs_enabled) {
+ return 0;
}
- iov[1].iov_base = s->cvq_cmd_in_buffer;
- ok = vhost_vdpa_cvq_map_buf(&s->vhost_vdpa, NULL, 0,
- sizeof(virtio_net_ctrl_ack), iov[1].iov_base,
- &in_copied, true);
- if (unlikely(!ok)) {
+ r = vhost_vdpa_cvq_map_buf(&s->vhost_vdpa, s->cvq_cmd_out_buffer,
+ vhost_vdpa_net_cvq_cmd_page_len(), false);
+ if (unlikely(r < 0)) {
+ return r;
+ }
+
+ r = vhost_vdpa_cvq_map_buf(&s->vhost_vdpa, s->cvq_cmd_in_buffer,
+ vhost_vdpa_net_cvq_cmd_page_len(), true);
+ if (unlikely(r < 0)) {
vhost_vdpa_cvq_unmap_buf(&s->vhost_vdpa, s->cvq_cmd_out_buffer);
- return false;
}
- iov[1].iov_len = sizeof(virtio_net_ctrl_ack);
- return true;
+ return r;
+}
+
+static void vhost_vdpa_net_cvq_stop(NetClientState *nc)
+{
+ VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
+
+ assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);
+
+ if (s->vhost_vdpa.shadow_vqs_enabled) {
+ vhost_vdpa_cvq_unmap_buf(&s->vhost_vdpa, s->cvq_cmd_out_buffer);
+ vhost_vdpa_cvq_unmap_buf(&s->vhost_vdpa, s->cvq_cmd_in_buffer);
+ }
}
static NetClientInfo net_vhost_vdpa_cvq_info = {
.type = NET_CLIENT_DRIVER_VHOST_VDPA,
.size = sizeof(VhostVDPAState),
.receive = vhost_vdpa_receive,
+ .start = vhost_vdpa_net_cvq_start,
+ .stop = vhost_vdpa_net_cvq_stop,
.cleanup = vhost_vdpa_cleanup,
.has_vnet_hdr = vhost_vdpa_has_vnet_hdr,
.has_ufo = vhost_vdpa_has_ufo,
@@ -356,19 +355,17 @@ static NetClientInfo net_vhost_vdpa_cvq_info = {
* Do not forward commands not supported by SVQ. Otherwise, the device could
* accept it and qemu would not know how to update the device model.
*/
-static bool vhost_vdpa_net_cvq_validate_cmd(const struct iovec *out,
- size_t out_num)
+static bool vhost_vdpa_net_cvq_validate_cmd(const void *out_buf, size_t len)
{
struct virtio_net_ctrl_hdr ctrl;
- size_t n;
- n = iov_to_buf(out, out_num, 0, &ctrl, sizeof(ctrl));
- if (unlikely(n < sizeof(ctrl))) {
+ if (unlikely(len < sizeof(ctrl))) {
qemu_log_mask(LOG_GUEST_ERROR,
- "%s: invalid legnth of out buffer %zu\n", __func__, n);
+ "%s: invalid legnth of out buffer %zu\n", __func__, len);
return false;
}
+ memcpy(&ctrl, out_buf, sizeof(ctrl));
switch (ctrl.class) {
case VIRTIO_NET_CTRL_MAC:
switch (ctrl.cmd) {
@@ -400,10 +397,14 @@ static int vhost_vdpa_net_handle_ctrl_avail(VhostShadowVirtqueue *svq,
VhostVDPAState *s = opaque;
size_t in_len, dev_written;
virtio_net_ctrl_ack status = VIRTIO_NET_ERR;
- /* out and in buffers sent to the device */
- struct iovec dev_buffers[2] = {
- { .iov_base = s->cvq_cmd_out_buffer },
- { .iov_base = s->cvq_cmd_in_buffer },
+ /* Out buffer sent to both the vdpa device and the device model */
+ struct iovec out = {
+ .iov_base = s->cvq_cmd_out_buffer,
+ };
+ /* In buffer sent to the device */
+ const struct iovec dev_in = {
+ .iov_base = s->cvq_cmd_in_buffer,
+ .iov_len = sizeof(virtio_net_ctrl_ack),
};
/* in buffer used for device model */
const struct iovec in = {
@@ -413,17 +414,15 @@ static int vhost_vdpa_net_handle_ctrl_avail(VhostShadowVirtqueue *svq,
int r = -EINVAL;
bool ok;
- ok = vhost_vdpa_net_cvq_map_elem(s, elem, dev_buffers);
- if (unlikely(!ok)) {
- goto out;
- }
-
- ok = vhost_vdpa_net_cvq_validate_cmd(&dev_buffers[0], 1);
+ out.iov_len = iov_to_buf(elem->out_sg, elem->out_num, 0,
+ s->cvq_cmd_out_buffer,
+ vhost_vdpa_net_cvq_cmd_len());
+ ok = vhost_vdpa_net_cvq_validate_cmd(s->cvq_cmd_out_buffer, out.iov_len);
if (unlikely(!ok)) {
goto out;
}
- r = vhost_svq_add(svq, &dev_buffers[0], 1, &dev_buffers[1], 1, elem);
+ r = vhost_svq_add(svq, &out, 1, &dev_in, 1, elem);
if (unlikely(r != 0)) {
if (unlikely(r == -ENOSPC)) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: No space on device queue\n",
@@ -443,13 +442,13 @@ static int vhost_vdpa_net_handle_ctrl_avail(VhostShadowVirtqueue *svq,
goto out;
}
- memcpy(&status, dev_buffers[1].iov_base, sizeof(status));
+ memcpy(&status, s->cvq_cmd_in_buffer, sizeof(status));
if (status != VIRTIO_NET_OK) {
goto out;
}
status = VIRTIO_NET_ERR;
- virtio_net_handle_ctrl_iov(svq->vdev, &in, 1, dev_buffers, 1);
+ virtio_net_handle_ctrl_iov(svq->vdev, &in, 1, &out, 1);
if (status != VIRTIO_NET_OK) {
error_report("Bad CVQ processing in model");
}
@@ -462,12 +461,6 @@ out:
}
vhost_svq_push_elem(svq, elem, MIN(in_len, sizeof(status)));
g_free(elem);
- if (dev_buffers[0].iov_base) {
- vhost_vdpa_cvq_unmap_buf(&s->vhost_vdpa, dev_buffers[0].iov_base);
- }
- if (dev_buffers[1].iov_base) {
- vhost_vdpa_cvq_unmap_buf(&s->vhost_vdpa, dev_buffers[1].iov_base);
- }
return r;
}
--
2.27.0

View File

@ -0,0 +1,36 @@
From b34bcf052293861e8b88a41dad194d0889c6692f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Mon, 14 Mar 2022 18:34:53 +0100
Subject: [PATCH] vdpa: Never set log_base addr if SVQ is enabled
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Setting the log address would make the device start reporting invalid
dirty memory because the SVQ vrings are located in qemu's memory.
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
hw/virtio/vhost-vdpa.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index 428137f654..840141321a 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -1092,7 +1092,8 @@ static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started)
static int vhost_vdpa_set_log_base(struct vhost_dev *dev, uint64_t base,
struct vhost_log *log)
{
- if (vhost_vdpa_one_time_request(dev)) {
+ struct vhost_vdpa *v = dev->opaque;
+ if (v->shadow_vqs_enabled || vhost_vdpa_one_time_request(dev)) {
return 0;
}
--
2.27.0

View File

@ -0,0 +1,40 @@
From f52985fb819fbf8efb162a25096abb4c174b9f40 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Tue, 23 Aug 2022 20:20:05 +0200
Subject: [PATCH] vdpa: Remove SVQ vring from iova_tree at shutdown
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Although the device will be reset before usage, the right thing to do is
to clean it.
Reported-by: Lei Yang <leiyang@redhat.com>
Fixes: 34e3c94eda ("vdpa: Add custom IOTLB translations to SVQ")
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
hw/virtio/vhost-vdpa.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index 0f640f670b..3be6988e9c 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -900,6 +900,12 @@ static bool vhost_vdpa_svq_unmap_ring(struct vhost_vdpa *v,
size = ROUND_UP(result->size, qemu_real_host_page_size);
r = vhost_vdpa_dma_unmap(v, result->iova, size);
+ if (unlikely(r < 0)) {
+ error_report("Unable to unmap SVQ vring: %s (%d)", g_strerror(-r), -r);
+ return false;
+ }
+
+ vhost_iova_tree_remove(v->iova_tree, *result);
return r == 0;
}
--
2.27.0

View File

@ -0,0 +1,94 @@
From 6cb9e17dcc07d6fc1467a585fb015991191a92da Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Thu, 20 Oct 2022 10:02:30 +0200
Subject: [PATCH] vdpa: Remove shadow CVQ command check
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The guest will see undefined behavior if it issue not negotiate
commands, bit it is expected somehow.
Simplify code deleting this check.
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
net/vhost-vdpa.c | 48 ------------------------------------------------
1 file changed, 48 deletions(-)
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index f4f6b8587f..c8c433002d 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -469,48 +469,6 @@ static NetClientInfo net_vhost_vdpa_cvq_info = {
.check_peer_type = vhost_vdpa_check_peer_type,
};
-/**
- * Do not forward commands not supported by SVQ. Otherwise, the device could
- * accept it and qemu would not know how to update the device model.
- */
-static bool vhost_vdpa_net_cvq_validate_cmd(const void *out_buf, size_t len)
-{
- struct virtio_net_ctrl_hdr ctrl;
-
- if (unlikely(len < sizeof(ctrl))) {
- qemu_log_mask(LOG_GUEST_ERROR,
- "%s: invalid legnth of out buffer %zu\n", __func__, len);
- return false;
- }
-
- memcpy(&ctrl, out_buf, sizeof(ctrl));
- switch (ctrl.class) {
- case VIRTIO_NET_CTRL_MAC:
- switch (ctrl.cmd) {
- case VIRTIO_NET_CTRL_MAC_ADDR_SET:
- return true;
- default:
- qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid mac cmd %u\n",
- __func__, ctrl.cmd);
- };
- break;
- case VIRTIO_NET_CTRL_MQ:
- switch (ctrl.cmd) {
- case VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET:
- return true;
- default:
- qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid mq cmd %u\n",
- __func__, ctrl.cmd);
- };
- break;
- default:
- qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid control class %u\n",
- __func__, ctrl.class);
- };
-
- return false;
-}
-
/**
* Validate and copy control virtqueue commands.
*
@@ -534,16 +492,10 @@ static int vhost_vdpa_net_handle_ctrl_avail(VhostShadowVirtqueue *svq,
.iov_len = sizeof(status),
};
ssize_t dev_written = -EINVAL;
- bool ok;
out.iov_len = iov_to_buf(elem->out_sg, elem->out_num, 0,
s->cvq_cmd_out_buffer,
vhost_vdpa_net_cvq_cmd_len());
- ok = vhost_vdpa_net_cvq_validate_cmd(s->cvq_cmd_out_buffer, out.iov_len);
- if (unlikely(!ok)) {
- goto out;
- }
-
dev_written = vhost_vdpa_net_cvq_add(s, out.iov_len, sizeof(status));
if (unlikely(dev_written < 0)) {
goto out;
--
2.27.0

View File

@ -0,0 +1,63 @@
From 8f2a04c1b5790f6e00160920c3bc88801b5afc16 Mon Sep 17 00:00:00 2001
From: Hawkins Jiawei <yin31149@gmail.com>
Date: Tue, 4 Jul 2023 11:34:34 +0800
Subject: [PATCH] vdpa: Return -EIO if device ack is VIRTIO_NET_ERR in
_load_mq()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
According to VirtIO standard, "The class, command and
command-specific-data are set by the driver,
and the device sets the ack byte.
There is little it can do except issue a diagnostic
if ack is not VIRTIO_NET_OK."
Therefore, QEMU should stop sending the queued SVQ commands and
cancel the device startup if the device's ack is not VIRTIO_NET_OK.
Yet the problem is that, vhost_vdpa_net_load_mq() returns 1 based on
`*s->status != VIRTIO_NET_OK` when the device's ack is VIRTIO_NET_ERR.
As a result, net->nc->info->load() also returns 1, this makes
vhost_net_start_one() incorrectly assume the device state is
successfully loaded by vhost_vdpa_net_load() and return 0, instead of
goto `fail` label to cancel the device startup, as vhost_net_start_one()
only cancels the device startup when net->nc->info->load() returns a
negative value.
This patch fixes this problem by returning -EIO when the device's
ack is not VIRTIO_NET_OK.
Fixes: f64c7cda69 ("vdpa: Add vhost_vdpa_net_load_mq")
Signed-off-by: Hawkins Jiawei <yin31149@gmail.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Acked-by: Eugenio Pérez <eperezma@redhat.com>
Message-Id: <ec515ebb0b4f56368751b9e318e245a5d994fa72.1688438055.git.yin31149@gmail.com>
Tested-by: Lei Yang <leiyang@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
net/vhost-vdpa.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index 9af9f6554e..8192045735 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -553,8 +553,11 @@ static int vhost_vdpa_net_load_mq(VhostVDPAState *s,
if (unlikely(dev_written < 0)) {
return dev_written;
}
+ if (*s->status != VIRTIO_NET_OK) {
+ return -EIO;
+ }
- return *s->status != VIRTIO_NET_OK;
+ return 0;
}
static int vhost_vdpa_net_load(NetClientState *nc)
--
2.27.0

View File

@ -0,0 +1,62 @@
From 1c9d6dde6fabf6c1f6a4aeb388921a83279d3071 Mon Sep 17 00:00:00 2001
From: Hawkins Jiawei <yin31149@gmail.com>
Date: Tue, 4 Jul 2023 11:34:33 +0800
Subject: [PATCH] vdpa: Return -EIO if device ack is VIRTIO_NET_ERR in
_load_mac()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
According to VirtIO standard, "The class, command and
command-specific-data are set by the driver,
and the device sets the ack byte.
There is little it can do except issue a diagnostic
if ack is not VIRTIO_NET_OK."
Therefore, QEMU should stop sending the queued SVQ commands and
cancel the device startup if the device's ack is not VIRTIO_NET_OK.
Yet the problem is that, vhost_vdpa_net_load_mac() returns 1 based on
`*s->status != VIRTIO_NET_OK` when the device's ack is VIRTIO_NET_ERR.
As a result, net->nc->info->load() also returns 1, this makes
vhost_net_start_one() incorrectly assume the device state is
successfully loaded by vhost_vdpa_net_load() and return 0, instead of
goto `fail` label to cancel the device startup, as vhost_net_start_one()
only cancels the device startup when net->nc->info->load() returns a
negative value.
This patch fixes this problem by returning -EIO when the device's
ack is not VIRTIO_NET_OK.
Fixes: f73c0c43ac ("vdpa: extract vhost_vdpa_net_load_mac from vhost_vdpa_net_load")
Signed-off-by: Hawkins Jiawei <yin31149@gmail.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Acked-by: Eugenio Pérez <eperezma@redhat.com>
Message-Id: <a21731518644abbd0c495c5b7960527c5911f80d.1688438055.git.yin31149@gmail.com>
Tested-by: Lei Yang <leiyang@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
net/vhost-vdpa.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index afca8740bc..9af9f6554e 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -527,8 +527,9 @@ static int vhost_vdpa_net_load_mac(VhostVDPAState *s, const VirtIONet *n)
if (unlikely(dev_written < 0)) {
return dev_written;
}
-
- return *s->status != VIRTIO_NET_OK;
+ if (*s->status != VIRTIO_NET_OK) {
+ return -EIO;
+ }
}
return 0;
--
2.27.0

View File

@ -0,0 +1,39 @@
From a498bc3ae687778dad2f8161ff17532432df0c1c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Tue, 23 Aug 2022 20:20:02 +0200
Subject: [PATCH] vdpa: Skip the maps not in the iova tree
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Next patch will skip the registering of dma maps that the vdpa device
rejects in the iova tree. We need to consider that here or we cause a
SIGSEGV accessing result.
Reported-by: Lei Yang <leiyang@redhat.com>
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
hw/virtio/vhost-vdpa.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index d0cf7a0745..c551665f5d 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -291,6 +291,10 @@ static void vhost_vdpa_listener_region_del(MemoryListener *listener,
};
result = vhost_iova_tree_find_iova(v->iova_tree, &mem_region);
+ if (!result) {
+ /* The memory listener map wasn't mapped */
+ return;
+ }
iova = result->iova;
vhost_iova_tree_remove(v->iova_tree, result);
}
--
2.27.0

View File

@ -0,0 +1,70 @@
From 1c3e4f7326031d0b689821f655a4352bb746a405 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Tue, 23 Aug 2022 20:20:08 +0200
Subject: [PATCH] vdpa: Use ring hwaddr at vhost_vdpa_svq_unmap_ring
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Reduce code duplication.
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
hw/virtio/vhost-vdpa.c | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index 31c1b71498..d7bdc0f37c 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -886,10 +886,12 @@ static int vhost_vdpa_svq_set_fds(struct vhost_dev *dev,
/**
* Unmap a SVQ area in the device
*/
-static void vhost_vdpa_svq_unmap_ring(struct vhost_vdpa *v,
- const DMAMap *needle)
+static void vhost_vdpa_svq_unmap_ring(struct vhost_vdpa *v, hwaddr addr)
{
- const DMAMap *result = vhost_iova_tree_find_iova(v->iova_tree, needle);
+ const DMAMap needle = {
+ .translated_addr = addr,
+ };
+ const DMAMap *result = vhost_iova_tree_find_iova(v->iova_tree, &needle);
hwaddr size;
int r;
@@ -911,17 +913,14 @@ static void vhost_vdpa_svq_unmap_ring(struct vhost_vdpa *v,
static void vhost_vdpa_svq_unmap_rings(struct vhost_dev *dev,
const VhostShadowVirtqueue *svq)
{
- DMAMap needle = {};
struct vhost_vdpa *v = dev->opaque;
struct vhost_vring_addr svq_addr;
vhost_svq_get_vring_addr(svq, &svq_addr);
- needle.translated_addr = svq_addr.desc_user_addr;
- vhost_vdpa_svq_unmap_ring(v, &needle);
+ vhost_vdpa_svq_unmap_ring(v, svq_addr.desc_user_addr);
- needle.translated_addr = svq_addr.used_user_addr;
- vhost_vdpa_svq_unmap_ring(v, &needle);
+ vhost_vdpa_svq_unmap_ring(v, svq_addr.used_user_addr);
}
/**
@@ -999,7 +998,7 @@ static bool vhost_vdpa_svq_map_rings(struct vhost_dev *dev,
ok = vhost_vdpa_svq_map_ring(v, &device_region, errp);
if (unlikely(!ok)) {
error_prepend(errp, "Cannot create vq device region: ");
- vhost_vdpa_svq_unmap_ring(v, &driver_region);
+ vhost_vdpa_svq_unmap_ring(v, driver_region.translated_addr);
}
addr->used_user_addr = device_region.iova;
--
2.27.0

View File

@ -0,0 +1,104 @@
From 1ae2ad1afcb032dc933104da5ad922173961caf8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Mon, 14 Mar 2022 18:34:46 +0100
Subject: [PATCH] vdpa: adapt vhost_ops callbacks to svq
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
First half of the buffers forwarding part, preparing vhost-vdpa
callbacks to SVQ to offer it. QEMU cannot enable it at this moment, so
this is effectively dead code at the moment, but it helps to reduce
patch size.
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
hw/virtio/vhost-vdpa.c | 48 ++++++++++++++++++++++++++++++++++++------
1 file changed, 41 insertions(+), 7 deletions(-)
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index 8ee63933a8..2f0e6a9bef 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -735,6 +735,13 @@ static int vhost_vdpa_get_config(struct vhost_dev *dev, uint8_t *config,
return ret;
}
+static int vhost_vdpa_set_dev_vring_base(struct vhost_dev *dev,
+ struct vhost_vring_state *ring)
+{
+ trace_vhost_vdpa_set_vring_base(dev, ring->index, ring->num);
+ return vhost_vdpa_call(dev, VHOST_SET_VRING_BASE, ring);
+}
+
static int vhost_vdpa_set_vring_dev_kick(struct vhost_dev *dev,
struct vhost_vring_file *file)
{
@@ -749,6 +756,18 @@ static int vhost_vdpa_set_vring_dev_call(struct vhost_dev *dev,
return vhost_vdpa_call(dev, VHOST_SET_VRING_CALL, file);
}
+static int vhost_vdpa_set_vring_dev_addr(struct vhost_dev *dev,
+ struct vhost_vring_addr *addr)
+{
+ trace_vhost_vdpa_set_vring_addr(dev, addr->index, addr->flags,
+ addr->desc_user_addr, addr->used_user_addr,
+ addr->avail_user_addr,
+ addr->log_guest_addr);
+
+ return vhost_vdpa_call(dev, VHOST_SET_VRING_ADDR, addr);
+
+}
+
/**
* Set the shadow virtqueue descriptors to the device
*
@@ -858,11 +877,17 @@ static int vhost_vdpa_set_log_base(struct vhost_dev *dev, uint64_t base,
static int vhost_vdpa_set_vring_addr(struct vhost_dev *dev,
struct vhost_vring_addr *addr)
{
- trace_vhost_vdpa_set_vring_addr(dev, addr->index, addr->flags,
- addr->desc_user_addr, addr->used_user_addr,
- addr->avail_user_addr,
- addr->log_guest_addr);
- return vhost_vdpa_call(dev, VHOST_SET_VRING_ADDR, addr);
+ struct vhost_vdpa *v = dev->opaque;
+
+ if (v->shadow_vqs_enabled) {
+ /*
+ * Device vring addr was set at device start. SVQ base is handled by
+ * VirtQueue code.
+ */
+ return 0;
+ }
+
+ return vhost_vdpa_set_vring_dev_addr(dev, addr);
}
static int vhost_vdpa_set_vring_num(struct vhost_dev *dev,
@@ -875,8 +900,17 @@ static int vhost_vdpa_set_vring_num(struct vhost_dev *dev,
static int vhost_vdpa_set_vring_base(struct vhost_dev *dev,
struct vhost_vring_state *ring)
{
- trace_vhost_vdpa_set_vring_base(dev, ring->index, ring->num);
- return vhost_vdpa_call(dev, VHOST_SET_VRING_BASE, ring);
+ struct vhost_vdpa *v = dev->opaque;
+
+ if (v->shadow_vqs_enabled) {
+ /*
+ * Device vring base was set at device start. SVQ base is handled by
+ * VirtQueue code.
+ */
+ return 0;
+ }
+
+ return vhost_vdpa_set_dev_vring_base(dev, ring);
}
static int vhost_vdpa_get_vring_base(struct vhost_dev *dev,
--
2.27.0

View File

@ -0,0 +1,227 @@
From 657f5e7b200bec7b124ca5e2cf4d8e1b721cbfde Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Thu, 15 Dec 2022 12:31:41 +0100
Subject: [PATCH] vdpa: add asid parameter to vhost_vdpa_dma_map/unmap
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
So the caller can choose which ASID is destined.
No need to update the batch functions as they will always be called from
memory listener updates at the moment. Memory listener updates will
always update ASID 0, as it's the passthrough ASID.
All vhost devices's ASID are 0 at this moment.
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Message-Id: <20221215113144.322011-10-eperezma@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
hw/virtio/trace-events | 4 +--
hw/virtio/vhost-vdpa.c | 36 ++++++++++++++------
include/hw/virtio/vhost-vdpa.h | 14 ++++++--
include/standard-headers/linux/vhost_types.h | 2 +-
net/vhost-vdpa.c | 6 ++--
5 files changed, 42 insertions(+), 20 deletions(-)
diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
index 35d4c00e59..edbbbeb621 100644
--- a/hw/virtio/trace-events
+++ b/hw/virtio/trace-events
@@ -29,8 +29,8 @@ vhost_user_read(uint32_t req, uint32_t flags) "req:%d flags:0x%"PRIx32""
vhost_user_write(uint32_t req, uint32_t flags) "req:%d flags:0x%"PRIx32""
# vhost-vdpa.c
-vhost_vdpa_dma_map(void *vdpa, int fd, uint32_t msg_type, uint64_t iova, uint64_t size, uint64_t uaddr, uint8_t perm, uint8_t type) "vdpa:%p fd: %d msg_type: %"PRIu32" iova: 0x%"PRIx64" size: 0x%"PRIx64" uaddr: 0x%"PRIx64" perm: 0x%"PRIx8" type: %"PRIu8
-vhost_vdpa_dma_unmap(void *vdpa, int fd, uint32_t msg_type, uint64_t iova, uint64_t size, uint8_t type) "vdpa:%p fd: %d msg_type: %"PRIu32" iova: 0x%"PRIx64" size: 0x%"PRIx64" type: %"PRIu8
+vhost_vdpa_dma_map(void *vdpa, int fd, uint32_t msg_type, uint32_t asid, uint64_t iova, uint64_t size, uint64_t uaddr, uint8_t perm, uint8_t type) "vdpa:%p fd: %d msg_type: %"PRIu32" asid: %"PRIu32" iova: 0x%"PRIx64" size: 0x%"PRIx64" uaddr: 0x%"PRIx64" perm: 0x%"PRIx8" type: %"PRIu8
+vhost_vdpa_dma_unmap(void *vdpa, int fd, uint32_t msg_type, uint32_t asid, uint64_t iova, uint64_t size, uint8_t type) "vdpa:%p fd: %d msg_type: %"PRIu32" asid: %"PRIu32" iova: 0x%"PRIx64" size: 0x%"PRIx64" type: %"PRIu8
vhost_vdpa_listener_begin_batch(void *v, int fd, uint32_t msg_type, uint8_t type) "vdpa:%p fd: %d msg_type: %"PRIu32" type: %"PRIu8
vhost_vdpa_listener_commit(void *v, int fd, uint32_t msg_type, uint8_t type) "vdpa:%p fd: %d msg_type: %"PRIu32" type: %"PRIu8
vhost_vdpa_listener_region_add(void *vdpa, uint64_t iova, uint64_t llend, void *vaddr, bool readonly) "vdpa: %p iova 0x%"PRIx64" llend 0x%"PRIx64" vaddr: %p read-only: %d"
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index 450b5effd2..f4a0878e34 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -74,22 +74,28 @@ static bool vhost_vdpa_listener_skipped_section(MemoryRegionSection *section,
return false;
}
-int vhost_vdpa_dma_map(struct vhost_vdpa *v, hwaddr iova, hwaddr size,
- void *vaddr, bool readonly)
+/*
+ * The caller must set asid = 0 if the device does not support asid.
+ * This is not an ABI break since it is set to 0 by the initializer anyway.
+ */
+int vhost_vdpa_dma_map(struct vhost_vdpa *v, uint32_t asid, hwaddr iova,
+ hwaddr size, void *vaddr, bool readonly)
{
struct vhost_msg_v2 msg = {};
int fd = v->device_fd;
int ret = 0;
msg.type = v->msg_type;
+ msg.asid = asid;
msg.iotlb.iova = iova;
msg.iotlb.size = size;
msg.iotlb.uaddr = (uint64_t)(uintptr_t)vaddr;
msg.iotlb.perm = readonly ? VHOST_ACCESS_RO : VHOST_ACCESS_RW;
msg.iotlb.type = VHOST_IOTLB_UPDATE;
- trace_vhost_vdpa_dma_map(v, fd, msg.type, msg.iotlb.iova, msg.iotlb.size,
- msg.iotlb.uaddr, msg.iotlb.perm, msg.iotlb.type);
+ trace_vhost_vdpa_dma_map(v, fd, msg.type, msg.asid, msg.iotlb.iova,
+ msg.iotlb.size, msg.iotlb.uaddr, msg.iotlb.perm,
+ msg.iotlb.type);
if (write(fd, &msg, sizeof(msg)) != sizeof(msg)) {
error_report("failed to write, fd=%d, errno=%d (%s)",
@@ -100,18 +106,24 @@ int vhost_vdpa_dma_map(struct vhost_vdpa *v, hwaddr iova, hwaddr size,
return ret;
}
-int vhost_vdpa_dma_unmap(struct vhost_vdpa *v, hwaddr iova, hwaddr size)
+/*
+ * The caller must set asid = 0 if the device does not support asid.
+ * This is not an ABI break since it is set to 0 by the initializer anyway.
+ */
+int vhost_vdpa_dma_unmap(struct vhost_vdpa *v, uint32_t asid, hwaddr iova,
+ hwaddr size)
{
struct vhost_msg_v2 msg = {};
int fd = v->device_fd;
int ret = 0;
msg.type = v->msg_type;
+ msg.asid = asid;
msg.iotlb.iova = iova;
msg.iotlb.size = size;
msg.iotlb.type = VHOST_IOTLB_INVALIDATE;
- trace_vhost_vdpa_dma_unmap(v, fd, msg.type, msg.iotlb.iova,
+ trace_vhost_vdpa_dma_unmap(v, fd, msg.type, msg.asid, msg.iotlb.iova,
msg.iotlb.size, msg.iotlb.type);
if (write(fd, &msg, sizeof(msg)) != sizeof(msg)) {
@@ -231,8 +243,8 @@ static void vhost_vdpa_listener_region_add(MemoryListener *listener,
}
vhost_vdpa_iotlb_batch_begin_once(v);
- ret = vhost_vdpa_dma_map(v, iova, int128_get64(llsize),
- vaddr, section->readonly);
+ ret = vhost_vdpa_dma_map(v, VHOST_VDPA_GUEST_PA_ASID, iova,
+ int128_get64(llsize), vaddr, section->readonly);
if (ret) {
error_report("vhost vdpa map fail!");
goto fail_map;
@@ -305,7 +317,8 @@ static void vhost_vdpa_listener_region_del(MemoryListener *listener,
vhost_iova_tree_remove(v->iova_tree, *result);
}
vhost_vdpa_iotlb_batch_begin_once(v);
- ret = vhost_vdpa_dma_unmap(v, iova, int128_get64(llsize));
+ ret = vhost_vdpa_dma_unmap(v, VHOST_VDPA_GUEST_PA_ASID, iova,
+ int128_get64(llsize));
if (ret) {
error_report("vhost_vdpa dma unmap error!");
}
@@ -872,7 +885,7 @@ static void vhost_vdpa_svq_unmap_ring(struct vhost_vdpa *v, hwaddr addr)
}
size = ROUND_UP(result->size, qemu_real_host_page_size);
- r = vhost_vdpa_dma_unmap(v, result->iova, size);
+ r = vhost_vdpa_dma_unmap(v, v->address_space_id, result->iova, size);
if (unlikely(r < 0)) {
error_report("Unable to unmap SVQ vring: %s (%d)", g_strerror(-r), -r);
return;
@@ -912,7 +925,8 @@ static bool vhost_vdpa_svq_map_ring(struct vhost_vdpa *v, DMAMap *needle,
return false;
}
- r = vhost_vdpa_dma_map(v, needle->iova, needle->size + 1,
+ r = vhost_vdpa_dma_map(v, v->address_space_id, needle->iova,
+ needle->size + 1,
(void *)(uintptr_t)needle->translated_addr,
needle->perm == IOMMU_RO);
if (unlikely(r != 0)) {
diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h
index 1111d85643..e57dfa1fd1 100644
--- a/include/hw/virtio/vhost-vdpa.h
+++ b/include/hw/virtio/vhost-vdpa.h
@@ -19,6 +19,12 @@
#include "hw/virtio/virtio.h"
#include "standard-headers/linux/vhost_types.h"
+/*
+ * ASID dedicated to map guest's addresses. If SVQ is disabled it maps GPA to
+ * qemu's IOVA. If SVQ is enabled it maps also the SVQ vring here
+ */
+#define VHOST_VDPA_GUEST_PA_ASID 0
+
typedef struct VhostVDPAHostNotifier {
MemoryRegion mr;
void *addr;
@@ -29,6 +35,7 @@ typedef struct vhost_vdpa {
int index;
uint32_t msg_type;
bool iotlb_batch_begin_sent;
+ uint32_t address_space_id;
MemoryListener listener;
struct vhost_vdpa_iova_range iova_range;
uint64_t acked_features;
@@ -42,8 +49,9 @@ typedef struct vhost_vdpa {
VhostVDPAHostNotifier notifier[VIRTIO_QUEUE_MAX];
} VhostVDPA;
-int vhost_vdpa_dma_map(struct vhost_vdpa *v, hwaddr iova, hwaddr size,
- void *vaddr, bool readonly);
-int vhost_vdpa_dma_unmap(struct vhost_vdpa *v, hwaddr iova, hwaddr size);
+int vhost_vdpa_dma_map(struct vhost_vdpa *v, uint32_t asid, hwaddr iova,
+ hwaddr size, void *vaddr, bool readonly);
+int vhost_vdpa_dma_unmap(struct vhost_vdpa *v, uint32_t asid, hwaddr iova,
+ hwaddr size);
#endif
diff --git a/include/standard-headers/linux/vhost_types.h b/include/standard-headers/linux/vhost_types.h
index 0bd2684a2a..fa267e39d4 100644
--- a/include/standard-headers/linux/vhost_types.h
+++ b/include/standard-headers/linux/vhost_types.h
@@ -87,7 +87,7 @@ struct vhost_msg {
struct vhost_msg_v2 {
uint32_t type;
- uint32_t reserved;
+ uint32_t asid;
union {
struct vhost_iotlb_msg iotlb;
uint8_t padding[64];
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index e250d34462..cb1cc2523d 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -266,7 +266,7 @@ static void vhost_vdpa_cvq_unmap_buf(struct vhost_vdpa *v, void *addr)
return;
}
- r = vhost_vdpa_dma_unmap(v, map->iova, map->size + 1);
+ r = vhost_vdpa_dma_unmap(v, v->address_space_id, map->iova, map->size + 1);
if (unlikely(r != 0)) {
error_report("Device cannot unmap: %s(%d)", g_strerror(r), r);
}
@@ -306,8 +306,8 @@ static int vhost_vdpa_cvq_map_buf(struct vhost_vdpa *v, void *buf, size_t size,
return r;
}
- r = vhost_vdpa_dma_map(v, map.iova, vhost_vdpa_net_cvq_cmd_page_len(), buf,
- !write);
+ r = vhost_vdpa_dma_map(v, v->address_space_id, map.iova,
+ vhost_vdpa_net_cvq_cmd_page_len(), buf, !write);
if (unlikely(r < 0)) {
goto dma_map_err;
}
--
2.27.0

View File

@ -0,0 +1,53 @@
From a5717856457e72575a32dfc8e28ec6ba6dcf6d59 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Tue, 23 Aug 2022 20:30:32 +0200
Subject: [PATCH] vdpa: add net_vhost_vdpa_cvq_info NetClientInfo
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Next patches will add a new info callback to restore NIC status through
CVQ. Since only the CVQ vhost device is needed, create it with a new
NetClientInfo.
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
net/vhost-vdpa.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index 8cfd086639..04cb08d418 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -342,6 +342,16 @@ static bool vhost_vdpa_net_cvq_map_elem(VhostVDPAState *s,
return true;
}
+static NetClientInfo net_vhost_vdpa_cvq_info = {
+ .type = NET_CLIENT_DRIVER_VHOST_VDPA,
+ .size = sizeof(VhostVDPAState),
+ .receive = vhost_vdpa_receive,
+ .cleanup = vhost_vdpa_cleanup,
+ .has_vnet_hdr = vhost_vdpa_has_vnet_hdr,
+ .has_ufo = vhost_vdpa_has_ufo,
+ .check_peer_type = vhost_vdpa_check_peer_type,
+};
+
/**
* Do not forward commands not supported by SVQ. Otherwise, the device could
* accept it and qemu would not know how to update the device model.
@@ -483,7 +493,7 @@ static NetClientState *net_vhost_vdpa_init(NetClientState *peer,
nc = qemu_new_net_client(&net_vhost_vdpa_info, peer, device,
name);
} else {
- nc = qemu_new_net_control_client(&net_vhost_vdpa_info, peer,
+ nc = qemu_new_net_control_client(&net_vhost_vdpa_cvq_info, peer,
device, name);
}
snprintf(nc->info_str, sizeof(nc->info_str), TYPE_VHOST_VDPA);
--
2.27.0

View File

@ -0,0 +1,86 @@
From e64b1a8253b9161e16b0a7f6c3beb77fb854660d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Thu, 15 Dec 2022 12:31:43 +0100
Subject: [PATCH] vdpa: add shadow_data to vhost_vdpa
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The memory listener that thells the device how to convert GPA to qemu's
va is registered against CVQ vhost_vdpa. memory listener translations
are always ASID 0, CVQ ones are ASID 1 if supported.
Let's tell the listener if it needs to register them on iova tree or
not.
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Message-Id: <20221215113144.322011-12-eperezma@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
hw/virtio/vhost-vdpa.c | 6 +++---
include/hw/virtio/vhost-vdpa.h | 2 ++
net/vhost-vdpa.c | 1 +
3 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index f4a0878e34..6d0d85b733 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -226,7 +226,7 @@ static void vhost_vdpa_listener_region_add(MemoryListener *listener,
vaddr, section->readonly);
llsize = int128_sub(llend, int128_make64(iova));
- if (v->shadow_vqs_enabled) {
+ if (v->shadow_data) {
int r;
mem_region.translated_addr = (hwaddr)(uintptr_t)vaddr,
@@ -253,7 +253,7 @@ static void vhost_vdpa_listener_region_add(MemoryListener *listener,
return;
fail_map:
- if (v->shadow_vqs_enabled) {
+ if (v->shadow_data) {
vhost_iova_tree_remove(v->iova_tree, mem_region);
}
@@ -298,7 +298,7 @@ static void vhost_vdpa_listener_region_del(MemoryListener *listener,
llsize = int128_sub(llend, int128_make64(iova));
- if (v->shadow_vqs_enabled) {
+ if (v->shadow_data) {
const DMAMap *result;
const void *vaddr = memory_region_get_ram_ptr(section->mr) +
section->offset_within_region +
diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h
index e57dfa1fd1..45b969a311 100644
--- a/include/hw/virtio/vhost-vdpa.h
+++ b/include/hw/virtio/vhost-vdpa.h
@@ -40,6 +40,8 @@ typedef struct vhost_vdpa {
struct vhost_vdpa_iova_range iova_range;
uint64_t acked_features;
bool shadow_vqs_enabled;
+ /* Vdpa must send shadow addresses as IOTLB key for data queues, not GPA */
+ bool shadow_data;
/* IOVA mapping used by the Shadow Virtqueue */
VhostIOVATree *iova_tree;
GPtrArray *shadow_vqs;
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index 7adba2c2b6..21fb89bb6b 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -580,6 +580,7 @@ static NetClientState *net_vhost_vdpa_init(NetClientState *peer,
s->always_svq = svq;
s->vhost_vdpa.shadow_vqs_enabled = svq;
s->vhost_vdpa.iova_range = iova_range;
+ s->vhost_vdpa.shadow_data = svq;
s->vhost_vdpa.iova_tree = iova_tree;
if (!is_datapath) {
s->cvq_cmd_out_buffer = qemu_memalign(qemu_real_host_page_size,
--
2.27.0

View File

@ -0,0 +1,68 @@
From 9cd4a76f615cea230ffc33d5b3666f84216f694b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Thu, 15 Dec 2022 12:31:37 +0100
Subject: [PATCH] vdpa: add vhost_vdpa_net_valid_svq_features
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
It will be reused at vdpa device start so let's extract in its own
function.
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Message-Id: <20221215113144.322011-6-eperezma@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
net/vhost-vdpa.c | 26 +++++++++++++++++---------
1 file changed, 17 insertions(+), 9 deletions(-)
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index eae2ed364f..217d2545c1 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -105,6 +105,22 @@ VHostNetState *vhost_vdpa_get_vhost_net(NetClientState *nc)
return s->vhost_net;
}
+static bool vhost_vdpa_net_valid_svq_features(uint64_t features, Error **errp)
+{
+ uint64_t invalid_dev_features =
+ features & ~vdpa_svq_device_features &
+ /* Transport are all accepted at this point */
+ ~MAKE_64BIT_MASK(VIRTIO_TRANSPORT_F_START,
+ VIRTIO_TRANSPORT_F_END - VIRTIO_TRANSPORT_F_START);
+
+ if (invalid_dev_features) {
+ error_setg(errp, "vdpa svq does not work with features 0x%" PRIx64,
+ invalid_dev_features);
+ }
+
+ return !invalid_dev_features;
+}
+
static int vhost_vdpa_net_check_device_id(struct vhost_net *net)
{
uint32_t device_id;
@@ -683,15 +699,7 @@ int net_init_vhost_vdpa(const Netdev *netdev, const char *name,
if (opts->x_svq) {
struct vhost_vdpa_iova_range iova_range;
- uint64_t invalid_dev_features =
- features & ~vdpa_svq_device_features &
- /* Transport are all accepted at this point */
- ~MAKE_64BIT_MASK(VIRTIO_TRANSPORT_F_START,
- VIRTIO_TRANSPORT_F_END - VIRTIO_TRANSPORT_F_START);
-
- if (invalid_dev_features) {
- error_setg(errp, "vdpa svq does not work with features 0x%" PRIx64,
- invalid_dev_features);
+ if (!vhost_vdpa_net_valid_svq_features(features, errp)) {
goto err_svq;
}
--
2.27.0

View File

@ -0,0 +1,42 @@
From fea179d880cd502f291cc6079b565bc059612d48 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Thu, 15 Dec 2022 12:31:40 +0100
Subject: [PATCH] vdpa: allocate SVQ array unconditionally
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
SVQ may run or not in a device depending on runtime conditions (for
example, if the device can move CVQ to its own group or not).
Allocate the SVQ array unconditionally at startup, since its hard to
move this allocation elsewhere.
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Message-Id: <20221215113144.322011-9-eperezma@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
hw/virtio/vhost-vdpa.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index 59bfdbfc24..450b5effd2 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -535,10 +535,6 @@ static void vhost_vdpa_svq_cleanup(struct vhost_dev *dev)
struct vhost_vdpa *v = dev->opaque;
size_t idx;
- if (!v->shadow_vqs) {
- return;
- }
-
for (idx = 0; idx < v->shadow_vqs->len; ++idx) {
vhost_svq_stop(g_ptr_array_index(v->shadow_vqs, idx));
}
--
2.27.0

View File

@ -0,0 +1,224 @@
From e2e9aeaacdb28b6c2a1bfcfef09113dc9b26a420 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Thu, 15 Dec 2022 12:31:44 +0100
Subject: [PATCH] vdpa: always start CVQ in SVQ mode if possible
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Isolate control virtqueue in its own group, allowing to intercept control
commands but letting dataplane run totally passthrough to the guest.
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Message-Id: <20221215113144.322011-13-eperezma@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
hw/virtio/vhost-vdpa.c | 3 +-
include/standard-headers/linux/vhost_types.h | 5 +
linux-headers/linux/vhost.h | 14 +++
net/vhost-vdpa.c | 110 ++++++++++++++++++-
4 files changed, 130 insertions(+), 2 deletions(-)
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index 6d0d85b733..8b44f5a7b8 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -641,7 +641,8 @@ static int vhost_vdpa_set_backend_cap(struct vhost_dev *dev)
{
uint64_t features;
uint64_t f = 0x1ULL << VHOST_BACKEND_F_IOTLB_MSG_V2 |
- 0x1ULL << VHOST_BACKEND_F_IOTLB_BATCH;
+ 0x1ULL << VHOST_BACKEND_F_IOTLB_BATCH |
+ 0x1ULL << VHOST_BACKEND_F_IOTLB_ASID;
int r;
if (vhost_vdpa_call(dev, VHOST_GET_BACKEND_FEATURES, &features)) {
diff --git a/include/standard-headers/linux/vhost_types.h b/include/standard-headers/linux/vhost_types.h
index fa267e39d4..17833e320e 100644
--- a/include/standard-headers/linux/vhost_types.h
+++ b/include/standard-headers/linux/vhost_types.h
@@ -153,4 +153,9 @@ struct vhost_vdpa_iova_range {
/* vhost-net should add virtio_net_hdr for RX, and strip for TX packets. */
#define VHOST_NET_F_VIRTIO_NET_HDR 27
+/* IOTLB can accept address space identifier through V2 type of IOTLB
+ * message
+ */
+#define VHOST_BACKEND_F_IOTLB_ASID 0x3
+
#endif
diff --git a/linux-headers/linux/vhost.h b/linux-headers/linux/vhost.h
index 5d99e7c242..b6ded7f831 100644
--- a/linux-headers/linux/vhost.h
+++ b/linux-headers/linux/vhost.h
@@ -157,4 +157,18 @@
/* Get the count of all virtqueues */
#define VHOST_VDPA_GET_VQS_COUNT _IOR(VHOST_VIRTIO, 0x80, __u32)
+/* Get the group for a virtqueue: read index, write group in num,
+ * The virtqueue index is stored in the index field of
+ * vhost_vring_state. The group for this specific virtqueue is
+ * returned via num field of vhost_vring_state.
+ */
+#define VHOST_VDPA_GET_VRING_GROUP _IOWR(VHOST_VIRTIO, 0x7B, \
+ struct vhost_vring_state)
+/* Set the ASID for a virtqueue group. The group index is stored in
+ * the index field of vhost_vring_state, the ASID associated with this
+ * group is stored at num field of vhost_vring_state.
+ */
+#define VHOST_VDPA_SET_GROUP_ASID _IOW(VHOST_VIRTIO, 0x7C, \
+ struct vhost_vring_state)
+
#endif
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index 21fb89bb6b..24c4c2ef51 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -100,6 +100,8 @@ static const uint64_t vdpa_svq_device_features =
BIT_ULL(VIRTIO_NET_F_RSC_EXT) |
BIT_ULL(VIRTIO_NET_F_STANDBY);
+#define VHOST_VDPA_NET_CVQ_ASID 1
+
VHostNetState *vhost_vdpa_get_vhost_net(NetClientState *nc)
{
VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
@@ -250,6 +252,40 @@ static NetClientInfo net_vhost_vdpa_info = {
.check_peer_type = vhost_vdpa_check_peer_type,
};
+static int64_t vhost_vdpa_get_vring_group(int device_fd, unsigned vq_index)
+{
+ struct vhost_vring_state state = {
+ .index = vq_index,
+ };
+ int r = ioctl(device_fd, VHOST_VDPA_GET_VRING_GROUP, &state);
+
+ if (unlikely(r < 0)) {
+ error_report("Cannot get VQ %u group: %s", vq_index,
+ g_strerror(errno));
+ return r;
+ }
+
+ return state.num;
+}
+
+static int vhost_vdpa_set_address_space_id(struct vhost_vdpa *v,
+ unsigned vq_group,
+ unsigned asid_num)
+{
+ struct vhost_vring_state asid = {
+ .index = vq_group,
+ .num = asid_num,
+ };
+ int r;
+
+ r = ioctl(v->device_fd, VHOST_VDPA_SET_GROUP_ASID, &asid);
+ if (unlikely(r < 0)) {
+ error_report("Can't set vq group %u asid %u, errno=%d (%s)",
+ asid.index, asid.num, errno, g_strerror(errno));
+ }
+ return r;
+}
+
static void vhost_vdpa_cvq_unmap_buf(struct vhost_vdpa *v, void *addr)
{
VhostIOVATree *tree = v->iova_tree;
@@ -324,11 +360,75 @@ dma_map_err:
static int vhost_vdpa_net_cvq_start(NetClientState *nc)
{
VhostVDPAState *s;
- int r;
+ struct vhost_vdpa *v;
+ uint64_t backend_features;
+ int64_t cvq_group;
+ int cvq_index, r;
assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);
s = DO_UPCAST(VhostVDPAState, nc, nc);
+ v = &s->vhost_vdpa;
+
+ v->shadow_data = s->always_svq;
+ v->shadow_vqs_enabled = s->always_svq;
+ s->vhost_vdpa.address_space_id = VHOST_VDPA_GUEST_PA_ASID;
+
+ if (s->always_svq) {
+ /* SVQ is already configured for all virtqueues */
+ goto out;
+ }
+
+ /*
+ * If we early return in these cases SVQ will not be enabled. The migration
+ * will be blocked as long as vhost-vdpa backends will not offer _F_LOG.
+ *
+ * Calling VHOST_GET_BACKEND_FEATURES as they are not available in v->dev
+ * yet.
+ */
+ r = ioctl(v->device_fd, VHOST_GET_BACKEND_FEATURES, &backend_features);
+ if (unlikely(r < 0)) {
+ error_report("Cannot get vdpa backend_features: %s(%d)",
+ g_strerror(errno), errno);
+ return -1;
+ }
+ if (!(backend_features & VHOST_BACKEND_F_IOTLB_ASID) ||
+ !vhost_vdpa_net_valid_svq_features(v->dev->features, NULL)) {
+ return 0;
+ }
+
+ /*
+ * Check if all the virtqueues of the virtio device are in a different vq
+ * than the last vq. VQ group of last group passed in cvq_group.
+ */
+ cvq_index = v->dev->vq_index_end - 1;
+ cvq_group = vhost_vdpa_get_vring_group(v->device_fd, cvq_index);
+ if (unlikely(cvq_group < 0)) {
+ return cvq_group;
+ }
+ for (int i = 0; i < cvq_index; ++i) {
+ int64_t group = vhost_vdpa_get_vring_group(v->device_fd, i);
+
+ if (unlikely(group < 0)) {
+ return group;
+ }
+
+ if (group == cvq_group) {
+ return 0;
+ }
+ }
+
+ r = vhost_vdpa_set_address_space_id(v, cvq_group, VHOST_VDPA_NET_CVQ_ASID);
+ if (unlikely(r < 0)) {
+ return r;
+ }
+
+ v->iova_tree = vhost_iova_tree_new(v->iova_range.first,
+ v->iova_range.last);
+ v->shadow_vqs_enabled = true;
+ s->vhost_vdpa.address_space_id = VHOST_VDPA_NET_CVQ_ASID;
+
+out:
if (!s->vhost_vdpa.shadow_vqs_enabled) {
return 0;
}
@@ -357,6 +457,14 @@ static void vhost_vdpa_net_cvq_stop(NetClientState *nc)
if (s->vhost_vdpa.shadow_vqs_enabled) {
vhost_vdpa_cvq_unmap_buf(&s->vhost_vdpa, s->cvq_cmd_out_buffer);
vhost_vdpa_cvq_unmap_buf(&s->vhost_vdpa, s->status);
+ if (!s->always_svq) {
+ /*
+ * If only the CVQ is shadowed we can delete this safely.
+ * If all the VQs are shadows this will be needed by the time the
+ * device is started again to register SVQ vrings and similar.
+ */
+ g_clear_pointer(&s->vhost_vdpa.iova_tree, vhost_iova_tree_delete);
+ }
}
}
--
2.27.0

View File

@ -0,0 +1,79 @@
From aa9c65215f37fc54a280ce89a2cbfd6235e8ec9f Mon Sep 17 00:00:00 2001
From: Longpeng <longpeng2@huawei.com>
Date: Tue, 27 Dec 2022 15:20:15 +0800
Subject: [PATCH] vdpa: commit all host notifier MRs in a single MR transaction
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This allows the vhost-vdpa device to batch the setup of all its MRs of
host notifiers.
This significantly reduces the device starting time, e.g. the time spend
on setup the host notifier MRs reduce from 423ms to 32ms for a VM with
64 vCPUs and 3 vhost-vDPA generic devices (vdpa_sim_blk, 64vq per device).
Signed-off-by: Longpeng <longpeng2@huawei.com>
Message-Id: <20221227072015.3134-4-longpeng2@huawei.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
hw/virtio/vhost-vdpa.c | 25 +++++++++++++++++++------
1 file changed, 19 insertions(+), 6 deletions(-)
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index f93fac538c..2fd7af1c6b 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -522,9 +522,18 @@ static void vhost_vdpa_host_notifiers_uninit(struct vhost_dev *dev, int n)
{
int i;
+ /*
+ * Pack all the changes to the memory regions in a single
+ * transaction to avoid a few updating of the address space
+ * topology.
+ */
+ memory_region_transaction_begin();
+
for (i = dev->vq_index; i < dev->vq_index + n; i++) {
vhost_vdpa_host_notifier_uninit(dev, i);
}
+
+ memory_region_transaction_commit();
}
static void vhost_vdpa_host_notifiers_init(struct vhost_dev *dev)
@@ -537,17 +546,21 @@ static void vhost_vdpa_host_notifiers_init(struct vhost_dev *dev)
return;
}
+ /*
+ * Pack all the changes to the memory regions in a single
+ * transaction to avoid a few updating of the address space
+ * topology.
+ */
+ memory_region_transaction_begin();
+
for (i = dev->vq_index; i < dev->vq_index + dev->nvqs; i++) {
if (vhost_vdpa_host_notifier_init(dev, i)) {
- goto err;
+ vhost_vdpa_host_notifiers_uninit(dev, i - dev->vq_index);
+ break;
}
}
- return;
-
-err:
- vhost_vdpa_host_notifiers_uninit(dev, i - dev->vq_index);
- return;
+ memory_region_transaction_commit();
}
static void vhost_vdpa_svq_cleanup(struct vhost_dev *dev)
--
2.27.0

View File

@ -0,0 +1,104 @@
From f5d338d28758db5066f199c35d56e0953edcc5d9 Mon Sep 17 00:00:00 2001
From: Longpeng <longpeng2@huawei.com>
Date: Sat, 24 Dec 2022 19:48:47 +0800
Subject: [PATCH] vdpa-dev: get iova range explicitly
In commit a585fad26b ("vdpa: request iova_range only once") we remove
GET_IOVA_RANGE form vhost_vdpa_init, the generic vdpa device will start
without iova_range populated, so the device won't work. Let's call
GET_IOVA_RANGE ioctl explicitly.
Fixes: a585fad26b2e6ccc ("vdpa: request iova_range only once")
Signed-off-by: Longpeng <longpeng2@huawei.com>
Message-Id: <20221224114848.3062-2-longpeng2@huawei.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
hw/virtio/vdpa-dev.c | 9 +++++++++
hw/virtio/vhost-vdpa.c | 7 +++++++
include/hw/virtio/vhost-vdpa.h | 2 ++
net/vhost-vdpa.c | 8 --------
4 files changed, 18 insertions(+), 8 deletions(-)
diff --git a/hw/virtio/vdpa-dev.c b/hw/virtio/vdpa-dev.c
index 465b08c0e3..254a213117 100644
--- a/hw/virtio/vdpa-dev.c
+++ b/hw/virtio/vdpa-dev.c
@@ -53,6 +53,7 @@ static void vhost_vdpa_device_realize(DeviceState *dev, Error **errp)
{
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
VhostVdpaDevice *v = VHOST_VDPA_DEVICE(vdev);
+ struct vhost_vdpa_iova_range iova_range;
uint16_t max_queue_size;
struct vhost_virtqueue *vqs;
int i, ret;
@@ -108,6 +109,14 @@ static void vhost_vdpa_device_realize(DeviceState *dev, Error **errp)
v->dev.backend_features = 0;
v->started = false;
+ ret = vhost_vdpa_get_iova_range(v->vhostfd, &iova_range);
+ if (ret < 0) {
+ error_setg(errp, "vhost-vdpa-device: get iova range failed: %s",
+ strerror(-ret));
+ goto free_vqs;
+ }
+ v->vdpa.iova_range = iova_range;
+
ret = vhost_dev_init(&v->dev, &v->vdpa, VHOST_BACKEND_TYPE_VDPA, 0, NULL);
if (ret < 0) {
error_setg(errp, "vhost-vdpa-device: vhost initialization failed: %s",
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index c9289e2c01..f93fac538c 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -380,6 +380,13 @@ static int vhost_vdpa_add_status(struct vhost_dev *dev, uint8_t status)
return 0;
}
+int vhost_vdpa_get_iova_range(int fd, struct vhost_vdpa_iova_range *iova_range)
+{
+ int ret = ioctl(fd, VHOST_VDPA_GET_IOVA_RANGE, iova_range);
+
+ return ret < 0 ? -errno : 0;
+}
+
/*
* The use of this function is for requests that only need to be
* applied once. Typically such request occurs at the beginning
diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h
index 45b969a311..7997f09a8d 100644
--- a/include/hw/virtio/vhost-vdpa.h
+++ b/include/hw/virtio/vhost-vdpa.h
@@ -51,6 +51,8 @@ typedef struct vhost_vdpa {
VhostVDPAHostNotifier notifier[VIRTIO_QUEUE_MAX];
} VhostVDPA;
+int vhost_vdpa_get_iova_range(int fd, struct vhost_vdpa_iova_range *iova_range);
+
int vhost_vdpa_dma_map(struct vhost_vdpa *v, uint32_t asid, hwaddr iova,
hwaddr size, void *vaddr, bool readonly);
int vhost_vdpa_dma_unmap(struct vhost_vdpa *v, uint32_t asid, hwaddr iova,
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index 3dcf341722..3c370f2dc5 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -717,14 +717,6 @@ static NetClientState *net_vhost_vdpa_init(NetClientState *peer,
return nc;
}
-static int vhost_vdpa_get_iova_range(int fd,
- struct vhost_vdpa_iova_range *iova_range)
-{
- int ret = ioctl(fd, VHOST_VDPA_GET_IOVA_RANGE, iova_range);
-
- return ret < 0 ? -errno : 0;
-}
-
static int vhost_vdpa_get_features(int fd, uint64_t *features, Error **errp)
{
int ret = ioctl(fd, VHOST_GET_FEATURES, features);
--
2.27.0

View File

@ -0,0 +1,52 @@
From 5bd89df7b5c1448f22f37a918569d0367458591b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Fri, 2 Jun 2023 16:38:52 +0200
Subject: [PATCH] vdpa: do not block migration if device has cvq and x-svq=on
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
It was a mistake to forbid in all cases, as SVQ is already able to send
all the CVQ messages before start forwarding data vqs. It actually
caused a regression, making impossible to migrate device previously
migratable.
Fixes: 36e4647247f2 ("vdpa: add vhost_vdpa_net_valid_svq_features")
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Message-Id: <20230602143854.1879091-2-eperezma@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Tested-by: Lei Yang <leiyang@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
net/vhost-vdpa.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index dc1b4c4be2..cdc54a7b54 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -723,13 +723,16 @@ static NetClientState *net_vhost_vdpa_init(NetClientState *peer,
s->vhost_vdpa.shadow_vq_ops_opaque = s;
/*
- * TODO: We cannot migrate devices with CVQ as there is no way to set
- * the device state (MAC, MQ, etc) before starting the datapath.
+ * TODO: We cannot migrate devices with CVQ and no x-svq enabled as
+ * there is no way to set the device state (MAC, MQ, etc) before
+ * starting the datapath.
*
* Migration blocker ownership now belongs to s->vhost_vdpa.
*/
- error_setg(&s->vhost_vdpa.migration_blocker,
- "net vdpa cannot migrate with CVQ feature");
+ if (!svq) {
+ error_setg(&s->vhost_vdpa.migration_blocker,
+ "net vdpa cannot migrate with CVQ feature");
+ }
}
ret = vhost_vdpa_add(nc, (void *)&s->vhost_vdpa, queue_pair_index, nvqs);
if (ret) {
--
2.27.0

View File

@ -0,0 +1,35 @@
From 17cd7f504c47c532eae6b8ecfc21b0e5796e08da Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Wed, 21 Dec 2022 12:50:15 +0100
Subject: [PATCH] vdpa: do not handle VIRTIO_NET_F_GUEST_ANNOUNCE in vhost-vdpa
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
So qemu emulates it even in case the device does not support it.
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Message-Id: <20221221115015.1400889-5-eperezma@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
net/vhost-vdpa.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index 48dd9d15f6..3dcf341722 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -72,7 +72,6 @@ const int vdpa_feature_bits[] = {
VIRTIO_F_RING_PACKED,
VIRTIO_NET_F_RSS,
VIRTIO_NET_F_HASH_REPORT,
- VIRTIO_NET_F_GUEST_ANNOUNCE,
VIRTIO_NET_F_STATUS,
VHOST_INVALID_FEATURE_BIT
};
--
2.27.0

View File

@ -0,0 +1,74 @@
From 556aa09e618b0fb40f038b11eafc69750c71f26e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Tue, 23 Aug 2022 20:20:03 +0200
Subject: [PATCH] vdpa: do not save failed dma maps in SVQ iova tree
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
If a map fails for whatever reason, it must not be saved in the tree.
Otherwise, qemu will try to unmap it in cleanup, leaving to more errors.
Fixes: 34e3c94eda ("vdpa: Add custom IOTLB translations to SVQ")
Reported-by: Lei Yang <leiyang@redhat.com>
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
hw/virtio/vhost-vdpa.c | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index c551665f5d..02dab41c42 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -178,6 +178,7 @@ static void vhost_vdpa_listener_commit(MemoryListener *listener)
static void vhost_vdpa_listener_region_add(MemoryListener *listener,
MemoryRegionSection *section)
{
+ DMAMap mem_region = {};
struct vhost_vdpa *v = container_of(listener, struct vhost_vdpa, listener);
hwaddr iova;
Int128 llend, llsize;
@@ -214,13 +215,13 @@ static void vhost_vdpa_listener_region_add(MemoryListener *listener,
llsize = int128_sub(llend, int128_make64(iova));
if (v->shadow_vqs_enabled) {
- DMAMap mem_region = {
- .translated_addr = (hwaddr)(uintptr_t)vaddr,
- .size = int128_get64(llsize) - 1,
- .perm = IOMMU_ACCESS_FLAG(true, section->readonly),
- };
+ int r;
- int r = vhost_iova_tree_map_alloc(v->iova_tree, &mem_region);
+ mem_region.translated_addr = (hwaddr)(uintptr_t)vaddr,
+ mem_region.size = int128_get64(llsize) - 1,
+ mem_region.perm = IOMMU_ACCESS_FLAG(true, section->readonly),
+
+ r = vhost_iova_tree_map_alloc(v->iova_tree, &mem_region);
if (unlikely(r != IOVA_OK)) {
error_report("Can't allocate a mapping (%d)", r);
goto fail;
@@ -234,11 +235,16 @@ static void vhost_vdpa_listener_region_add(MemoryListener *listener,
vaddr, section->readonly);
if (ret) {
error_report("vhost vdpa map fail!");
- goto fail;
+ goto fail_map;
}
return;
+fail_map:
+ if (v->shadow_vqs_enabled) {
+ vhost_iova_tree_remove(v->iova_tree, &mem_region);
+ }
+
fail:
/*
* On the initfn path, store the first error in the container so we
--
2.27.0

View File

@ -0,0 +1,144 @@
From af761da9860bd79bd9d214c15d2d30010e73aafa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Tue, 23 Aug 2022 20:30:34 +0200
Subject: [PATCH] vdpa: extract vhost_vdpa_net_cvq_add from
vhost_vdpa_net_handle_ctrl_avail
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
So we can reuse it to inject state messages.
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
--
v7:
* Remove double free error
v6:
* Do not assume in buffer sent to the device is sizeof(virtio_net_ctrl_ack)
v5:
* Do not use an artificial !NULL VirtQueueElement
* Use only out size instead of iovec dev_buffers for these functions.
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
net/vhost-vdpa.c | 59 +++++++++++++++++++++++++++++++-----------------
1 file changed, 38 insertions(+), 21 deletions(-)
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index 882f5ee89c..b24e0919d0 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -339,6 +339,38 @@ static void vhost_vdpa_net_cvq_stop(NetClientState *nc)
}
}
+static ssize_t vhost_vdpa_net_cvq_add(VhostVDPAState *s, size_t out_len,
+ size_t in_len)
+{
+ /* Buffers for the device */
+ const struct iovec out = {
+ .iov_base = s->cvq_cmd_out_buffer,
+ .iov_len = out_len,
+ };
+ const struct iovec in = {
+ .iov_base = s->cvq_cmd_in_buffer,
+ .iov_len = sizeof(virtio_net_ctrl_ack),
+ };
+ VhostShadowVirtqueue *svq = g_ptr_array_index(s->vhost_vdpa.shadow_vqs, 0);
+ int r;
+
+ r = vhost_svq_add(svq, &out, 1, &in, 1, NULL);
+ if (unlikely(r != 0)) {
+ if (unlikely(r == -ENOSPC)) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No space on device queue\n",
+ __func__);
+ }
+ return r;
+ }
+
+ /*
+ * We can poll here since we've had BQL from the time we sent the
+ * descriptor. Also, we need to take the answer before SVQ pulls by itself,
+ * when BQL is released
+ */
+ return vhost_svq_poll(svq);
+}
+
static NetClientInfo net_vhost_vdpa_cvq_info = {
.type = NET_CLIENT_DRIVER_VHOST_VDPA,
.size = sizeof(VhostVDPAState),
@@ -395,23 +427,18 @@ static int vhost_vdpa_net_handle_ctrl_avail(VhostShadowVirtqueue *svq,
void *opaque)
{
VhostVDPAState *s = opaque;
- size_t in_len, dev_written;
+ size_t in_len;
virtio_net_ctrl_ack status = VIRTIO_NET_ERR;
/* Out buffer sent to both the vdpa device and the device model */
struct iovec out = {
.iov_base = s->cvq_cmd_out_buffer,
};
- /* In buffer sent to the device */
- const struct iovec dev_in = {
- .iov_base = s->cvq_cmd_in_buffer,
- .iov_len = sizeof(virtio_net_ctrl_ack),
- };
/* in buffer used for device model */
const struct iovec in = {
.iov_base = &status,
.iov_len = sizeof(status),
};
- int r = -EINVAL;
+ ssize_t dev_written = -EINVAL;
bool ok;
out.iov_len = iov_to_buf(elem->out_sg, elem->out_num, 0,
@@ -422,21 +449,11 @@ static int vhost_vdpa_net_handle_ctrl_avail(VhostShadowVirtqueue *svq,
goto out;
}
- r = vhost_svq_add(svq, &out, 1, &dev_in, 1, elem);
- if (unlikely(r != 0)) {
- if (unlikely(r == -ENOSPC)) {
- qemu_log_mask(LOG_GUEST_ERROR, "%s: No space on device queue\n",
- __func__);
- }
+ dev_written = vhost_vdpa_net_cvq_add(s, out.iov_len, sizeof(status));
+ if (unlikely(dev_written < 0)) {
goto out;
}
- /*
- * We can poll here since we've had BQL from the time we sent the
- * descriptor. Also, we need to take the answer before SVQ pulls by itself,
- * when BQL is released
- */
- dev_written = vhost_svq_poll(svq);
if (unlikely(dev_written < sizeof(status))) {
error_report("Insufficient written data (%zu)", dev_written);
goto out;
@@ -444,7 +461,7 @@ static int vhost_vdpa_net_handle_ctrl_avail(VhostShadowVirtqueue *svq,
memcpy(&status, s->cvq_cmd_in_buffer, sizeof(status));
if (status != VIRTIO_NET_OK) {
- goto out;
+ return VIRTIO_NET_ERR;
}
status = VIRTIO_NET_ERR;
@@ -461,7 +478,7 @@ out:
}
vhost_svq_push_elem(svq, elem, MIN(in_len, sizeof(status)));
g_free(elem);
- return r;
+ return dev_written < 0 ? dev_written : 0;
}
static const VhostShadowVirtqueueOps vhost_vdpa_net_svq_ops = {
--
2.27.0

View File

@ -0,0 +1,106 @@
From 2038b0811acd3255d315354c8468bc565a51a4af Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Tue, 6 Sep 2022 17:07:15 +0200
Subject: [PATCH] vdpa: extract vhost_vdpa_net_load_mac from
vhost_vdpa_net_load
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Since there may be many commands we need to issue to load the NIC
state, let's split them in individual functions
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
net/vhost-vdpa.c | 62 +++++++++++++++++++++++++++++++-----------------
1 file changed, 40 insertions(+), 22 deletions(-)
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index 2700ef656f..15cd38b52e 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -373,12 +373,47 @@ static ssize_t vhost_vdpa_net_cvq_add(VhostVDPAState *s, size_t out_len,
return vhost_svq_poll(svq);
}
+static ssize_t vhost_vdpa_net_load_cmd(VhostVDPAState *s, uint8_t class,
+ uint8_t cmd, const void *data,
+ size_t data_size)
+{
+ const struct virtio_net_ctrl_hdr ctrl = {
+ .class = class,
+ .cmd = cmd,
+ };
+
+ assert(data_size < vhost_vdpa_net_cvq_cmd_page_len() - sizeof(ctrl));
+
+ memcpy(s->cvq_cmd_out_buffer, &ctrl, sizeof(ctrl));
+ memcpy(s->cvq_cmd_out_buffer + sizeof(ctrl), data, data_size);
+
+ return vhost_vdpa_net_cvq_add(s, sizeof(ctrl) + data_size,
+ sizeof(virtio_net_ctrl_ack));
+}
+
+static int vhost_vdpa_net_load_mac(VhostVDPAState *s, const VirtIONet *n)
+{
+ uint64_t features = n->parent_obj.guest_features;
+ if (features & BIT_ULL(VIRTIO_NET_F_CTRL_MAC_ADDR)) {
+ ssize_t dev_written = vhost_vdpa_net_load_cmd(s, VIRTIO_NET_CTRL_MAC,
+ VIRTIO_NET_CTRL_MAC_ADDR_SET,
+ n->mac, sizeof(n->mac));
+ if (unlikely(dev_written < 0)) {
+ return dev_written;
+ }
+
+ return *s->status != VIRTIO_NET_OK;
+ }
+
+ return 0;
+}
+
static int vhost_vdpa_net_load(NetClientState *nc)
{
VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
- const struct vhost_vdpa *v = &s->vhost_vdpa;
+ struct vhost_vdpa *v = &s->vhost_vdpa;
const VirtIONet *n;
- uint64_t features;
+ int r;
assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);
@@ -387,26 +422,9 @@ static int vhost_vdpa_net_load(NetClientState *nc)
}
n = VIRTIO_NET(v->dev->vdev);
- features = n->parent_obj.guest_features;
- if (features & BIT_ULL(VIRTIO_NET_F_CTRL_MAC_ADDR)) {
- const struct virtio_net_ctrl_hdr ctrl = {
- .class = VIRTIO_NET_CTRL_MAC,
- .cmd = VIRTIO_NET_CTRL_MAC_ADDR_SET,
- };
- char *cursor = s->cvq_cmd_out_buffer;
- ssize_t dev_written;
-
- memcpy(cursor, &ctrl, sizeof(ctrl));
- cursor += sizeof(ctrl);
- memcpy(cursor, n->mac, sizeof(n->mac));
-
- dev_written = vhost_vdpa_net_cvq_add(s, sizeof(ctrl) + sizeof(n->mac),
- sizeof(virtio_net_ctrl_ack));
- if (unlikely(dev_written < 0)) {
- return dev_written;
- }
-
- return *s->status != VIRTIO_NET_OK;
+ r = vhost_vdpa_net_load_mac(s, n);
+ if (unlikely(r < 0)) {
+ return r;
}
return 0;
--
2.27.0

View File

@ -0,0 +1,38 @@
From 404c9b2cb537a42be18a1b1aaf32df662ed951e0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Tue, 17 Jan 2023 11:53:08 +0100
Subject: [PATCH] vdpa: fix VHOST_BACKEND_F_IOTLB_ASID flag check
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
VHOST_BACKEND_F_IOTLB_ASID is the feature bit, not the bitmask. Since
the device under test also provided VHOST_BACKEND_F_IOTLB_MSG_V2 and
VHOST_BACKEND_F_IOTLB_BATCH, this went unnoticed.
Fixes: c1a1008685 ("vdpa: always start CVQ in SVQ mode if possible")
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
net/vhost-vdpa.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index cdc54a7b54..a1b931ae2c 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -391,7 +391,7 @@ static int vhost_vdpa_net_cvq_start(NetClientState *nc)
g_strerror(errno), errno);
return -1;
}
- if (!(backend_features & VHOST_BACKEND_F_IOTLB_ASID) ||
+ if (!(backend_features & BIT_ULL(VHOST_BACKEND_F_IOTLB_ASID)) ||
!vhost_vdpa_net_valid_svq_features(v->dev->features, NULL)) {
return 0;
}
--
2.27.0

View File

@ -0,0 +1,39 @@
From 5da8eddfa24d42a3ef60e111becafa29549e7100 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
Date: Fri, 2 Jun 2023 19:34:51 +0200
Subject: [PATCH] vdpa: fix not using CVQ buffer in case of error
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Bug introducing when refactoring. Otherway, the guest never received
the used buffer.
Fixes: be4278b65fc1 ("vdpa: extract vhost_vdpa_net_cvq_add from vhost_vdpa_net_handle_ctrl_avail")
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Message-Id: <20230602173451.1917999-1-eperezma@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Tested-by: Lei Yang <leiyang@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
net/vhost-vdpa.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index 94f74b54ae..afca8740bc 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -642,7 +642,7 @@ static int vhost_vdpa_net_handle_ctrl_avail(VhostShadowVirtqueue *svq,
}
if (*s->status != VIRTIO_NET_OK) {
- return VIRTIO_NET_ERR;
+ goto out;
}
status = VIRTIO_NET_ERR;
--
2.27.0

Some files were not shown because too many files have changed in this diff Show More