From: "Dr. David Alan Gilbert (git)" <dgilbert@redhat.com>
To: qemu-devel@nongnu.org, mst@redhat.com, imammedo@redhat.com
Cc: maxime.coquelin@redhat.com
Subject: [Qemu-devel] [PATCH v6 2/7] vhost: Simplify ring verification checks
Date: Tue, 16 Jan 2018 18:04:03 +0000 [thread overview]
Message-ID: <20180116180408.11279-3-dgilbert@redhat.com> (raw)
In-Reply-To: <20180116180408.11279-1-dgilbert@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>
---
hw/virtio/vhost.c | 75 +++++++++++++++++++++++++++++--------------------------
1 file changed, 40 insertions(+), 35 deletions(-)
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 610bfe6945..999ce48259 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -449,35 +449,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)
+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)
{
- hwaddr l;
- void *p;
- int r = 0;
+ 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 (!ranges_overlap(start_addr, size, part_addr, part_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;
@@ -491,22 +493,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;
}
@@ -629,13 +634,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;
@@ -652,12 +655,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) {
--
2.14.3
next prev parent reply other threads:[~2018-01-16 18:06 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-01-16 18:04 [Qemu-devel] [PATCH v6 0/7] Rework vhost memory region updates Dr. David Alan Gilbert (git)
2018-01-16 18:04 ` [Qemu-devel] [PATCH v6 1/7] vhost: Build temporary section list and deref after commit Dr. David Alan Gilbert (git)
2018-01-16 18:04 ` Dr. David Alan Gilbert (git) [this message]
2018-01-16 18:04 ` [Qemu-devel] [PATCH v6 3/7] vhost: Merge sections added to temporary list Dr. David Alan Gilbert (git)
2018-01-16 18:04 ` [Qemu-devel] [PATCH v6 4/7] vhost: Regenerate region list from changed sections list Dr. David Alan Gilbert (git)
2018-01-16 18:04 ` [Qemu-devel] [PATCH v6 5/7] vhost: Clean out old vhost_set_memory and friends Dr. David Alan Gilbert (git)
2018-01-16 18:04 ` [Qemu-devel] [PATCH v6 6/7] vhost: Merge and delete unused callbacks Dr. David Alan Gilbert (git)
2018-01-16 18:04 ` [Qemu-devel] [PATCH v6 7/7] vhost: Move log_dirty check Dr. David Alan Gilbert (git)
2018-01-18 19:33 ` [Qemu-devel] [PATCH v6 0/7] Rework vhost memory region updates Michael S. Tsirkin
2018-01-18 19:59 ` Dr. David Alan Gilbert
2018-01-18 20:16 ` Michael S. Tsirkin
2018-01-19 10:41 ` Dr. David Alan Gilbert
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=20180116180408.11279-3-dgilbert@redhat.com \
--to=dgilbert@redhat.com \
--cc=imammedo@redhat.com \
--cc=maxime.coquelin@redhat.com \
--cc=mst@redhat.com \
--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).