proxy.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  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. #include "qemu/osdep.h"
  9. #include "hw/remote/proxy.h"
  10. #include "hw/pci/pci.h"
  11. #include "qapi/error.h"
  12. #include "io/channel-util.h"
  13. #include "hw/qdev-properties.h"
  14. #include "monitor/monitor.h"
  15. #include "migration/blocker.h"
  16. #include "qemu/sockets.h"
  17. #include "hw/remote/mpqemu-link.h"
  18. #include "qemu/error-report.h"
  19. #include "hw/remote/proxy-memory-listener.h"
  20. #include "qom/object.h"
  21. #include "qemu/event_notifier.h"
  22. #include "sysemu/kvm.h"
  23. #include "util/event_notifier-posix.c"
  24. static void probe_pci_info(PCIDevice *dev, Error **errp);
  25. static void proxy_device_reset(DeviceState *dev);
  26. static void proxy_intx_update(PCIDevice *pci_dev)
  27. {
  28. PCIProxyDev *dev = PCI_PROXY_DEV(pci_dev);
  29. PCIINTxRoute route;
  30. int pin = pci_get_byte(pci_dev->config + PCI_INTERRUPT_PIN) - 1;
  31. if (dev->virq != -1) {
  32. kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, &dev->intr, dev->virq);
  33. dev->virq = -1;
  34. }
  35. route = pci_device_route_intx_to_irq(pci_dev, pin);
  36. dev->virq = route.irq;
  37. if (dev->virq != -1) {
  38. kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, &dev->intr,
  39. &dev->resample, dev->virq);
  40. }
  41. }
  42. static void setup_irqfd(PCIProxyDev *dev)
  43. {
  44. PCIDevice *pci_dev = PCI_DEVICE(dev);
  45. MPQemuMsg msg;
  46. Error *local_err = NULL;
  47. event_notifier_init(&dev->intr, 0);
  48. event_notifier_init(&dev->resample, 0);
  49. memset(&msg, 0, sizeof(MPQemuMsg));
  50. msg.cmd = MPQEMU_CMD_SET_IRQFD;
  51. msg.num_fds = 2;
  52. msg.fds[0] = event_notifier_get_fd(&dev->intr);
  53. msg.fds[1] = event_notifier_get_fd(&dev->resample);
  54. msg.size = 0;
  55. if (!mpqemu_msg_send(&msg, dev->ioc, &local_err)) {
  56. error_report_err(local_err);
  57. }
  58. dev->virq = -1;
  59. proxy_intx_update(pci_dev);
  60. pci_device_set_intx_routing_notifier(pci_dev, proxy_intx_update);
  61. }
  62. static void pci_proxy_dev_realize(PCIDevice *device, Error **errp)
  63. {
  64. ERRP_GUARD();
  65. PCIProxyDev *dev = PCI_PROXY_DEV(device);
  66. uint8_t *pci_conf = device->config;
  67. int fd;
  68. if (!dev->fd) {
  69. error_setg(errp, "fd parameter not specified for %s",
  70. DEVICE(device)->id);
  71. return;
  72. }
  73. fd = monitor_fd_param(monitor_cur(), dev->fd, errp);
  74. if (fd == -1) {
  75. error_prepend(errp, "proxy: unable to parse fd %s: ", dev->fd);
  76. return;
  77. }
  78. if (!fd_is_socket(fd)) {
  79. error_setg(errp, "proxy: fd %d is not a socket", fd);
  80. close(fd);
  81. return;
  82. }
  83. dev->ioc = qio_channel_new_fd(fd, errp);
  84. if (!dev->ioc) {
  85. close(fd);
  86. return;
  87. }
  88. error_setg(&dev->migration_blocker, "%s does not support migration",
  89. TYPE_PCI_PROXY_DEV);
  90. if (migrate_add_blocker(dev->migration_blocker, errp) < 0) {
  91. error_free(dev->migration_blocker);
  92. object_unref(dev->ioc);
  93. return;
  94. }
  95. qemu_mutex_init(&dev->io_mutex);
  96. qio_channel_set_blocking(dev->ioc, true, NULL);
  97. pci_conf[PCI_LATENCY_TIMER] = 0xff;
  98. pci_conf[PCI_INTERRUPT_PIN] = 0x01;
  99. proxy_memory_listener_configure(&dev->proxy_listener, dev->ioc);
  100. setup_irqfd(dev);
  101. probe_pci_info(PCI_DEVICE(dev), errp);
  102. }
  103. static void pci_proxy_dev_exit(PCIDevice *pdev)
  104. {
  105. PCIProxyDev *dev = PCI_PROXY_DEV(pdev);
  106. if (dev->ioc) {
  107. qio_channel_close(dev->ioc, NULL);
  108. }
  109. migrate_del_blocker(dev->migration_blocker);
  110. error_free(dev->migration_blocker);
  111. proxy_memory_listener_deconfigure(&dev->proxy_listener);
  112. event_notifier_cleanup(&dev->intr);
  113. event_notifier_cleanup(&dev->resample);
  114. }
  115. static void config_op_send(PCIProxyDev *pdev, uint32_t addr, uint32_t *val,
  116. int len, unsigned int op)
  117. {
  118. MPQemuMsg msg = { 0 };
  119. uint64_t ret = -EINVAL;
  120. Error *local_err = NULL;
  121. msg.cmd = op;
  122. msg.data.pci_conf_data.addr = addr;
  123. msg.data.pci_conf_data.val = (op == MPQEMU_CMD_PCI_CFGWRITE) ? *val : 0;
  124. msg.data.pci_conf_data.len = len;
  125. msg.size = sizeof(PciConfDataMsg);
  126. ret = mpqemu_msg_send_and_await_reply(&msg, pdev, &local_err);
  127. if (local_err) {
  128. error_report_err(local_err);
  129. }
  130. if (ret == UINT64_MAX) {
  131. error_report("Failed to perform PCI config %s operation",
  132. (op == MPQEMU_CMD_PCI_CFGREAD) ? "READ" : "WRITE");
  133. }
  134. if (op == MPQEMU_CMD_PCI_CFGREAD) {
  135. *val = (uint32_t)ret;
  136. }
  137. }
  138. static uint32_t pci_proxy_read_config(PCIDevice *d, uint32_t addr, int len)
  139. {
  140. uint32_t val;
  141. config_op_send(PCI_PROXY_DEV(d), addr, &val, len, MPQEMU_CMD_PCI_CFGREAD);
  142. return val;
  143. }
  144. static void pci_proxy_write_config(PCIDevice *d, uint32_t addr, uint32_t val,
  145. int len)
  146. {
  147. /*
  148. * Some of the functions access the copy of remote device's PCI config
  149. * space which is cached in the proxy device. Therefore, maintain
  150. * it updated.
  151. */
  152. pci_default_write_config(d, addr, val, len);
  153. config_op_send(PCI_PROXY_DEV(d), addr, &val, len, MPQEMU_CMD_PCI_CFGWRITE);
  154. }
  155. static Property proxy_properties[] = {
  156. DEFINE_PROP_STRING("fd", PCIProxyDev, fd),
  157. DEFINE_PROP_END_OF_LIST(),
  158. };
  159. static void pci_proxy_dev_class_init(ObjectClass *klass, void *data)
  160. {
  161. DeviceClass *dc = DEVICE_CLASS(klass);
  162. PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
  163. k->realize = pci_proxy_dev_realize;
  164. k->exit = pci_proxy_dev_exit;
  165. k->config_read = pci_proxy_read_config;
  166. k->config_write = pci_proxy_write_config;
  167. dc->reset = proxy_device_reset;
  168. device_class_set_props(dc, proxy_properties);
  169. }
  170. static const TypeInfo pci_proxy_dev_type_info = {
  171. .name = TYPE_PCI_PROXY_DEV,
  172. .parent = TYPE_PCI_DEVICE,
  173. .instance_size = sizeof(PCIProxyDev),
  174. .class_init = pci_proxy_dev_class_init,
  175. .interfaces = (InterfaceInfo[]) {
  176. { INTERFACE_CONVENTIONAL_PCI_DEVICE },
  177. { },
  178. },
  179. };
  180. static void pci_proxy_dev_register_types(void)
  181. {
  182. type_register_static(&pci_proxy_dev_type_info);
  183. }
  184. type_init(pci_proxy_dev_register_types)
  185. static void send_bar_access_msg(PCIProxyDev *pdev, MemoryRegion *mr,
  186. bool write, hwaddr addr, uint64_t *val,
  187. unsigned size, bool memory)
  188. {
  189. MPQemuMsg msg = { 0 };
  190. long ret = -EINVAL;
  191. Error *local_err = NULL;
  192. msg.size = sizeof(BarAccessMsg);
  193. msg.data.bar_access.addr = mr->addr + addr;
  194. msg.data.bar_access.size = size;
  195. msg.data.bar_access.memory = memory;
  196. if (write) {
  197. msg.cmd = MPQEMU_CMD_BAR_WRITE;
  198. msg.data.bar_access.val = *val;
  199. } else {
  200. msg.cmd = MPQEMU_CMD_BAR_READ;
  201. }
  202. ret = mpqemu_msg_send_and_await_reply(&msg, pdev, &local_err);
  203. if (local_err) {
  204. error_report_err(local_err);
  205. }
  206. if (!write) {
  207. *val = ret;
  208. }
  209. }
  210. static void proxy_bar_write(void *opaque, hwaddr addr, uint64_t val,
  211. unsigned size)
  212. {
  213. ProxyMemoryRegion *pmr = opaque;
  214. send_bar_access_msg(pmr->dev, &pmr->mr, true, addr, &val, size,
  215. pmr->memory);
  216. }
  217. static uint64_t proxy_bar_read(void *opaque, hwaddr addr, unsigned size)
  218. {
  219. ProxyMemoryRegion *pmr = opaque;
  220. uint64_t val;
  221. send_bar_access_msg(pmr->dev, &pmr->mr, false, addr, &val, size,
  222. pmr->memory);
  223. return val;
  224. }
  225. const MemoryRegionOps proxy_mr_ops = {
  226. .read = proxy_bar_read,
  227. .write = proxy_bar_write,
  228. .endianness = DEVICE_NATIVE_ENDIAN,
  229. .impl = {
  230. .min_access_size = 1,
  231. .max_access_size = 8,
  232. },
  233. };
  234. static void probe_pci_info(PCIDevice *dev, Error **errp)
  235. {
  236. PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
  237. uint32_t orig_val, new_val, base_class, val;
  238. PCIProxyDev *pdev = PCI_PROXY_DEV(dev);
  239. DeviceClass *dc = DEVICE_CLASS(pc);
  240. uint8_t type;
  241. int i, size;
  242. config_op_send(pdev, PCI_VENDOR_ID, &val, 2, MPQEMU_CMD_PCI_CFGREAD);
  243. pc->vendor_id = (uint16_t)val;
  244. config_op_send(pdev, PCI_DEVICE_ID, &val, 2, MPQEMU_CMD_PCI_CFGREAD);
  245. pc->device_id = (uint16_t)val;
  246. config_op_send(pdev, PCI_CLASS_DEVICE, &val, 2, MPQEMU_CMD_PCI_CFGREAD);
  247. pc->class_id = (uint16_t)val;
  248. config_op_send(pdev, PCI_SUBSYSTEM_ID, &val, 2, MPQEMU_CMD_PCI_CFGREAD);
  249. pc->subsystem_id = (uint16_t)val;
  250. base_class = pc->class_id >> 4;
  251. switch (base_class) {
  252. case PCI_BASE_CLASS_BRIDGE:
  253. set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
  254. break;
  255. case PCI_BASE_CLASS_STORAGE:
  256. set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
  257. break;
  258. case PCI_BASE_CLASS_NETWORK:
  259. case PCI_BASE_CLASS_WIRELESS:
  260. set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
  261. break;
  262. case PCI_BASE_CLASS_INPUT:
  263. set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
  264. break;
  265. case PCI_BASE_CLASS_DISPLAY:
  266. set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
  267. break;
  268. case PCI_BASE_CLASS_PROCESSOR:
  269. set_bit(DEVICE_CATEGORY_CPU, dc->categories);
  270. break;
  271. default:
  272. set_bit(DEVICE_CATEGORY_MISC, dc->categories);
  273. break;
  274. }
  275. for (i = 0; i < PCI_NUM_REGIONS; i++) {
  276. config_op_send(pdev, PCI_BASE_ADDRESS_0 + (4 * i), &orig_val, 4,
  277. MPQEMU_CMD_PCI_CFGREAD);
  278. new_val = 0xffffffff;
  279. config_op_send(pdev, PCI_BASE_ADDRESS_0 + (4 * i), &new_val, 4,
  280. MPQEMU_CMD_PCI_CFGWRITE);
  281. config_op_send(pdev, PCI_BASE_ADDRESS_0 + (4 * i), &new_val, 4,
  282. MPQEMU_CMD_PCI_CFGREAD);
  283. size = (~(new_val & 0xFFFFFFF0)) + 1;
  284. config_op_send(pdev, PCI_BASE_ADDRESS_0 + (4 * i), &orig_val, 4,
  285. MPQEMU_CMD_PCI_CFGWRITE);
  286. type = (new_val & 0x1) ?
  287. PCI_BASE_ADDRESS_SPACE_IO : PCI_BASE_ADDRESS_SPACE_MEMORY;
  288. if (size) {
  289. g_autofree char *name = g_strdup_printf("bar-region-%d", i);
  290. pdev->region[i].dev = pdev;
  291. pdev->region[i].present = true;
  292. if (type == PCI_BASE_ADDRESS_SPACE_MEMORY) {
  293. pdev->region[i].memory = true;
  294. }
  295. memory_region_init_io(&pdev->region[i].mr, OBJECT(pdev),
  296. &proxy_mr_ops, &pdev->region[i],
  297. name, size);
  298. pci_register_bar(dev, i, type, &pdev->region[i].mr);
  299. }
  300. }
  301. }
  302. static void proxy_device_reset(DeviceState *dev)
  303. {
  304. PCIProxyDev *pdev = PCI_PROXY_DEV(dev);
  305. MPQemuMsg msg = { 0 };
  306. Error *local_err = NULL;
  307. msg.cmd = MPQEMU_CMD_DEVICE_RESET;
  308. msg.size = 0;
  309. mpqemu_msg_send_and_await_reply(&msg, pdev, &local_err);
  310. if (local_err) {
  311. error_report_err(local_err);
  312. }
  313. }