xref: /qemu/hw/vfio-user/pci.c (revision 692e0ec50c2f38a7952f7e7c4c375c77b141f6b2)
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     if (!vfio_pci_populate_device(vdev, errp)) {
130         goto error;
131     }
132 
133     if (!vfio_pci_config_setup(vdev, errp)) {
134         goto error;
135     }
136 
137     /*
138      * vfio_pci_config_setup will have registered the device's BARs
139      * and setup any MSIX BARs, so errors after it succeeds must
140      * use out_teardown
141      */
142 
143     if (!vfio_pci_add_capabilities(vdev, errp)) {
144         goto out_teardown;
145     }
146 
147     if (!vfio_pci_interrupt_setup(vdev, errp)) {
148         goto out_teardown;
149     }
150 
151     vfio_pci_register_err_notifier(vdev);
152     vfio_pci_register_req_notifier(vdev);
153 
154     return;
155 
156 out_teardown:
157     vfio_pci_teardown_msi(vdev);
158     vfio_pci_bars_exit(vdev);
159 error:
160     error_prepend(errp, VFIO_MSG_PREFIX, vdev->vbasedev.name);
161     vfio_pci_put_device(vdev);
162 }
163 
164 static void vfio_user_instance_init(Object *obj)
165 {
166     PCIDevice *pci_dev = PCI_DEVICE(obj);
167     VFIOPCIDevice *vdev = VFIO_PCI_BASE(obj);
168     VFIODevice *vbasedev = &vdev->vbasedev;
169 
170     device_add_bootindex_property(obj, &vdev->bootindex,
171                                   "bootindex", NULL,
172                                   &pci_dev->qdev);
173     vdev->host.domain = ~0U;
174     vdev->host.bus = ~0U;
175     vdev->host.slot = ~0U;
176     vdev->host.function = ~0U;
177 
178     vfio_device_init(vbasedev, VFIO_DEVICE_TYPE_PCI, &vfio_user_pci_ops,
179                      DEVICE(vdev), false);
180 
181     vdev->nv_gpudirect_clique = 0xFF;
182 
183     /*
184      * QEMU_PCI_CAP_EXPRESS initialization does not depend on QEMU command
185      * line, therefore, no need to wait to realize like other devices.
186      */
187     pci_dev->cap_present |= QEMU_PCI_CAP_EXPRESS;
188 }
189 
190 static void vfio_user_instance_finalize(Object *obj)
191 {
192     VFIOPCIDevice *vdev = VFIO_PCI_BASE(obj);
193     VFIODevice *vbasedev = &vdev->vbasedev;
194 
195     vfio_pci_put_device(vdev);
196 
197     if (vbasedev->proxy != NULL) {
198         vfio_user_disconnect(vbasedev->proxy);
199     }
200 }
201 
202 static const Property vfio_user_pci_dev_properties[] = {
203     DEFINE_PROP_UINT32("x-pci-vendor-id", VFIOPCIDevice,
204                        vendor_id, PCI_ANY_ID),
205     DEFINE_PROP_UINT32("x-pci-device-id", VFIOPCIDevice,
206                        device_id, PCI_ANY_ID),
207     DEFINE_PROP_UINT32("x-pci-sub-vendor-id", VFIOPCIDevice,
208                        sub_vendor_id, PCI_ANY_ID),
209     DEFINE_PROP_UINT32("x-pci-sub-device-id", VFIOPCIDevice,
210                        sub_device_id, PCI_ANY_ID),
211     DEFINE_PROP_BOOL("x-send-queued", VFIOUserPCIDevice, send_queued, false),
212 };
213 
214 static void vfio_user_pci_set_socket(Object *obj, Visitor *v, const char *name,
215                                      void *opaque, Error **errp)
216 {
217     VFIOUserPCIDevice *udev = VFIO_USER_PCI(obj);
218     bool success;
219 
220     if (udev->device.vbasedev.proxy) {
221         error_setg(errp, "Proxy is connected");
222         return;
223     }
224 
225     qapi_free_SocketAddress(udev->socket);
226 
227     udev->socket = NULL;
228 
229     success = visit_type_SocketAddress(v, name, &udev->socket, errp);
230 
231     if (!success) {
232         return;
233     }
234 
235     if (udev->socket->type != SOCKET_ADDRESS_TYPE_UNIX) {
236         error_setg(errp, "Unsupported socket type %s",
237                    SocketAddressType_str(udev->socket->type));
238         qapi_free_SocketAddress(udev->socket);
239         udev->socket = NULL;
240         return;
241     }
242 }
243 
244 static void vfio_user_pci_dev_class_init(ObjectClass *klass, const void *data)
245 {
246     DeviceClass *dc = DEVICE_CLASS(klass);
247     PCIDeviceClass *pdc = PCI_DEVICE_CLASS(klass);
248 
249     device_class_set_props(dc, vfio_user_pci_dev_properties);
250 
251     object_class_property_add(klass, "socket", "SocketAddress", NULL,
252                               vfio_user_pci_set_socket, NULL, NULL);
253     object_class_property_set_description(klass, "socket",
254                                           "SocketAddress (UNIX sockets only)");
255 
256     dc->desc = "VFIO over socket PCI device assignment";
257     pdc->realize = vfio_user_pci_realize;
258 }
259 
260 static const TypeInfo vfio_user_pci_dev_info = {
261     .name = TYPE_VFIO_USER_PCI,
262     .parent = TYPE_VFIO_PCI_BASE,
263     .instance_size = sizeof(VFIOUserPCIDevice),
264     .class_init = vfio_user_pci_dev_class_init,
265     .instance_init = vfio_user_instance_init,
266     .instance_finalize = vfio_user_instance_finalize,
267 };
268 
269 static void register_vfio_user_dev_type(void)
270 {
271     type_register_static(&vfio_user_pci_dev_info);
272 }
273 
274  type_init(register_vfio_user_dev_type)
275