thebeanogamer / rpms / qemu-kvm

Forked from rpms/qemu-kvm 5 months ago
Clone

Blame SOURCES/kvm-vhost-Track-descriptor-chain-in-private-at-SVQ.patch

29b115
From 486647551223cc01f4dba87197030bbf4e674f0f Mon Sep 17 00:00:00 2001
29b115
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
29b115
Date: Thu, 21 Jul 2022 15:24:48 +0200
29b115
Subject: [PATCH 01/32] vhost: Track descriptor chain in private at SVQ
29b115
MIME-Version: 1.0
29b115
Content-Type: text/plain; charset=UTF-8
29b115
Content-Transfer-Encoding: 8bit
29b115
29b115
RH-Author: Eugenio Pérez <eperezma@redhat.com>
29b115
RH-MergeRequest: 108: Net Control Virtqueue shadow Support
29b115
RH-Commit: [1/27] 26d16dc383e3064ac6e4288d5c52b39fee0ad204 (eperezmartin/qemu-kvm)
29b115
RH-Bugzilla: 1939363
29b115
RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
29b115
RH-Acked-by: Cindy Lu <lulu@redhat.com>
29b115
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
29b115
29b115
Bugzilla: https://bugzilla.redhat.com/1939363
29b115
29b115
Upstream Status: git://git.qemu.org/qemu.git
29b115
29b115
commit 495fe3a78749c39c0e772c4e1a55d6cb8a7e5292
29b115
Author: Eugenio Pérez <eperezma@redhat.com>
29b115
Date:   Thu May 12 19:57:42 2022 +0200
29b115
29b115
    vhost: Track descriptor chain in private at SVQ
29b115
29b115
    The device could have access to modify them, and it definitely have
29b115
    access when we implement packed vq. Harden SVQ maintaining a private
29b115
    copy of the descriptor chain. Other fields like buffer addresses are
29b115
    already maintained sepparatedly.
29b115
29b115
    Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
29b115
    Message-Id: <20220512175747.142058-2-eperezma@redhat.com>
29b115
    Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
29b115
    Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
29b115
29b115
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
29b115
---
29b115
 hw/virtio/vhost-shadow-virtqueue.c | 12 +++++++-----
29b115
 hw/virtio/vhost-shadow-virtqueue.h |  6 ++++++
29b115
 2 files changed, 13 insertions(+), 5 deletions(-)
29b115
29b115
diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c
29b115
index b232803d1b..3155801f50 100644
29b115
--- a/hw/virtio/vhost-shadow-virtqueue.c
29b115
+++ b/hw/virtio/vhost-shadow-virtqueue.c
29b115
@@ -138,6 +138,7 @@ static void vhost_vring_write_descs(VhostShadowVirtqueue *svq, hwaddr *sg,
29b115
     for (n = 0; n < num; n++) {
29b115
         if (more_descs || (n + 1 < num)) {
29b115
             descs[i].flags = flags | cpu_to_le16(VRING_DESC_F_NEXT);
29b115
+            descs[i].next = cpu_to_le16(svq->desc_next[i]);
29b115
         } else {
29b115
             descs[i].flags = flags;
29b115
         }
29b115
@@ -145,10 +146,10 @@ static void vhost_vring_write_descs(VhostShadowVirtqueue *svq, hwaddr *sg,
29b115
         descs[i].len = cpu_to_le32(iovec[n].iov_len);
29b115
 
29b115
         last = i;
29b115
-        i = cpu_to_le16(descs[i].next);
29b115
+        i = cpu_to_le16(svq->desc_next[i]);
29b115
     }
29b115
 
29b115
-    svq->free_head = le16_to_cpu(descs[last].next);
29b115
+    svq->free_head = le16_to_cpu(svq->desc_next[last]);
29b115
 }
29b115
 
29b115
 static bool vhost_svq_add_split(VhostShadowVirtqueue *svq,
29b115
@@ -336,7 +337,6 @@ static void vhost_svq_disable_notification(VhostShadowVirtqueue *svq)
29b115
 static VirtQueueElement *vhost_svq_get_buf(VhostShadowVirtqueue *svq,
29b115
                                            uint32_t *len)
29b115
 {
29b115
-    vring_desc_t *descs = svq->vring.desc;
29b115
     const vring_used_t *used = svq->vring.used;
29b115
     vring_used_elem_t used_elem;
29b115
     uint16_t last_used;
29b115
@@ -365,7 +365,7 @@ static VirtQueueElement *vhost_svq_get_buf(VhostShadowVirtqueue *svq,
29b115
         return NULL;
29b115
     }
29b115
 
29b115
-    descs[used_elem.id].next = svq->free_head;
29b115
+    svq->desc_next[used_elem.id] = svq->free_head;
29b115
     svq->free_head = used_elem.id;
29b115
 
29b115
     *len = used_elem.len;
29b115
@@ -540,8 +540,9 @@ void vhost_svq_start(VhostShadowVirtqueue *svq, VirtIODevice *vdev,
29b115
     svq->vring.used = qemu_memalign(qemu_real_host_page_size, device_size);
29b115
     memset(svq->vring.used, 0, device_size);
29b115
     svq->ring_id_maps = g_new0(VirtQueueElement *, svq->vring.num);
29b115
+    svq->desc_next = g_new0(uint16_t, svq->vring.num);
29b115
     for (unsigned i = 0; i < svq->vring.num - 1; i++) {
29b115
-        svq->vring.desc[i].next = cpu_to_le16(i + 1);
29b115
+        svq->desc_next[i] = cpu_to_le16(i + 1);
29b115
     }
29b115
 }
29b115
 
29b115
@@ -574,6 +575,7 @@ void vhost_svq_stop(VhostShadowVirtqueue *svq)
29b115
         virtqueue_detach_element(svq->vq, next_avail_elem, 0);
29b115
     }
29b115
     svq->vq = NULL;
29b115
+    g_free(svq->desc_next);
29b115
     g_free(svq->ring_id_maps);
29b115
     qemu_vfree(svq->vring.desc);
29b115
     qemu_vfree(svq->vring.used);
29b115
diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h
29b115
index e5e24c536d..c132c994e9 100644
29b115
--- a/hw/virtio/vhost-shadow-virtqueue.h
29b115
+++ b/hw/virtio/vhost-shadow-virtqueue.h
29b115
@@ -53,6 +53,12 @@ typedef struct VhostShadowVirtqueue {
29b115
     /* Next VirtQueue element that guest made available */
29b115
     VirtQueueElement *next_guest_avail_elem;
29b115
 
29b115
+    /*
29b115
+     * Backup next field for each descriptor so we can recover securely, not
29b115
+     * needing to trust the device access.
29b115
+     */
29b115
+    uint16_t *desc_next;
29b115
+
29b115
     /* Next head to expose to the device */
29b115
     uint16_t shadow_avail_idx;
29b115
 
29b115
-- 
29b115
2.31.1
29b115