xref: /qemu/hw/vfio-user/pci.c (revision 019232358124e4f4b929e40fa23253de60eec73e)
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  * The server maintains the device's pending interrupts,
29  * via its MSIX table and PBA, so we treat these accesses
30  * like PCI config space and forward them.
31  */
32 static uint64_t vfio_user_pba_read(void *opaque, hwaddr addr,
33                                    unsigned size)
34 {
35     VFIOPCIDevice *vdev = opaque;
36     VFIORegion *region = &vdev->bars[vdev->msix->pba_bar].region;
37     uint64_t data;
38 
39     /* server copy is what matters */
40     data = vfio_region_read(region, addr + vdev->msix->pba_offset, size);
41     return data;
42 }
43 
44 static void vfio_user_pba_write(void *opaque, hwaddr addr,
45                                   uint64_t data, unsigned size)
46 {
47     /* dropped */
48 }
49 
50 static const MemoryRegionOps vfio_user_pba_ops = {
51     .read = vfio_user_pba_read,
52     .write = vfio_user_pba_write,
53     .endianness = DEVICE_LITTLE_ENDIAN,
54 };
55 
56 static void vfio_user_msix_setup(VFIOPCIDevice *vdev)
57 {
58     MemoryRegion *vfio_reg, *msix_reg, *pba_reg;
59 
60     pba_reg = g_new0(MemoryRegion, 1);
61     vdev->msix->pba_region = pba_reg;
62 
63     vfio_reg = vdev->bars[vdev->msix->pba_bar].mr;
64     msix_reg = &vdev->pdev.msix_pba_mmio;
65     memory_region_init_io(pba_reg, OBJECT(vdev), &vfio_user_pba_ops, vdev,
66                           "VFIO MSIX PBA", int128_get64(msix_reg->size));
67     memory_region_add_subregion_overlap(vfio_reg, vdev->msix->pba_offset,
68                                         pba_reg, 1);
69 }
70 
71 static void vfio_user_msix_teardown(VFIOPCIDevice *vdev)
72 {
73     MemoryRegion *mr, *sub;
74 
75     mr = vdev->bars[vdev->msix->pba_bar].mr;
76     sub = vdev->msix->pba_region;
77     memory_region_del_subregion(mr, sub);
78 
79     g_free(vdev->msix->pba_region);
80     vdev->msix->pba_region = NULL;
81 }
82 
83 /*
84  * Incoming request message callback.
85  *
86  * Runs off main loop, so BQL held.
87  */
88 static void vfio_user_pci_process_req(void *opaque, VFIOUserMsg *msg)
89 {
90 
91 }
92 
93 /*
94  * Emulated devices don't use host hot reset
95  */
96 static void vfio_user_compute_needs_reset(VFIODevice *vbasedev)
97 {
98     vbasedev->needs_reset = false;
99 }
100 
101 static Object *vfio_user_pci_get_object(VFIODevice *vbasedev)
102 {
103     VFIOUserPCIDevice *vdev = container_of(vbasedev, VFIOUserPCIDevice,
104                                            device.vbasedev);
105 
106     return OBJECT(vdev);
107 }
108 
109 static VFIODeviceOps vfio_user_pci_ops = {
110     .vfio_compute_needs_reset = vfio_user_compute_needs_reset,
111     .vfio_eoi = vfio_pci_intx_eoi,
112     .vfio_get_object = vfio_user_pci_get_object,
113     /* No live migration support yet. */
114     .vfio_save_config = NULL,
115     .vfio_load_config = NULL,
116 };
117 
118 static void vfio_user_pci_realize(PCIDevice *pdev, Error **errp)
119 {
120     ERRP_GUARD();
121     VFIOUserPCIDevice *udev = VFIO_USER_PCI(pdev);
122     VFIOPCIDevice *vdev = VFIO_PCI_BASE(pdev);
123     VFIODevice *vbasedev = &vdev->vbasedev;
124     const char *sock_name;
125     AddressSpace *as;
126     SocketAddress addr;
127     VFIOUserProxy *proxy;
128 
129     if (!udev->socket) {
130         error_setg(errp, "No socket specified");
131         error_append_hint(errp, "e.g. -device '{"
132             "\"driver\":\"vfio-user-pci\", "
133             "\"socket\": {\"path\": \"/tmp/vfio-user.sock\", "
134             "\"type\": \"unix\"}'"
135             "}'\n");
136         return;
137     }
138 
139     sock_name = udev->socket->u.q_unix.path;
140 
141     vbasedev->name = g_strdup_printf("vfio-user:%s", sock_name);
142 
143     memset(&addr, 0, sizeof(addr));
144     addr.type = SOCKET_ADDRESS_TYPE_UNIX;
145     addr.u.q_unix.path = (char *)sock_name;
146     proxy = vfio_user_connect_dev(&addr, errp);
147     if (!proxy) {
148         return;
149     }
150     vbasedev->proxy = proxy;
151     vfio_user_set_handler(vbasedev, vfio_user_pci_process_req, vdev);
152 
153     vbasedev->name = g_strdup_printf("vfio-user:%s", sock_name);
154 
155     if (udev->send_queued) {
156         proxy->flags |= VFIO_PROXY_FORCE_QUEUED;
157     }
158 
159     if (!vfio_user_validate_version(proxy, errp)) {
160         goto error;
161     }
162 
163     /*
164      * Use socket-based device I/O instead of vfio kernel driver.
165      */
166     vbasedev->io_ops = &vfio_user_device_io_ops_sock;
167 
168     /*
169      * vfio-user devices are effectively mdevs (don't use a host iommu).
170      */
171     vbasedev->mdev = true;
172 
173     /*
174      * Enable per-region fds.
175      */
176     vbasedev->use_region_fds = true;
177 
178     as = pci_device_iommu_address_space(pdev);
179     if (!vfio_device_attach_by_iommu_type(TYPE_VFIO_IOMMU_USER,
180                                           vbasedev->name, vbasedev,
181                                           as, errp)) {
182         goto error;
183     }
184 
185     if (!vfio_pci_populate_device(vdev, errp)) {
186         goto error;
187     }
188 
189     if (!vfio_pci_config_setup(vdev, errp)) {
190         goto error;
191     }
192 
193     /*
194      * vfio_pci_config_setup will have registered the device's BARs
195      * and setup any MSIX BARs, so errors after it succeeds must
196      * use out_teardown
197      */
198 
199     if (!vfio_pci_add_capabilities(vdev, errp)) {
200         goto out_teardown;
201     }
202 
203     if (vdev->msix != NULL) {
204         vfio_user_msix_setup(vdev);
205     }
206 
207     if (!vfio_pci_interrupt_setup(vdev, errp)) {
208         goto out_teardown;
209     }
210 
211     vfio_pci_register_err_notifier(vdev);
212     vfio_pci_register_req_notifier(vdev);
213 
214     return;
215 
216 out_teardown:
217     vfio_pci_teardown_msi(vdev);
218     vfio_pci_bars_exit(vdev);
219 error:
220     error_prepend(errp, VFIO_MSG_PREFIX, vdev->vbasedev.name);
221     vfio_pci_put_device(vdev);
222 }
223 
224 static void vfio_user_instance_init(Object *obj)
225 {
226     PCIDevice *pci_dev = PCI_DEVICE(obj);
227     VFIOPCIDevice *vdev = VFIO_PCI_BASE(obj);
228     VFIODevice *vbasedev = &vdev->vbasedev;
229 
230     device_add_bootindex_property(obj, &vdev->bootindex,
231                                   "bootindex", NULL,
232                                   &pci_dev->qdev);
233     vdev->host.domain = ~0U;
234     vdev->host.bus = ~0U;
235     vdev->host.slot = ~0U;
236     vdev->host.function = ~0U;
237 
238     vfio_device_init(vbasedev, VFIO_DEVICE_TYPE_PCI, &vfio_user_pci_ops,
239                      DEVICE(vdev), false);
240 
241     vdev->nv_gpudirect_clique = 0xFF;
242 
243     /*
244      * QEMU_PCI_CAP_EXPRESS initialization does not depend on QEMU command
245      * line, therefore, no need to wait to realize like other devices.
246      */
247     pci_dev->cap_present |= QEMU_PCI_CAP_EXPRESS;
248 }
249 
250 static void vfio_user_instance_finalize(Object *obj)
251 {
252     VFIOPCIDevice *vdev = VFIO_PCI_BASE(obj);
253     VFIODevice *vbasedev = &vdev->vbasedev;
254 
255     if (vdev->msix != NULL) {
256         vfio_user_msix_teardown(vdev);
257     }
258 
259     vfio_pci_put_device(vdev);
260 
261     if (vbasedev->proxy != NULL) {
262         vfio_user_disconnect(vbasedev->proxy);
263     }
264 }
265 
266 static void vfio_user_pci_reset(DeviceState *dev)
267 {
268     VFIOPCIDevice *vdev = VFIO_PCI_BASE(dev);
269     VFIODevice *vbasedev = &vdev->vbasedev;
270 
271     vfio_pci_pre_reset(vdev);
272 
273     if (vbasedev->reset_works) {
274         vfio_user_device_reset(vbasedev->proxy);
275     }
276 
277     vfio_pci_post_reset(vdev);
278 }
279 
280 static const Property vfio_user_pci_dev_properties[] = {
281     DEFINE_PROP_UINT32("x-pci-vendor-id", VFIOPCIDevice,
282                        vendor_id, PCI_ANY_ID),
283     DEFINE_PROP_UINT32("x-pci-device-id", VFIOPCIDevice,
284                        device_id, PCI_ANY_ID),
285     DEFINE_PROP_UINT32("x-pci-sub-vendor-id", VFIOPCIDevice,
286                        sub_vendor_id, PCI_ANY_ID),
287     DEFINE_PROP_UINT32("x-pci-sub-device-id", VFIOPCIDevice,
288                        sub_device_id, PCI_ANY_ID),
289     DEFINE_PROP_BOOL("x-send-queued", VFIOUserPCIDevice, send_queued, false),
290 };
291 
292 static void vfio_user_pci_set_socket(Object *obj, Visitor *v, const char *name,
293                                      void *opaque, Error **errp)
294 {
295     VFIOUserPCIDevice *udev = VFIO_USER_PCI(obj);
296     bool success;
297 
298     if (udev->device.vbasedev.proxy) {
299         error_setg(errp, "Proxy is connected");
300         return;
301     }
302 
303     qapi_free_SocketAddress(udev->socket);
304 
305     udev->socket = NULL;
306 
307     success = visit_type_SocketAddress(v, name, &udev->socket, errp);
308 
309     if (!success) {
310         return;
311     }
312 
313     if (udev->socket->type != SOCKET_ADDRESS_TYPE_UNIX) {
314         error_setg(errp, "Unsupported socket type %s",
315                    SocketAddressType_str(udev->socket->type));
316         qapi_free_SocketAddress(udev->socket);
317         udev->socket = NULL;
318         return;
319     }
320 }
321 
322 static void vfio_user_pci_dev_class_init(ObjectClass *klass, const void *data)
323 {
324     DeviceClass *dc = DEVICE_CLASS(klass);
325     PCIDeviceClass *pdc = PCI_DEVICE_CLASS(klass);
326 
327     device_class_set_legacy_reset(dc, vfio_user_pci_reset);
328     device_class_set_props(dc, vfio_user_pci_dev_properties);
329 
330     object_class_property_add(klass, "socket", "SocketAddress", NULL,
331                               vfio_user_pci_set_socket, NULL, NULL);
332     object_class_property_set_description(klass, "socket",
333                                           "SocketAddress (UNIX sockets only)");
334 
335     dc->desc = "VFIO over socket PCI device assignment";
336     pdc->realize = vfio_user_pci_realize;
337 }
338 
339 static const TypeInfo vfio_user_pci_dev_info = {
340     .name = TYPE_VFIO_USER_PCI,
341     .parent = TYPE_VFIO_PCI_BASE,
342     .instance_size = sizeof(VFIOUserPCIDevice),
343     .class_init = vfio_user_pci_dev_class_init,
344     .instance_init = vfio_user_instance_init,
345     .instance_finalize = vfio_user_instance_finalize,
346 };
347 
348 static void register_vfio_user_dev_type(void)
349 {
350     type_register_static(&vfio_user_pci_dev_info);
351 }
352 
353  type_init(register_vfio_user_dev_type)
354