proxy.c 11 KB

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