xref: /openbmc/qemu/hw/virtio/vhost-user.c (revision 406d2aa2)
1 /*
2  * vhost-user
3  *
4  * Copyright (c) 2013 Virtual Open Systems Sarl.
5  *
6  * This work is licensed under the terms of the GNU GPL, version 2 or later.
7  * See the COPYING file in the top-level directory.
8  *
9  */
10 
11 #include "qemu/osdep.h"
12 #include "qapi/error.h"
13 #include "hw/virtio/vhost.h"
14 #include "hw/virtio/vhost-backend.h"
15 #include "hw/virtio/virtio-net.h"
16 #include "chardev/char-fe.h"
17 #include "sysemu/kvm.h"
18 #include "qemu/error-report.h"
19 #include "qemu/sockets.h"
20 
21 #include <sys/ioctl.h>
22 #include <sys/socket.h>
23 #include <sys/un.h>
24 #include <linux/vhost.h>
25 
26 #define VHOST_MEMORY_MAX_NREGIONS    8
27 #define VHOST_USER_F_PROTOCOL_FEATURES 30
28 
29 /*
30  * Maximum size of virtio device config space
31  */
32 #define VHOST_USER_MAX_CONFIG_SIZE 256
33 
34 enum VhostUserProtocolFeature {
35     VHOST_USER_PROTOCOL_F_MQ = 0,
36     VHOST_USER_PROTOCOL_F_LOG_SHMFD = 1,
37     VHOST_USER_PROTOCOL_F_RARP = 2,
38     VHOST_USER_PROTOCOL_F_REPLY_ACK = 3,
39     VHOST_USER_PROTOCOL_F_NET_MTU = 4,
40     VHOST_USER_PROTOCOL_F_SLAVE_REQ = 5,
41     VHOST_USER_PROTOCOL_F_CROSS_ENDIAN = 6,
42 
43     VHOST_USER_PROTOCOL_F_MAX
44 };
45 
46 #define VHOST_USER_PROTOCOL_FEATURE_MASK ((1 << VHOST_USER_PROTOCOL_F_MAX) - 1)
47 
48 typedef enum VhostUserRequest {
49     VHOST_USER_NONE = 0,
50     VHOST_USER_GET_FEATURES = 1,
51     VHOST_USER_SET_FEATURES = 2,
52     VHOST_USER_SET_OWNER = 3,
53     VHOST_USER_RESET_OWNER = 4,
54     VHOST_USER_SET_MEM_TABLE = 5,
55     VHOST_USER_SET_LOG_BASE = 6,
56     VHOST_USER_SET_LOG_FD = 7,
57     VHOST_USER_SET_VRING_NUM = 8,
58     VHOST_USER_SET_VRING_ADDR = 9,
59     VHOST_USER_SET_VRING_BASE = 10,
60     VHOST_USER_GET_VRING_BASE = 11,
61     VHOST_USER_SET_VRING_KICK = 12,
62     VHOST_USER_SET_VRING_CALL = 13,
63     VHOST_USER_SET_VRING_ERR = 14,
64     VHOST_USER_GET_PROTOCOL_FEATURES = 15,
65     VHOST_USER_SET_PROTOCOL_FEATURES = 16,
66     VHOST_USER_GET_QUEUE_NUM = 17,
67     VHOST_USER_SET_VRING_ENABLE = 18,
68     VHOST_USER_SEND_RARP = 19,
69     VHOST_USER_NET_SET_MTU = 20,
70     VHOST_USER_SET_SLAVE_REQ_FD = 21,
71     VHOST_USER_IOTLB_MSG = 22,
72     VHOST_USER_SET_VRING_ENDIAN = 23,
73     VHOST_USER_GET_CONFIG = 24,
74     VHOST_USER_SET_CONFIG = 25,
75     VHOST_USER_MAX
76 } VhostUserRequest;
77 
78 typedef enum VhostUserSlaveRequest {
79     VHOST_USER_SLAVE_NONE = 0,
80     VHOST_USER_SLAVE_IOTLB_MSG = 1,
81     VHOST_USER_SLAVE_CONFIG_CHANGE_MSG = 2,
82     VHOST_USER_SLAVE_MAX
83 }  VhostUserSlaveRequest;
84 
85 typedef struct VhostUserMemoryRegion {
86     uint64_t guest_phys_addr;
87     uint64_t memory_size;
88     uint64_t userspace_addr;
89     uint64_t mmap_offset;
90 } VhostUserMemoryRegion;
91 
92 typedef struct VhostUserMemory {
93     uint32_t nregions;
94     uint32_t padding;
95     VhostUserMemoryRegion regions[VHOST_MEMORY_MAX_NREGIONS];
96 } VhostUserMemory;
97 
98 typedef struct VhostUserLog {
99     uint64_t mmap_size;
100     uint64_t mmap_offset;
101 } VhostUserLog;
102 
103 typedef struct VhostUserConfig {
104     uint32_t offset;
105     uint32_t size;
106     uint32_t flags;
107     uint8_t region[VHOST_USER_MAX_CONFIG_SIZE];
108 } VhostUserConfig;
109 
110 static VhostUserConfig c __attribute__ ((unused));
111 #define VHOST_USER_CONFIG_HDR_SIZE (sizeof(c.offset) \
112                                    + sizeof(c.size) \
113                                    + sizeof(c.flags))
114 
115 typedef struct VhostUserMsg {
116     VhostUserRequest request;
117 
118 #define VHOST_USER_VERSION_MASK     (0x3)
119 #define VHOST_USER_REPLY_MASK       (0x1<<2)
120 #define VHOST_USER_NEED_REPLY_MASK  (0x1 << 3)
121     uint32_t flags;
122     uint32_t size; /* the following payload size */
123     union {
124 #define VHOST_USER_VRING_IDX_MASK   (0xff)
125 #define VHOST_USER_VRING_NOFD_MASK  (0x1<<8)
126         uint64_t u64;
127         struct vhost_vring_state state;
128         struct vhost_vring_addr addr;
129         VhostUserMemory memory;
130         VhostUserLog log;
131         struct vhost_iotlb_msg iotlb;
132         VhostUserConfig config;
133     } payload;
134 } QEMU_PACKED VhostUserMsg;
135 
136 static VhostUserMsg m __attribute__ ((unused));
137 #define VHOST_USER_HDR_SIZE (sizeof(m.request) \
138                             + sizeof(m.flags) \
139                             + sizeof(m.size))
140 
141 #define VHOST_USER_PAYLOAD_SIZE (sizeof(m) - VHOST_USER_HDR_SIZE)
142 
143 /* The version of the protocol we support */
144 #define VHOST_USER_VERSION    (0x1)
145 
146 struct vhost_user {
147     CharBackend *chr;
148     int slave_fd;
149 };
150 
151 static bool ioeventfd_enabled(void)
152 {
153     return kvm_enabled() && kvm_eventfds_enabled();
154 }
155 
156 static int vhost_user_read(struct vhost_dev *dev, VhostUserMsg *msg)
157 {
158     struct vhost_user *u = dev->opaque;
159     CharBackend *chr = u->chr;
160     uint8_t *p = (uint8_t *) msg;
161     int r, size = VHOST_USER_HDR_SIZE;
162 
163     r = qemu_chr_fe_read_all(chr, p, size);
164     if (r != size) {
165         error_report("Failed to read msg header. Read %d instead of %d."
166                      " Original request %d.", r, size, msg->request);
167         goto fail;
168     }
169 
170     /* validate received flags */
171     if (msg->flags != (VHOST_USER_REPLY_MASK | VHOST_USER_VERSION)) {
172         error_report("Failed to read msg header."
173                 " Flags 0x%x instead of 0x%x.", msg->flags,
174                 VHOST_USER_REPLY_MASK | VHOST_USER_VERSION);
175         goto fail;
176     }
177 
178     /* validate message size is sane */
179     if (msg->size > VHOST_USER_PAYLOAD_SIZE) {
180         error_report("Failed to read msg header."
181                 " Size %d exceeds the maximum %zu.", msg->size,
182                 VHOST_USER_PAYLOAD_SIZE);
183         goto fail;
184     }
185 
186     if (msg->size) {
187         p += VHOST_USER_HDR_SIZE;
188         size = msg->size;
189         r = qemu_chr_fe_read_all(chr, p, size);
190         if (r != size) {
191             error_report("Failed to read msg payload."
192                          " Read %d instead of %d.", r, msg->size);
193             goto fail;
194         }
195     }
196 
197     return 0;
198 
199 fail:
200     return -1;
201 }
202 
203 static int process_message_reply(struct vhost_dev *dev,
204                                  const VhostUserMsg *msg)
205 {
206     VhostUserMsg msg_reply;
207 
208     if ((msg->flags & VHOST_USER_NEED_REPLY_MASK) == 0) {
209         return 0;
210     }
211 
212     if (vhost_user_read(dev, &msg_reply) < 0) {
213         return -1;
214     }
215 
216     if (msg_reply.request != msg->request) {
217         error_report("Received unexpected msg type."
218                      "Expected %d received %d",
219                      msg->request, msg_reply.request);
220         return -1;
221     }
222 
223     return msg_reply.payload.u64 ? -1 : 0;
224 }
225 
226 static bool vhost_user_one_time_request(VhostUserRequest request)
227 {
228     switch (request) {
229     case VHOST_USER_SET_OWNER:
230     case VHOST_USER_RESET_OWNER:
231     case VHOST_USER_SET_MEM_TABLE:
232     case VHOST_USER_GET_QUEUE_NUM:
233     case VHOST_USER_NET_SET_MTU:
234         return true;
235     default:
236         return false;
237     }
238 }
239 
240 /* most non-init callers ignore the error */
241 static int vhost_user_write(struct vhost_dev *dev, VhostUserMsg *msg,
242                             int *fds, int fd_num)
243 {
244     struct vhost_user *u = dev->opaque;
245     CharBackend *chr = u->chr;
246     int ret, size = VHOST_USER_HDR_SIZE + msg->size;
247 
248     /*
249      * For non-vring specific requests, like VHOST_USER_SET_MEM_TABLE,
250      * we just need send it once in the first time. For later such
251      * request, we just ignore it.
252      */
253     if (vhost_user_one_time_request(msg->request) && dev->vq_index != 0) {
254         msg->flags &= ~VHOST_USER_NEED_REPLY_MASK;
255         return 0;
256     }
257 
258     if (qemu_chr_fe_set_msgfds(chr, fds, fd_num) < 0) {
259         error_report("Failed to set msg fds.");
260         return -1;
261     }
262 
263     ret = qemu_chr_fe_write_all(chr, (const uint8_t *) msg, size);
264     if (ret != size) {
265         error_report("Failed to write msg."
266                      " Wrote %d instead of %d.", ret, size);
267         return -1;
268     }
269 
270     return 0;
271 }
272 
273 static int vhost_user_set_log_base(struct vhost_dev *dev, uint64_t base,
274                                    struct vhost_log *log)
275 {
276     int fds[VHOST_MEMORY_MAX_NREGIONS];
277     size_t fd_num = 0;
278     bool shmfd = virtio_has_feature(dev->protocol_features,
279                                     VHOST_USER_PROTOCOL_F_LOG_SHMFD);
280     VhostUserMsg msg = {
281         .request = VHOST_USER_SET_LOG_BASE,
282         .flags = VHOST_USER_VERSION,
283         .payload.log.mmap_size = log->size * sizeof(*(log->log)),
284         .payload.log.mmap_offset = 0,
285         .size = sizeof(msg.payload.log),
286     };
287 
288     if (shmfd && log->fd != -1) {
289         fds[fd_num++] = log->fd;
290     }
291 
292     if (vhost_user_write(dev, &msg, fds, fd_num) < 0) {
293         return -1;
294     }
295 
296     if (shmfd) {
297         msg.size = 0;
298         if (vhost_user_read(dev, &msg) < 0) {
299             return -1;
300         }
301 
302         if (msg.request != VHOST_USER_SET_LOG_BASE) {
303             error_report("Received unexpected msg type. "
304                          "Expected %d received %d",
305                          VHOST_USER_SET_LOG_BASE, msg.request);
306             return -1;
307         }
308     }
309 
310     return 0;
311 }
312 
313 static int vhost_user_set_mem_table(struct vhost_dev *dev,
314                                     struct vhost_memory *mem)
315 {
316     int fds[VHOST_MEMORY_MAX_NREGIONS];
317     int i, fd;
318     size_t fd_num = 0;
319     bool reply_supported = virtio_has_feature(dev->protocol_features,
320                                               VHOST_USER_PROTOCOL_F_REPLY_ACK);
321 
322     VhostUserMsg msg = {
323         .request = VHOST_USER_SET_MEM_TABLE,
324         .flags = VHOST_USER_VERSION,
325     };
326 
327     if (reply_supported) {
328         msg.flags |= VHOST_USER_NEED_REPLY_MASK;
329     }
330 
331     for (i = 0; i < dev->mem->nregions; ++i) {
332         struct vhost_memory_region *reg = dev->mem->regions + i;
333         ram_addr_t offset;
334         MemoryRegion *mr;
335 
336         assert((uintptr_t)reg->userspace_addr == reg->userspace_addr);
337         mr = memory_region_from_host((void *)(uintptr_t)reg->userspace_addr,
338                                      &offset);
339         fd = memory_region_get_fd(mr);
340         if (fd > 0) {
341             msg.payload.memory.regions[fd_num].userspace_addr = reg->userspace_addr;
342             msg.payload.memory.regions[fd_num].memory_size  = reg->memory_size;
343             msg.payload.memory.regions[fd_num].guest_phys_addr = reg->guest_phys_addr;
344             msg.payload.memory.regions[fd_num].mmap_offset = offset;
345             assert(fd_num < VHOST_MEMORY_MAX_NREGIONS);
346             fds[fd_num++] = fd;
347         }
348     }
349 
350     msg.payload.memory.nregions = fd_num;
351 
352     if (!fd_num) {
353         error_report("Failed initializing vhost-user memory map, "
354                      "consider using -object memory-backend-file share=on");
355         return -1;
356     }
357 
358     msg.size = sizeof(msg.payload.memory.nregions);
359     msg.size += sizeof(msg.payload.memory.padding);
360     msg.size += fd_num * sizeof(VhostUserMemoryRegion);
361 
362     if (vhost_user_write(dev, &msg, fds, fd_num) < 0) {
363         return -1;
364     }
365 
366     if (reply_supported) {
367         return process_message_reply(dev, &msg);
368     }
369 
370     return 0;
371 }
372 
373 static int vhost_user_set_vring_addr(struct vhost_dev *dev,
374                                      struct vhost_vring_addr *addr)
375 {
376     VhostUserMsg msg = {
377         .request = VHOST_USER_SET_VRING_ADDR,
378         .flags = VHOST_USER_VERSION,
379         .payload.addr = *addr,
380         .size = sizeof(msg.payload.addr),
381     };
382 
383     if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
384         return -1;
385     }
386 
387     return 0;
388 }
389 
390 static int vhost_user_set_vring_endian(struct vhost_dev *dev,
391                                        struct vhost_vring_state *ring)
392 {
393     bool cross_endian = virtio_has_feature(dev->protocol_features,
394                                            VHOST_USER_PROTOCOL_F_CROSS_ENDIAN);
395     VhostUserMsg msg = {
396         .request = VHOST_USER_SET_VRING_ENDIAN,
397         .flags = VHOST_USER_VERSION,
398         .payload.state = *ring,
399         .size = sizeof(msg.payload.state),
400     };
401 
402     if (!cross_endian) {
403         error_report("vhost-user trying to send unhandled ioctl");
404         return -1;
405     }
406 
407     if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
408         return -1;
409     }
410 
411     return 0;
412 }
413 
414 static int vhost_set_vring(struct vhost_dev *dev,
415                            unsigned long int request,
416                            struct vhost_vring_state *ring)
417 {
418     VhostUserMsg msg = {
419         .request = request,
420         .flags = VHOST_USER_VERSION,
421         .payload.state = *ring,
422         .size = sizeof(msg.payload.state),
423     };
424 
425     if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
426         return -1;
427     }
428 
429     return 0;
430 }
431 
432 static int vhost_user_set_vring_num(struct vhost_dev *dev,
433                                     struct vhost_vring_state *ring)
434 {
435     return vhost_set_vring(dev, VHOST_USER_SET_VRING_NUM, ring);
436 }
437 
438 static int vhost_user_set_vring_base(struct vhost_dev *dev,
439                                      struct vhost_vring_state *ring)
440 {
441     return vhost_set_vring(dev, VHOST_USER_SET_VRING_BASE, ring);
442 }
443 
444 static int vhost_user_set_vring_enable(struct vhost_dev *dev, int enable)
445 {
446     int i;
447 
448     if (!virtio_has_feature(dev->features, VHOST_USER_F_PROTOCOL_FEATURES)) {
449         return -1;
450     }
451 
452     for (i = 0; i < dev->nvqs; ++i) {
453         struct vhost_vring_state state = {
454             .index = dev->vq_index + i,
455             .num   = enable,
456         };
457 
458         vhost_set_vring(dev, VHOST_USER_SET_VRING_ENABLE, &state);
459     }
460 
461     return 0;
462 }
463 
464 static int vhost_user_get_vring_base(struct vhost_dev *dev,
465                                      struct vhost_vring_state *ring)
466 {
467     VhostUserMsg msg = {
468         .request = VHOST_USER_GET_VRING_BASE,
469         .flags = VHOST_USER_VERSION,
470         .payload.state = *ring,
471         .size = sizeof(msg.payload.state),
472     };
473 
474     if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
475         return -1;
476     }
477 
478     if (vhost_user_read(dev, &msg) < 0) {
479         return -1;
480     }
481 
482     if (msg.request != VHOST_USER_GET_VRING_BASE) {
483         error_report("Received unexpected msg type. Expected %d received %d",
484                      VHOST_USER_GET_VRING_BASE, msg.request);
485         return -1;
486     }
487 
488     if (msg.size != sizeof(msg.payload.state)) {
489         error_report("Received bad msg size.");
490         return -1;
491     }
492 
493     *ring = msg.payload.state;
494 
495     return 0;
496 }
497 
498 static int vhost_set_vring_file(struct vhost_dev *dev,
499                                 VhostUserRequest request,
500                                 struct vhost_vring_file *file)
501 {
502     int fds[VHOST_MEMORY_MAX_NREGIONS];
503     size_t fd_num = 0;
504     VhostUserMsg msg = {
505         .request = request,
506         .flags = VHOST_USER_VERSION,
507         .payload.u64 = file->index & VHOST_USER_VRING_IDX_MASK,
508         .size = sizeof(msg.payload.u64),
509     };
510 
511     if (ioeventfd_enabled() && file->fd > 0) {
512         fds[fd_num++] = file->fd;
513     } else {
514         msg.payload.u64 |= VHOST_USER_VRING_NOFD_MASK;
515     }
516 
517     if (vhost_user_write(dev, &msg, fds, fd_num) < 0) {
518         return -1;
519     }
520 
521     return 0;
522 }
523 
524 static int vhost_user_set_vring_kick(struct vhost_dev *dev,
525                                      struct vhost_vring_file *file)
526 {
527     return vhost_set_vring_file(dev, VHOST_USER_SET_VRING_KICK, file);
528 }
529 
530 static int vhost_user_set_vring_call(struct vhost_dev *dev,
531                                      struct vhost_vring_file *file)
532 {
533     return vhost_set_vring_file(dev, VHOST_USER_SET_VRING_CALL, file);
534 }
535 
536 static int vhost_user_set_u64(struct vhost_dev *dev, int request, uint64_t u64)
537 {
538     VhostUserMsg msg = {
539         .request = request,
540         .flags = VHOST_USER_VERSION,
541         .payload.u64 = u64,
542         .size = sizeof(msg.payload.u64),
543     };
544 
545     if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
546         return -1;
547     }
548 
549     return 0;
550 }
551 
552 static int vhost_user_set_features(struct vhost_dev *dev,
553                                    uint64_t features)
554 {
555     return vhost_user_set_u64(dev, VHOST_USER_SET_FEATURES, features);
556 }
557 
558 static int vhost_user_set_protocol_features(struct vhost_dev *dev,
559                                             uint64_t features)
560 {
561     return vhost_user_set_u64(dev, VHOST_USER_SET_PROTOCOL_FEATURES, features);
562 }
563 
564 static int vhost_user_get_u64(struct vhost_dev *dev, int request, uint64_t *u64)
565 {
566     VhostUserMsg msg = {
567         .request = request,
568         .flags = VHOST_USER_VERSION,
569     };
570 
571     if (vhost_user_one_time_request(request) && dev->vq_index != 0) {
572         return 0;
573     }
574 
575     if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
576         return -1;
577     }
578 
579     if (vhost_user_read(dev, &msg) < 0) {
580         return -1;
581     }
582 
583     if (msg.request != request) {
584         error_report("Received unexpected msg type. Expected %d received %d",
585                      request, msg.request);
586         return -1;
587     }
588 
589     if (msg.size != sizeof(msg.payload.u64)) {
590         error_report("Received bad msg size.");
591         return -1;
592     }
593 
594     *u64 = msg.payload.u64;
595 
596     return 0;
597 }
598 
599 static int vhost_user_get_features(struct vhost_dev *dev, uint64_t *features)
600 {
601     return vhost_user_get_u64(dev, VHOST_USER_GET_FEATURES, features);
602 }
603 
604 static int vhost_user_set_owner(struct vhost_dev *dev)
605 {
606     VhostUserMsg msg = {
607         .request = VHOST_USER_SET_OWNER,
608         .flags = VHOST_USER_VERSION,
609     };
610 
611     if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
612         return -1;
613     }
614 
615     return 0;
616 }
617 
618 static int vhost_user_reset_device(struct vhost_dev *dev)
619 {
620     VhostUserMsg msg = {
621         .request = VHOST_USER_RESET_OWNER,
622         .flags = VHOST_USER_VERSION,
623     };
624 
625     if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
626         return -1;
627     }
628 
629     return 0;
630 }
631 
632 static int vhost_user_slave_handle_config_change(struct vhost_dev *dev)
633 {
634     int ret = -1;
635 
636     if (!dev->config_ops) {
637         return -1;
638     }
639 
640     if (dev->config_ops->vhost_dev_config_notifier) {
641         ret = dev->config_ops->vhost_dev_config_notifier(dev);
642     }
643 
644     return ret;
645 }
646 
647 static void slave_read(void *opaque)
648 {
649     struct vhost_dev *dev = opaque;
650     struct vhost_user *u = dev->opaque;
651     VhostUserMsg msg = { 0, };
652     int size, ret = 0;
653 
654     /* Read header */
655     size = read(u->slave_fd, &msg, VHOST_USER_HDR_SIZE);
656     if (size != VHOST_USER_HDR_SIZE) {
657         error_report("Failed to read from slave.");
658         goto err;
659     }
660 
661     if (msg.size > VHOST_USER_PAYLOAD_SIZE) {
662         error_report("Failed to read msg header."
663                 " Size %d exceeds the maximum %zu.", msg.size,
664                 VHOST_USER_PAYLOAD_SIZE);
665         goto err;
666     }
667 
668     /* Read payload */
669     size = read(u->slave_fd, &msg.payload, msg.size);
670     if (size != msg.size) {
671         error_report("Failed to read payload from slave.");
672         goto err;
673     }
674 
675     switch (msg.request) {
676     case VHOST_USER_SLAVE_IOTLB_MSG:
677         ret = vhost_backend_handle_iotlb_msg(dev, &msg.payload.iotlb);
678         break;
679     case VHOST_USER_SLAVE_CONFIG_CHANGE_MSG :
680         ret = vhost_user_slave_handle_config_change(dev);
681         break;
682     default:
683         error_report("Received unexpected msg type.");
684         ret = -EINVAL;
685     }
686 
687     /*
688      * REPLY_ACK feature handling. Other reply types has to be managed
689      * directly in their request handlers.
690      */
691     if (msg.flags & VHOST_USER_NEED_REPLY_MASK) {
692         msg.flags &= ~VHOST_USER_NEED_REPLY_MASK;
693         msg.flags |= VHOST_USER_REPLY_MASK;
694 
695         msg.payload.u64 = !!ret;
696         msg.size = sizeof(msg.payload.u64);
697 
698         size = write(u->slave_fd, &msg, VHOST_USER_HDR_SIZE + msg.size);
699         if (size != VHOST_USER_HDR_SIZE + msg.size) {
700             error_report("Failed to send msg reply to slave.");
701             goto err;
702         }
703     }
704 
705     return;
706 
707 err:
708     qemu_set_fd_handler(u->slave_fd, NULL, NULL, NULL);
709     close(u->slave_fd);
710     u->slave_fd = -1;
711     return;
712 }
713 
714 static int vhost_setup_slave_channel(struct vhost_dev *dev)
715 {
716     VhostUserMsg msg = {
717         .request = VHOST_USER_SET_SLAVE_REQ_FD,
718         .flags = VHOST_USER_VERSION,
719     };
720     struct vhost_user *u = dev->opaque;
721     int sv[2], ret = 0;
722     bool reply_supported = virtio_has_feature(dev->protocol_features,
723                                               VHOST_USER_PROTOCOL_F_REPLY_ACK);
724 
725     if (!virtio_has_feature(dev->protocol_features,
726                             VHOST_USER_PROTOCOL_F_SLAVE_REQ)) {
727         return 0;
728     }
729 
730     if (socketpair(PF_UNIX, SOCK_STREAM, 0, sv) == -1) {
731         error_report("socketpair() failed");
732         return -1;
733     }
734 
735     u->slave_fd = sv[0];
736     qemu_set_fd_handler(u->slave_fd, slave_read, NULL, dev);
737 
738     if (reply_supported) {
739         msg.flags |= VHOST_USER_NEED_REPLY_MASK;
740     }
741 
742     ret = vhost_user_write(dev, &msg, &sv[1], 1);
743     if (ret) {
744         goto out;
745     }
746 
747     if (reply_supported) {
748         ret = process_message_reply(dev, &msg);
749     }
750 
751 out:
752     close(sv[1]);
753     if (ret) {
754         qemu_set_fd_handler(u->slave_fd, NULL, NULL, NULL);
755         close(u->slave_fd);
756         u->slave_fd = -1;
757     }
758 
759     return ret;
760 }
761 
762 static int vhost_user_init(struct vhost_dev *dev, void *opaque)
763 {
764     uint64_t features, protocol_features;
765     struct vhost_user *u;
766     int err;
767 
768     assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER);
769 
770     u = g_new0(struct vhost_user, 1);
771     u->chr = opaque;
772     u->slave_fd = -1;
773     dev->opaque = u;
774 
775     err = vhost_user_get_features(dev, &features);
776     if (err < 0) {
777         return err;
778     }
779 
780     if (virtio_has_feature(features, VHOST_USER_F_PROTOCOL_FEATURES)) {
781         dev->backend_features |= 1ULL << VHOST_USER_F_PROTOCOL_FEATURES;
782 
783         err = vhost_user_get_u64(dev, VHOST_USER_GET_PROTOCOL_FEATURES,
784                                  &protocol_features);
785         if (err < 0) {
786             return err;
787         }
788 
789         dev->protocol_features =
790             protocol_features & VHOST_USER_PROTOCOL_FEATURE_MASK;
791         err = vhost_user_set_protocol_features(dev, dev->protocol_features);
792         if (err < 0) {
793             return err;
794         }
795 
796         /* query the max queues we support if backend supports Multiple Queue */
797         if (dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_MQ)) {
798             err = vhost_user_get_u64(dev, VHOST_USER_GET_QUEUE_NUM,
799                                      &dev->max_queues);
800             if (err < 0) {
801                 return err;
802             }
803         }
804 
805         if (virtio_has_feature(features, VIRTIO_F_IOMMU_PLATFORM) &&
806                 !(virtio_has_feature(dev->protocol_features,
807                     VHOST_USER_PROTOCOL_F_SLAVE_REQ) &&
808                  virtio_has_feature(dev->protocol_features,
809                     VHOST_USER_PROTOCOL_F_REPLY_ACK))) {
810             error_report("IOMMU support requires reply-ack and "
811                          "slave-req protocol features.");
812             return -1;
813         }
814     }
815 
816     if (dev->migration_blocker == NULL &&
817         !virtio_has_feature(dev->protocol_features,
818                             VHOST_USER_PROTOCOL_F_LOG_SHMFD)) {
819         error_setg(&dev->migration_blocker,
820                    "Migration disabled: vhost-user backend lacks "
821                    "VHOST_USER_PROTOCOL_F_LOG_SHMFD feature.");
822     }
823 
824     err = vhost_setup_slave_channel(dev);
825     if (err < 0) {
826         return err;
827     }
828 
829     return 0;
830 }
831 
832 static int vhost_user_cleanup(struct vhost_dev *dev)
833 {
834     struct vhost_user *u;
835 
836     assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER);
837 
838     u = dev->opaque;
839     if (u->slave_fd >= 0) {
840         qemu_set_fd_handler(u->slave_fd, NULL, NULL, NULL);
841         close(u->slave_fd);
842         u->slave_fd = -1;
843     }
844     g_free(u);
845     dev->opaque = 0;
846 
847     return 0;
848 }
849 
850 static int vhost_user_get_vq_index(struct vhost_dev *dev, int idx)
851 {
852     assert(idx >= dev->vq_index && idx < dev->vq_index + dev->nvqs);
853 
854     return idx;
855 }
856 
857 static int vhost_user_memslots_limit(struct vhost_dev *dev)
858 {
859     return VHOST_MEMORY_MAX_NREGIONS;
860 }
861 
862 static bool vhost_user_requires_shm_log(struct vhost_dev *dev)
863 {
864     assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER);
865 
866     return virtio_has_feature(dev->protocol_features,
867                               VHOST_USER_PROTOCOL_F_LOG_SHMFD);
868 }
869 
870 static int vhost_user_migration_done(struct vhost_dev *dev, char* mac_addr)
871 {
872     VhostUserMsg msg = { 0 };
873 
874     assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER);
875 
876     /* If guest supports GUEST_ANNOUNCE do nothing */
877     if (virtio_has_feature(dev->acked_features, VIRTIO_NET_F_GUEST_ANNOUNCE)) {
878         return 0;
879     }
880 
881     /* if backend supports VHOST_USER_PROTOCOL_F_RARP ask it to send the RARP */
882     if (virtio_has_feature(dev->protocol_features,
883                            VHOST_USER_PROTOCOL_F_RARP)) {
884         msg.request = VHOST_USER_SEND_RARP;
885         msg.flags = VHOST_USER_VERSION;
886         memcpy((char *)&msg.payload.u64, mac_addr, 6);
887         msg.size = sizeof(msg.payload.u64);
888 
889         return vhost_user_write(dev, &msg, NULL, 0);
890     }
891     return -1;
892 }
893 
894 static bool vhost_user_can_merge(struct vhost_dev *dev,
895                                  uint64_t start1, uint64_t size1,
896                                  uint64_t start2, uint64_t size2)
897 {
898     ram_addr_t offset;
899     int mfd, rfd;
900     MemoryRegion *mr;
901 
902     mr = memory_region_from_host((void *)(uintptr_t)start1, &offset);
903     mfd = memory_region_get_fd(mr);
904 
905     mr = memory_region_from_host((void *)(uintptr_t)start2, &offset);
906     rfd = memory_region_get_fd(mr);
907 
908     return mfd == rfd;
909 }
910 
911 static int vhost_user_net_set_mtu(struct vhost_dev *dev, uint16_t mtu)
912 {
913     VhostUserMsg msg;
914     bool reply_supported = virtio_has_feature(dev->protocol_features,
915                                               VHOST_USER_PROTOCOL_F_REPLY_ACK);
916 
917     if (!(dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_NET_MTU))) {
918         return 0;
919     }
920 
921     msg.request = VHOST_USER_NET_SET_MTU;
922     msg.payload.u64 = mtu;
923     msg.size = sizeof(msg.payload.u64);
924     msg.flags = VHOST_USER_VERSION;
925     if (reply_supported) {
926         msg.flags |= VHOST_USER_NEED_REPLY_MASK;
927     }
928 
929     if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
930         return -1;
931     }
932 
933     /* If reply_ack supported, slave has to ack specified MTU is valid */
934     if (reply_supported) {
935         return process_message_reply(dev, &msg);
936     }
937 
938     return 0;
939 }
940 
941 static int vhost_user_send_device_iotlb_msg(struct vhost_dev *dev,
942                                             struct vhost_iotlb_msg *imsg)
943 {
944     VhostUserMsg msg = {
945         .request = VHOST_USER_IOTLB_MSG,
946         .size = sizeof(msg.payload.iotlb),
947         .flags = VHOST_USER_VERSION | VHOST_USER_NEED_REPLY_MASK,
948         .payload.iotlb = *imsg,
949     };
950 
951     if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
952         return -EFAULT;
953     }
954 
955     return process_message_reply(dev, &msg);
956 }
957 
958 
959 static void vhost_user_set_iotlb_callback(struct vhost_dev *dev, int enabled)
960 {
961     /* No-op as the receive channel is not dedicated to IOTLB messages. */
962 }
963 
964 static int vhost_user_get_config(struct vhost_dev *dev, uint8_t *config,
965                                  uint32_t config_len)
966 {
967     VhostUserMsg msg = {
968         msg.request = VHOST_USER_GET_CONFIG,
969         msg.flags = VHOST_USER_VERSION,
970         msg.size = VHOST_USER_CONFIG_HDR_SIZE + config_len,
971     };
972 
973     if (config_len > VHOST_USER_MAX_CONFIG_SIZE) {
974         return -1;
975     }
976 
977     msg.payload.config.offset = 0;
978     msg.payload.config.size = config_len;
979     if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
980         return -1;
981     }
982 
983     if (vhost_user_read(dev, &msg) < 0) {
984         return -1;
985     }
986 
987     if (msg.request != VHOST_USER_GET_CONFIG) {
988         error_report("Received unexpected msg type. Expected %d received %d",
989                      VHOST_USER_GET_CONFIG, msg.request);
990         return -1;
991     }
992 
993     if (msg.size != VHOST_USER_CONFIG_HDR_SIZE + config_len) {
994         error_report("Received bad msg size.");
995         return -1;
996     }
997 
998     memcpy(config, msg.payload.config.region, config_len);
999 
1000     return 0;
1001 }
1002 
1003 static int vhost_user_set_config(struct vhost_dev *dev, const uint8_t *data,
1004                                  uint32_t offset, uint32_t size, uint32_t flags)
1005 {
1006     uint8_t *p;
1007     bool reply_supported = virtio_has_feature(dev->protocol_features,
1008                                               VHOST_USER_PROTOCOL_F_REPLY_ACK);
1009 
1010     VhostUserMsg msg = {
1011         msg.request = VHOST_USER_SET_CONFIG,
1012         msg.flags = VHOST_USER_VERSION,
1013         msg.size = VHOST_USER_CONFIG_HDR_SIZE + size,
1014     };
1015 
1016     if (reply_supported) {
1017         msg.flags |= VHOST_USER_NEED_REPLY_MASK;
1018     }
1019 
1020     if (size > VHOST_USER_MAX_CONFIG_SIZE) {
1021         return -1;
1022     }
1023 
1024     msg.payload.config.offset = offset,
1025     msg.payload.config.size = size,
1026     msg.payload.config.flags = flags,
1027     p = msg.payload.config.region;
1028     memcpy(p, data, size);
1029 
1030     if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
1031         return -1;
1032     }
1033 
1034     if (reply_supported) {
1035         return process_message_reply(dev, &msg);
1036     }
1037 
1038     return 0;
1039 }
1040 
1041 const VhostOps user_ops = {
1042         .backend_type = VHOST_BACKEND_TYPE_USER,
1043         .vhost_backend_init = vhost_user_init,
1044         .vhost_backend_cleanup = vhost_user_cleanup,
1045         .vhost_backend_memslots_limit = vhost_user_memslots_limit,
1046         .vhost_set_log_base = vhost_user_set_log_base,
1047         .vhost_set_mem_table = vhost_user_set_mem_table,
1048         .vhost_set_vring_addr = vhost_user_set_vring_addr,
1049         .vhost_set_vring_endian = vhost_user_set_vring_endian,
1050         .vhost_set_vring_num = vhost_user_set_vring_num,
1051         .vhost_set_vring_base = vhost_user_set_vring_base,
1052         .vhost_get_vring_base = vhost_user_get_vring_base,
1053         .vhost_set_vring_kick = vhost_user_set_vring_kick,
1054         .vhost_set_vring_call = vhost_user_set_vring_call,
1055         .vhost_set_features = vhost_user_set_features,
1056         .vhost_get_features = vhost_user_get_features,
1057         .vhost_set_owner = vhost_user_set_owner,
1058         .vhost_reset_device = vhost_user_reset_device,
1059         .vhost_get_vq_index = vhost_user_get_vq_index,
1060         .vhost_set_vring_enable = vhost_user_set_vring_enable,
1061         .vhost_requires_shm_log = vhost_user_requires_shm_log,
1062         .vhost_migration_done = vhost_user_migration_done,
1063         .vhost_backend_can_merge = vhost_user_can_merge,
1064         .vhost_net_set_mtu = vhost_user_net_set_mtu,
1065         .vhost_set_iotlb_callback = vhost_user_set_iotlb_callback,
1066         .vhost_send_device_iotlb_msg = vhost_user_send_device_iotlb_msg,
1067         .vhost_get_config = vhost_user_get_config,
1068         .vhost_set_config = vhost_user_set_config,
1069 };
1070