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