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