[Qemu-devel] [RFC v2 11/32] vhub: Open userfaultfd

Dr. David Alan Gilbert (git) posted 32 patches 8 years, 5 months ago
There is a newer version of this series
[Qemu-devel] [RFC v2 11/32] vhub: Open userfaultfd
Posted by Dr. David Alan Gilbert (git) 8 years, 5 months ago
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>

Open a userfaultfd (on a postcopy_advise) and send it back in
the reply to the qemu for it to monitor.

Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
---
 contrib/libvhost-user/libvhost-user.c | 26 +++++++++++++++++++++++---
 contrib/libvhost-user/libvhost-user.h |  3 +++
 2 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/contrib/libvhost-user/libvhost-user.c b/contrib/libvhost-user/libvhost-user.c
index 47884c0a15..f9b5b12b28 100644
--- a/contrib/libvhost-user/libvhost-user.c
+++ b/contrib/libvhost-user/libvhost-user.c
@@ -15,6 +15,7 @@
 
 #include <qemu/osdep.h>
 #include <sys/eventfd.h>
+#include <sys/syscall.h>
 #include <linux/vhost.h>
 
 #include "qemu/atomic.h"
@@ -773,11 +774,30 @@ vu_set_vring_enable_exec(VuDev *dev, VhostUserMsg *vmsg)
 static bool
 vu_set_postcopy_advise(VuDev *dev, VhostUserMsg *vmsg)
 {
-    /* TODO: Open ufd, pass it back in the request
-     * TODO: Add addresses 
-     */
+    struct uffdio_api api_struct;
+
+    dev->postcopy_ufd = syscall(__NR_userfaultfd, O_CLOEXEC | O_NONBLOCK);
+    /* TODO: Add addresses */
     vmsg->payload.u64 = 0xcafe;
     vmsg->size = sizeof(vmsg->payload.u64);
+
+    if (dev->postcopy_ufd == -1) {
+        vu_panic(dev, "Userfaultfd not available: %s", strerror(errno));
+        goto out;
+    }
+    api_struct.api = UFFD_API;
+    api_struct.features = 0;
+    if (ioctl(dev->postcopy_ufd, UFFDIO_API, &api_struct)) {
+        vu_panic(dev, "Failed UFFDIO_API: %s", strerror(errno));
+        close(dev->postcopy_ufd);
+        dev->postcopy_ufd = -1;
+        goto out;
+    }
+    /* TODO: Stash feature flags somewhere */
+out:
+    /* Return a ufd to the QEMU */
+    vmsg->fd_num = 1;
+    vmsg->fds[0] = dev->postcopy_ufd;
     return true; /* = send a reply */
 }
 
diff --git a/contrib/libvhost-user/libvhost-user.h b/contrib/libvhost-user/libvhost-user.h
index 3987ce643d..3e8efdd919 100644
--- a/contrib/libvhost-user/libvhost-user.h
+++ b/contrib/libvhost-user/libvhost-user.h
@@ -234,6 +234,9 @@ struct VuDev {
      * re-initialize */
     vu_panic_cb panic;
     const VuDevIface *iface;
+
+    /* Postcopy data */
+    int postcopy_ufd;
 };
 
 typedef struct VuVirtqElement {
-- 
2.13.5


Re: [Qemu-devel] [RFC v2 11/32] vhub: Open userfaultfd
Posted by Peter Xu 8 years, 5 months ago
On Thu, Aug 24, 2017 at 08:27:09PM +0100, Dr. David Alan Gilbert (git) wrote:
> From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
> 
> Open a userfaultfd (on a postcopy_advise) and send it back in
> the reply to the qemu for it to monitor.
> 
> Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
> ---
>  contrib/libvhost-user/libvhost-user.c | 26 +++++++++++++++++++++++---
>  contrib/libvhost-user/libvhost-user.h |  3 +++
>  2 files changed, 26 insertions(+), 3 deletions(-)
> 
> diff --git a/contrib/libvhost-user/libvhost-user.c b/contrib/libvhost-user/libvhost-user.c
> index 47884c0a15..f9b5b12b28 100644
> --- a/contrib/libvhost-user/libvhost-user.c
> +++ b/contrib/libvhost-user/libvhost-user.c
> @@ -15,6 +15,7 @@
>  
>  #include <qemu/osdep.h>
>  #include <sys/eventfd.h>
> +#include <sys/syscall.h>
>  #include <linux/vhost.h>
>  
>  #include "qemu/atomic.h"
> @@ -773,11 +774,30 @@ vu_set_vring_enable_exec(VuDev *dev, VhostUserMsg *vmsg)
>  static bool
>  vu_set_postcopy_advise(VuDev *dev, VhostUserMsg *vmsg)
>  {
> -    /* TODO: Open ufd, pass it back in the request
> -     * TODO: Add addresses 
> -     */
> +    struct uffdio_api api_struct;
> +
> +    dev->postcopy_ufd = syscall(__NR_userfaultfd, O_CLOEXEC | O_NONBLOCK);
> +    /* TODO: Add addresses */
>      vmsg->payload.u64 = 0xcafe;
>      vmsg->size = sizeof(vmsg->payload.u64);
> +
> +    if (dev->postcopy_ufd == -1) {
> +        vu_panic(dev, "Userfaultfd not available: %s", strerror(errno));
> +        goto out;

We got error but still goto out?  I feel like we should reply with
some kind of error code when any error happens.

> +    }
> +    api_struct.api = UFFD_API;
> +    api_struct.features = 0;
> +    if (ioctl(dev->postcopy_ufd, UFFDIO_API, &api_struct)) {
> +        vu_panic(dev, "Failed UFFDIO_API: %s", strerror(errno));
> +        close(dev->postcopy_ufd);
> +        dev->postcopy_ufd = -1;
> +        goto out;

Same here.

> +    }
> +    /* TODO: Stash feature flags somewhere */
> +out:
> +    /* Return a ufd to the QEMU */
> +    vmsg->fd_num = 1;
> +    vmsg->fds[0] = dev->postcopy_ufd;
>      return true; /* = send a reply */
>  }
>  
> diff --git a/contrib/libvhost-user/libvhost-user.h b/contrib/libvhost-user/libvhost-user.h
> index 3987ce643d..3e8efdd919 100644
> --- a/contrib/libvhost-user/libvhost-user.h
> +++ b/contrib/libvhost-user/libvhost-user.h
> @@ -234,6 +234,9 @@ struct VuDev {
>       * re-initialize */
>      vu_panic_cb panic;
>      const VuDevIface *iface;
> +
> +    /* Postcopy data */
> +    int postcopy_ufd;
>  };
>  
>  typedef struct VuVirtqElement {
> -- 
> 2.13.5
> 

-- 
Peter Xu

Re: [Qemu-devel] [RFC v2 11/32] vhub: Open userfaultfd
Posted by Dr. David Alan Gilbert 8 years, 4 months ago
* Peter Xu (peterx@redhat.com) wrote:
> On Thu, Aug 24, 2017 at 08:27:09PM +0100, Dr. David Alan Gilbert (git) wrote:
> > From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
> > 
> > Open a userfaultfd (on a postcopy_advise) and send it back in
> > the reply to the qemu for it to monitor.
> > 
> > Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
> > ---
> >  contrib/libvhost-user/libvhost-user.c | 26 +++++++++++++++++++++++---
> >  contrib/libvhost-user/libvhost-user.h |  3 +++
> >  2 files changed, 26 insertions(+), 3 deletions(-)
> > 
> > diff --git a/contrib/libvhost-user/libvhost-user.c b/contrib/libvhost-user/libvhost-user.c
> > index 47884c0a15..f9b5b12b28 100644
> > --- a/contrib/libvhost-user/libvhost-user.c
> > +++ b/contrib/libvhost-user/libvhost-user.c
> > @@ -15,6 +15,7 @@
> >  
> >  #include <qemu/osdep.h>
> >  #include <sys/eventfd.h>
> > +#include <sys/syscall.h>
> >  #include <linux/vhost.h>
> >  
> >  #include "qemu/atomic.h"
> > @@ -773,11 +774,30 @@ vu_set_vring_enable_exec(VuDev *dev, VhostUserMsg *vmsg)
> >  static bool
> >  vu_set_postcopy_advise(VuDev *dev, VhostUserMsg *vmsg)
> >  {
> > -    /* TODO: Open ufd, pass it back in the request
> > -     * TODO: Add addresses 
> > -     */
> > +    struct uffdio_api api_struct;
> > +
> > +    dev->postcopy_ufd = syscall(__NR_userfaultfd, O_CLOEXEC | O_NONBLOCK);
> > +    /* TODO: Add addresses */
> >      vmsg->payload.u64 = 0xcafe;
> >      vmsg->size = sizeof(vmsg->payload.u64);
> > +
> > +    if (dev->postcopy_ufd == -1) {
> > +        vu_panic(dev, "Userfaultfd not available: %s", strerror(errno));
> > +        goto out;
> 
> We got error but still goto out?  I feel like we should reply with
> some kind of error code when any error happens.

See that the out: code returns the dev->postcopy_ufd to qemu
and in this case it's -1 so it is already flagged as an error.

> > +    }
> > +    api_struct.api = UFFD_API;
> > +    api_struct.features = 0;
> > +    if (ioctl(dev->postcopy_ufd, UFFDIO_API, &api_struct)) {
> > +        vu_panic(dev, "Failed UFFDIO_API: %s", strerror(errno));
> > +        close(dev->postcopy_ufd);
> > +        dev->postcopy_ufd = -1;
> > +        goto out;
> 
> Same here.

And there we explicitly set dev->postcopy_ufd = -1 before going to out
so it's sent as the error value.

> > +    }
> > +    /* TODO: Stash feature flags somewhere */
> > +out:
> > +    /* Return a ufd to the QEMU */
> > +    vmsg->fd_num = 1;
> > +    vmsg->fds[0] = dev->postcopy_ufd;

^^^ see that's where the -1's end up.
> >      return true; /* = send a reply */
> >  }

Dave

> >  
> > diff --git a/contrib/libvhost-user/libvhost-user.h b/contrib/libvhost-user/libvhost-user.h
> > index 3987ce643d..3e8efdd919 100644
> > --- a/contrib/libvhost-user/libvhost-user.h
> > +++ b/contrib/libvhost-user/libvhost-user.h
> > @@ -234,6 +234,9 @@ struct VuDev {
> >       * re-initialize */
> >      vu_panic_cb panic;
> >      const VuDevIface *iface;
> > +
> > +    /* Postcopy data */
> > +    int postcopy_ufd;
> >  };
> >  
> >  typedef struct VuVirtqElement {
> > -- 
> > 2.13.5
> > 
> 
> -- 
> Peter Xu
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK

Re: [Qemu-devel] [RFC v2 11/32] vhub: Open userfaultfd
Posted by Marc-André Lureau 8 years, 5 months ago
I would rather use libvhost-user: message prefix (same for similar
libvhost-user patches)

On Thu, Aug 24, 2017 at 12:27 PM, Dr. David Alan Gilbert (git)
<dgilbert@redhat.com> wrote:
> From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
>
> Open a userfaultfd (on a postcopy_advise) and send it back in
> the reply to the qemu for it to monitor.
>
> Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
> ---
>  contrib/libvhost-user/libvhost-user.c | 26 +++++++++++++++++++++++---
>  contrib/libvhost-user/libvhost-user.h |  3 +++
>  2 files changed, 26 insertions(+), 3 deletions(-)
>
> diff --git a/contrib/libvhost-user/libvhost-user.c b/contrib/libvhost-user/libvhost-user.c
> index 47884c0a15..f9b5b12b28 100644
> --- a/contrib/libvhost-user/libvhost-user.c
> +++ b/contrib/libvhost-user/libvhost-user.c
> @@ -15,6 +15,7 @@
>
>  #include <qemu/osdep.h>
>  #include <sys/eventfd.h>
> +#include <sys/syscall.h>
>  #include <linux/vhost.h>
>
>  #include "qemu/atomic.h"
> @@ -773,11 +774,30 @@ vu_set_vring_enable_exec(VuDev *dev, VhostUserMsg *vmsg)
>  static bool
>  vu_set_postcopy_advise(VuDev *dev, VhostUserMsg *vmsg)
>  {
> -    /* TODO: Open ufd, pass it back in the request
> -     * TODO: Add addresses
> -     */
> +    struct uffdio_api api_struct;
> +
> +    dev->postcopy_ufd = syscall(__NR_userfaultfd, O_CLOEXEC | O_NONBLOCK);

This will likely fail to compile on !Linux, could you add some
appropriate #ifdef?

> +    /* TODO: Add addresses */
>      vmsg->payload.u64 = 0xcafe;
>      vmsg->size = sizeof(vmsg->payload.u64);
> +
> +    if (dev->postcopy_ufd == -1) {
> +        vu_panic(dev, "Userfaultfd not available: %s", strerror(errno));
> +        goto out;
> +    }
> +    api_struct.api = UFFD_API;
> +    api_struct.features = 0;
> +    if (ioctl(dev->postcopy_ufd, UFFDIO_API, &api_struct)) {
> +        vu_panic(dev, "Failed UFFDIO_API: %s", strerror(errno));
> +        close(dev->postcopy_ufd);
> +        dev->postcopy_ufd = -1;
> +        goto out;
> +    }
> +    /* TODO: Stash feature flags somewhere */
> +out:
> +    /* Return a ufd to the QEMU */
> +    vmsg->fd_num = 1;
> +    vmsg->fds[0] = dev->postcopy_ufd;
>      return true; /* = send a reply */
>  }
>
> diff --git a/contrib/libvhost-user/libvhost-user.h b/contrib/libvhost-user/libvhost-user.h
> index 3987ce643d..3e8efdd919 100644
> --- a/contrib/libvhost-user/libvhost-user.h
> +++ b/contrib/libvhost-user/libvhost-user.h
> @@ -234,6 +234,9 @@ struct VuDev {
>       * re-initialize */
>      vu_panic_cb panic;
>      const VuDevIface *iface;
> +
> +    /* Postcopy data */
> +    int postcopy_ufd;
>  };
>
>  typedef struct VuVirtqElement {
> --
> 2.13.5
>
>



-- 
Marc-André Lureau

Re: [Qemu-devel] [RFC v2 11/32] vhub: Open userfaultfd
Posted by Dr. David Alan Gilbert 8 years, 5 months ago
* Marc-André Lureau (marcandre.lureau@gmail.com) wrote:
> I would rather use libvhost-user: message prefix (same for similar
> libvhost-user patches)

Done.

> On Thu, Aug 24, 2017 at 12:27 PM, Dr. David Alan Gilbert (git)
> <dgilbert@redhat.com> wrote:
> > From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
> >
> > Open a userfaultfd (on a postcopy_advise) and send it back in
> > the reply to the qemu for it to monitor.
> >
> > Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
> > ---
> >  contrib/libvhost-user/libvhost-user.c | 26 +++++++++++++++++++++++---
> >  contrib/libvhost-user/libvhost-user.h |  3 +++
> >  2 files changed, 26 insertions(+), 3 deletions(-)
> >
> > diff --git a/contrib/libvhost-user/libvhost-user.c b/contrib/libvhost-user/libvhost-user.c
> > index 47884c0a15..f9b5b12b28 100644
> > --- a/contrib/libvhost-user/libvhost-user.c
> > +++ b/contrib/libvhost-user/libvhost-user.c
> > @@ -15,6 +15,7 @@
> >
> >  #include <qemu/osdep.h>
> >  #include <sys/eventfd.h>
> > +#include <sys/syscall.h>
> >  #include <linux/vhost.h>
> >
> >  #include "qemu/atomic.h"
> > @@ -773,11 +774,30 @@ vu_set_vring_enable_exec(VuDev *dev, VhostUserMsg *vmsg)
> >  static bool
> >  vu_set_postcopy_advise(VuDev *dev, VhostUserMsg *vmsg)
> >  {
> > -    /* TODO: Open ufd, pass it back in the request
> > -     * TODO: Add addresses
> > -     */
> > +    struct uffdio_api api_struct;
> > +
> > +    dev->postcopy_ufd = syscall(__NR_userfaultfd, O_CLOEXEC | O_NONBLOCK);
> 
> This will likely fail to compile on !Linux, could you add some
> appropriate #ifdef?

Note that we already #include <linux/vhost.h> so this file only builds
on Linux anyway before I came along, however I'll add some ifdef's for
my new code.

Dave


> > +    /* TODO: Add addresses */
> >      vmsg->payload.u64 = 0xcafe;
> >      vmsg->size = sizeof(vmsg->payload.u64);
> > +
> > +    if (dev->postcopy_ufd == -1) {
> > +        vu_panic(dev, "Userfaultfd not available: %s", strerror(errno));
> > +        goto out;
> > +    }
> > +    api_struct.api = UFFD_API;
> > +    api_struct.features = 0;
> > +    if (ioctl(dev->postcopy_ufd, UFFDIO_API, &api_struct)) {
> > +        vu_panic(dev, "Failed UFFDIO_API: %s", strerror(errno));
> > +        close(dev->postcopy_ufd);
> > +        dev->postcopy_ufd = -1;
> > +        goto out;
> > +    }
> > +    /* TODO: Stash feature flags somewhere */
> > +out:
> > +    /* Return a ufd to the QEMU */
> > +    vmsg->fd_num = 1;
> > +    vmsg->fds[0] = dev->postcopy_ufd;
> >      return true; /* = send a reply */
> >  }
> >
> > diff --git a/contrib/libvhost-user/libvhost-user.h b/contrib/libvhost-user/libvhost-user.h
> > index 3987ce643d..3e8efdd919 100644
> > --- a/contrib/libvhost-user/libvhost-user.h
> > +++ b/contrib/libvhost-user/libvhost-user.h
> > @@ -234,6 +234,9 @@ struct VuDev {
> >       * re-initialize */
> >      vu_panic_cb panic;
> >      const VuDevIface *iface;
> > +
> > +    /* Postcopy data */
> > +    int postcopy_ufd;
> >  };
> >
> >  typedef struct VuVirtqElement {
> > --
> > 2.13.5
> >
> >
> 
> 
> 
> -- 
> Marc-André Lureau
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK