Imported Upstream version 16.07.2
[deb_dpdk.git] / lib / librte_vhost / virtio-net.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include <linux/vhost.h>
35 #include <linux/virtio_net.h>
36 #include <stddef.h>
37 #include <stdint.h>
38 #include <stdlib.h>
39 #include <assert.h>
40 #include <sys/mman.h>
41 #include <unistd.h>
42 #ifdef RTE_LIBRTE_VHOST_NUMA
43 #include <numaif.h>
44 #endif
45
46 #include <sys/socket.h>
47
48 #include <rte_ethdev.h>
49 #include <rte_log.h>
50 #include <rte_string_fns.h>
51 #include <rte_memory.h>
52 #include <rte_malloc.h>
53 #include <rte_virtio_net.h>
54
55 #include "vhost-net.h"
56
57 #define MAX_VHOST_DEVICE        1024
58 static struct virtio_net *vhost_devices[MAX_VHOST_DEVICE];
59
60 /* device ops to add/remove device to/from data core. */
61 struct virtio_net_device_ops const *notify_ops;
62
63 #define VHOST_USER_F_PROTOCOL_FEATURES  30
64
65 /* Features supported by this lib. */
66 #define VHOST_SUPPORTED_FEATURES ((1ULL << VIRTIO_NET_F_MRG_RXBUF) | \
67                                 (1ULL << VIRTIO_NET_F_CTRL_VQ) | \
68                                 (1ULL << VIRTIO_NET_F_CTRL_RX) | \
69                                 (1ULL << VIRTIO_NET_F_GUEST_ANNOUNCE) | \
70                                 (VHOST_SUPPORTS_MQ)            | \
71                                 (1ULL << VIRTIO_F_VERSION_1)   | \
72                                 (1ULL << VHOST_F_LOG_ALL)      | \
73                                 (1ULL << VHOST_USER_F_PROTOCOL_FEATURES) | \
74                                 (1ULL << VIRTIO_NET_F_HOST_TSO4) | \
75                                 (1ULL << VIRTIO_NET_F_HOST_TSO6) | \
76                                 (1ULL << VIRTIO_NET_F_CSUM)    | \
77                                 (1ULL << VIRTIO_NET_F_GUEST_CSUM) | \
78                                 (1ULL << VIRTIO_NET_F_GUEST_TSO4) | \
79                                 (1ULL << VIRTIO_NET_F_GUEST_TSO6))
80
81 static uint64_t VHOST_FEATURES = VHOST_SUPPORTED_FEATURES;
82
83
84 /*
85  * Converts QEMU virtual address to Vhost virtual address. This function is
86  * used to convert the ring addresses to our address space.
87  */
88 static uint64_t
89 qva_to_vva(struct virtio_net *dev, uint64_t qemu_va)
90 {
91         struct virtio_memory_regions *region;
92         uint64_t vhost_va = 0;
93         uint32_t regionidx = 0;
94
95         /* Find the region where the address lives. */
96         for (regionidx = 0; regionidx < dev->mem->nregions; regionidx++) {
97                 region = &dev->mem->regions[regionidx];
98                 if ((qemu_va >= region->userspace_address) &&
99                         (qemu_va <= region->userspace_address +
100                         region->memory_size)) {
101                         vhost_va = qemu_va + region->guest_phys_address +
102                                 region->address_offset -
103                                 region->userspace_address;
104                         break;
105                 }
106         }
107         return vhost_va;
108 }
109
110 struct virtio_net *
111 get_device(int vid)
112 {
113         struct virtio_net *dev = vhost_devices[vid];
114
115         if (unlikely(!dev)) {
116                 RTE_LOG(ERR, VHOST_CONFIG,
117                         "(%d) device not found.\n", vid);
118         }
119
120         return dev;
121 }
122
123 static void
124 cleanup_vq(struct vhost_virtqueue *vq, int destroy)
125 {
126         if ((vq->callfd >= 0) && (destroy != 0))
127                 close(vq->callfd);
128         if (vq->kickfd >= 0)
129                 close(vq->kickfd);
130 }
131
132 /*
133  * Unmap any memory, close any file descriptors and
134  * free any memory owned by a device.
135  */
136 static void
137 cleanup_device(struct virtio_net *dev, int destroy)
138 {
139         uint32_t i;
140
141         vhost_backend_cleanup(dev);
142
143         for (i = 0; i < dev->virt_qp_nb; i++) {
144                 cleanup_vq(dev->virtqueue[i * VIRTIO_QNUM + VIRTIO_RXQ], destroy);
145                 cleanup_vq(dev->virtqueue[i * VIRTIO_QNUM + VIRTIO_TXQ], destroy);
146         }
147 }
148
149 /*
150  * Release virtqueues and device memory.
151  */
152 static void
153 free_device(struct virtio_net *dev)
154 {
155         uint32_t i;
156
157         for (i = 0; i < dev->virt_qp_nb; i++)
158                 rte_free(dev->virtqueue[i * VIRTIO_QNUM]);
159
160         rte_free(dev);
161 }
162
163 static void
164 init_vring_queue(struct vhost_virtqueue *vq, int qp_idx)
165 {
166         memset(vq, 0, sizeof(struct vhost_virtqueue));
167
168         vq->kickfd = VIRTIO_UNINITIALIZED_EVENTFD;
169         vq->callfd = VIRTIO_UNINITIALIZED_EVENTFD;
170
171         /* Backends are set to -1 indicating an inactive device. */
172         vq->backend = -1;
173
174         /* always set the default vq pair to enabled */
175         if (qp_idx == 0)
176                 vq->enabled = 1;
177 }
178
179 static void
180 init_vring_queue_pair(struct virtio_net *dev, uint32_t qp_idx)
181 {
182         uint32_t base_idx = qp_idx * VIRTIO_QNUM;
183
184         init_vring_queue(dev->virtqueue[base_idx + VIRTIO_RXQ], qp_idx);
185         init_vring_queue(dev->virtqueue[base_idx + VIRTIO_TXQ], qp_idx);
186 }
187
188 static void
189 reset_vring_queue(struct vhost_virtqueue *vq, int qp_idx)
190 {
191         int callfd;
192
193         callfd = vq->callfd;
194         init_vring_queue(vq, qp_idx);
195         vq->callfd = callfd;
196 }
197
198 static void
199 reset_vring_queue_pair(struct virtio_net *dev, uint32_t qp_idx)
200 {
201         uint32_t base_idx = qp_idx * VIRTIO_QNUM;
202
203         reset_vring_queue(dev->virtqueue[base_idx + VIRTIO_RXQ], qp_idx);
204         reset_vring_queue(dev->virtqueue[base_idx + VIRTIO_TXQ], qp_idx);
205 }
206
207 static int
208 alloc_vring_queue_pair(struct virtio_net *dev, uint32_t qp_idx)
209 {
210         struct vhost_virtqueue *virtqueue = NULL;
211         uint32_t virt_rx_q_idx = qp_idx * VIRTIO_QNUM + VIRTIO_RXQ;
212         uint32_t virt_tx_q_idx = qp_idx * VIRTIO_QNUM + VIRTIO_TXQ;
213
214         virtqueue = rte_malloc(NULL,
215                                sizeof(struct vhost_virtqueue) * VIRTIO_QNUM, 0);
216         if (virtqueue == NULL) {
217                 RTE_LOG(ERR, VHOST_CONFIG,
218                         "Failed to allocate memory for virt qp:%d.\n", qp_idx);
219                 return -1;
220         }
221
222         dev->virtqueue[virt_rx_q_idx] = virtqueue;
223         dev->virtqueue[virt_tx_q_idx] = virtqueue + VIRTIO_TXQ;
224
225         init_vring_queue_pair(dev, qp_idx);
226
227         dev->virt_qp_nb += 1;
228
229         return 0;
230 }
231
232 /*
233  * Reset some variables in device structure, while keeping few
234  * others untouched, such as vid, ifname, virt_qp_nb: they
235  * should be same unless the device is removed.
236  */
237 static void
238 reset_device(struct virtio_net *dev)
239 {
240         uint32_t i;
241
242         dev->features = 0;
243         dev->protocol_features = 0;
244         dev->flags = 0;
245
246         for (i = 0; i < dev->virt_qp_nb; i++)
247                 reset_vring_queue_pair(dev, i);
248 }
249
250 /*
251  * Function is called from the CUSE open function. The device structure is
252  * initialised and a new entry is added to the device configuration linked
253  * list.
254  */
255 int
256 vhost_new_device(void)
257 {
258         struct virtio_net *dev;
259         int i;
260
261         dev = rte_zmalloc(NULL, sizeof(struct virtio_net), 0);
262         if (dev == NULL) {
263                 RTE_LOG(ERR, VHOST_CONFIG,
264                         "Failed to allocate memory for new dev.\n");
265                 return -1;
266         }
267
268         for (i = 0; i < MAX_VHOST_DEVICE; i++) {
269                 if (vhost_devices[i] == NULL)
270                         break;
271         }
272         if (i == MAX_VHOST_DEVICE) {
273                 RTE_LOG(ERR, VHOST_CONFIG,
274                         "Failed to find a free slot for new device.\n");
275                 return -1;
276         }
277
278         vhost_devices[i] = dev;
279         dev->vid = i;
280
281         return i;
282 }
283
284 /*
285  * Function is called from the CUSE release function. This function will
286  * cleanup the device and remove it from device configuration linked list.
287  */
288 void
289 vhost_destroy_device(int vid)
290 {
291         struct virtio_net *dev = get_device(vid);
292
293         if (dev == NULL)
294                 return;
295
296         if (dev->flags & VIRTIO_DEV_RUNNING) {
297                 dev->flags &= ~VIRTIO_DEV_RUNNING;
298                 notify_ops->destroy_device(vid);
299         }
300
301         cleanup_device(dev, 1);
302         free_device(dev);
303
304         vhost_devices[vid] = NULL;
305 }
306
307 void
308 vhost_set_ifname(int vid, const char *if_name, unsigned int if_len)
309 {
310         struct virtio_net *dev;
311         unsigned int len;
312
313         dev = get_device(vid);
314         if (dev == NULL)
315                 return;
316
317         len = if_len > sizeof(dev->ifname) ?
318                 sizeof(dev->ifname) : if_len;
319
320         strncpy(dev->ifname, if_name, len);
321         dev->ifname[sizeof(dev->ifname) - 1] = '\0';
322 }
323
324
325 /*
326  * Called from CUSE IOCTL: VHOST_SET_OWNER
327  * This function just returns success at the moment unless
328  * the device hasn't been initialised.
329  */
330 int
331 vhost_set_owner(int vid)
332 {
333         struct virtio_net *dev;
334
335         dev = get_device(vid);
336         if (dev == NULL)
337                 return -1;
338
339         return 0;
340 }
341
342 /*
343  * Called from CUSE IOCTL: VHOST_RESET_OWNER
344  */
345 int
346 vhost_reset_owner(int vid)
347 {
348         struct virtio_net *dev;
349
350         dev = get_device(vid);
351         if (dev == NULL)
352                 return -1;
353
354         if (dev->flags & VIRTIO_DEV_RUNNING) {
355                 dev->flags &= ~VIRTIO_DEV_RUNNING;
356                 notify_ops->destroy_device(vid);
357         }
358
359         cleanup_device(dev, 0);
360         reset_device(dev);
361         return 0;
362 }
363
364 /*
365  * Called from CUSE IOCTL: VHOST_GET_FEATURES
366  * The features that we support are requested.
367  */
368 int
369 vhost_get_features(int vid, uint64_t *pu)
370 {
371         struct virtio_net *dev;
372
373         dev = get_device(vid);
374         if (dev == NULL)
375                 return -1;
376
377         /* Send our supported features. */
378         *pu = VHOST_FEATURES;
379         return 0;
380 }
381
382 /*
383  * Called from CUSE IOCTL: VHOST_SET_FEATURES
384  * We receive the negotiated features supported by us and the virtio device.
385  */
386 int
387 vhost_set_features(int vid, uint64_t *pu)
388 {
389         struct virtio_net *dev;
390
391         dev = get_device(vid);
392         if (dev == NULL)
393                 return -1;
394         if (*pu & ~VHOST_FEATURES)
395                 return -1;
396
397         dev->features = *pu;
398         if (dev->features &
399                 ((1 << VIRTIO_NET_F_MRG_RXBUF) | (1ULL << VIRTIO_F_VERSION_1))) {
400                 dev->vhost_hlen = sizeof(struct virtio_net_hdr_mrg_rxbuf);
401         } else {
402                 dev->vhost_hlen = sizeof(struct virtio_net_hdr);
403         }
404         LOG_DEBUG(VHOST_CONFIG,
405                 "(%d) mergeable RX buffers %s, virtio 1 %s\n",
406                 dev->vid,
407                 (dev->features & (1 << VIRTIO_NET_F_MRG_RXBUF)) ? "on" : "off",
408                 (dev->features & (1ULL << VIRTIO_F_VERSION_1)) ? "on" : "off");
409
410         return 0;
411 }
412
413 /*
414  * Called from CUSE IOCTL: VHOST_SET_VRING_NUM
415  * The virtio device sends us the size of the descriptor ring.
416  */
417 int
418 vhost_set_vring_num(int vid, struct vhost_vring_state *state)
419 {
420         struct virtio_net *dev;
421
422         dev = get_device(vid);
423         if (dev == NULL)
424                 return -1;
425
426         /* State->index refers to the queue index. The txq is 1, rxq is 0. */
427         dev->virtqueue[state->index]->size = state->num;
428
429         return 0;
430 }
431
432 /*
433  * Reallocate virtio_dev and vhost_virtqueue data structure to make them on the
434  * same numa node as the memory of vring descriptor.
435  */
436 #ifdef RTE_LIBRTE_VHOST_NUMA
437 static struct virtio_net*
438 numa_realloc(struct virtio_net *dev, int index)
439 {
440         int oldnode, newnode;
441         struct virtio_net *old_dev;
442         struct vhost_virtqueue *old_vq, *vq;
443         int ret;
444
445         /*
446          * vq is allocated on pairs, we should try to do realloc
447          * on first queue of one queue pair only.
448          */
449         if (index % VIRTIO_QNUM != 0)
450                 return dev;
451
452         old_dev = dev;
453         vq = old_vq = dev->virtqueue[index];
454
455         ret = get_mempolicy(&newnode, NULL, 0, old_vq->desc,
456                             MPOL_F_NODE | MPOL_F_ADDR);
457
458         /* check if we need to reallocate vq */
459         ret |= get_mempolicy(&oldnode, NULL, 0, old_vq,
460                              MPOL_F_NODE | MPOL_F_ADDR);
461         if (ret) {
462                 RTE_LOG(ERR, VHOST_CONFIG,
463                         "Unable to get vq numa information.\n");
464                 return dev;
465         }
466         if (oldnode != newnode) {
467                 RTE_LOG(INFO, VHOST_CONFIG,
468                         "reallocate vq from %d to %d node\n", oldnode, newnode);
469                 vq = rte_malloc_socket(NULL, sizeof(*vq) * VIRTIO_QNUM, 0,
470                                        newnode);
471                 if (!vq)
472                         return dev;
473
474                 memcpy(vq, old_vq, sizeof(*vq) * VIRTIO_QNUM);
475                 rte_free(old_vq);
476         }
477
478         /* check if we need to reallocate dev */
479         ret = get_mempolicy(&oldnode, NULL, 0, old_dev,
480                             MPOL_F_NODE | MPOL_F_ADDR);
481         if (ret) {
482                 RTE_LOG(ERR, VHOST_CONFIG,
483                         "Unable to get dev numa information.\n");
484                 goto out;
485         }
486         if (oldnode != newnode) {
487                 RTE_LOG(INFO, VHOST_CONFIG,
488                         "reallocate dev from %d to %d node\n",
489                         oldnode, newnode);
490                 dev = rte_malloc_socket(NULL, sizeof(*dev), 0, newnode);
491                 if (!dev) {
492                         dev = old_dev;
493                         goto out;
494                 }
495
496                 memcpy(dev, old_dev, sizeof(*dev));
497                 rte_free(old_dev);
498         }
499
500 out:
501         dev->virtqueue[index] = vq;
502         dev->virtqueue[index + 1] = vq + 1;
503         vhost_devices[dev->vid] = dev;
504
505         return dev;
506 }
507 #else
508 static struct virtio_net*
509 numa_realloc(struct virtio_net *dev, int index __rte_unused)
510 {
511         return dev;
512 }
513 #endif
514
515 /*
516  * Called from CUSE IOCTL: VHOST_SET_VRING_ADDR
517  * The virtio device sends us the desc, used and avail ring addresses.
518  * This function then converts these to our address space.
519  */
520 int
521 vhost_set_vring_addr(int vid, struct vhost_vring_addr *addr)
522 {
523         struct virtio_net *dev;
524         struct vhost_virtqueue *vq;
525
526         dev = get_device(vid);
527         if ((dev == NULL) || (dev->mem == NULL))
528                 return -1;
529
530         /* addr->index refers to the queue index. The txq 1, rxq is 0. */
531         vq = dev->virtqueue[addr->index];
532
533         /* The addresses are converted from QEMU virtual to Vhost virtual. */
534         vq->desc = (struct vring_desc *)(uintptr_t)qva_to_vva(dev,
535                         addr->desc_user_addr);
536         if (vq->desc == 0) {
537                 RTE_LOG(ERR, VHOST_CONFIG,
538                         "(%d) failed to find desc ring address.\n",
539                         dev->vid);
540                 return -1;
541         }
542
543         dev = numa_realloc(dev, addr->index);
544         vq = dev->virtqueue[addr->index];
545
546         vq->avail = (struct vring_avail *)(uintptr_t)qva_to_vva(dev,
547                         addr->avail_user_addr);
548         if (vq->avail == 0) {
549                 RTE_LOG(ERR, VHOST_CONFIG,
550                         "(%d) failed to find avail ring address.\n",
551                         dev->vid);
552                 return -1;
553         }
554
555         vq->used = (struct vring_used *)(uintptr_t)qva_to_vva(dev,
556                         addr->used_user_addr);
557         if (vq->used == 0) {
558                 RTE_LOG(ERR, VHOST_CONFIG,
559                         "(%d) failed to find used ring address.\n",
560                         dev->vid);
561                 return -1;
562         }
563
564         if (vq->last_used_idx != vq->used->idx) {
565                 RTE_LOG(WARNING, VHOST_CONFIG,
566                         "last_used_idx (%u) and vq->used->idx (%u) mismatches; "
567                         "some packets maybe resent for Tx and dropped for Rx\n",
568                         vq->last_used_idx, vq->used->idx);
569                 vq->last_used_idx     = vq->used->idx;
570         }
571
572         vq->log_guest_addr = addr->log_guest_addr;
573
574         LOG_DEBUG(VHOST_CONFIG, "(%d) mapped address desc: %p\n",
575                         dev->vid, vq->desc);
576         LOG_DEBUG(VHOST_CONFIG, "(%d) mapped address avail: %p\n",
577                         dev->vid, vq->avail);
578         LOG_DEBUG(VHOST_CONFIG, "(%d) mapped address used: %p\n",
579                         dev->vid, vq->used);
580         LOG_DEBUG(VHOST_CONFIG, "(%d) log_guest_addr: %" PRIx64 "\n",
581                         dev->vid, vq->log_guest_addr);
582
583         return 0;
584 }
585
586 /*
587  * Called from CUSE IOCTL: VHOST_SET_VRING_BASE
588  * The virtio device sends us the available ring last used index.
589  */
590 int
591 vhost_set_vring_base(int vid, struct vhost_vring_state *state)
592 {
593         struct virtio_net *dev;
594
595         dev = get_device(vid);
596         if (dev == NULL)
597                 return -1;
598
599         /* State->index refers to the queue index. The txq is 1, rxq is 0. */
600         dev->virtqueue[state->index]->last_used_idx = state->num;
601
602         return 0;
603 }
604
605 /*
606  * Called from CUSE IOCTL: VHOST_GET_VRING_BASE
607  * We send the virtio device our available ring last used index.
608  */
609 int
610 vhost_get_vring_base(int vid, uint32_t index,
611         struct vhost_vring_state *state)
612 {
613         struct virtio_net *dev;
614
615         dev = get_device(vid);
616         if (dev == NULL)
617                 return -1;
618
619         state->index = index;
620         /* State->index refers to the queue index. The txq is 1, rxq is 0. */
621         state->num = dev->virtqueue[state->index]->last_used_idx;
622
623         return 0;
624 }
625
626
627 /*
628  * Called from CUSE IOCTL: VHOST_SET_VRING_CALL
629  * The virtio device sends an eventfd to interrupt the guest. This fd gets
630  * copied into our process space.
631  */
632 int
633 vhost_set_vring_call(int vid, struct vhost_vring_file *file)
634 {
635         struct virtio_net *dev;
636         struct vhost_virtqueue *vq;
637         uint32_t cur_qp_idx = file->index / VIRTIO_QNUM;
638
639         dev = get_device(vid);
640         if (dev == NULL)
641                 return -1;
642
643         /*
644          * FIXME: VHOST_SET_VRING_CALL is the first per-vring message
645          * we get, so we do vring queue pair allocation here.
646          */
647         if (cur_qp_idx + 1 > dev->virt_qp_nb) {
648                 if (alloc_vring_queue_pair(dev, cur_qp_idx) < 0)
649                         return -1;
650         }
651
652         /* file->index refers to the queue index. The txq is 1, rxq is 0. */
653         vq = dev->virtqueue[file->index];
654         assert(vq != NULL);
655
656         if (vq->callfd >= 0)
657                 close(vq->callfd);
658
659         vq->callfd = file->fd;
660
661         return 0;
662 }
663
664 /*
665  * Called from CUSE IOCTL: VHOST_SET_VRING_KICK
666  * The virtio device sends an eventfd that it can use to notify us.
667  * This fd gets copied into our process space.
668  */
669 int
670 vhost_set_vring_kick(int vid, struct vhost_vring_file *file)
671 {
672         struct virtio_net *dev;
673         struct vhost_virtqueue *vq;
674
675         dev = get_device(vid);
676         if (dev == NULL)
677                 return -1;
678
679         /* file->index refers to the queue index. The txq is 1, rxq is 0. */
680         vq = dev->virtqueue[file->index];
681
682         if (vq->kickfd >= 0)
683                 close(vq->kickfd);
684
685         vq->kickfd = file->fd;
686
687         return 0;
688 }
689
690 /*
691  * Called from CUSE IOCTL: VHOST_NET_SET_BACKEND
692  * To complete device initialisation when the virtio driver is loaded,
693  * we are provided with a valid fd for a tap device (not used by us).
694  * If this happens then we can add the device to a data core.
695  * When the virtio driver is removed we get fd=-1.
696  * At that point we remove the device from the data core.
697  * The device will still exist in the device configuration linked list.
698  */
699 int
700 vhost_set_backend(int vid, struct vhost_vring_file *file)
701 {
702         struct virtio_net *dev;
703
704         dev = get_device(vid);
705         if (dev == NULL)
706                 return -1;
707
708         /* file->index refers to the queue index. The txq is 1, rxq is 0. */
709         dev->virtqueue[file->index]->backend = file->fd;
710
711         /*
712          * If the device isn't already running and both backend fds are set,
713          * we add the device.
714          */
715         if (!(dev->flags & VIRTIO_DEV_RUNNING)) {
716                 if (dev->virtqueue[VIRTIO_TXQ]->backend != VIRTIO_DEV_STOPPED &&
717                     dev->virtqueue[VIRTIO_RXQ]->backend != VIRTIO_DEV_STOPPED) {
718                         if (notify_ops->new_device(vid) < 0)
719                                 return -1;
720                         dev->flags |= VIRTIO_DEV_RUNNING;
721                 }
722         } else if (file->fd == VIRTIO_DEV_STOPPED) {
723                 dev->flags &= ~VIRTIO_DEV_RUNNING;
724                 notify_ops->destroy_device(vid);
725         }
726
727         return 0;
728 }
729
730 int
731 rte_vhost_get_numa_node(int vid)
732 {
733 #ifdef RTE_LIBRTE_VHOST_NUMA
734         struct virtio_net *dev = get_device(vid);
735         int numa_node;
736         int ret;
737
738         if (dev == NULL)
739                 return -1;
740
741         ret = get_mempolicy(&numa_node, NULL, 0, dev,
742                             MPOL_F_NODE | MPOL_F_ADDR);
743         if (ret < 0) {
744                 RTE_LOG(ERR, VHOST_CONFIG,
745                         "(%d) failed to query numa node: %d\n", vid, ret);
746                 return -1;
747         }
748
749         return numa_node;
750 #else
751         RTE_SET_USED(vid);
752         return -1;
753 #endif
754 }
755
756 uint32_t
757 rte_vhost_get_queue_num(int vid)
758 {
759         struct virtio_net *dev = get_device(vid);
760
761         if (dev == NULL)
762                 return 0;
763
764         return dev->virt_qp_nb;
765 }
766
767 int
768 rte_vhost_get_ifname(int vid, char *buf, size_t len)
769 {
770         struct virtio_net *dev = get_device(vid);
771
772         if (dev == NULL)
773                 return -1;
774
775         len = RTE_MIN(len, sizeof(dev->ifname));
776
777         strncpy(buf, dev->ifname, len);
778         buf[len - 1] = '\0';
779
780         return 0;
781 }
782
783 uint16_t
784 rte_vhost_avail_entries(int vid, uint16_t queue_id)
785 {
786         struct virtio_net *dev;
787         struct vhost_virtqueue *vq;
788
789         dev = get_device(vid);
790         if (!dev)
791                 return 0;
792
793         vq = dev->virtqueue[queue_id];
794         if (!vq->enabled)
795                 return 0;
796
797         return *(volatile uint16_t *)&vq->avail->idx - vq->last_used_idx;
798 }
799
800 int
801 rte_vhost_enable_guest_notification(int vid, uint16_t queue_id, int enable)
802 {
803         struct virtio_net *dev = get_device(vid);
804
805         if (dev == NULL)
806                 return -1;
807
808         if (enable) {
809                 RTE_LOG(ERR, VHOST_CONFIG,
810                         "guest notification isn't supported.\n");
811                 return -1;
812         }
813
814         dev->virtqueue[queue_id]->used->flags = VRING_USED_F_NO_NOTIFY;
815         return 0;
816 }
817
818 uint64_t rte_vhost_feature_get(void)
819 {
820         return VHOST_FEATURES;
821 }
822
823 int rte_vhost_feature_disable(uint64_t feature_mask)
824 {
825         VHOST_FEATURES = VHOST_FEATURES & ~feature_mask;
826         return 0;
827 }
828
829 int rte_vhost_feature_enable(uint64_t feature_mask)
830 {
831         if ((feature_mask & VHOST_SUPPORTED_FEATURES) == feature_mask) {
832                 VHOST_FEATURES = VHOST_FEATURES | feature_mask;
833                 return 0;
834         }
835         return -1;
836 }
837
838 /*
839  * Register ops so that we can add/remove device to data core.
840  */
841 int
842 rte_vhost_driver_callback_register(struct virtio_net_device_ops const * const ops)
843 {
844         notify_ops = ops;
845
846         return 0;
847 }