xref: /qemu/hw/vfio-user/pci.c (revision 0b3d881a061b284a3db00d7fe9d33581fb424287)
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