vhost: add IOTLB helper functions
[dpdk.git] / lib / librte_vhost / vhost.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2010-2016 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 #ifdef RTE_LIBRTE_VHOST_NUMA
40 #include <numaif.h>
41 #endif
42
43 #include <rte_errno.h>
44 #include <rte_ethdev.h>
45 #include <rte_log.h>
46 #include <rte_string_fns.h>
47 #include <rte_memory.h>
48 #include <rte_malloc.h>
49 #include <rte_vhost.h>
50
51 #include "vhost.h"
52
53 struct virtio_net *vhost_devices[MAX_VHOST_DEVICE];
54
55 struct virtio_net *
56 get_device(int vid)
57 {
58         struct virtio_net *dev = vhost_devices[vid];
59
60         if (unlikely(!dev)) {
61                 RTE_LOG(ERR, VHOST_CONFIG,
62                         "(%d) device not found.\n", vid);
63         }
64
65         return dev;
66 }
67
68 static void
69 cleanup_vq(struct vhost_virtqueue *vq, int destroy)
70 {
71         if ((vq->callfd >= 0) && (destroy != 0))
72                 close(vq->callfd);
73         if (vq->kickfd >= 0)
74                 close(vq->kickfd);
75 }
76
77 /*
78  * Unmap any memory, close any file descriptors and
79  * free any memory owned by a device.
80  */
81 void
82 cleanup_device(struct virtio_net *dev, int destroy)
83 {
84         uint32_t i;
85
86         vhost_backend_cleanup(dev);
87
88         for (i = 0; i < dev->nr_vring; i++)
89                 cleanup_vq(dev->virtqueue[i], destroy);
90 }
91
92 /*
93  * Release virtqueues and device memory.
94  */
95 static void
96 free_device(struct virtio_net *dev)
97 {
98         uint32_t i;
99         struct vhost_virtqueue *vq;
100
101         for (i = 0; i < dev->nr_vring; i++) {
102                 vq = dev->virtqueue[i];
103
104                 rte_free(vq->shadow_used_ring);
105                 rte_free(vq->batch_copy_elems);
106                 rte_mempool_free(vq->iotlb_pool);
107                 rte_free(vq);
108         }
109
110         rte_free(dev);
111 }
112
113 static void
114 init_vring_queue(struct vhost_virtqueue *vq)
115 {
116         memset(vq, 0, sizeof(struct vhost_virtqueue));
117
118         vq->kickfd = VIRTIO_UNINITIALIZED_EVENTFD;
119         vq->callfd = VIRTIO_UNINITIALIZED_EVENTFD;
120
121         /* Backends are set to -1 indicating an inactive device. */
122         vq->backend = -1;
123
124         /*
125          * always set the vq to enabled; this is to keep compatibility
126          * with the old QEMU, whereas there is no SET_VRING_ENABLE message.
127          */
128         vq->enabled = 1;
129
130         TAILQ_INIT(&vq->zmbuf_list);
131 }
132
133 static void
134 reset_vring_queue(struct vhost_virtqueue *vq)
135 {
136         int callfd;
137
138         callfd = vq->callfd;
139         init_vring_queue(vq);
140         vq->callfd = callfd;
141 }
142
143 int
144 alloc_vring_queue(struct virtio_net *dev, uint32_t vring_idx)
145 {
146         struct vhost_virtqueue *vq;
147
148         vq = rte_malloc(NULL, sizeof(struct vhost_virtqueue), 0);
149         if (vq == NULL) {
150                 RTE_LOG(ERR, VHOST_CONFIG,
151                         "Failed to allocate memory for vring:%u.\n", vring_idx);
152                 return -1;
153         }
154
155         dev->virtqueue[vring_idx] = vq;
156         init_vring_queue(vq);
157
158         dev->nr_vring += 1;
159
160         return 0;
161 }
162
163 /*
164  * Reset some variables in device structure, while keeping few
165  * others untouched, such as vid, ifname, nr_vring: they
166  * should be same unless the device is removed.
167  */
168 void
169 reset_device(struct virtio_net *dev)
170 {
171         uint32_t i;
172
173         dev->features = 0;
174         dev->protocol_features = 0;
175         dev->flags = 0;
176
177         for (i = 0; i < dev->nr_vring; i++)
178                 reset_vring_queue(dev->virtqueue[i]);
179 }
180
181 /*
182  * Invoked when there is a new vhost-user connection established (when
183  * there is a new virtio device being attached).
184  */
185 int
186 vhost_new_device(void)
187 {
188         struct virtio_net *dev;
189         int i;
190
191         dev = rte_zmalloc(NULL, sizeof(struct virtio_net), 0);
192         if (dev == NULL) {
193                 RTE_LOG(ERR, VHOST_CONFIG,
194                         "Failed to allocate memory for new dev.\n");
195                 return -1;
196         }
197
198         for (i = 0; i < MAX_VHOST_DEVICE; i++) {
199                 if (vhost_devices[i] == NULL)
200                         break;
201         }
202         if (i == MAX_VHOST_DEVICE) {
203                 RTE_LOG(ERR, VHOST_CONFIG,
204                         "Failed to find a free slot for new device.\n");
205                 rte_free(dev);
206                 return -1;
207         }
208
209         vhost_devices[i] = dev;
210         dev->vid = i;
211         dev->slave_req_fd = -1;
212
213         return i;
214 }
215
216 /*
217  * Invoked when there is the vhost-user connection is broken (when
218  * the virtio device is being detached).
219  */
220 void
221 vhost_destroy_device(int vid)
222 {
223         struct virtio_net *dev = get_device(vid);
224
225         if (dev == NULL)
226                 return;
227
228         if (dev->flags & VIRTIO_DEV_RUNNING) {
229                 dev->flags &= ~VIRTIO_DEV_RUNNING;
230                 dev->notify_ops->destroy_device(vid);
231         }
232
233         cleanup_device(dev, 1);
234         free_device(dev);
235
236         vhost_devices[vid] = NULL;
237 }
238
239 void
240 vhost_set_ifname(int vid, const char *if_name, unsigned int if_len)
241 {
242         struct virtio_net *dev;
243         unsigned int len;
244
245         dev = get_device(vid);
246         if (dev == NULL)
247                 return;
248
249         len = if_len > sizeof(dev->ifname) ?
250                 sizeof(dev->ifname) : if_len;
251
252         strncpy(dev->ifname, if_name, len);
253         dev->ifname[sizeof(dev->ifname) - 1] = '\0';
254 }
255
256 void
257 vhost_enable_dequeue_zero_copy(int vid)
258 {
259         struct virtio_net *dev = get_device(vid);
260
261         if (dev == NULL)
262                 return;
263
264         dev->dequeue_zero_copy = 1;
265 }
266
267 int
268 rte_vhost_get_mtu(int vid, uint16_t *mtu)
269 {
270         struct virtio_net *dev = get_device(vid);
271
272         if (!dev)
273                 return -ENODEV;
274
275         if (!(dev->flags & VIRTIO_DEV_READY))
276                 return -EAGAIN;
277
278         if (!(dev->features & (1ULL << VIRTIO_NET_F_MTU)))
279                 return -ENOTSUP;
280
281         *mtu = dev->mtu;
282
283         return 0;
284 }
285
286 int
287 rte_vhost_get_numa_node(int vid)
288 {
289 #ifdef RTE_LIBRTE_VHOST_NUMA
290         struct virtio_net *dev = get_device(vid);
291         int numa_node;
292         int ret;
293
294         if (dev == NULL)
295                 return -1;
296
297         ret = get_mempolicy(&numa_node, NULL, 0, dev,
298                             MPOL_F_NODE | MPOL_F_ADDR);
299         if (ret < 0) {
300                 RTE_LOG(ERR, VHOST_CONFIG,
301                         "(%d) failed to query numa node: %s\n",
302                         vid, rte_strerror(errno));
303                 return -1;
304         }
305
306         return numa_node;
307 #else
308         RTE_SET_USED(vid);
309         return -1;
310 #endif
311 }
312
313 uint32_t
314 rte_vhost_get_queue_num(int vid)
315 {
316         struct virtio_net *dev = get_device(vid);
317
318         if (dev == NULL)
319                 return 0;
320
321         return dev->nr_vring / 2;
322 }
323
324 uint16_t
325 rte_vhost_get_vring_num(int vid)
326 {
327         struct virtio_net *dev = get_device(vid);
328
329         if (dev == NULL)
330                 return 0;
331
332         return dev->nr_vring;
333 }
334
335 int
336 rte_vhost_get_ifname(int vid, char *buf, size_t len)
337 {
338         struct virtio_net *dev = get_device(vid);
339
340         if (dev == NULL)
341                 return -1;
342
343         len = RTE_MIN(len, sizeof(dev->ifname));
344
345         strncpy(buf, dev->ifname, len);
346         buf[len - 1] = '\0';
347
348         return 0;
349 }
350
351 int
352 rte_vhost_get_negotiated_features(int vid, uint64_t *features)
353 {
354         struct virtio_net *dev;
355
356         dev = get_device(vid);
357         if (!dev)
358                 return -1;
359
360         *features = dev->features;
361         return 0;
362 }
363
364 int
365 rte_vhost_get_mem_table(int vid, struct rte_vhost_memory **mem)
366 {
367         struct virtio_net *dev;
368         struct rte_vhost_memory *m;
369         size_t size;
370
371         dev = get_device(vid);
372         if (!dev)
373                 return -1;
374
375         size = dev->mem->nregions * sizeof(struct rte_vhost_mem_region);
376         m = malloc(sizeof(struct rte_vhost_memory) + size);
377         if (!m)
378                 return -1;
379
380         m->nregions = dev->mem->nregions;
381         memcpy(m->regions, dev->mem->regions, size);
382         *mem = m;
383
384         return 0;
385 }
386
387 int
388 rte_vhost_get_vhost_vring(int vid, uint16_t vring_idx,
389                           struct rte_vhost_vring *vring)
390 {
391         struct virtio_net *dev;
392         struct vhost_virtqueue *vq;
393
394         dev = get_device(vid);
395         if (!dev)
396                 return -1;
397
398         if (vring_idx >= VHOST_MAX_VRING)
399                 return -1;
400
401         vq = dev->virtqueue[vring_idx];
402         if (!vq)
403                 return -1;
404
405         vring->desc  = vq->desc;
406         vring->avail = vq->avail;
407         vring->used  = vq->used;
408         vring->log_guest_addr  = vq->log_guest_addr;
409
410         vring->callfd  = vq->callfd;
411         vring->kickfd  = vq->kickfd;
412         vring->size    = vq->size;
413
414         return 0;
415 }
416
417 uint16_t
418 rte_vhost_avail_entries(int vid, uint16_t queue_id)
419 {
420         struct virtio_net *dev;
421         struct vhost_virtqueue *vq;
422
423         dev = get_device(vid);
424         if (!dev)
425                 return 0;
426
427         vq = dev->virtqueue[queue_id];
428         if (!vq->enabled)
429                 return 0;
430
431         return *(volatile uint16_t *)&vq->avail->idx - vq->last_used_idx;
432 }
433
434 int
435 rte_vhost_enable_guest_notification(int vid, uint16_t queue_id, int enable)
436 {
437         struct virtio_net *dev = get_device(vid);
438
439         if (dev == NULL)
440                 return -1;
441
442         if (enable) {
443                 RTE_LOG(ERR, VHOST_CONFIG,
444                         "guest notification isn't supported.\n");
445                 return -1;
446         }
447
448         dev->virtqueue[queue_id]->used->flags = VRING_USED_F_NO_NOTIFY;
449         return 0;
450 }
451
452 void
453 rte_vhost_log_write(int vid, uint64_t addr, uint64_t len)
454 {
455         struct virtio_net *dev = get_device(vid);
456
457         if (dev == NULL)
458                 return;
459
460         vhost_log_write(dev, addr, len);
461 }
462
463 void
464 rte_vhost_log_used_vring(int vid, uint16_t vring_idx,
465                          uint64_t offset, uint64_t len)
466 {
467         struct virtio_net *dev;
468         struct vhost_virtqueue *vq;
469
470         dev = get_device(vid);
471         if (dev == NULL)
472                 return;
473
474         if (vring_idx >= VHOST_MAX_VRING)
475                 return;
476         vq = dev->virtqueue[vring_idx];
477         if (!vq)
478                 return;
479
480         vhost_log_used_vring(dev, vq, offset, len);
481 }
482
483 uint32_t
484 rte_vhost_rx_queue_count(int vid, uint16_t qid)
485 {
486         struct virtio_net *dev;
487         struct vhost_virtqueue *vq;
488
489         dev = get_device(vid);
490         if (dev == NULL)
491                 return 0;
492
493         if (unlikely(qid >= dev->nr_vring || (qid & 1) == 0)) {
494                 RTE_LOG(ERR, VHOST_DATA, "(%d) %s: invalid virtqueue idx %d.\n",
495                         dev->vid, __func__, qid);
496                 return 0;
497         }
498
499         vq = dev->virtqueue[qid];
500         if (vq == NULL)
501                 return 0;
502
503         if (unlikely(vq->enabled == 0 || vq->avail == NULL))
504                 return 0;
505
506         return *((volatile uint16_t *)&vq->avail->idx) - vq->last_avail_idx;
507 }