From: "Michael S. Tsirkin" <mst@redhat.com>
To: linux-kernel@vger.kernel.org
Cc: rusty@au1.ibm.com, virtualization@lists.linux-foundation.org,
pbonzini@redhat.com, David Miller <davem@davemloft.net>
Subject: [PATCH v4 06/42] virtio_ring: switch to new memory access APIs
Date: Tue, 25 Nov 2014 18:41:48 +0200 [thread overview]
Message-ID: <1416933600-21398-7-git-send-email-mst@redhat.com> (raw)
In-Reply-To: <1416933600-21398-1-git-send-email-mst@redhat.com>
Use virtioXX_to_cpu and friends for access to
all multibyte structures in memory.
Note: this is intentionally mechanical.
A follow-up patch will split long lines etc.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
drivers/virtio/virtio_ring.c | 89 ++++++++++++++++++++++----------------------
1 file changed, 45 insertions(+), 44 deletions(-)
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index 61a1fe1..b311fa7 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -99,7 +99,8 @@ struct vring_virtqueue
#define to_vvq(_vq) container_of(_vq, struct vring_virtqueue, vq)
-static struct vring_desc *alloc_indirect(unsigned int total_sg, gfp_t gfp)
+static struct vring_desc *alloc_indirect(struct virtqueue *_vq,
+ unsigned int total_sg, gfp_t gfp)
{
struct vring_desc *desc;
unsigned int i;
@@ -116,7 +117,7 @@ static struct vring_desc *alloc_indirect(unsigned int total_sg, gfp_t gfp)
return NULL;
for (i = 0; i < total_sg; i++)
- desc[i].next = i+1;
+ desc[i].next = cpu_to_virtio16(_vq->vdev, i + 1);
return desc;
}
@@ -165,17 +166,17 @@ static inline int virtqueue_add(struct virtqueue *_vq,
/* If the host supports indirect descriptor tables, and we have multiple
* buffers, then go indirect. FIXME: tune this threshold */
if (vq->indirect && total_sg > 1 && vq->vq.num_free)
- desc = alloc_indirect(total_sg, gfp);
+ desc = alloc_indirect(_vq, total_sg, gfp);
else
desc = NULL;
if (desc) {
/* Use a single buffer which doesn't continue */
- vq->vring.desc[head].flags = VRING_DESC_F_INDIRECT;
- vq->vring.desc[head].addr = virt_to_phys(desc);
+ vq->vring.desc[head].flags = cpu_to_virtio16(_vq->vdev, VRING_DESC_F_INDIRECT);
+ vq->vring.desc[head].addr = cpu_to_virtio64(_vq->vdev, virt_to_phys(desc));
/* avoid kmemleak false positive (hidden by virt_to_phys) */
kmemleak_ignore(desc);
- vq->vring.desc[head].len = total_sg * sizeof(struct vring_desc);
+ vq->vring.desc[head].len = cpu_to_virtio32(_vq->vdev, total_sg * sizeof(struct vring_desc));
/* Set up rest to use this indirect table. */
i = 0;
@@ -205,28 +206,28 @@ static inline int virtqueue_add(struct virtqueue *_vq,
for (n = 0; n < out_sgs; n++) {
for (sg = sgs[n]; sg; sg = sg_next(sg)) {
- desc[i].flags = VRING_DESC_F_NEXT;
- desc[i].addr = sg_phys(sg);
- desc[i].len = sg->length;
+ desc[i].flags = cpu_to_virtio16(_vq->vdev, VRING_DESC_F_NEXT);
+ desc[i].addr = cpu_to_virtio64(_vq->vdev, sg_phys(sg));
+ desc[i].len = cpu_to_virtio32(_vq->vdev, sg->length);
prev = i;
- i = desc[i].next;
+ i = virtio16_to_cpu(_vq->vdev, desc[i].next);
}
}
for (; n < (out_sgs + in_sgs); n++) {
for (sg = sgs[n]; sg; sg = sg_next(sg)) {
- desc[i].flags = VRING_DESC_F_NEXT|VRING_DESC_F_WRITE;
- desc[i].addr = sg_phys(sg);
- desc[i].len = sg->length;
+ desc[i].flags = cpu_to_virtio16(_vq->vdev, VRING_DESC_F_NEXT | VRING_DESC_F_WRITE);
+ desc[i].addr = cpu_to_virtio64(_vq->vdev, sg_phys(sg));
+ desc[i].len = cpu_to_virtio32(_vq->vdev, sg->length);
prev = i;
- i = desc[i].next;
+ i = virtio16_to_cpu(_vq->vdev, desc[i].next);
}
}
/* Last one doesn't continue. */
- desc[prev].flags &= ~VRING_DESC_F_NEXT;
+ desc[prev].flags &= cpu_to_virtio16(_vq->vdev, ~VRING_DESC_F_NEXT);
/* Update free pointer */
if (indirect)
- vq->free_head = vq->vring.desc[head].next;
+ vq->free_head = virtio16_to_cpu(_vq->vdev, vq->vring.desc[head].next);
else
vq->free_head = i;
@@ -235,13 +236,13 @@ static inline int virtqueue_add(struct virtqueue *_vq,
/* Put entry in available array (but don't update avail->idx until they
* do sync). */
- avail = (vq->vring.avail->idx & (vq->vring.num-1));
- vq->vring.avail->ring[avail] = head;
+ avail = virtio16_to_cpu(_vq->vdev, vq->vring.avail->idx) & (vq->vring.num - 1);
+ vq->vring.avail->ring[avail] = cpu_to_virtio16(_vq->vdev, head);
/* Descriptors and available array need to be set before we expose the
* new available array entries. */
virtio_wmb(vq->weak_barriers);
- vq->vring.avail->idx++;
+ vq->vring.avail->idx = cpu_to_virtio16(_vq->vdev, virtio16_to_cpu(_vq->vdev, vq->vring.avail->idx) + 1);
vq->num_added++;
/* This is very unlikely, but theoretically possible. Kick
@@ -354,8 +355,8 @@ bool virtqueue_kick_prepare(struct virtqueue *_vq)
* event. */
virtio_mb(vq->weak_barriers);
- old = vq->vring.avail->idx - vq->num_added;
- new = vq->vring.avail->idx;
+ old = virtio16_to_cpu(_vq->vdev, vq->vring.avail->idx) - vq->num_added;
+ new = virtio16_to_cpu(_vq->vdev, vq->vring.avail->idx);
vq->num_added = 0;
#ifdef DEBUG
@@ -367,10 +368,10 @@ bool virtqueue_kick_prepare(struct virtqueue *_vq)
#endif
if (vq->event) {
- needs_kick = vring_need_event(vring_avail_event(&vq->vring),
+ needs_kick = vring_need_event(virtio16_to_cpu(_vq->vdev, vring_avail_event(&vq->vring)),
new, old);
} else {
- needs_kick = !(vq->vring.used->flags & VRING_USED_F_NO_NOTIFY);
+ needs_kick = !(vq->vring.used->flags & cpu_to_virtio16(_vq->vdev, VRING_USED_F_NO_NOTIFY));
}
END_USE(vq);
return needs_kick;
@@ -432,15 +433,15 @@ static void detach_buf(struct vring_virtqueue *vq, unsigned int head)
i = head;
/* Free the indirect table */
- if (vq->vring.desc[i].flags & VRING_DESC_F_INDIRECT)
- kfree(phys_to_virt(vq->vring.desc[i].addr));
+ if (vq->vring.desc[i].flags & cpu_to_virtio16(vq->vq.vdev, VRING_DESC_F_INDIRECT))
+ kfree(phys_to_virt(virtio64_to_cpu(vq->vq.vdev, vq->vring.desc[i].addr)));
- while (vq->vring.desc[i].flags & VRING_DESC_F_NEXT) {
- i = vq->vring.desc[i].next;
+ while (vq->vring.desc[i].flags & cpu_to_virtio16(vq->vq.vdev, VRING_DESC_F_NEXT)) {
+ i = virtio16_to_cpu(vq->vq.vdev, vq->vring.desc[i].next);
vq->vq.num_free++;
}
- vq->vring.desc[i].next = vq->free_head;
+ vq->vring.desc[i].next = cpu_to_virtio16(vq->vq.vdev, vq->free_head);
vq->free_head = head;
/* Plus final descriptor */
vq->vq.num_free++;
@@ -448,7 +449,7 @@ static void detach_buf(struct vring_virtqueue *vq, unsigned int head)
static inline bool more_used(const struct vring_virtqueue *vq)
{
- return vq->last_used_idx != vq->vring.used->idx;
+ return vq->last_used_idx != virtio16_to_cpu(vq->vq.vdev, vq->vring.used->idx);
}
/**
@@ -491,8 +492,8 @@ void *virtqueue_get_buf(struct virtqueue *_vq, unsigned int *len)
virtio_rmb(vq->weak_barriers);
last_used = (vq->last_used_idx & (vq->vring.num - 1));
- i = vq->vring.used->ring[last_used].id;
- *len = vq->vring.used->ring[last_used].len;
+ i = virtio32_to_cpu(_vq->vdev, vq->vring.used->ring[last_used].id);
+ *len = virtio32_to_cpu(_vq->vdev, vq->vring.used->ring[last_used].len);
if (unlikely(i >= vq->vring.num)) {
BAD_RING(vq, "id %u out of range\n", i);
@@ -510,8 +511,8 @@ void *virtqueue_get_buf(struct virtqueue *_vq, unsigned int *len)
/* If we expect an interrupt for the next entry, tell host
* by writing event index and flush out the write before
* the read in the next get_buf call. */
- if (!(vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT)) {
- vring_used_event(&vq->vring) = vq->last_used_idx;
+ if (!(vq->vring.avail->flags & cpu_to_virtio16(_vq->vdev, VRING_AVAIL_F_NO_INTERRUPT))) {
+ vring_used_event(&vq->vring) = cpu_to_virtio16(_vq->vdev, vq->last_used_idx);
virtio_mb(vq->weak_barriers);
}
@@ -537,7 +538,7 @@ void virtqueue_disable_cb(struct virtqueue *_vq)
{
struct vring_virtqueue *vq = to_vvq(_vq);
- vq->vring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
+ vq->vring.avail->flags |= cpu_to_virtio16(_vq->vdev, VRING_AVAIL_F_NO_INTERRUPT);
}
EXPORT_SYMBOL_GPL(virtqueue_disable_cb);
@@ -565,8 +566,8 @@ unsigned virtqueue_enable_cb_prepare(struct virtqueue *_vq)
/* Depending on the VIRTIO_RING_F_EVENT_IDX feature, we need to
* either clear the flags bit or point the event index at the next
* entry. Always do both to keep code simple. */
- vq->vring.avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT;
- vring_used_event(&vq->vring) = last_used_idx = vq->last_used_idx;
+ vq->vring.avail->flags &= cpu_to_virtio16(_vq->vdev, ~VRING_AVAIL_F_NO_INTERRUPT);
+ vring_used_event(&vq->vring) = cpu_to_virtio16(_vq->vdev, last_used_idx = vq->last_used_idx);
END_USE(vq);
return last_used_idx;
}
@@ -586,7 +587,7 @@ bool virtqueue_poll(struct virtqueue *_vq, unsigned last_used_idx)
struct vring_virtqueue *vq = to_vvq(_vq);
virtio_mb(vq->weak_barriers);
- return (u16)last_used_idx != vq->vring.used->idx;
+ return (u16)last_used_idx != virtio16_to_cpu(_vq->vdev, vq->vring.used->idx);
}
EXPORT_SYMBOL_GPL(virtqueue_poll);
@@ -633,12 +634,12 @@ bool virtqueue_enable_cb_delayed(struct virtqueue *_vq)
/* Depending on the VIRTIO_RING_F_USED_EVENT_IDX feature, we need to
* either clear the flags bit or point the event index at the next
* entry. Always do both to keep code simple. */
- vq->vring.avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT;
+ vq->vring.avail->flags &= cpu_to_virtio16(_vq->vdev, ~VRING_AVAIL_F_NO_INTERRUPT);
/* TODO: tune this threshold */
- bufs = (u16)(vq->vring.avail->idx - vq->last_used_idx) * 3 / 4;
- vring_used_event(&vq->vring) = vq->last_used_idx + bufs;
+ bufs = (u16)(virtio16_to_cpu(_vq->vdev, vq->vring.avail->idx) - vq->last_used_idx) * 3 / 4;
+ vring_used_event(&vq->vring) = cpu_to_virtio16(_vq->vdev, vq->last_used_idx + bufs);
virtio_mb(vq->weak_barriers);
- if (unlikely((u16)(vq->vring.used->idx - vq->last_used_idx) > bufs)) {
+ if (unlikely((u16)(virtio16_to_cpu(_vq->vdev, vq->vring.used->idx) - vq->last_used_idx) > bufs)) {
END_USE(vq);
return false;
}
@@ -670,7 +671,7 @@ void *virtqueue_detach_unused_buf(struct virtqueue *_vq)
/* detach_buf clears data, so grab it now. */
buf = vq->data[i];
detach_buf(vq, i);
- vq->vring.avail->idx--;
+ vq->vring.avail->idx = cpu_to_virtio16(_vq->vdev, virtio16_to_cpu(_vq->vdev, vq->vring.avail->idx) - 1);
END_USE(vq);
return buf;
}
@@ -747,12 +748,12 @@ struct virtqueue *vring_new_virtqueue(unsigned int index,
/* No callback? Tell other side not to bother us. */
if (!callback)
- vq->vring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
+ vq->vring.avail->flags |= cpu_to_virtio16(vdev, VRING_AVAIL_F_NO_INTERRUPT);
/* Put everything in free lists. */
vq->free_head = 0;
for (i = 0; i < num-1; i++) {
- vq->vring.desc[i].next = i+1;
+ vq->vring.desc[i].next = cpu_to_virtio16(vdev, i + 1);
vq->data[i] = NULL;
}
vq->data[i] = NULL;
--
MST
next prev parent reply other threads:[~2014-11-25 16:41 UTC|newest]
Thread overview: 73+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <1416933600-21398-1-git-send-email-mst@redhat.com>
2014-11-25 16:41 ` [PATCH v4 01/42] virtio: use u32, not bitmap for struct virtio_device's features Michael S. Tsirkin
2014-11-25 16:41 ` [PATCH v4 02/42] virtio: add support for 64 bit features Michael S. Tsirkin
2014-11-26 16:48 ` Greg Kurz
2014-11-26 16:56 ` Michael S. Tsirkin
2014-11-25 16:41 ` [PATCH v4 03/42] virtio: add virtio 1.0 feature bit Michael S. Tsirkin
2014-11-25 16:41 ` [PATCH v4 04/42] virtio: disable virtio 1.0 in transports Michael S. Tsirkin
2014-11-25 17:29 ` Cornelia Huck
2014-11-25 21:20 ` Michael S. Tsirkin
2014-11-26 9:09 ` Cornelia Huck
2014-11-27 10:54 ` Michael S. Tsirkin
2014-11-27 11:02 ` Cornelia Huck
2014-11-27 11:06 ` Michael S. Tsirkin
2014-11-25 16:41 ` [PATCH v4 05/42] virtio: memory access APIs Michael S. Tsirkin
2014-11-25 17:42 ` Cornelia Huck
2014-11-25 16:41 ` Michael S. Tsirkin [this message]
2014-11-25 16:41 ` [PATCH v4 07/42] virtio_config: endian conversion for v1.0 Michael S. Tsirkin
2014-11-25 16:41 ` [PATCH v4 08/42] virtio: allow transports to get avail/used addresses Michael S. Tsirkin
2014-11-25 16:42 ` [PATCH v4 09/42] virtio: set FEATURES_OK Michael S. Tsirkin
2014-11-25 17:48 ` Cornelia Huck
2014-11-25 21:38 ` Michael S. Tsirkin
2014-11-26 9:18 ` Cornelia Huck
2014-11-25 16:42 ` [PATCH v4 10/42] virtio: simplify feature bit handling Michael S. Tsirkin
2014-11-25 16:42 ` [PATCH v4 11/42] virtio: add legacy feature table support Michael S. Tsirkin
2014-11-25 17:53 ` Cornelia Huck
2014-11-25 21:39 ` Michael S. Tsirkin
2014-11-26 9:19 ` Cornelia Huck
2014-11-25 16:42 ` [PATCH v4 12/42] virtio_net: v1.0 endianness Michael S. Tsirkin
2014-11-25 16:42 ` [PATCH v4 13/42] virtio_blk: v1.0 support Michael S. Tsirkin
2014-11-25 16:42 ` [PATCH v4 18/42] virtio_blk: make serial attribute static Michael S. Tsirkin
2014-11-26 8:48 ` Gerd Hoffmann
2014-11-26 9:50 ` Cornelia Huck
2014-11-25 16:42 ` [PATCH v4 19/42] virtio_blk: fix race at module removal Michael S. Tsirkin
2014-11-25 16:42 ` [PATCH v4 20/42] virtio_net: pass vi around Michael S. Tsirkin
2014-11-25 16:42 ` [PATCH v4 21/42] virtio_net: get rid of virtio_net_hdr/skb_vnet_hdr Michael S. Tsirkin
2014-11-25 16:42 ` [PATCH v4 22/42] virtio_net: stricter short buffer length checks Michael S. Tsirkin
2014-11-25 16:43 ` [PATCH v4 23/42] virtio_net: bigger header when VERSION_1 is set Michael S. Tsirkin
2014-11-26 13:04 ` Cornelia Huck
2014-11-25 16:43 ` [PATCH v4 24/42] virtio_net: enable v1.0 support Michael S. Tsirkin
2014-11-25 16:43 ` [PATCH v4 25/42] vhost: add memory access wrappers Michael S. Tsirkin
2014-11-26 13:54 ` Cornelia Huck
2014-11-26 14:05 ` Michael S. Tsirkin
2014-11-26 14:17 ` Cornelia Huck
2014-11-26 14:24 ` Michael S. Tsirkin
2014-11-25 16:43 ` [PATCH v4 26/42] vhost/net: force len for TX to host endian Michael S. Tsirkin
2014-11-25 16:43 ` [PATCH v4 27/42] vhost: virtio 1.0 endian-ness support Michael S. Tsirkin
2014-11-25 16:43 ` [PATCH v4 28/42] vhost: make features 64 bit Michael S. Tsirkin
2014-11-25 16:43 ` [PATCH v4 29/42] vhost/net: virtio 1.0 byte swap Michael S. Tsirkin
2014-11-25 16:43 ` [PATCH v4 30/42] vhost/net: larger header for virtio 1.0 Michael S. Tsirkin
2014-11-25 16:43 ` [PATCH v4 31/42] vhost/net: enable " Michael S. Tsirkin
2014-11-25 16:43 ` [PATCH v4 32/42] vhost/net: suppress compiler warning Michael S. Tsirkin
2014-11-25 16:44 ` [PATCH v4 38/42] virtio_scsi: v1.0 support Michael S. Tsirkin
2014-11-25 16:44 ` [PATCH v4 40/42] virtio_scsi: export to userspace Michael S. Tsirkin
2014-11-25 16:44 ` [PATCH v4 41/42] vhost/scsi: partial virtio 1.0 support Michael S. Tsirkin
[not found] ` <1416933600-21398-8-git-send-email-mst@redhat.com>
2014-11-25 17:45 ` [PATCH v4 07/42] virtio_config: endian conversion for v1.0 Cornelia Huck
2014-11-25 21:36 ` Michael S. Tsirkin
2014-11-26 9:13 ` Cornelia Huck
[not found] ` <1416933600-21398-14-git-send-email-mst@redhat.com>
2014-11-25 17:55 ` [PATCH v4 13/42] virtio_blk: v1.0 support Cornelia Huck
[not found] ` <20141125185516.7570c6e7.cornelia.huck@de.ibm.com>
2014-11-25 21:43 ` Michael S. Tsirkin
2014-11-26 15:40 ` David Hildenbrand
2014-11-26 15:48 ` Michael S. Tsirkin
[not found] ` <1416933600-21398-20-git-send-email-mst@redhat.com>
2014-11-26 9:53 ` [PATCH v4 19/42] virtio_blk: fix race at module removal Cornelia Huck
[not found] ` <1416933600-21398-21-git-send-email-mst@redhat.com>
2014-11-26 12:35 ` [PATCH v4 20/42] virtio_net: pass vi around Cornelia Huck
[not found] ` <1416933600-21398-22-git-send-email-mst@redhat.com>
2014-11-26 12:50 ` [PATCH v4 21/42] virtio_net: get rid of virtio_net_hdr/skb_vnet_hdr Cornelia Huck
2014-11-26 13:11 ` Michael S. Tsirkin
[not found] ` <1416933600-21398-23-git-send-email-mst@redhat.com>
2014-11-26 13:00 ` [PATCH v4 22/42] virtio_net: stricter short buffer length checks Cornelia Huck
[not found] ` <1416933600-21398-25-git-send-email-mst@redhat.com>
2014-11-26 13:08 ` [PATCH v4 24/42] virtio_net: enable v1.0 support Cornelia Huck
2014-11-26 13:28 ` Michael S. Tsirkin
[not found] ` <1416933600-21398-27-git-send-email-mst@redhat.com>
2014-11-26 14:31 ` [PATCH v4 26/42] vhost/net: force len for TX to host endian Cornelia Huck
2014-11-26 14:44 ` Michael S. Tsirkin
2014-11-26 14:54 ` Cornelia Huck
2014-11-26 15:01 ` Michael S. Tsirkin
[not found] ` <1416933600-21398-39-git-send-email-mst@redhat.com>
2014-11-26 14:51 ` [PATCH v4 38/42] virtio_scsi: v1.0 support Cornelia Huck
2014-11-26 14:56 ` Michael S. Tsirkin
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=1416933600-21398-7-git-send-email-mst@redhat.com \
--to=mst@redhat.com \
--cc=davem@davemloft.net \
--cc=linux-kernel@vger.kernel.org \
--cc=pbonzini@redhat.com \
--cc=rusty@au1.ibm.com \
--cc=virtualization@lists.linux-foundation.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).