qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Michael S. Tsirkin" <mst@redhat.com>
To: qemu-devel@nongnu.org
Cc: Peter Maydell <peter.maydell@linaro.org>,
	"Dr. David Alan Gilbert" <dgilbert@redhat.com>,
	Igor Mammedov <imammedo@redhat.com>
Subject: [Qemu-devel] [PULL 05/26] vhost: Simplify ring verification checks
Date: Thu, 8 Feb 2018 21:09:02 +0200	[thread overview]
Message-ID: <1518116908-10852-6-git-send-email-mst@redhat.com> (raw)
In-Reply-To: <1518116908-10852-1-git-send-email-mst@redhat.com>

From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>

vhost_verify_ring_mappings() were used to verify that
rings are still accessible and related memory hasn't
been moved after flatview is updated.

It was doing checks by mapping ring's GPA+len and
checking that HVA hadn't changed with new memory map.
To avoid maybe expensive mapping call, we were
identifying address range that changed and were doing
mapping only if ring was in changed range.

However it's not neccessary to perform ring's GPA
mapping as we already have its current HVA and all
we need is to verify that ring's GPA translates to
the same HVA in updated flatview.

This will allow the following patches to simplify the range
comparison that was previously needed to avoid expensive
verify_ring_mapping calls.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
with modifications by:
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 hw/virtio/vhost.c | 79 +++++++++++++++++++++++++++++--------------------------
 1 file changed, 42 insertions(+), 37 deletions(-)

diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 92c9500..91cab51 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -455,35 +455,37 @@ static void vhost_memory_unmap(struct vhost_dev *dev, void *buffer,
     }
 }
 
-static int vhost_verify_ring_part_mapping(struct vhost_dev *dev,
-                                          void *part,
-                                          uint64_t part_addr,
-                                          uint64_t part_size,
-                                          uint64_t start_addr,
-                                          uint64_t size)
-{
-    hwaddr l;
-    void *p;
-    int r = 0;
-
-    if (!ranges_overlap(start_addr, size, part_addr, part_size)) {
+static int vhost_verify_ring_part_mapping(void *ring_hva,
+                                          uint64_t ring_gpa,
+                                          uint64_t ring_size,
+                                          void *reg_hva,
+                                          uint64_t reg_gpa,
+                                          uint64_t reg_size)
+{
+    uint64_t hva_ring_offset;
+    uint64_t ring_last = range_get_last(ring_gpa, ring_size);
+    uint64_t reg_last = range_get_last(reg_gpa, reg_size);
+
+    if (ring_last < reg_gpa || ring_gpa > reg_last) {
         return 0;
     }
-    l = part_size;
-    p = vhost_memory_map(dev, part_addr, &l, 1);
-    if (!p || l != part_size) {
-        r = -ENOMEM;
+    /* check that whole ring's is mapped */
+    if (ring_last > reg_last) {
+        return -ENOMEM;
     }
-    if (p != part) {
-        r = -EBUSY;
+    /* check that ring's MemoryRegion wasn't replaced */
+    hva_ring_offset = ring_gpa - reg_gpa;
+    if (ring_hva != reg_hva + hva_ring_offset) {
+        return -EBUSY;
     }
-    vhost_memory_unmap(dev, p, l, 0, 0);
-    return r;
+
+    return 0;
 }
 
 static int vhost_verify_ring_mappings(struct vhost_dev *dev,
-                                      uint64_t start_addr,
-                                      uint64_t size)
+                                      void *reg_hva,
+                                      uint64_t reg_gpa,
+                                      uint64_t reg_size)
 {
     int i, j;
     int r = 0;
@@ -497,22 +499,25 @@ static int vhost_verify_ring_mappings(struct vhost_dev *dev,
         struct vhost_virtqueue *vq = dev->vqs + i;
 
         j = 0;
-        r = vhost_verify_ring_part_mapping(dev, vq->desc, vq->desc_phys,
-                                           vq->desc_size, start_addr, size);
+        r = vhost_verify_ring_part_mapping(
+                vq->desc, vq->desc_phys, vq->desc_size,
+                reg_hva, reg_gpa, reg_size);
         if (r) {
             break;
         }
 
         j++;
-        r = vhost_verify_ring_part_mapping(dev, vq->avail, vq->avail_phys,
-                                           vq->avail_size, start_addr, size);
+        r = vhost_verify_ring_part_mapping(
+                vq->desc, vq->desc_phys, vq->desc_size,
+                reg_hva, reg_gpa, reg_size);
         if (r) {
             break;
         }
 
         j++;
-        r = vhost_verify_ring_part_mapping(dev, vq->used, vq->used_phys,
-                                           vq->used_size, start_addr, size);
+        r = vhost_verify_ring_part_mapping(
+                vq->desc, vq->desc_phys, vq->desc_size,
+                reg_hva, reg_gpa, reg_size);
         if (r) {
             break;
         }
@@ -635,13 +640,11 @@ static void vhost_commit(MemoryListener *listener)
 {
     struct vhost_dev *dev = container_of(listener, struct vhost_dev,
                                          memory_listener);
-    hwaddr start_addr = 0;
-    ram_addr_t size = 0;
     MemoryRegionSection *old_sections;
     int n_old_sections;
-
     uint64_t log_size;
     int r;
+    int i;
 
     old_sections = dev->mem_sections;
     n_old_sections = dev->n_mem_sections;
@@ -658,12 +661,14 @@ static void vhost_commit(MemoryListener *listener)
         goto out;
     }
 
-    if (dev->started) {
-        start_addr = dev->mem_changed_start_addr;
-        size = dev->mem_changed_end_addr - dev->mem_changed_start_addr + 1;
-
-        r = vhost_verify_ring_mappings(dev, start_addr, size);
-        assert(r >= 0);
+    for (i = 0; i < dev->mem->nregions; i++) {
+        if (vhost_verify_ring_mappings(dev,
+                       (void *)(uintptr_t)dev->mem->regions[i].userspace_addr,
+                       dev->mem->regions[i].guest_phys_addr,
+                       dev->mem->regions[i].memory_size)) {
+            error_report("Verify ring failure on region %d", i);
+            abort();
+        }
     }
 
     if (!dev->log_enabled) {
-- 
MST

  parent reply	other threads:[~2018-02-08 19:09 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-02-08 19:08 [Qemu-devel] [PULL 00/26] virtio, vhost, pci, pc: features, fixes and cleanups Michael S. Tsirkin
2018-02-08 19:08 ` [Qemu-devel] [PULL 02/26] virtio: remove event notifier cleanup call on de-assign Michael S. Tsirkin
2018-02-08 19:08 ` [Qemu-devel] [PULL 01/26] Revert "vhost: add traces for memory listeners" Michael S. Tsirkin
2018-02-08 19:09 ` [Qemu-devel] [PULL 04/26] vhost: Build temporary section list and deref after commit Michael S. Tsirkin
2018-02-08 19:09 ` [Qemu-devel] [PULL 06/26] vhost: Merge sections added to temporary list Michael S. Tsirkin
2018-02-08 19:09 ` Michael S. Tsirkin [this message]
2018-02-08 19:09 ` [Qemu-devel] [PULL 07/26] vhost: Regenerate region list from changed sections list Michael S. Tsirkin
2018-02-08 19:09 ` [Qemu-devel] [PULL 08/26] vhost: Clean out old vhost_set_memory and friends Michael S. Tsirkin
2018-02-08 19:09 ` [Qemu-devel] [PULL 09/26] vhost: Merge and delete unused callbacks Michael S. Tsirkin
2018-02-08 19:09 ` [Qemu-devel] [PULL 11/26] pci-bridge/i82801b11: clear bridge registers on platform reset Michael S. Tsirkin
2018-03-23 18:42   ` Laszlo Ersek
2018-04-05 21:32     ` Michael Roth
2018-02-08 19:09 ` [Qemu-devel] [PULL 10/26] vhost: Move log_dirty check Michael S. Tsirkin
2018-02-08 19:09 ` [Qemu-devel] [PULL 12/26] pci/bus: let it has higher migration priority Michael S. Tsirkin
2018-02-08 19:09 ` [Qemu-devel] [PULL 13/26] virtio-blk: enable multiple vectors when using multiple I/O queues Michael S. Tsirkin
2018-02-08 19:09 ` [Qemu-devel] [PULL 14/26] pci: removed the is_express field since a uniform interface was inserted Michael S. Tsirkin
2018-02-08 19:09 ` [Qemu-devel] [PULL 15/26] cryptodev: add vhost-user as a new cryptodev backend Michael S. Tsirkin
2018-02-13 16:54   ` Michael S. Tsirkin
2018-02-08 19:09 ` [Qemu-devel] [PULL 17/26] cryptodev-vhost-user: add crypto session handler Michael S. Tsirkin
2018-02-08 19:09 ` [Qemu-devel] [PULL 16/26] cryptodev: add vhost support Michael S. Tsirkin
2018-02-08 19:09 ` [Qemu-devel] [PULL 20/26] libvhost-user: Fix resource leak Michael S. Tsirkin
2018-02-08 19:09 ` [Qemu-devel] [PULL 19/26] virtio-balloon: unref the memory region before continuing Michael S. Tsirkin
2018-02-08 19:09 ` [Qemu-devel] [PULL 18/26] cryptodev-vhost-user: set the key length Michael S. Tsirkin
2018-02-08 19:09 ` [Qemu-devel] [PULL 21/26] libvhost-user: Support across-memory-boundary access Michael S. Tsirkin
2018-02-08 19:09 ` [Qemu-devel] [PULL 22/26] hw/pci-bridge: fix pcie root port's IO hints capability Michael S. Tsirkin
2018-02-08 19:09 ` [Qemu-devel] [PULL 23/26] tests: acpi: fix FADT not being compared to reference table Michael S. Tsirkin
2018-02-08 19:09 ` [Qemu-devel] [PULL 26/26] virtio-balloon: include statistics of disk/file caches Michael S. Tsirkin
2018-02-08 19:09 ` [Qemu-devel] [PULL 25/26] acpi-test: update FADT Michael S. Tsirkin
2018-02-08 19:09 ` [Qemu-devel] [PULL 24/26] lpc: drop pcie host dependency Michael S. Tsirkin
2018-02-08 19:11 ` [Qemu-devel] [PULL 03/26] virtio: improve virtio devices initialization time Michael S. Tsirkin
2018-02-09 10:06 ` [Qemu-devel] [PULL 00/26] virtio, vhost, pci, pc: features, fixes and cleanups Peter Maydell
2018-02-09 17:07   ` Michael S. Tsirkin
2018-02-12  9:35     ` Peter Maydell
2018-02-13 16:33       ` Peter Maydell
2018-02-13 16:52         ` Michael S. Tsirkin
2018-02-13 18:23           ` Peter Maydell
2018-02-14  2:21           ` Zhoujian (jay)
2018-02-10 11:26   ` Gonglei (Arei)

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1518116908-10852-6-git-send-email-mst@redhat.com \
    --to=mst@redhat.com \
    --cc=dgilbert@redhat.com \
    --cc=imammedo@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).