vhost: check all range is mapped when translating GPAs
[dpdk.git] / lib / librte_vhost / vhost.h
index 58aec2e..f7dbd2c 100644 (file)
@@ -1,11 +1,12 @@
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
+ * Copyright(c) 2010-2018 Intel Corporation
  */
 
 #ifndef _VHOST_NET_CDEV_H_
 #define _VHOST_NET_CDEV_H_
 #include <stdint.h>
 #include <stdio.h>
+#include <stdbool.h>
 #include <sys/types.h>
 #include <sys/queue.h>
 #include <unistd.h>
@@ -19,6 +20,7 @@
 #include <rte_rwlock.h>
 
 #include "rte_vhost.h"
+#include "rte_vdpa.h"
 
 /* Used to indicate that the device is running on a data core */
 #define VIRTIO_DEV_RUNNING 1
@@ -26,6 +28,8 @@
 #define VIRTIO_DEV_READY 2
 /* Used to indicate that the built-in vhost net device backend is enabled */
 #define VIRTIO_DEV_BUILTIN_VIRTIO_NET 4
+/* Used to indicate that the device has its own data path and configured */
+#define VIRTIO_DEV_VDPA_CONFIGURED 8
 
 /* Backend value set by guest. */
 #define VIRTIO_DEV_STOPPED -1
@@ -174,8 +178,6 @@ struct vhost_msg {
  #define VIRTIO_F_VERSION_1 32
 #endif
 
-#define VHOST_USER_F_PROTOCOL_FEATURES 30
-
 /* Features supported by this builtin vhost-user net driver. */
 #define VIRTIO_NET_SUPPORTED_FEATURES ((1ULL << VIRTIO_NET_F_MRG_RXBUF) | \
                                (1ULL << VIRTIO_F_ANY_LAYOUT) | \
@@ -209,6 +211,51 @@ struct guest_page {
        uint64_t size;
 };
 
+/**
+ * function prototype for the vhost backend to handler specific vhost user
+ * messages prior to the master message handling
+ *
+ * @param vid
+ *  vhost device id
+ * @param msg
+ *  Message pointer.
+ * @param require_reply
+ *  If the handler requires sending a reply, this varaible shall be written 1,
+ *  otherwise 0.
+ * @param skip_master
+ *  If the handler requires skipping the master message handling, this variable
+ *  shall be written 1, otherwise 0.
+ * @return
+ *  0 on success, -1 on failure
+ */
+typedef int (*vhost_msg_pre_handle)(int vid, void *msg,
+               uint32_t *require_reply, uint32_t *skip_master);
+
+/**
+ * function prototype for the vhost backend to handler specific vhost user
+ * messages after the master message handling is done
+ *
+ * @param vid
+ *  vhost device id
+ * @param msg
+ *  Message pointer.
+ * @param require_reply
+ *  If the handler requires sending a reply, this varaible shall be written 1,
+ *  otherwise 0.
+ * @return
+ *  0 on success, -1 on failure
+ */
+typedef int (*vhost_msg_post_handle)(int vid, void *msg,
+               uint32_t *require_reply);
+
+/**
+ * pre and post vhost user message handlers
+ */
+struct vhost_user_extern_ops {
+       vhost_msg_pre_handle pre_msg_handle;
+       vhost_msg_post_handle post_msg_handle;
+};
+
 /**
  * Device structure contains all configuration information relating
  * to the device.
@@ -241,24 +288,30 @@ struct virtio_net {
        struct guest_page       *guest_pages;
 
        int                     slave_req_fd;
-} __rte_cache_aligned;
 
+       /*
+        * Device id to identify a specific backend device.
+        * It's set to -1 for the default software implementation.
+        */
+       int                     vdpa_dev_id;
+
+       /* private data for virtio device */
+       void                    *extern_data;
+       /* pre and post vhost user message handlers for the device */
+       struct vhost_user_extern_ops extern_ops;
+} __rte_cache_aligned;
 
 #define VHOST_LOG_PAGE 4096
 
 /*
- * Atomically set a bit in memory.
+ * Mark all pages belonging to the same dirty log bitmap byte
+ * as dirty. The goal is to avoid concurrency between different
+ * threads doing atomic read-modify-writes on the same byte.
  */
-static __rte_always_inline void
-vhost_set_bit(unsigned int nr, volatile uint8_t *addr)
-{
-       __sync_fetch_and_or_8(addr, (1U << nr));
-}
-
 static __rte_always_inline void
 vhost_log_page(uint8_t *log_base, uint64_t page)
 {
-       vhost_set_bit(page % 8, &log_base[page / 8]);
+       log_base[page / 8] = 0xff;
 }
 
 static __rte_always_inline void
@@ -367,6 +420,9 @@ void free_vq(struct vhost_virtqueue *vq);
 
 int alloc_vring_queue(struct virtio_net *dev, uint32_t vring_idx);
 
+void vhost_attach_vdpa_device(int vid, int did);
+void vhost_detach_vdpa_device(int vid);
+
 void vhost_set_ifname(int, const char *if_name, unsigned int if_len);
 void vhost_enable_dequeue_zero_copy(int vid);
 void vhost_set_builtin_virtio_net(int vid, bool enable);
@@ -381,18 +437,18 @@ struct vhost_device_ops const *vhost_driver_callback_get(const char *path);
 void vhost_backend_cleanup(struct virtio_net *dev);
 
 uint64_t __vhost_iova_to_vva(struct virtio_net *dev, struct vhost_virtqueue *vq,
-                       uint64_t iova, uint64_t size, uint8_t perm);
+                       uint64_t iova, uint64_t *len, uint8_t perm);
 int vring_translate(struct virtio_net *dev, struct vhost_virtqueue *vq);
 void vring_invalidate(struct virtio_net *dev, struct vhost_virtqueue *vq);
 
 static __rte_always_inline uint64_t
 vhost_iova_to_vva(struct virtio_net *dev, struct vhost_virtqueue *vq,
-                       uint64_t iova, uint64_t size, uint8_t perm)
+                       uint64_t iova, uint64_t *len, uint8_t perm)
 {
        if (!(dev->features & (1ULL << VIRTIO_F_IOMMU_PLATFORM)))
                return rte_vhost_gpa_to_vva(dev->mem, iova);
 
-       return __vhost_iova_to_vva(dev, vq, iova, size, perm);
+       return __vhost_iova_to_vva(dev, vq, iova, len, perm);
 }
 
 #define vhost_used_event(vr) \