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