xref: /openbmc/qemu/hw/remote/proxy.c (revision 9f8112073aad8e485ac012ee18809457ab7f23a6)
1 /*
2  * Copyright © 2018, 2021 Oracle and/or its affiliates.
3  *
4  * This work is licensed under the terms of the GNU GPL, version 2 or later.
5  * See the COPYING file in the top-level directory.
6  *
7  */
8 
9 #include "qemu/osdep.h"
10 #include "qemu-common.h"
11 
12 #include "hw/remote/proxy.h"
13 #include "hw/pci/pci.h"
14 #include "qapi/error.h"
15 #include "io/channel-util.h"
16 #include "hw/qdev-properties.h"
17 #include "monitor/monitor.h"
18 #include "migration/blocker.h"
19 #include "qemu/sockets.h"
20 
21 static void pci_proxy_dev_realize(PCIDevice *device, Error **errp)
22 {
23     ERRP_GUARD();
24     PCIProxyDev *dev = PCI_PROXY_DEV(device);
25     int fd;
26 
27     if (!dev->fd) {
28         error_setg(errp, "fd parameter not specified for %s",
29                    DEVICE(device)->id);
30         return;
31     }
32 
33     fd = monitor_fd_param(monitor_cur(), dev->fd, errp);
34     if (fd == -1) {
35         error_prepend(errp, "proxy: unable to parse fd %s: ", dev->fd);
36         return;
37     }
38 
39     if (!fd_is_socket(fd)) {
40         error_setg(errp, "proxy: fd %d is not a socket", fd);
41         close(fd);
42         return;
43     }
44 
45     dev->ioc = qio_channel_new_fd(fd, errp);
46 
47     error_setg(&dev->migration_blocker, "%s does not support migration",
48                TYPE_PCI_PROXY_DEV);
49     migrate_add_blocker(dev->migration_blocker, errp);
50 
51     qemu_mutex_init(&dev->io_mutex);
52     qio_channel_set_blocking(dev->ioc, true, NULL);
53 }
54 
55 static void pci_proxy_dev_exit(PCIDevice *pdev)
56 {
57     PCIProxyDev *dev = PCI_PROXY_DEV(pdev);
58 
59     if (dev->ioc) {
60         qio_channel_close(dev->ioc, NULL);
61     }
62 
63     migrate_del_blocker(dev->migration_blocker);
64 
65     error_free(dev->migration_blocker);
66 }
67 
68 static Property proxy_properties[] = {
69     DEFINE_PROP_STRING("fd", PCIProxyDev, fd),
70     DEFINE_PROP_END_OF_LIST(),
71 };
72 
73 static void pci_proxy_dev_class_init(ObjectClass *klass, void *data)
74 {
75     DeviceClass *dc = DEVICE_CLASS(klass);
76     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
77 
78     k->realize = pci_proxy_dev_realize;
79     k->exit = pci_proxy_dev_exit;
80     device_class_set_props(dc, proxy_properties);
81 }
82 
83 static const TypeInfo pci_proxy_dev_type_info = {
84     .name          = TYPE_PCI_PROXY_DEV,
85     .parent        = TYPE_PCI_DEVICE,
86     .instance_size = sizeof(PCIProxyDev),
87     .class_init    = pci_proxy_dev_class_init,
88     .interfaces = (InterfaceInfo[]) {
89         { INTERFACE_CONVENTIONAL_PCI_DEVICE },
90         { },
91     },
92 };
93 
94 static void pci_proxy_dev_register_types(void)
95 {
96     type_register_static(&pci_proxy_dev_type_info);
97 }
98 
99 type_init(pci_proxy_dev_register_types)
100