https://blog.csdn.net/qq_20817327/article/details/106655151
net/tap.c
static void net_init_tap_one { 699 vhostfd = open("/dev/vhost-net", O_RDWR); 700 if (vhostfd < 0) { 701 if (tap->has_vhostforce && tap->vhostforce) { 702 error_setg_errno(errp, errno, 703 "tap: open vhost char device failed"); 704 } else { 705 warn_report("tap: open vhost char device failed: %s", 706 strerror(errno)); 707 } 708 return; 709 } 710 qemu_set_nonblock(vhostfd); 711 } 712 options.opaque = (void *)(uintptr_t)vhostfd; 713 714 s->vhost_net = vhost_net_init(&options); }
vhost_virtqueue_init
[root@bogon qemu]# grep 'vhost_ops =' -rn * backends/cryptodev-vhost.c:161: vhost_ops = crypto->dev.vhost_ops; hw/virtio/vhost-vsock.c:42: const VhostOps *vhost_ops = vsock->vhost_dev.vhost_ops; hw/virtio/vhost-vsock.c:59: const VhostOps *vhost_ops = vsock->vhost_dev.vhost_ops; hw/virtio/vhost-backend.c:280: dev->vhost_ops = &kernel_ops; hw/virtio/vhost-backend.c:285: dev->vhost_ops = &user_ops; hw/scsi/vhost-scsi.c:46: const VhostOps *vhost_ops = vsc->dev.vhost_ops; hw/scsi/vhost-scsi.c:64: const VhostOps *vhost_ops = vsc->dev.vhost_ops; hw/scsi/vhost-scsi.c:75: const VhostOps *vhost_ops = vsc->dev.vhost_ops; hw/net/vhost_net.c:384: const VhostOps *vhost_ops = net->dev.vhost_ops; hw/net/vhost_net.c:431: const VhostOps *vhost_ops = net->dev.vhost_ops; hw/net/vhost_net.c:444: const VhostOps *vhost_ops = net->dev.vhost_ops; [root@bogon qemu]#
[root@bogon qemu]# grep 'vhost_net =' -rn * hw/net/vhost_net.c:405: VHostNetState *vhost_net = 0; hw/net/vhost_net.c:413: vhost_net = tap_get_vhost_net(nc); hw/net/vhost_net.c:417: vhost_net = vhost_user_get_vhost_net(nc); net/vhost-user.c:107: s->vhost_net = net; net/vhost-user.c:157: s->vhost_net = NULL; net/tap.c:317: s->vhost_net = NULL; net/tap.c:392: s->vhost_net = NULL; net/tap.c:714: s->vhost_net = vhost_net_init(&options)
403 VHostNetState *get_vhost_net(NetClientState *nc) 404 { 405 VHostNetState *vhost_net = 0; 406 407 if (!nc) { 408 return 0; 409 } 410 411 switch (nc->info->type) { 412 case NET_CLIENT_DRIVER_TAP: 413 vhost_net = tap_get_vhost_net(nc); 414 break; 415 #ifdef CONFIG_VHOST_NET_USER 416 case NET_CLIENT_DRIVER_VHOST_USER: 417 vhost_net = vhost_user_get_vhost_net(nc); 418 assert(vhost_net); 419 break; 420 #endif 421 default: 422 break; 423 } 424 425 return vhost_net; 426 }
[root@bogon qemu]# grep vhost_user_get_vhost_net -rn * Binary file build/aarch64-softmmu/qemu-system-aarch64 matches Binary file build/net/vhost-user.o matches Binary file build/hw/net/vhost_net.o matches hw/net/vhost_net.c:417: vhost_net = vhost_user_get_vhost_net(nc); include/net/vhost-user.h:15:struct vhost_net *vhost_user_get_vhost_net(NetClientState *nc); net/vhost-user.c:34:VHostNetState *vhost_user_get_vhost_net(NetClientState *nc) [root@bogon qemu]# vi
1147 static int vhost_virtqueue_init(struct vhost_dev *dev, 1148 struct vhost_virtqueue *vq, int n) 1149 { 1150 int vhost_vq_index = dev->vhost_ops->vhost_get_vq_index(dev, n); 1151 struct vhost_vring_file file = { 1152 .index = vhost_vq_index, 1153 }; 1154 int r = event_notifier_init(&vq->masked_notifier, 0); 1155 if (r < 0) { 1156 return r; 1157 } 1158 1159 file.fd = event_notifier_get_fd(&vq->masked_notifier); 1160 r = dev->vhost_ops->vhost_set_vring_call(dev, &file); 1161 if (r) { 1162 VHOST_OPS_DEBUG("vhost_set_vring_call failed"); 1163 r = -errno; 1164 goto fail_call; 1165 } 1166 1167 vq->dev = dev; 1168 1169 return 0; 1170 fail_call: 1171 event_notifier_cleanup(&vq->masked_notifier); 1172 return r; 1173 } hw/virtio/vhost.c
hw/virtio/vhost.c:1043: r = dev->vhost_ops->vhost_set_vring_call(dev, &file); hw/virtio/vhost.c:1160: r = dev->vhost_ops->vhost_set_vring_call(dev, &file); hw/virtio/vhost.c:1162: VHOST_OPS_DEBUG("vhost_set_vring_call failed"); hw/virtio/vhost.c:1420: r = hdev->vhost_ops->vhost_set_vring_call(hdev, &file); hw/virtio/vhost.c:1422: VHOST_OPS_DEBUG("vhost_set_vring_call failed"); hw/virtio/vhost-user.c:1935: .vhost_set_vring_call = vhost_user_set_vring_call, hw/virtio/vhost-backend.c:256: .vhost_set_vring_call = vhost_kernel_set_vring_call, include/hw/virtio/vhost-backend.h:67:typedef int (*vhost_set_vring_call_op)(struct vhost_dev *dev, include/hw/virtio/vhost-backend.h:133: vhost_set_vring_call_op vhost_set_vring_call; [root@bogon qemu]#
vhost_kernel_set_vring_call
139 static int vhost_kernel_set_vring_call(struct vhost_dev *dev, 140 struct vhost_vring_file *file) 141 { 142 return vhost_kernel_call(dev, VHOST_SET_VRING_CALL, file); 143 }
21 static int vhost_kernel_call(struct vhost_dev *dev, unsigned long int request, 22 void *arg) 23 { 24 int fd = (uintptr_t) dev->opaque; 25 26 assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_KERNEL); 27 28 return ioctl(fd, request, arg); 29 }
vhost_user_set_vring_call
795 static int vhost_user_set_vring_call(struct vhost_dev *dev, 796 struct vhost_vring_file *file) 797 { 798 return vhost_set_vring_file(dev, VHOST_USER_SET_VRING_CALL, file); 799 }
763 static int vhost_set_vring_file(struct vhost_dev *dev, 764 VhostUserRequest request, 765 struct vhost_vring_file *file) 766 { 767 int fds[VHOST_MEMORY_MAX_NREGIONS]; 768 size_t fd_num = 0; 769 VhostUserMsg msg = { 770 .hdr.request = request, 771 .hdr.flags = VHOST_USER_VERSION, 772 .payload.u64 = file->index & VHOST_USER_VRING_IDX_MASK, 773 .hdr.size = sizeof(msg.payload.u64), 774 }; 775 776 if (ioeventfd_enabled() && file->fd > 0) { 777 fds[fd_num++] = file->fd; 778 } else { 779 msg.payload.u64 |= VHOST_USER_VRING_NOFD_MASK; 780 } 781 782 if (vhost_user_write(dev, &msg, fds, fd_num) < 0) { 783 return -1; 784 } 785 786 return 0; 787 }