From: Mark McLoughlin <markmc@redhat.com>
To: qemu-devel <qemu-devel@nongnu.org>
Subject: [Qemu-devel] [PATCH 1/2] virtio: make vring_desc_*() take phys addrs
Date: Wed, 17 Jun 2009 11:37:32 +0100 [thread overview]
Message-ID: <1245235052.27028.40.camel@blaa> (raw)
In-Reply-To: <1245234943.27028.38.camel@blaa>
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 <markmc@redhat.com>
---
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
next prev parent reply other threads:[~2009-06-17 10:37 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-06-17 10:35 [Qemu-devel] [PATCH 0/2] virtio indirect ring entries Mark McLoughlin
2009-06-17 10:37 ` Mark McLoughlin [this message]
2009-06-17 10:38 ` [Qemu-devel] [PATCH 2/2] virtio: add support for " Mark McLoughlin
2009-06-17 11:44 ` [Qemu-devel] [PATCH 0/2] virtio " Jamie Lokier
-- strict thread matches above, loose matches on Subject: below --
2008-12-18 17:24 [Qemu-devel] [PATCH 0/2] virtio: " Mark McLoughlin
2008-12-18 17:24 ` [Qemu-devel] [PATCH 1/2] virtio: make vring_desc_*() take phys addrs Mark McLoughlin
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=1245235052.27028.40.camel@blaa \
--to=markmc@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).