1 /* 2 * vfio PCI device over a UNIX socket. 3 * 4 * Copyright © 2018, 2021 Oracle and/or its affiliates. 5 * 6 * SPDX-License-Identifier: GPL-2.0-or-later 7 */ 8 9 #include <sys/ioctl.h> 10 #include "qemu/osdep.h" 11 #include "qapi-visit-sockets.h" 12 13 #include "hw/qdev-properties.h" 14 #include "hw/vfio/pci.h" 15 #include "hw/vfio-user/device.h" 16 #include "hw/vfio-user/proxy.h" 17 18 #define TYPE_VFIO_USER_PCI "vfio-user-pci" 19 OBJECT_DECLARE_SIMPLE_TYPE(VFIOUserPCIDevice, VFIO_USER_PCI) 20 21 struct VFIOUserPCIDevice { 22 VFIOPCIDevice device; 23 SocketAddress *socket; 24 bool send_queued; /* all sends are queued */ 25 }; 26 27 /* 28 * Incoming request message callback. 29 * 30 * Runs off main loop, so BQL held. 31 */ 32 static void vfio_user_pci_process_req(void *opaque, VFIOUserMsg *msg) 33 { 34 35 } 36 37 /* 38 * Emulated devices don't use host hot reset 39 */ 40 static void vfio_user_compute_needs_reset(VFIODevice *vbasedev) 41 { 42 vbasedev->needs_reset = false; 43 } 44 45 static Object *vfio_user_pci_get_object(VFIODevice *vbasedev) 46 { 47 VFIOUserPCIDevice *vdev = container_of(vbasedev, VFIOUserPCIDevice, 48 device.vbasedev); 49 50 return OBJECT(vdev); 51 } 52 53 static VFIODeviceOps vfio_user_pci_ops = { 54 .vfio_compute_needs_reset = vfio_user_compute_needs_reset, 55 .vfio_eoi = vfio_pci_intx_eoi, 56 .vfio_get_object = vfio_user_pci_get_object, 57 /* No live migration support yet. */ 58 .vfio_save_config = NULL, 59 .vfio_load_config = NULL, 60 }; 61 62 static void vfio_user_pci_realize(PCIDevice *pdev, Error **errp) 63 { 64 ERRP_GUARD(); 65 VFIOUserPCIDevice *udev = VFIO_USER_PCI(pdev); 66 VFIOPCIDevice *vdev = VFIO_PCI_BASE(pdev); 67 VFIODevice *vbasedev = &vdev->vbasedev; 68 const char *sock_name; 69 AddressSpace *as; 70 SocketAddress addr; 71 VFIOUserProxy *proxy; 72 73 if (!udev->socket) { 74 error_setg(errp, "No socket specified"); 75 error_append_hint(errp, "e.g. -device '{" 76 "\"driver\":\"vfio-user-pci\", " 77 "\"socket\": {\"path\": \"/tmp/vfio-user.sock\", " 78 "\"type\": \"unix\"}'" 79 "}'\n"); 80 return; 81 } 82 83 sock_name = udev->socket->u.q_unix.path; 84 85 vbasedev->name = g_strdup_printf("vfio-user:%s", sock_name); 86 87 memset(&addr, 0, sizeof(addr)); 88 addr.type = SOCKET_ADDRESS_TYPE_UNIX; 89 addr.u.q_unix.path = (char *)sock_name; 90 proxy = vfio_user_connect_dev(&addr, errp); 91 if (!proxy) { 92 return; 93 } 94 vbasedev->proxy = proxy; 95 vfio_user_set_handler(vbasedev, vfio_user_pci_process_req, vdev); 96 97 vbasedev->name = g_strdup_printf("vfio-user:%s", sock_name); 98 99 if (udev->send_queued) { 100 proxy->flags |= VFIO_PROXY_FORCE_QUEUED; 101 } 102 103 if (!vfio_user_validate_version(proxy, errp)) { 104 goto error; 105 } 106 107 /* 108 * Use socket-based device I/O instead of vfio kernel driver. 109 */ 110 vbasedev->io_ops = &vfio_user_device_io_ops_sock; 111 112 /* 113 * vfio-user devices are effectively mdevs (don't use a host iommu). 114 */ 115 vbasedev->mdev = true; 116 117 /* 118 * Enable per-region fds. 119 */ 120 vbasedev->use_region_fds = true; 121 122 as = pci_device_iommu_address_space(pdev); 123 if (!vfio_device_attach_by_iommu_type(TYPE_VFIO_IOMMU_USER, 124 vbasedev->name, vbasedev, 125 as, errp)) { 126 goto error; 127 } 128 129 return; 130 131 error: 132 error_prepend(errp, VFIO_MSG_PREFIX, vdev->vbasedev.name); 133 } 134 135 static void vfio_user_instance_init(Object *obj) 136 { 137 PCIDevice *pci_dev = PCI_DEVICE(obj); 138 VFIOPCIDevice *vdev = VFIO_PCI_BASE(obj); 139 VFIODevice *vbasedev = &vdev->vbasedev; 140 141 device_add_bootindex_property(obj, &vdev->bootindex, 142 "bootindex", NULL, 143 &pci_dev->qdev); 144 vdev->host.domain = ~0U; 145 vdev->host.bus = ~0U; 146 vdev->host.slot = ~0U; 147 vdev->host.function = ~0U; 148 149 vfio_device_init(vbasedev, VFIO_DEVICE_TYPE_PCI, &vfio_user_pci_ops, 150 DEVICE(vdev), false); 151 152 vdev->nv_gpudirect_clique = 0xFF; 153 154 /* 155 * QEMU_PCI_CAP_EXPRESS initialization does not depend on QEMU command 156 * line, therefore, no need to wait to realize like other devices. 157 */ 158 pci_dev->cap_present |= QEMU_PCI_CAP_EXPRESS; 159 } 160 161 static void vfio_user_instance_finalize(Object *obj) 162 { 163 VFIOPCIDevice *vdev = VFIO_PCI_BASE(obj); 164 VFIODevice *vbasedev = &vdev->vbasedev; 165 166 vfio_pci_put_device(vdev); 167 168 if (vbasedev->proxy != NULL) { 169 vfio_user_disconnect(vbasedev->proxy); 170 } 171 } 172 173 static const Property vfio_user_pci_dev_properties[] = { 174 DEFINE_PROP_UINT32("x-pci-vendor-id", VFIOPCIDevice, 175 vendor_id, PCI_ANY_ID), 176 DEFINE_PROP_UINT32("x-pci-device-id", VFIOPCIDevice, 177 device_id, PCI_ANY_ID), 178 DEFINE_PROP_UINT32("x-pci-sub-vendor-id", VFIOPCIDevice, 179 sub_vendor_id, PCI_ANY_ID), 180 DEFINE_PROP_UINT32("x-pci-sub-device-id", VFIOPCIDevice, 181 sub_device_id, PCI_ANY_ID), 182 DEFINE_PROP_BOOL("x-send-queued", VFIOUserPCIDevice, send_queued, false), 183 }; 184 185 static void vfio_user_pci_set_socket(Object *obj, Visitor *v, const char *name, 186 void *opaque, Error **errp) 187 { 188 VFIOUserPCIDevice *udev = VFIO_USER_PCI(obj); 189 bool success; 190 191 if (udev->device.vbasedev.proxy) { 192 error_setg(errp, "Proxy is connected"); 193 return; 194 } 195 196 qapi_free_SocketAddress(udev->socket); 197 198 udev->socket = NULL; 199 200 success = visit_type_SocketAddress(v, name, &udev->socket, errp); 201 202 if (!success) { 203 return; 204 } 205 206 if (udev->socket->type != SOCKET_ADDRESS_TYPE_UNIX) { 207 error_setg(errp, "Unsupported socket type %s", 208 SocketAddressType_str(udev->socket->type)); 209 qapi_free_SocketAddress(udev->socket); 210 udev->socket = NULL; 211 return; 212 } 213 } 214 215 static void vfio_user_pci_dev_class_init(ObjectClass *klass, const void *data) 216 { 217 DeviceClass *dc = DEVICE_CLASS(klass); 218 PCIDeviceClass *pdc = PCI_DEVICE_CLASS(klass); 219 220 device_class_set_props(dc, vfio_user_pci_dev_properties); 221 222 object_class_property_add(klass, "socket", "SocketAddress", NULL, 223 vfio_user_pci_set_socket, NULL, NULL); 224 object_class_property_set_description(klass, "socket", 225 "SocketAddress (UNIX sockets only)"); 226 227 dc->desc = "VFIO over socket PCI device assignment"; 228 pdc->realize = vfio_user_pci_realize; 229 } 230 231 static const TypeInfo vfio_user_pci_dev_info = { 232 .name = TYPE_VFIO_USER_PCI, 233 .parent = TYPE_VFIO_PCI_BASE, 234 .instance_size = sizeof(VFIOUserPCIDevice), 235 .class_init = vfio_user_pci_dev_class_init, 236 .instance_init = vfio_user_instance_init, 237 .instance_finalize = vfio_user_instance_finalize, 238 }; 239 240 static void register_vfio_user_dev_type(void) 241 { 242 type_register_static(&vfio_user_pci_dev_info); 243 } 244 245 type_init(register_vfio_user_dev_type) 246