835ab3a314316767dca7b6c5e40e75002948e13e
[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         vq->log_guest_addr = addr->log_guest_addr;
565
566         LOG_DEBUG(VHOST_CONFIG, "(%d) mapped address desc: %p\n",
567                         dev->vid, vq->desc);
568         LOG_DEBUG(VHOST_CONFIG, "(%d) mapped address avail: %p\n",
569                         dev->vid, vq->avail);
570         LOG_DEBUG(VHOST_CONFIG, "(%d) mapped address used: %p\n",
571                         dev->vid, vq->used);
572         LOG_DEBUG(VHOST_CONFIG, "(%d) log_guest_addr: %" PRIx64 "\n",
573                         dev->vid, vq->log_guest_addr);
574
575         return 0;
576 }
577
578 /*
579  * Called from CUSE IOCTL: VHOST_SET_VRING_BASE
580  * The virtio device sends us the available ring last used index.
581  */
582 int
583 vhost_set_vring_base(int vid, struct vhost_vring_state *state)
584 {
585         struct virtio_net *dev;
586
587         dev = get_device(vid);
588         if (dev == NULL)
589                 return -1;
590
591         /* State->index refers to the queue index. The txq is 1, rxq is 0. */
592         dev->virtqueue[state->index]->last_used_idx = state->num;
593         dev->virtqueue[state->index]->last_used_idx_res = state->num;
594
595         return 0;
596 }
597
598 /*
599  * Called from CUSE IOCTL: VHOST_GET_VRING_BASE
600  * We send the virtio device our available ring last used index.
601  */
602 int
603 vhost_get_vring_base(int vid, uint32_t index,
604         struct vhost_vring_state *state)
605 {
606         struct virtio_net *dev;
607
608         dev = get_device(vid);
609         if (dev == NULL)
610                 return -1;
611
612         state->index = index;
613         /* State->index refers to the queue index. The txq is 1, rxq is 0. */
614         state->num = dev->virtqueue[state->index]->last_used_idx;
615
616         return 0;
617 }
618
619
620 /*
621  * Called from CUSE IOCTL: VHOST_SET_VRING_CALL
622  * The virtio device sends an eventfd to interrupt the guest. This fd gets
623  * copied into our process space.
624  */
625 int
626 vhost_set_vring_call(int vid, struct vhost_vring_file *file)
627 {
628         struct virtio_net *dev;
629         struct vhost_virtqueue *vq;
630         uint32_t cur_qp_idx = file->index / VIRTIO_QNUM;
631
632         dev = get_device(vid);
633         if (dev == NULL)
634                 return -1;
635
636         /*
637          * FIXME: VHOST_SET_VRING_CALL is the first per-vring message
638          * we get, so we do vring queue pair allocation here.
639          */
640         if (cur_qp_idx + 1 > dev->virt_qp_nb) {
641                 if (alloc_vring_queue_pair(dev, cur_qp_idx) < 0)
642                         return -1;
643         }
644
645         /* file->index refers to the queue index. The txq is 1, rxq is 0. */
646         vq = dev->virtqueue[file->index];
647         assert(vq != NULL);
648
649         if (vq->callfd >= 0)
650                 close(vq->callfd);
651
652         vq->callfd = file->fd;
653
654         return 0;
655 }
656
657 /*
658  * Called from CUSE IOCTL: VHOST_SET_VRING_KICK
659  * The virtio device sends an eventfd that it can use to notify us.
660  * This fd gets copied into our process space.
661  */
662 int
663 vhost_set_vring_kick(int vid, struct vhost_vring_file *file)
664 {
665         struct virtio_net *dev;
666         struct vhost_virtqueue *vq;
667
668         dev = get_device(vid);
669         if (dev == NULL)
670                 return -1;
671
672         /* file->index refers to the queue index. The txq is 1, rxq is 0. */
673         vq = dev->virtqueue[file->index];
674
675         if (vq->kickfd >= 0)
676                 close(vq->kickfd);
677
678         vq->kickfd = file->fd;
679
680         return 0;
681 }
682
683 /*
684  * Called from CUSE IOCTL: VHOST_NET_SET_BACKEND
685  * To complete device initialisation when the virtio driver is loaded,
686  * we are provided with a valid fd for a tap device (not used by us).
687  * If this happens then we can add the device to a data core.
688  * When the virtio driver is removed we get fd=-1.
689  * At that point we remove the device from the data core.
690  * The device will still exist in the device configuration linked list.
691  */
692 int
693 vhost_set_backend(int vid, struct vhost_vring_file *file)
694 {
695         struct virtio_net *dev;
696
697         dev = get_device(vid);
698         if (dev == NULL)
699                 return -1;
700
701         /* file->index refers to the queue index. The txq is 1, rxq is 0. */
702         dev->virtqueue[file->index]->backend = file->fd;
703
704         /*
705          * If the device isn't already running and both backend fds are set,
706          * we add the device.
707          */
708         if (!(dev->flags & VIRTIO_DEV_RUNNING)) {
709                 if (dev->virtqueue[VIRTIO_TXQ]->backend != VIRTIO_DEV_STOPPED &&
710                     dev->virtqueue[VIRTIO_RXQ]->backend != VIRTIO_DEV_STOPPED) {
711                         if (notify_ops->new_device(vid) < 0)
712                                 return -1;
713                         dev->flags |= VIRTIO_DEV_RUNNING;
714                 }
715         } else if (file->fd == VIRTIO_DEV_STOPPED) {
716                 dev->flags &= ~VIRTIO_DEV_RUNNING;
717                 notify_ops->destroy_device(vid);
718         }
719
720         return 0;
721 }
722
723 int
724 rte_vhost_get_numa_node(int vid)
725 {
726 #ifdef RTE_LIBRTE_VHOST_NUMA
727         struct virtio_net *dev = get_device(vid);
728         int numa_node;
729         int ret;
730
731         if (dev == NULL)
732                 return -1;
733
734         ret = get_mempolicy(&numa_node, NULL, 0, dev,
735                             MPOL_F_NODE | MPOL_F_ADDR);
736         if (ret < 0) {
737                 RTE_LOG(ERR, VHOST_CONFIG,
738                         "(%d) failed to query numa node: %d\n", vid, ret);
739                 return -1;
740         }
741
742         return numa_node;
743 #else
744         RTE_SET_USED(vid);
745         return -1;
746 #endif
747 }
748
749 uint32_t
750 rte_vhost_get_queue_num(int vid)
751 {
752         struct virtio_net *dev = get_device(vid);
753
754         if (dev == NULL)
755                 return 0;
756
757         return dev->virt_qp_nb;
758 }
759
760 int
761 rte_vhost_get_ifname(int vid, char *buf, size_t len)
762 {
763         struct virtio_net *dev = get_device(vid);
764
765         if (dev == NULL)
766                 return -1;
767
768         len = RTE_MIN(len, sizeof(dev->ifname));
769
770         strncpy(buf, dev->ifname, len);
771         buf[len - 1] = '\0';
772
773         return 0;
774 }
775
776 uint16_t
777 rte_vhost_avail_entries(int vid, uint16_t queue_id)
778 {
779         struct virtio_net *dev;
780         struct vhost_virtqueue *vq;
781
782         dev = get_device(vid);
783         if (!dev)
784                 return 0;
785
786         vq = dev->virtqueue[queue_id];
787         if (!vq->enabled)
788                 return 0;
789
790         return *(volatile uint16_t *)&vq->avail->idx - vq->last_used_idx_res;
791 }
792
793 int
794 rte_vhost_enable_guest_notification(int vid, uint16_t queue_id, int enable)
795 {
796         struct virtio_net *dev = get_device(vid);
797
798         if (dev == NULL)
799                 return -1;
800
801         if (enable) {
802                 RTE_LOG(ERR, VHOST_CONFIG,
803                         "guest notification isn't supported.\n");
804                 return -1;
805         }
806
807         dev->virtqueue[queue_id]->used->flags = VRING_USED_F_NO_NOTIFY;
808         return 0;
809 }
810
811 uint64_t rte_vhost_feature_get(void)
812 {
813         return VHOST_FEATURES;
814 }
815
816 int rte_vhost_feature_disable(uint64_t feature_mask)
817 {
818         VHOST_FEATURES = VHOST_FEATURES & ~feature_mask;
819         return 0;
820 }
821
822 int rte_vhost_feature_enable(uint64_t feature_mask)
823 {
824         if ((feature_mask & VHOST_SUPPORTED_FEATURES) == feature_mask) {
825                 VHOST_FEATURES = VHOST_FEATURES | feature_mask;
826                 return 0;
827         }
828         return -1;
829 }
830
831 /*
832  * Register ops so that we can add/remove device to data core.
833  */
834 int
835 rte_vhost_driver_callback_register(struct virtio_net_device_ops const * const ops)
836 {
837         notify_ops = ops;
838
839         return 0;
840 }