diff options
author | Dr. David Alan Gilbert <dgilbert@redhat.com> | 2018-03-12 17:21:03 +0000 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2018-03-20 05:03:27 +0200 |
commit | 2a84ffc0be7e54f2f4b76cb3ebfdde0b37bba9f0 (patch) | |
tree | 6f14b50e56fb97f95c2db8c33cf8b56ba5d2678f | |
parent | d6e47717b028f0404073d9c60f2fa50d79252333 (diff) | |
download | qemu-2a84ffc0be7e54f2f4b76cb3ebfdde0b37bba9f0.tar.gz |
libvhost-user: Open userfaultfd
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>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
-rw-r--r-- | contrib/libvhost-user/libvhost-user.c | 42 | ||||
-rw-r--r-- | contrib/libvhost-user/libvhost-user.h | 3 |
2 files changed, 43 insertions, 2 deletions
diff --git a/contrib/libvhost-user/libvhost-user.c b/contrib/libvhost-user/libvhost-user.c index ed9f3148d3..9e31f47b7a 100644 --- a/contrib/libvhost-user/libvhost-user.c +++ b/contrib/libvhost-user/libvhost-user.c @@ -26,9 +26,20 @@ #include <sys/socket.h> #include <sys/eventfd.h> #include <sys/mman.h> +#include "qemu/compiler.h" + +#if defined(__linux__) +#include <sys/syscall.h> +#include <fcntl.h> +#include <sys/ioctl.h> #include <linux/vhost.h> -#include "qemu/compiler.h" +#ifdef __NR_userfaultfd +#include <linux/userfaultfd.h> +#endif + +#endif + #include "qemu/atomic.h" #include "libvhost-user.h" @@ -888,8 +899,35 @@ vu_set_config(VuDev *dev, VhostUserMsg *vmsg) static bool vu_set_postcopy_advise(VuDev *dev, VhostUserMsg *vmsg) { - /* TODO: Open ufd, pass it back in the request */ + dev->postcopy_ufd = -1; +#ifdef UFFDIO_API + struct uffdio_api api_struct; + + dev->postcopy_ufd = syscall(__NR_userfaultfd, O_CLOEXEC | O_NONBLOCK); vmsg->size = 0; +#endif + + if (dev->postcopy_ufd == -1) { + vu_panic(dev, "Userfaultfd not available: %s", strerror(errno)); + goto out; + } + +#ifdef UFFDIO_API + 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 */ +#endif + +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 00d78a8810..074b7860f6 100644 --- a/contrib/libvhost-user/libvhost-user.h +++ b/contrib/libvhost-user/libvhost-user.h @@ -282,6 +282,9 @@ struct VuDev { * re-initialize */ vu_panic_cb panic; const VuDevIface *iface; + + /* Postcopy data */ + int postcopy_ufd; }; typedef struct VuVirtqElement { |