From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MGsWS-0000Jh-P9 for qemu-devel@nongnu.org; Wed, 17 Jun 2009 06:37:40 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MGsWO-0000FQ-0Q for qemu-devel@nongnu.org; Wed, 17 Jun 2009 06:37:40 -0400 Received: from [199.232.76.173] (port=55401 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MGsWN-0000FL-Ps for qemu-devel@nongnu.org; Wed, 17 Jun 2009 06:37:35 -0400 Received: from mx2.redhat.com ([66.187.237.31]:48673) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1MGsWN-0008VF-9J for qemu-devel@nongnu.org; Wed, 17 Jun 2009 06:37:35 -0400 Received: from int-mx2.corp.redhat.com (int-mx2.corp.redhat.com [172.16.27.26]) by mx2.redhat.com (8.13.8/8.13.8) with ESMTP id n5HAbYGi002520 for ; Wed, 17 Jun 2009 06:37:34 -0400 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx2.corp.redhat.com (8.13.1/8.13.1) with ESMTP id n5HAbY8I023384 for ; Wed, 17 Jun 2009 06:37:34 -0400 Received: from [127.0.0.1] (sebastian-int.corp.redhat.com [172.16.52.221]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id n5HAbWVA017275 for ; Wed, 17 Jun 2009 06:37:33 -0400 From: Mark McLoughlin In-Reply-To: <1245234943.27028.38.camel@blaa> References: <1245234943.27028.38.camel@blaa> Content-Type: text/plain Date: Wed, 17 Jun 2009 11:37:32 +0100 Message-Id: <1245235052.27028.40.camel@blaa> Mime-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [Qemu-devel] [PATCH 1/2] virtio: make vring_desc_*() take phys addrs Reply-To: Mark McLoughlin List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel Change the vring descriptor helpers to take the physical address of the descriptor table rather than a virtqueue. This is needed in order to allow these helpers to be used with an indirect descriptor table. Signed-off-by: Mark McLoughlin --- hw/virtio.c | 59 +++++++++++++++++++++++++++++++++-------------------------- 1 files changed, 33 insertions(+), 26 deletions(-) diff --git a/hw/virtio.c b/hw/virtio.c index 45a49fa..1e8376d 100644 --- a/hw/virtio.c +++ b/hw/virtio.c @@ -85,31 +85,31 @@ static void virtqueue_init(VirtQueue *vq) VIRTIO_PCI_VRING_ALIGN); } -static inline uint64_t vring_desc_addr(VirtQueue *vq, int i) +static inline uint64_t vring_desc_addr(target_phys_addr_t desc_pa, int i) { target_phys_addr_t pa; - pa = vq->vring.desc + sizeof(VRingDesc) * i + offsetof(VRingDesc, addr); + pa = desc_pa + sizeof(VRingDesc) * i + offsetof(VRingDesc, addr); return ldq_phys(pa); } -static inline uint32_t vring_desc_len(VirtQueue *vq, int i) +static inline uint32_t vring_desc_len(target_phys_addr_t desc_pa, int i) { target_phys_addr_t pa; - pa = vq->vring.desc + sizeof(VRingDesc) * i + offsetof(VRingDesc, len); + pa = desc_pa + sizeof(VRingDesc) * i + offsetof(VRingDesc, len); return ldl_phys(pa); } -static inline uint16_t vring_desc_flags(VirtQueue *vq, int i) +static inline uint16_t vring_desc_flags(target_phys_addr_t desc_pa, int i) { target_phys_addr_t pa; - pa = vq->vring.desc + sizeof(VRingDesc) * i + offsetof(VRingDesc, flags); + pa = desc_pa + sizeof(VRingDesc) * i + offsetof(VRingDesc, flags); return lduw_phys(pa); } -static inline uint16_t vring_desc_next(VirtQueue *vq, int i) +static inline uint16_t vring_desc_next(target_phys_addr_t desc_pa, int i) { target_phys_addr_t pa; - pa = vq->vring.desc + sizeof(VRingDesc) * i + offsetof(VRingDesc, next); + pa = desc_pa + sizeof(VRingDesc) * i + offsetof(VRingDesc, next); return lduw_phys(pa); } @@ -269,20 +269,21 @@ static unsigned int virtqueue_get_head(VirtQueue *vq, unsigned int idx) return head; } -static unsigned virtqueue_next_desc(VirtQueue *vq, unsigned int i) +static unsigned virtqueue_next_desc(target_phys_addr_t desc_pa, + unsigned int i, unsigned int max) { unsigned int next; /* If this descriptor says it doesn't chain, we're done. */ - if (!(vring_desc_flags(vq, i) & VRING_DESC_F_NEXT)) - return vq->vring.num; + if (!(vring_desc_flags(desc_pa, i) & VRING_DESC_F_NEXT)) + return max; /* Check they're not leading us off end of descriptors. */ - next = vring_desc_next(vq, i); + next = vring_desc_next(desc_pa, i); /* Make sure compiler knows to grab that: we don't want it changing! */ wmb(); - if (next >= vq->vring.num) { + if (next >= max) { fprintf(stderr, "Desc next is %u", next); exit(1); } @@ -292,10 +293,12 @@ static unsigned virtqueue_next_desc(VirtQueue *vq, unsigned int i) int virtqueue_avail_bytes(VirtQueue *vq, int in_bytes, int out_bytes) { - unsigned int idx; + target_phys_addr_t desc_pa = vq->vring.desc; + unsigned int idx, max; int num_bufs, in_total, out_total; idx = vq->last_avail_idx; + max = vq->vring.num; num_bufs = in_total = out_total = 0; while (virtqueue_num_heads(vq, idx)) { @@ -304,21 +307,21 @@ int virtqueue_avail_bytes(VirtQueue *vq, int in_bytes, int out_bytes) i = virtqueue_get_head(vq, idx++); do { /* If we've got too many, that implies a descriptor loop. */ - if (++num_bufs > vq->vring.num) { + if (++num_bufs > max) { fprintf(stderr, "Looped descriptor"); exit(1); } - if (vring_desc_flags(vq, i) & VRING_DESC_F_WRITE) { + if (vring_desc_flags(desc_pa, i) & VRING_DESC_F_WRITE) { if (in_bytes > 0 && - (in_total += vring_desc_len(vq, i)) >= in_bytes) + (in_total += vring_desc_len(desc_pa, i)) >= in_bytes) return 1; } else { if (out_bytes > 0 && - (out_total += vring_desc_len(vq, i)) >= out_bytes) + (out_total += vring_desc_len(desc_pa, i)) >= out_bytes) return 1; } - } while ((i = virtqueue_next_desc(vq, i)) != vq->vring.num); + } while ((i = virtqueue_next_desc(desc_pa, i, max)) != max); } return 0; @@ -326,7 +329,8 @@ int virtqueue_avail_bytes(VirtQueue *vq, int in_bytes, int out_bytes) int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem) { - unsigned int i, head; + unsigned int i, head, max; + target_phys_addr_t desc_pa = vq->vring.desc; target_phys_addr_t len; if (!virtqueue_num_heads(vq, vq->last_avail_idx)) @@ -335,23 +339,26 @@ int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem) /* When we start there are none of either input nor output. */ elem->out_num = elem->in_num = 0; + max = vq->vring.num; + i = head = virtqueue_get_head(vq, vq->last_avail_idx++); do { struct iovec *sg; int is_write = 0; - if (vring_desc_flags(vq, i) & VRING_DESC_F_WRITE) { - elem->in_addr[elem->in_num] = vring_desc_addr(vq, i); + if (vring_desc_flags(desc_pa, i) & VRING_DESC_F_WRITE) { + elem->in_addr[elem->in_num] = vring_desc_addr(desc_pa, i); sg = &elem->in_sg[elem->in_num++]; is_write = 1; } else sg = &elem->out_sg[elem->out_num++]; /* Grab the first descriptor, and check it's OK. */ - sg->iov_len = vring_desc_len(vq, i); + sg->iov_len = vring_desc_len(desc_pa, i); len = sg->iov_len; - sg->iov_base = cpu_physical_memory_map(vring_desc_addr(vq, i), &len, is_write); + sg->iov_base = cpu_physical_memory_map(vring_desc_addr(desc_pa, i), + &len, is_write); if (sg->iov_base == NULL || len != sg->iov_len) { fprintf(stderr, "virtio: trying to map MMIO memory\n"); @@ -359,11 +366,11 @@ int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem) } /* If we've got too many, that implies a descriptor loop. */ - if ((elem->in_num + elem->out_num) > vq->vring.num) { + if ((elem->in_num + elem->out_num) > max) { fprintf(stderr, "Looped descriptor"); exit(1); } - } while ((i = virtqueue_next_desc(vq, i)) != vq->vring.num); + } while ((i = virtqueue_next_desc(desc_pa, i, max)) != max); elem->index = head; -- 1.6.0.6