}
}
+/* A test to see if we have userfault available */
+static bool
+have_userfault(void)
+{
+#if defined(__linux__) && defined(__NR_userfaultfd) &&\
+ defined(UFFD_FEATURE_MISSING_SHMEM) &&\
+ defined(UFFD_FEATURE_MISSING_HUGETLBFS)
+ /* Now test the kernel we're running on really has the features */
+ int ufd = syscall(__NR_userfaultfd, O_CLOEXEC | O_NONBLOCK);
+ struct uffdio_api api_struct;
+ if (ufd < 0) {
+ return false;
+ }
+
+ api_struct.api = UFFD_API;
+ api_struct.features = UFFD_FEATURE_MISSING_SHMEM |
+ UFFD_FEATURE_MISSING_HUGETLBFS;
+ if (ioctl(ufd, UFFDIO_API, &api_struct)) {
+ close(ufd);
+ return false;
+ }
+ close(ufd);
+ return true;
+
+#else
+ return false;
+#endif
+}
+
static bool
vu_message_read(VuDev *dev, int conn_fd, VhostUserMsg *vmsg)
{
uint64_t features = 1ULL << VHOST_USER_PROTOCOL_F_LOG_SHMFD |
1ULL << VHOST_USER_PROTOCOL_F_SLAVE_REQ;
+ if (have_userfault()) {
+ features |= 1ULL << VHOST_USER_PROTOCOL_F_PAGEFAULT;
+ }
+
if (dev->iface->get_protocol_features) {
features |= dev->iface->get_protocol_features(dev);
}