From: "Michael S. Tsirkin" <mst@redhat.com>
To: "Sjur Brændeland" <sjur@brendeland.net>
Cc: "Linus Walleij" <linus.walleij@linaro.org>,
virtualization@lists.linux-foundation.org,
"Sjur Brændeland" <sjur.brandeland@stericsson.com>
Subject: Re: [RFCv2 04/12] virtio-ring: Refactor out the functions accessing user memory
Date: Thu, 6 Dec 2012 11:52:37 +0200 [thread overview]
Message-ID: <20121206095237.GE10837@redhat.com> (raw)
In-Reply-To: <1354718230-4486-5-git-send-email-sjur@brendeland.net>
On Wed, Dec 05, 2012 at 03:37:02PM +0100, Sjur Brændeland wrote:
> Isolate the access to user-memory in separate inline
> functions. This open up for reuse from host-side virtioqueue
> implementation accessing virtio-ring in kernel space.
>
> Signed-off-by: Sjur Brændeland <sjur.brandeland@stericsson.com>
> ---
> drivers/virtio/virtio_ring_host.c | 81 ++++++++++++++++++++++++++-----------
> 1 files changed, 57 insertions(+), 24 deletions(-)
>
> diff --git a/drivers/virtio/virtio_ring_host.c b/drivers/virtio/virtio_ring_host.c
> index 192b838..0750099 100644
> --- a/drivers/virtio/virtio_ring_host.c
> +++ b/drivers/virtio/virtio_ring_host.c
> @@ -18,44 +18,45 @@
> #include <linux/virtio_ring.h>
> #include <linux/module.h>
> #include <linux/uaccess.h>
> +#include <linux/kconfig.h>
>
> MODULE_LICENSE("GPL");
>
> -struct vring_used_elem *vring_add_used_user(struct vring_host *vh,
> - unsigned int head, int len)
> +
> +static inline struct vring_used_elem *_vring_add_used(struct vring_host *vh,
> + u32 head, u32 len,
> + bool (*cpy)(void *dst,
> + void *src,
> + size_t s),
> + void (*wbarrier)(void))
> {
> struct vring_used_elem *used;
> + u16 last_used;
>
> /* The virtqueue contains a ring of used buffers. Get a pointer to the
> * next entry in that used ring. */
> - used = &vh->vr.used->ring[vh->last_used_idx % vh->vr.num];
> - if (__put_user(head, &used->id)) {
> - pr_debug("Failed to write used id");
> + used = &vh->vr.used->ring[vh->last_used_idx & (vh->vr.num - 1)];
> + if (!cpy(&used->id, &head, sizeof(used->id)) ||
> + !cpy(&used->len, &len, sizeof(used->len)))
> return NULL;
> - }
> - if (__put_user(len, &used->len)) {
> - pr_debug("Failed to write used len");
> + wbarrier();
> + last_used = vh->last_used_idx + 1;
> + if (!cpy(&vh->vr.used->idx, &last_used, sizeof(vh->vr.used->idx)))
> return NULL;
I think this is broken: we need a 16 bit access, this is
doing a memcpy which is byte by byte.
> - }
> - /* Make sure buffer is written before we update index. */
> - smp_wmb();
> - if (__put_user(vh->last_used_idx + 1, &vh->vr.used->idx)) {
> - pr_debug("Failed to increment used idx");
> - return NULL;
> - }
> - vh->last_used_idx++;
> + vh->last_used_idx = last_used;
> return used;
> }
> -EXPORT_SYMBOL(vring_add_used_user);
>
> -int vring_avail_desc_user(struct vring_host *vh)
> +static inline int _vring_avail_desc(struct vring_host *vh,
> + bool (*get)(u16 *dst, u16 *src),
> + void (*read_barrier)(void))
> {
> - int head;
> + u16 head;
> u16 last_avail_idx;
>
> /* Check it isn't doing very strange things with descriptor numbers. */
> last_avail_idx = vh->last_avail_idx;
> - if (unlikely(__get_user(vh->avail_idx, &vh->vr.avail->idx))) {
> + if (unlikely(!get(&vh->avail_idx, &vh->vr.avail->idx))) {
> pr_debug("Failed to access avail idx at %p\n",
> &vh->vr.avail->idx);
> return -EFAULT;
> @@ -69,13 +70,12 @@ int vring_avail_desc_user(struct vring_host *vh)
> return vh->vr.num;
>
> /* Only get avail ring entries after they have been exposed by guest. */
> - smp_rmb();
> + read_barrier();
>
> /* Grab the next descriptor number they're advertising, and increment
> * the index we've seen. */
> - if (unlikely(__get_user(head,
> - &vh->vr.avail->ring[last_avail_idx %
> - vh->vr.num]))) {
> + if (unlikely(!get(&head, &vh->vr.avail->ring[last_avail_idx &
> + (vh->vr.num - 1)]))) {
> pr_debug("Failed to read head: idx %d address %p\n",
> last_avail_idx,
> &vh->vr.avail->ring[last_avail_idx %
> @@ -92,6 +92,39 @@ int vring_avail_desc_user(struct vring_host *vh)
>
> return head;
> }
> +
> +static inline void smp_write_barrier(void)
> +{
> + smp_wmb();
> +}
> +
> +static inline void smp_read_barrier(void)
> +{
> + smp_rmb();
> +}
> +
> +static inline bool userspace_cpy_to(void *dst, void *src, size_t s)
> +{
> + return __copy_to_user(dst, src, s) == 0;
> +}
> +
> +static inline bool userspace_get(u16 *dst, u16 *src)
> +{
> + return __get_user(*dst, src);
> +}
> +
> +struct vring_used_elem *vring_add_used_user(struct vring_host *vh,
> + unsigned int head, int len)
> +{
> + return _vring_add_used(vh, head, len, userspace_cpy_to,
> + smp_write_barrier);
> +}
> +EXPORT_SYMBOL(vring_add_used_user);
> +
> +int vring_avail_desc_user(struct vring_host *vh)
> +{
> + return _vring_avail_desc(vh, userspace_get, smp_read_barrier);
> +}
> EXPORT_SYMBOL(vring_avail_desc_user);
>
> /* Each buffer in the virtqueues is actually a chain of descriptors. This
> --
> 1.7.5.4
next prev parent reply other threads:[~2012-12-06 9:52 UTC|newest]
Thread overview: 76+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-10-31 22:46 [RFC virtio-next 0/4] Introduce CAIF Virtio and reversed Vrings Sjur Brændeland
2012-10-31 22:46 ` Sjur Brændeland
2012-10-31 22:46 ` [RFC virtio-next 1/4] virtio: Move definitions to header file vring.h Sjur Brændeland
2012-10-31 22:46 ` Sjur Brændeland
2012-10-31 22:46 ` [RFC virtio-next 2/4] include/vring.h: Add support for reversed vritio rings Sjur Brændeland
2012-10-31 22:46 ` Sjur Brændeland
2012-10-31 22:46 ` [RFC virtio-next 3/4] virtio_ring: Call callback function even when used ring is empty Sjur Brændeland
2012-10-31 22:46 ` Sjur Brændeland
2012-10-31 22:46 ` [RFC virtio-next 4/4] caif_virtio: Add CAIF over virtio Sjur Brændeland
2012-10-31 22:46 ` Sjur Brændeland
2012-11-01 7:41 ` [RFC virtio-next 0/4] Introduce CAIF Virtio and reversed Vrings Rusty Russell
2012-11-01 7:41 ` Rusty Russell
2012-11-01 7:41 ` Rusty Russell
2012-11-05 12:12 ` Sjur Brændeland
2012-11-06 2:09 ` Rusty Russell
2012-11-06 2:09 ` Rusty Russell
2012-12-05 14:36 ` [RFCv2 00/12] Introduce host-side virtio queue and CAIF Virtio Sjur Brændeland
2012-12-05 14:36 ` [RFCv2 01/12] vhost: Use struct vring in vhost_virtqueue Sjur Brændeland
2012-12-05 14:37 ` [RFCv2 02/12] vhost: Isolate reusable vring related functions Sjur Brændeland
2012-12-05 14:37 ` [RFCv2 03/12] virtio-ring: Introduce file virtio_ring_host Sjur Brændeland
2012-12-05 14:37 ` [RFCv2 04/12] virtio-ring: Refactor out the functions accessing user memory Sjur Brændeland
2012-12-06 9:52 ` Michael S. Tsirkin [this message]
2012-12-06 11:03 ` Sjur BRENDELAND
2012-12-06 11:15 ` Michael S. Tsirkin
2012-12-07 11:05 ` Sjur BRENDELAND
2012-12-07 12:40 ` Michael S. Tsirkin
2012-12-07 13:02 ` Sjur BRENDELAND
2012-12-07 14:05 ` Michael S. Tsirkin
2012-12-05 14:37 ` [RFCv2 05/12] virtio-ring: Refactor move attributes to struct virtqueue Sjur Brændeland
2012-12-05 14:37 ` [RFCv2 06/12] virtio_ring: Move SMP macros to virtio_ring.h Sjur Brændeland
2012-12-05 14:37 ` [RFCv2 07/12] virtio-ring: Add Host side virtio-ring implementation Sjur Brændeland
2012-12-05 14:37 ` [RFCv2 08/12] virtio: Update vring_interrupt for host-side virtio queues Sjur Brændeland
2012-12-05 14:37 ` [RFCv2 09/12] virtio-ring: Add BUG_ON checking on host/guest ring type Sjur Brændeland
2012-12-05 14:37 ` [RFCv2 10/12] virtio: Add argument reversed to function find_vqs() Sjur Brændeland
2012-12-05 14:37 ` [RFCv2 11/12] remoteproc: Add support for host-virtqueues Sjur Brændeland
2012-12-05 14:37 ` [RFCv2 12/12] caif_virtio: Introduce caif over virtio Sjur Brændeland
2012-12-06 10:27 ` [RFCv2 00/12] Introduce host-side virtio queue and CAIF Virtio Michael S. Tsirkin
2012-12-21 6:11 ` Rusty Russell
2013-01-08 8:04 ` Sjur Brændeland
2013-01-08 23:17 ` Rusty Russell
2013-01-10 10:30 ` Rusty Russell
2013-01-10 10:30 ` Rusty Russell
2013-01-10 11:11 ` Michael S. Tsirkin
2013-01-10 11:11 ` Michael S. Tsirkin
2013-01-10 22:48 ` Rusty Russell
2013-01-11 7:31 ` Michael S. Tsirkin
2013-01-11 7:31 ` Michael S. Tsirkin
2013-01-12 0:20 ` Rusty Russell
2013-01-14 16:54 ` Michael S. Tsirkin
2013-01-10 18:39 ` Sjur Brændeland
2013-01-10 18:39 ` Sjur Brændeland
2013-01-10 23:35 ` Rusty Russell
2013-01-10 23:35 ` Rusty Russell
2013-01-11 6:37 ` Rusty Russell
2013-01-11 6:37 ` Rusty Russell
2013-01-11 15:02 ` Sjur Brændeland
2013-01-11 15:02 ` Sjur Brændeland
2013-01-12 0:26 ` Rusty Russell
2013-01-12 0:26 ` Rusty Russell
2013-01-14 17:39 ` Michael S. Tsirkin
2013-01-14 17:39 ` Michael S. Tsirkin
2013-01-16 3:13 ` Rusty Russell
2013-01-16 3:13 ` Rusty Russell
2013-01-16 8:16 ` Michael S. Tsirkin
2013-01-16 8:16 ` Michael S. Tsirkin
2013-01-17 2:10 ` Rusty Russell
2013-01-17 9:58 ` Michael S. Tsirkin
2013-01-17 9:58 ` Michael S. Tsirkin
2013-01-21 11:55 ` Rusty Russell
2013-01-21 11:55 ` Rusty Russell
2013-01-17 10:35 ` Rusty Russell
2013-01-17 10:35 ` Rusty Russell
2013-01-17 2:10 ` Rusty Russell
2013-01-11 14:52 ` Sjur Brændeland
2013-01-11 14:52 ` Sjur Brændeland
2012-11-05 12:12 ` [RFC virtio-next 0/4] Introduce CAIF Virtio and reversed Vrings Sjur Brændeland
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=20121206095237.GE10837@redhat.com \
--to=mst@redhat.com \
--cc=linus.walleij@linaro.org \
--cc=sjur.brandeland@stericsson.com \
--cc=sjur@brendeland.net \
--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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.