rte_vring_available_entries returns the available number of vring entries. gpa_to_vva translates guest physical address to vhost virtual address. rte_vhost_feature_disable/enable disables or enables VHOST features. rte_vhost_feature_get returns currently supported VHOST features. rte_vhost_enqueue_burst copies host packets to guest. rte_vhost_dequeue_burst gets to-be-sent packets from guest.
Signed-off-by: Huawei Xie <huawei.xie at intel.com> --- lib/librte_vhost/rte_virtio_net.h | 70 +++++++++++++++++++++++++++++++++++++++ lib/librte_vhost/virtio-net.c | 31 +++++++++++++++++ 2 files changed, 101 insertions(+) diff --git a/lib/librte_vhost/rte_virtio_net.h b/lib/librte_vhost/rte_virtio_net.h index 2766133..de2ced6 100644 --- a/lib/librte_vhost/rte_virtio_net.h +++ b/lib/librte_vhost/rte_virtio_net.h @@ -119,7 +119,49 @@ struct virtio_net_device_ops { void (* destroy_device) (volatile struct virtio_net *); /* Remove device. */ }; +static inline uint16_t __attribute__((always_inline)) +rte_vring_available_entries(struct virtio_net *dev, uint16_t queue_id) +{ + struct vhost_virtqueue *vq = dev->virtqueue[queue_id]; + return *(volatile uint16_t *)&vq->avail->idx - vq->last_used_idx_res; +} + +/** + * Function to convert guest physical addresses to vhost virtual addresses. + * This is used to convert guest virtio buffer addresses. + */ +static inline uint64_t __attribute__((always_inline)) +gpa_to_vva(struct virtio_net *dev, uint64_t guest_pa) +{ + struct virtio_memory_regions *region; + uint32_t regionidx; + uint64_t vhost_va = 0; + + for (regionidx = 0; regionidx < dev->mem->nregions; regionidx++) { + region = &dev->mem->regions[regionidx]; + if ((guest_pa >= region->guest_phys_address) && + (guest_pa <= region->guest_phys_address_end)) { + vhost_va = region->address_offset + guest_pa; + break; + } + } + return vhost_va; +} + +/** + * Disable features in feature_mask. Returns 0 on success. + */ +int rte_vhost_feature_disable(uint64_t feature_mask); + +/** + * Enable features in feature_mask. Returns 0 on success. + */ +int rte_vhost_feature_enable(uint64_t feature_mask); + +/* Returns currently supported vhost features */ +uint64_t rte_vhost_feature_get(void); +int rte_vhost_enable_guest_notification(struct virtio_net *dev, uint16_t queue_id, int enable); /* Register vhost driver. dev_name could be different for multiple instance support. */ int rte_vhost_driver_register(const char *dev_name); @@ -128,4 +170,32 @@ int rte_vhost_driver_register(const char *dev_name); int rte_vhost_driver_callback_register(struct virtio_net_device_ops const * const); /* Start vhost driver session blocking loop. */ int rte_vhost_driver_session_start(void); + +/** + * This function adds buffers to the virtio devices RX virtqueue. Buffers can + * be received from the physical port or from another virtual device. A packet + * count is returned to indicate the number of packets that were succesfully + * added to the RX queue. + * @param queue_id + * virtio queue index in mq case + * @return + * num of packets enqueued + */ +uint16_t rte_vhost_enqueue_burst(struct virtio_net *dev, uint16_t queue_id, + struct rte_mbuf **pkts, uint16_t count); + +/** + * This function gets guest buffers from the virtio device TX virtqueue, + * construct host mbufs, copies guest buffer content to host mbufs and + * store them in pkts to be processed. + * @param mbuf_pool + * mbuf_pool where host mbuf is allocated. + * @param queue_id + * virtio queue index in mq case. + * @return + * num of packets dequeued + */ +uint16_t rte_vhost_dequeue_burst(struct virtio_net *dev, uint16_t queue_id, + struct rte_mempool *mbuf_pool, struct rte_mbuf **pkts, uint16_t count); + #endif /* _VIRTIO_NET_H_ */ diff --git a/lib/librte_vhost/virtio-net.c b/lib/librte_vhost/virtio-net.c index 14e657b..de505c5 100644 --- a/lib/librte_vhost/virtio-net.c +++ b/lib/librte_vhost/virtio-net.c @@ -960,6 +960,37 @@ get_virtio_net_callbacks(void) return &vhost_device_ops; } +int rte_vhost_enable_guest_notification(struct virtio_net *dev, uint16_t queue_id, int enable) +{ + if (enable) { + RTE_LOG(ERR, VHOST_CONFIG, "guest notification isn't supported.\n"); + return -1; + } + + dev->virtqueue[queue_id]->used->flags = enable ? 0 : VRING_USED_F_NO_NOTIFY; + return 0; +} + +uint64_t rte_vhost_feature_get(void) +{ + return VHOST_FEATURES; +} + +int rte_vhost_feature_disable(uint64_t feature_mask) +{ + VHOST_FEATURES = VHOST_FEATURES & ~feature_mask; + return 0; +} + +int rte_vhost_feature_enable(uint64_t feature_mask) +{ + if ((feature_mask & VHOST_SUPPORTED_FEATURES) == feature_mask) { + VHOST_FEATURES = VHOST_FEATURES | feature_mask; + return 0; + } + return -1; +} + /* * Register ops so that we can add/remove device to data core. */ -- 1.8.1.4