vhost: move svq next desc array to descs state struct
It's the right place for it as it is part of the descriptor state. We save the memory management of the array, and make the code changes of the next patches easier. 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: Michael S. Tsirkin <mst@redhat.com> Message-Id: <20260304173535.2702587-3-eperezma@redhat.com>
Eugenio Pérez committed
Mar 4, 2026 at 18:35 UTC
927d0beaad0ac6db96865a96fdad0c1a93b3477d
2 files changed
+12
-14
hw/virtio/vhost-shadow-virtqueue.c
+6
-8
@@ -175,7 +175,7 @@ static bool vhost_svq_vring_write_descs(VhostShadowVirtqueue *svq, hwaddr *sg,
175
for (n = 0; n < num; n++) {
176
if (more_descs || (n + 1 < num)) {
177
descs[i].flags = flags | cpu_to_le16(VRING_DESC_F_NEXT);
178
- descs[i].next = cpu_to_le16(svq->desc_next[i]);
178
+ descs[i].next = cpu_to_le16(svq->desc_state[i].next);
179
} else {
180
descs[i].flags = flags;
181
}
@@ -183,10 +183,10 @@ static bool vhost_svq_vring_write_descs(VhostShadowVirtqueue *svq, hwaddr *sg,
183
descs[i].len = cpu_to_le32(iovec[n].iov_len);
184
185
last = i;
186
- i = svq->desc_next[i];
186
+ i = svq->desc_state[i].next;
187
}
188
189
- svq->free_head = svq->desc_next[last];
189
+ svq->free_head = svq->desc_state[last].next;
190
return true;
191
}
192
@@ -432,7 +432,7 @@ static uint16_t vhost_svq_last_desc_of_chain(const VhostShadowVirtqueue *svq,
432
uint16_t num, uint16_t i)
433
{
434
for (uint16_t j = 0; j < (num - 1); ++j) {
435
- i = svq->desc_next[i];
435
+ i = svq->desc_state[i].next;
436
}
437
438
return i;
@@ -473,7 +473,7 @@ static VirtQueueElement *vhost_svq_get_buf(VhostShadowVirtqueue *svq,
473
num = svq->desc_state[used_elem.id].ndescs;
474
svq->desc_state[used_elem.id].ndescs = 0;
475
last_used_chain = vhost_svq_last_desc_of_chain(svq, num, used_elem.id);
476
- svq->desc_next[last_used_chain] = svq->free_head;
476
+ svq->desc_state[last_used_chain].next = svq->free_head;
477
svq->free_head = used_elem.id;
478
svq->num_free += num;
479
@@ -705,9 +705,8 @@ void vhost_svq_start(VhostShadowVirtqueue *svq, VirtIODevice *vdev,
705
PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS,
706
-1, 0);
707
svq->desc_state = g_new0(SVQDescState, svq->vring.num);
708
- svq->desc_next = g_new0(uint16_t, svq->vring.num);
708
for (unsigned i = 0; i < svq->vring.num - 1; i++) {
710
- svq->desc_next[i] = i + 1;
709
+ svq->desc_state[i].next = i + 1;
710
}
711
}
712
@@ -744,7 +743,6 @@ void vhost_svq_stop(VhostShadowVirtqueue *svq)
743
virtqueue_unpop(svq->vq, next_avail_elem, 0);
744
}
745
svq->vq = NULL;
747
- g_free(svq->desc_next);
746
g_free(svq->desc_state);
747
munmap(svq->vring.desc, vhost_svq_driver_area_size(svq));
748
munmap(svq->vring.used, vhost_svq_device_area_size(svq));
hw/virtio/vhost-shadow-virtqueue.h
+6
-6
@@ -23,6 +23,12 @@ typedef struct SVQDescState {
23
* guest's
24
*/
25
unsigned int ndescs;
26
+
27
+ /*
28
+ * Backup next field for each descriptor so we can recover securely, not
29
+ * needing to trust the device access.
30
+ */
31
+ uint16_t next;
32
} SVQDescState;
33
34
typedef struct VhostShadowVirtqueue VhostShadowVirtqueue;
@@ -84,12 +90,6 @@ typedef struct VhostShadowVirtqueue {
90
/* Next VirtQueue element that guest made available */
91
VirtQueueElement *next_guest_avail_elem;
92
87
- /*
88
- * Backup next field for each descriptor so we can recover securely, not
89
- * needing to trust the device access.
90
- */
91
- uint16_t *desc_next;
92
-
93
/* Caller callbacks */
94
const VhostShadowVirtqueueOps *ops;
95