1 /* 2 * vhost-net support 3 * 4 * Copyright Red Hat, Inc. 2010 5 * 6 * Authors: 7 * Michael S. Tsirkin <mst@redhat.com> 8 * 9 * This work is licensed under the terms of the GNU GPL, version 2. See 10 * the COPYING file in the top-level directory. 11 * 12 * Contributions after 2012-01-13 are licensed under the terms of the 13 * GNU GPL, version 2 or (at your option) any later version. 14 */ 15 16 #include "qemu/osdep.h" 17 #include "net/net.h" 18 #include "net/tap.h" 19 #include "net/vhost-user.h" 20 21 #include "hw/virtio/virtio-net.h" 22 #include "net/vhost_net.h" 23 #include "qemu/error-report.h" 24 25 26 #ifdef CONFIG_VHOST_NET 27 #include <linux/vhost.h> 28 #include <sys/socket.h> 29 #include <linux/kvm.h> 30 #include <netpacket/packet.h> 31 #include <net/ethernet.h> 32 #include <net/if.h> 33 #include <netinet/in.h> 34 35 36 #include "standard-headers/linux/virtio_ring.h" 37 #include "hw/virtio/vhost.h" 38 #include "hw/virtio/virtio-bus.h" 39 40 struct vhost_net { 41 struct vhost_dev dev; 42 struct vhost_virtqueue vqs[2]; 43 int backend; 44 NetClientState *nc; 45 }; 46 47 /* Features supported by host kernel. */ 48 static const int kernel_feature_bits[] = { 49 VIRTIO_F_NOTIFY_ON_EMPTY, 50 VIRTIO_RING_F_INDIRECT_DESC, 51 VIRTIO_RING_F_EVENT_IDX, 52 VIRTIO_NET_F_MRG_RXBUF, 53 VIRTIO_F_VERSION_1, 54 VIRTIO_NET_F_MTU, 55 VIRTIO_F_IOMMU_PLATFORM, 56 VHOST_INVALID_FEATURE_BIT 57 }; 58 59 /* Features supported by others. */ 60 static const int user_feature_bits[] = { 61 VIRTIO_F_NOTIFY_ON_EMPTY, 62 VIRTIO_RING_F_INDIRECT_DESC, 63 VIRTIO_RING_F_EVENT_IDX, 64 65 VIRTIO_F_ANY_LAYOUT, 66 VIRTIO_F_VERSION_1, 67 VIRTIO_NET_F_CSUM, 68 VIRTIO_NET_F_GUEST_CSUM, 69 VIRTIO_NET_F_GSO, 70 VIRTIO_NET_F_GUEST_TSO4, 71 VIRTIO_NET_F_GUEST_TSO6, 72 VIRTIO_NET_F_GUEST_ECN, 73 VIRTIO_NET_F_GUEST_UFO, 74 VIRTIO_NET_F_HOST_TSO4, 75 VIRTIO_NET_F_HOST_TSO6, 76 VIRTIO_NET_F_HOST_ECN, 77 VIRTIO_NET_F_HOST_UFO, 78 VIRTIO_NET_F_MRG_RXBUF, 79 VIRTIO_NET_F_MTU, 80 VIRTIO_F_IOMMU_PLATFORM, 81 82 /* This bit implies RARP isn't sent by QEMU out of band */ 83 VIRTIO_NET_F_GUEST_ANNOUNCE, 84 85 VIRTIO_NET_F_MQ, 86 87 VHOST_INVALID_FEATURE_BIT 88 }; 89 90 static const int *vhost_net_get_feature_bits(struct vhost_net *net) 91 { 92 const int *feature_bits = 0; 93 94 switch (net->nc->info->type) { 95 case NET_CLIENT_DRIVER_TAP: 96 feature_bits = kernel_feature_bits; 97 break; 98 case NET_CLIENT_DRIVER_VHOST_USER: 99 feature_bits = user_feature_bits; 100 break; 101 default: 102 error_report("Feature bits not defined for this type: %d", 103 net->nc->info->type); 104 break; 105 } 106 107 return feature_bits; 108 } 109 110 uint64_t vhost_net_get_features(struct vhost_net *net, uint64_t features) 111 { 112 return vhost_get_features(&net->dev, vhost_net_get_feature_bits(net), 113 features); 114 } 115 116 void vhost_net_ack_features(struct vhost_net *net, uint64_t features) 117 { 118 net->dev.acked_features = net->dev.backend_features; 119 vhost_ack_features(&net->dev, vhost_net_get_feature_bits(net), features); 120 } 121 122 uint64_t vhost_net_get_max_queues(VHostNetState *net) 123 { 124 return net->dev.max_queues; 125 } 126 127 uint64_t vhost_net_get_acked_features(VHostNetState *net) 128 { 129 return net->dev.acked_features; 130 } 131 132 static int vhost_net_get_fd(NetClientState *backend) 133 { 134 switch (backend->info->type) { 135 case NET_CLIENT_DRIVER_TAP: 136 return tap_get_fd(backend); 137 default: 138 fprintf(stderr, "vhost-net requires tap backend\n"); 139 return -EBADFD; 140 } 141 } 142 143 struct vhost_net *vhost_net_init(VhostNetOptions *options) 144 { 145 int r; 146 bool backend_kernel = options->backend_type == VHOST_BACKEND_TYPE_KERNEL; 147 struct vhost_net *net = g_new0(struct vhost_net, 1); 148 uint64_t features = 0; 149 150 if (!options->net_backend) { 151 fprintf(stderr, "vhost-net requires net backend to be setup\n"); 152 goto fail; 153 } 154 net->nc = options->net_backend; 155 156 net->dev.max_queues = 1; 157 net->dev.nvqs = 2; 158 net->dev.vqs = net->vqs; 159 160 if (backend_kernel) { 161 r = vhost_net_get_fd(options->net_backend); 162 if (r < 0) { 163 goto fail; 164 } 165 net->dev.backend_features = qemu_has_vnet_hdr(options->net_backend) 166 ? 0 : (1ULL << VHOST_NET_F_VIRTIO_NET_HDR); 167 net->backend = r; 168 net->dev.protocol_features = 0; 169 } else { 170 net->dev.backend_features = 0; 171 net->dev.protocol_features = 0; 172 net->backend = -1; 173 174 /* vhost-user needs vq_index to initiate a specific queue pair */ 175 net->dev.vq_index = net->nc->queue_index * net->dev.nvqs; 176 } 177 178 r = vhost_dev_init(&net->dev, options->opaque, 179 options->backend_type, options->busyloop_timeout); 180 if (r < 0) { 181 goto fail; 182 } 183 if (backend_kernel) { 184 if (!qemu_has_vnet_hdr_len(options->net_backend, 185 sizeof(struct virtio_net_hdr_mrg_rxbuf))) { 186 net->dev.features &= ~(1ULL << VIRTIO_NET_F_MRG_RXBUF); 187 } 188 if (~net->dev.features & net->dev.backend_features) { 189 fprintf(stderr, "vhost lacks feature mask %" PRIu64 190 " for backend\n", 191 (uint64_t)(~net->dev.features & net->dev.backend_features)); 192 goto fail; 193 } 194 } 195 196 /* Set sane init value. Override when guest acks. */ 197 if (net->nc->info->type == NET_CLIENT_DRIVER_VHOST_USER) { 198 features = vhost_user_get_acked_features(net->nc); 199 if (~net->dev.features & features) { 200 fprintf(stderr, "vhost lacks feature mask %" PRIu64 201 " for backend\n", 202 (uint64_t)(~net->dev.features & features)); 203 goto fail; 204 } 205 } 206 207 vhost_net_ack_features(net, features); 208 209 return net; 210 211 fail: 212 vhost_dev_cleanup(&net->dev); 213 g_free(net); 214 return NULL; 215 } 216 217 static void vhost_net_set_vq_index(struct vhost_net *net, int vq_index) 218 { 219 net->dev.vq_index = vq_index; 220 } 221 222 static int vhost_net_start_one(struct vhost_net *net, 223 VirtIODevice *dev) 224 { 225 struct vhost_vring_file file = { }; 226 int r; 227 228 net->dev.nvqs = 2; 229 net->dev.vqs = net->vqs; 230 231 r = vhost_dev_enable_notifiers(&net->dev, dev); 232 if (r < 0) { 233 goto fail_notifiers; 234 } 235 236 r = vhost_dev_start(&net->dev, dev); 237 if (r < 0) { 238 goto fail_start; 239 } 240 241 if (net->nc->info->poll) { 242 net->nc->info->poll(net->nc, false); 243 } 244 245 if (net->nc->info->type == NET_CLIENT_DRIVER_TAP) { 246 qemu_set_fd_handler(net->backend, NULL, NULL, NULL); 247 file.fd = net->backend; 248 for (file.index = 0; file.index < net->dev.nvqs; ++file.index) { 249 r = vhost_net_set_backend(&net->dev, &file); 250 if (r < 0) { 251 r = -errno; 252 goto fail; 253 } 254 } 255 } 256 return 0; 257 fail: 258 file.fd = -1; 259 if (net->nc->info->type == NET_CLIENT_DRIVER_TAP) { 260 while (file.index-- > 0) { 261 int r = vhost_net_set_backend(&net->dev, &file); 262 assert(r >= 0); 263 } 264 } 265 if (net->nc->info->poll) { 266 net->nc->info->poll(net->nc, true); 267 } 268 vhost_dev_stop(&net->dev, dev); 269 fail_start: 270 vhost_dev_disable_notifiers(&net->dev, dev); 271 fail_notifiers: 272 return r; 273 } 274 275 static void vhost_net_stop_one(struct vhost_net *net, 276 VirtIODevice *dev) 277 { 278 struct vhost_vring_file file = { .fd = -1 }; 279 280 if (net->nc->info->type == NET_CLIENT_DRIVER_TAP) { 281 for (file.index = 0; file.index < net->dev.nvqs; ++file.index) { 282 int r = vhost_net_set_backend(&net->dev, &file); 283 assert(r >= 0); 284 } 285 } 286 if (net->nc->info->poll) { 287 net->nc->info->poll(net->nc, true); 288 } 289 vhost_dev_stop(&net->dev, dev); 290 vhost_dev_disable_notifiers(&net->dev, dev); 291 } 292 293 int vhost_net_start(VirtIODevice *dev, NetClientState *ncs, 294 int total_queues) 295 { 296 BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(dev))); 297 VirtioBusState *vbus = VIRTIO_BUS(qbus); 298 VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(vbus); 299 int r, e, i; 300 301 if (!k->set_guest_notifiers) { 302 error_report("binding does not support guest notifiers"); 303 return -ENOSYS; 304 } 305 306 for (i = 0; i < total_queues; i++) { 307 struct vhost_net *net; 308 309 net = get_vhost_net(ncs[i].peer); 310 vhost_net_set_vq_index(net, i * 2); 311 312 /* Suppress the masking guest notifiers on vhost user 313 * because vhost user doesn't interrupt masking/unmasking 314 * properly. 315 */ 316 if (net->nc->info->type == NET_CLIENT_DRIVER_VHOST_USER) { 317 dev->use_guest_notifier_mask = false; 318 } 319 } 320 321 r = k->set_guest_notifiers(qbus->parent, total_queues * 2, true); 322 if (r < 0) { 323 error_report("Error binding guest notifier: %d", -r); 324 goto err; 325 } 326 327 for (i = 0; i < total_queues; i++) { 328 r = vhost_net_start_one(get_vhost_net(ncs[i].peer), dev); 329 330 if (r < 0) { 331 goto err_start; 332 } 333 334 if (ncs[i].peer->vring_enable) { 335 /* restore vring enable state */ 336 r = vhost_set_vring_enable(ncs[i].peer, ncs[i].peer->vring_enable); 337 338 if (r < 0) { 339 goto err_start; 340 } 341 } 342 } 343 344 return 0; 345 346 err_start: 347 while (--i >= 0) { 348 vhost_net_stop_one(get_vhost_net(ncs[i].peer), dev); 349 } 350 e = k->set_guest_notifiers(qbus->parent, total_queues * 2, false); 351 if (e < 0) { 352 fprintf(stderr, "vhost guest notifier cleanup failed: %d\n", e); 353 fflush(stderr); 354 } 355 err: 356 return r; 357 } 358 359 void vhost_net_stop(VirtIODevice *dev, NetClientState *ncs, 360 int total_queues) 361 { 362 BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(dev))); 363 VirtioBusState *vbus = VIRTIO_BUS(qbus); 364 VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(vbus); 365 int i, r; 366 367 for (i = 0; i < total_queues; i++) { 368 vhost_net_stop_one(get_vhost_net(ncs[i].peer), dev); 369 } 370 371 r = k->set_guest_notifiers(qbus->parent, total_queues * 2, false); 372 if (r < 0) { 373 fprintf(stderr, "vhost guest notifier cleanup failed: %d\n", r); 374 fflush(stderr); 375 } 376 assert(r >= 0); 377 } 378 379 void vhost_net_cleanup(struct vhost_net *net) 380 { 381 vhost_dev_cleanup(&net->dev); 382 } 383 384 int vhost_net_notify_migration_done(struct vhost_net *net, char* mac_addr) 385 { 386 const VhostOps *vhost_ops = net->dev.vhost_ops; 387 388 assert(vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER); 389 assert(vhost_ops->vhost_migration_done); 390 391 return vhost_ops->vhost_migration_done(&net->dev, mac_addr); 392 } 393 394 bool vhost_net_virtqueue_pending(VHostNetState *net, int idx) 395 { 396 return vhost_virtqueue_pending(&net->dev, idx); 397 } 398 399 void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev, 400 int idx, bool mask) 401 { 402 vhost_virtqueue_mask(&net->dev, dev, idx, mask); 403 } 404 405 VHostNetState *get_vhost_net(NetClientState *nc) 406 { 407 VHostNetState *vhost_net = 0; 408 409 if (!nc) { 410 return 0; 411 } 412 413 switch (nc->info->type) { 414 case NET_CLIENT_DRIVER_TAP: 415 vhost_net = tap_get_vhost_net(nc); 416 break; 417 case NET_CLIENT_DRIVER_VHOST_USER: 418 vhost_net = vhost_user_get_vhost_net(nc); 419 assert(vhost_net); 420 break; 421 default: 422 break; 423 } 424 425 return vhost_net; 426 } 427 428 int vhost_set_vring_enable(NetClientState *nc, int enable) 429 { 430 VHostNetState *net = get_vhost_net(nc); 431 const VhostOps *vhost_ops = net->dev.vhost_ops; 432 433 nc->vring_enable = enable; 434 435 if (vhost_ops && vhost_ops->vhost_set_vring_enable) { 436 return vhost_ops->vhost_set_vring_enable(&net->dev, enable); 437 } 438 439 return 0; 440 } 441 442 int vhost_net_set_mtu(struct vhost_net *net, uint16_t mtu) 443 { 444 const VhostOps *vhost_ops = net->dev.vhost_ops; 445 446 if (!vhost_ops->vhost_net_set_mtu) { 447 return 0; 448 } 449 450 return vhost_ops->vhost_net_set_mtu(&net->dev, mtu); 451 } 452 453 #else 454 uint64_t vhost_net_get_max_queues(VHostNetState *net) 455 { 456 return 1; 457 } 458 459 struct vhost_net *vhost_net_init(VhostNetOptions *options) 460 { 461 error_report("vhost-net support is not compiled in"); 462 return NULL; 463 } 464 465 int vhost_net_start(VirtIODevice *dev, 466 NetClientState *ncs, 467 int total_queues) 468 { 469 return -ENOSYS; 470 } 471 void vhost_net_stop(VirtIODevice *dev, 472 NetClientState *ncs, 473 int total_queues) 474 { 475 } 476 477 void vhost_net_cleanup(struct vhost_net *net) 478 { 479 } 480 481 uint64_t vhost_net_get_features(struct vhost_net *net, uint64_t features) 482 { 483 return features; 484 } 485 486 void vhost_net_ack_features(struct vhost_net *net, uint64_t features) 487 { 488 } 489 490 uint64_t vhost_net_get_acked_features(VHostNetState *net) 491 { 492 return 0; 493 } 494 495 bool vhost_net_virtqueue_pending(VHostNetState *net, int idx) 496 { 497 return false; 498 } 499 500 void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev, 501 int idx, bool mask) 502 { 503 } 504 505 int vhost_net_notify_migration_done(struct vhost_net *net, char* mac_addr) 506 { 507 return -1; 508 } 509 510 VHostNetState *get_vhost_net(NetClientState *nc) 511 { 512 return 0; 513 } 514 515 int vhost_set_vring_enable(NetClientState *nc, int enable) 516 { 517 return 0; 518 } 519 520 int vhost_net_set_mtu(struct vhost_net *net, uint16_t mtu) 521 { 522 return 0; 523 } 524 #endif 525