[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL v2 22/34] vhost: Simplify ring verification checks
From: |
Michael S. Tsirkin |
Subject: |
[Qemu-devel] [PULL v2 22/34] vhost: Simplify ring verification checks |
Date: |
Tue, 16 Jan 2018 19:51:54 +0200 |
From: "Dr. David Alan Gilbert" <address@hidden>
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 <address@hidden>
with modifications by:
Signed-off-by: Dr. David Alan Gilbert <address@hidden>
Reviewed-by: Michael S. Tsirkin <address@hidden>
Signed-off-by: Michael S. Tsirkin <address@hidden>
Reviewed-by: Igor Mammedov <address@hidden>
---
hw/virtio/vhost.c | 79 ++++++++++++++++++++++++++++++-------------------------
1 file changed, 43 insertions(+), 36 deletions(-)
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 8a85dde..8fdd073 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)
-{
- 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;
@@ -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,16 @@ 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;
+ for (i = 0; i < dev->mem->nregions; i++) {
+ struct vhost_memory_region *reg = dev->mem->regions + i;
- r = vhost_verify_ring_mappings(dev, start_addr, size);
- assert(r >= 0);
+ if (vhost_verify_ring_mappings(dev,
+ (void *)(uintptr_t)reg->userspace_addr,
+ reg->guest_phys_addr,
+ reg->memory_size)) {
+ error_report("Verify ring failure on region %d", i);
+ abort();
+ }
}
if (!dev->log_enabled) {
--
MST
- [Qemu-devel] [PULL v2 11/34] intel-iommu: Redefine macros to enable supporting 48 bit address width, (continued)
- [Qemu-devel] [PULL v2 11/34] intel-iommu: Redefine macros to enable supporting 48 bit address width, Michael S. Tsirkin, 2018/01/16
- [Qemu-devel] [PULL v2 12/34] intel-iommu: Extend address width to 48 bits, Michael S. Tsirkin, 2018/01/16
- [Qemu-devel] [PULL v2 14/34] ACPI/unit-test: Add a testcase for RAM allocation in numa node, Michael S. Tsirkin, 2018/01/16
- [Qemu-devel] [PULL v2 13/34] hw/pci-bridge: fix QEMU crash because of pcie-root-port, Michael S. Tsirkin, 2018/01/16
- [Qemu-devel] [PULL v2 15/34] hw/acpi-build: Make next_base easy to follow, Michael S. Tsirkin, 2018/01/16
- [Qemu-devel] [PULL v2 16/34] vhost-user-test: fix features mask, Michael S. Tsirkin, 2018/01/16
- [Qemu-devel] [PULL v2 17/34] vhost-user-test: extract read-guest-mem test from main loop, Michael S. Tsirkin, 2018/01/16
- [Qemu-devel] [PULL v2 18/34] vhost-user-test: setup virtqueues in all tests, Michael S. Tsirkin, 2018/01/16
- [Qemu-devel] [PULL v2 19/34] vhost-user-test: make features mask an init_virtio_dev() argument, Michael S. Tsirkin, 2018/01/16
- [Qemu-devel] [PULL v2 20/34] vhost-user-test: use init_virtio_dev in multiqueue test, Michael S. Tsirkin, 2018/01/16
- [Qemu-devel] [PULL v2 22/34] vhost: Simplify ring verification checks,
Michael S. Tsirkin <=
- [Qemu-devel] [PULL v2 21/34] vhost: Build temporary section list and deref after commit, Michael S. Tsirkin, 2018/01/16
- [Qemu-devel] [PULL v2 23/34] vhost: Merge sections added to temporary list, Michael S. Tsirkin, 2018/01/16
- [Qemu-devel] [PULL v2 24/34] x86_iommu: Move machine check to x86_iommu_realize(), Michael S. Tsirkin, 2018/01/16
- [Qemu-devel] [PULL v2 25/34] x86_iommu: check if machine has PCI bus, Michael S. Tsirkin, 2018/01/16
- [Qemu-devel] [PULL v2 26/34] tests: acpi: move tested tables array allocation outside of test_acpi_dsdt_table(), Michael S. Tsirkin, 2018/01/16
- [Qemu-devel] [PULL v2 28/34] tests: acpi: rename test_acpi_tables()/test_dst_table() to reflect its usage, Michael S. Tsirkin, 2018/01/16
- [Qemu-devel] [PULL v2 27/34] tests: acpi: init table descriptor in test_dst_table(), Michael S. Tsirkin, 2018/01/16
- [Qemu-devel] [PULL v2 29/34] tests: acpi: add comments to fetch_rsdt_referenced_tables/data->tables usage, Michael S. Tsirkin, 2018/01/16
- [Qemu-devel] [PULL v2 30/34] vhost-user: factor out msg head and payload, Michael S. Tsirkin, 2018/01/16
- [Qemu-devel] [PULL v2 32/34] vhost: remove assertion to prevent crash, Michael S. Tsirkin, 2018/01/16