From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:36740) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UTCEy-0000lF-9N for qemu-devel@nongnu.org; Fri, 19 Apr 2013 10:24:42 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UTCEs-0003FF-Vc for qemu-devel@nongnu.org; Fri, 19 Apr 2013 10:24:40 -0400 Received: from mail-ea0-x234.google.com ([2a00:1450:4013:c01::234]:49587) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UTCEs-0003F7-Kk for qemu-devel@nongnu.org; Fri, 19 Apr 2013 10:24:34 -0400 Received: by mail-ea0-f180.google.com with SMTP id d10so1681705eaj.25 for ; Fri, 19 Apr 2013 07:24:33 -0700 (PDT) Sender: Paolo Bonzini From: Paolo Bonzini Date: Fri, 19 Apr 2013 16:24:14 +0200 Message-Id: <1366381460-6041-4-git-send-email-pbonzini@redhat.com> In-Reply-To: <1366381460-6041-1-git-send-email-pbonzini@redhat.com> References: <1366381460-6041-1-git-send-email-pbonzini@redhat.com> Subject: [Qemu-devel] [PATCH 3/9] vhost: Add vhost_commit callback for SeaBIOS ROM region re-mapping List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: asias@redhat.com, nab@linux-iscsi.org, "Michael S. Tsirkin" From: Nicholas Bellinger This patch follows MST's recommendation to move checks for vhost_verify_ring_mappings() -> cpu_physical_memory_map() operations from MemoryListener->region_[add,del]() -> vhost_set_memory() into final MemoryListener->commit() -> vhost_commit() callback. It addresses the case where virtio-scsi vq ioport RAM re-mapping to read-only SeaBIOS ROM triggers a cpu_physical_memory_map() NIL MemoryRegionSection pointer failure. Also save vhost_dev->mem_changed_[start,end]_addr values in vhost_set_memory() for final ranges_overlap checks. (Thanks Paolo!) Cc: Michael S. Tsirkin Cc: Paolo Bonzini Cc: Asias He Signed-off-by: Nicholas Bellinger Acked-by: Michael S. Tsirkin Signed-off-by: Paolo Bonzini --- hw/virtio/vhost.c | 53 +++++++++++++++++++++++++++++++++-------------- include/hw/virtio/vhost.h | 3 +++ 2 files changed, 41 insertions(+), 15 deletions(-) diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c index 636fad0..40feab4 100644 --- a/hw/virtio/vhost.c +++ b/hw/virtio/vhost.c @@ -382,8 +382,6 @@ static void vhost_set_memory(MemoryListener *listener, bool log_dirty = memory_region_is_logging(section->mr); int s = offsetof(struct vhost_memory, regions) + (dev->mem->nregions + 1) * sizeof dev->mem->regions[0]; - uint64_t log_size; - int r; void *ram; dev->mem = g_realloc(dev->mem, s); @@ -416,12 +414,47 @@ static void vhost_set_memory(MemoryListener *listener, /* Remove old mapping for this memory, if any. */ vhost_dev_unassign_memory(dev, start_addr, size); } + dev->mem_changed_start_addr = MIN(dev->mem_changed_start_addr, start_addr); + dev->mem_changed_end_addr = MAX(dev->mem_changed_end_addr, start_addr + size - 1); + dev->memory_changed = true; +} + +static bool vhost_section(MemoryRegionSection *section) +{ + return memory_region_is_ram(section->mr); +} + +static void vhost_begin(MemoryListener *listener) +{ + struct vhost_dev *dev = container_of(listener, struct vhost_dev, + memory_listener); + dev->mem_changed_end_addr = 0; + dev->mem_changed_start_addr = -1; +} +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; + uint64_t log_size; + int r; + + if (!dev->memory_changed) { + return; + } if (!dev->started) { return; } + if (dev->mem_changed_start_addr > dev->mem_changed_end_addr) { + return; + } 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); } @@ -429,6 +462,7 @@ static void vhost_set_memory(MemoryListener *listener, if (!dev->log_enabled) { r = ioctl(dev->control, VHOST_SET_MEM_TABLE, dev->mem); assert(r >= 0); + dev->memory_changed = false; return; } log_size = vhost_get_log_size(dev); @@ -445,19 +479,7 @@ static void vhost_set_memory(MemoryListener *listener, if (dev->log_size > log_size + VHOST_LOG_BUFFER) { vhost_dev_log_resize(dev, log_size); } -} - -static bool vhost_section(MemoryRegionSection *section) -{ - return memory_region_is_ram(section->mr); -} - -static void vhost_begin(MemoryListener *listener) -{ -} - -static void vhost_commit(MemoryListener *listener) -{ + dev->memory_changed = false; } static void vhost_region_add(MemoryListener *listener, @@ -842,6 +864,7 @@ int vhost_dev_init(struct vhost_dev *hdev, int devfd, const char *devpath, hdev->log_size = 0; hdev->log_enabled = false; hdev->started = false; + hdev->memory_changed = false; memory_listener_register(&hdev->memory_listener, &address_space_memory); hdev->force = force; return 0; diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h index b373be0..de24746 100644 --- a/include/hw/virtio/vhost.h +++ b/include/hw/virtio/vhost.h @@ -45,6 +45,9 @@ struct vhost_dev { vhost_log_chunk_t *log; unsigned long long log_size; bool force; + bool memory_changed; + hwaddr mem_changed_start_addr; + hwaddr mem_changed_end_addr; }; int vhost_dev_init(struct vhost_dev *hdev, int devfd, const char *devpath, -- 1.8.1.4