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