From patchwork Wed Jul 18 15:07:32 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 171732 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 5F4A42C007D for ; Thu, 19 Jul 2012 01:59:02 +1000 (EST) Received: from localhost ([::1]:36377 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SrVsY-0007G9-Gc for incoming@patchwork.ozlabs.org; Wed, 18 Jul 2012 11:09:30 -0400 Received: from eggs.gnu.org ([208.118.235.92]:52873) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SrVrj-0005RW-8z for qemu-devel@nongnu.org; Wed, 18 Jul 2012 11:08:45 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SrVrc-0000hx-Pa for qemu-devel@nongnu.org; Wed, 18 Jul 2012 11:08:39 -0400 Received: from e06smtp12.uk.ibm.com ([195.75.94.108]:49641) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SrVrc-0000ho-GQ for qemu-devel@nongnu.org; Wed, 18 Jul 2012 11:08:32 -0400 Received: from /spool/local by e06smtp12.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 18 Jul 2012 16:08:31 +0100 Received: from d06nrmr1407.portsmouth.uk.ibm.com (9.149.38.185) by e06smtp12.uk.ibm.com (192.168.101.142) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Wed, 18 Jul 2012 16:08:28 +0100 Received: from d06av07.portsmouth.uk.ibm.com (d06av07.portsmouth.uk.ibm.com [9.149.37.248]) by d06nrmr1407.portsmouth.uk.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id q6IF8RnV2637896 for ; Wed, 18 Jul 2012 16:08:28 +0100 Received: from d06av07.portsmouth.uk.ibm.com (d06av07.portsmouth.uk.ibm.com [127.0.0.1]) by d06av07.portsmouth.uk.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id q6IEn2L3003121 for ; Wed, 18 Jul 2012 10:49:03 -0400 Received: from localhost (sig-9-145-185-169.de.ibm.com [9.145.185.169]) by d06av07.portsmouth.uk.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id q6IEn2ig003097; Wed, 18 Jul 2012 10:49:02 -0400 From: Stefan Hajnoczi To: Date: Wed, 18 Jul 2012 16:07:32 +0100 Message-Id: <1342624074-24650-6-git-send-email-stefanha@linux.vnet.ibm.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1342624074-24650-1-git-send-email-stefanha@linux.vnet.ibm.com> References: <1342624074-24650-1-git-send-email-stefanha@linux.vnet.ibm.com> x-cbid: 12071815-8372-0000-0000-00000339CDEB X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 195.75.94.108 Cc: Kevin Wolf , Anthony Liguori , Stefan Hajnoczi , kvm@vger.kernel.org, "Michael S. Tsirkin" , Khoa Huynh , Paolo Bonzini , Asias He Subject: [Qemu-devel] [RFC v9 05/27] virtio-blk: Do cheapest possible memory mapping X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Instead of using QEMU memory access functions, grab the host address of guest physical address zero and simply add to this base address. This not only simplifies vring mapping but will also make virtqueue element access cheap by avoiding QEMU memory access functions in the I/O code path. Signed-off-by: Stefan Hajnoczi --- hw/virtio-blk.c | 58 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 30 insertions(+), 28 deletions(-) diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c index 4c790a3..abd9386 100644 --- a/hw/virtio-blk.c +++ b/hw/virtio-blk.c @@ -51,6 +51,8 @@ typedef struct VirtIOBlock EventNotifier io_notifier; /* Linux AIO eventfd */ EventHandler io_handler; /* Linux AIO completion handler */ EventHandler notify_handler; /* virtqueue notify handler */ + + void *phys_mem_zero_host_ptr; /* host pointer to guest RAM */ } VirtIOBlock; static VirtIOBlock *to_virtio_blk(VirtIODevice *vdev) @@ -58,43 +60,44 @@ static VirtIOBlock *to_virtio_blk(VirtIODevice *vdev) return (VirtIOBlock *)vdev; } +/* Map target physical address to host address + */ +static inline void *phys_to_host(VirtIOBlock *s, target_phys_addr_t phys) +{ + return s->phys_mem_zero_host_ptr + phys; +} + +/* Setup for cheap target physical to host address conversion + * + * This is a hack for direct access to guest memory, we're not really allowed + * to do this. + */ +static void setup_phys_to_host(VirtIOBlock *s) +{ + target_phys_addr_t len = 4096; /* RAM is really much larger but we cheat */ + s->phys_mem_zero_host_ptr = cpu_physical_memory_map(0, &len, 0); + if (!s->phys_mem_zero_host_ptr) { + fprintf(stderr, "setup_phys_to_host failed\n"); + exit(1); + } +} + /* Map the guest's vring to host memory * * This is not allowed but we know the ring won't move. */ -static void map_vring(struct vring *vring, VirtIODevice *vdev, int n) +static void map_vring(struct vring *vring, VirtIOBlock *s, VirtIODevice *vdev, int n) { - target_phys_addr_t physaddr, len; - vring->num = virtio_queue_get_num(vdev, n); - - physaddr = virtio_queue_get_desc_addr(vdev, n); - len = virtio_queue_get_desc_size(vdev, n); - vring->desc = cpu_physical_memory_map(physaddr, &len, 0); - - physaddr = virtio_queue_get_avail_addr(vdev, n); - len = virtio_queue_get_avail_size(vdev, n); - vring->avail = cpu_physical_memory_map(physaddr, &len, 0); - - physaddr = virtio_queue_get_used_addr(vdev, n); - len = virtio_queue_get_used_size(vdev, n); - vring->used = cpu_physical_memory_map(physaddr, &len, 0); - - if (!vring->desc || !vring->avail || !vring->used) { - fprintf(stderr, "virtio-blk failed to map vring\n"); - exit(1); - } + vring->desc = phys_to_host(s, virtio_queue_get_desc_addr(vdev, n)); + vring->avail = phys_to_host(s, virtio_queue_get_avail_addr(vdev, n)); + vring->used = phys_to_host(s, virtio_queue_get_used_addr(vdev, n)); fprintf(stderr, "virtio-blk vring physical=%#lx desc=%p avail=%p used=%p\n", virtio_queue_get_ring_addr(vdev, n), vring->desc, vring->avail, vring->used); } -static void unmap_vring(struct vring *vring, VirtIODevice *vdev, int n) -{ - cpu_physical_memory_unmap(vring->desc, virtio_queue_get_ring_size(vdev, n), 0, 0); -} - static void handle_io(void) { fprintf(stderr, "io completion happened\n"); @@ -149,7 +152,8 @@ static void add_event_handler(int epoll_fd, EventHandler *event_handler) static void data_plane_start(VirtIOBlock *s) { - map_vring(&s->vring, &s->vdev, 0); + setup_phys_to_host(s); + map_vring(&s->vring, s, &s->vdev, 0); /* Create epoll file descriptor */ s->epoll_fd = epoll_create1(EPOLL_CLOEXEC); @@ -199,8 +203,6 @@ static void data_plane_stop(VirtIOBlock *s) s->vdev.binding->set_host_notifier(s->vdev.binding_opaque, 0, false); close(s->epoll_fd); - - unmap_vring(&s->vring, &s->vdev, 0); } static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t val)