vhost-user-blk.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /*
  2. * libqos driver framework
  3. *
  4. * Based on tests/qtest/libqos/virtio-blk.c
  5. *
  6. * Copyright (c) 2020 Coiby Xu <coiby.xu@gmail.com>
  7. *
  8. * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
  9. *
  10. * This library is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU Lesser General Public
  12. * License version 2.1 as published by the Free Software Foundation.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, see <http://www.gnu.org/licenses/>
  21. */
  22. #include "qemu/osdep.h"
  23. #include "../libqtest.h"
  24. #include "qemu/module.h"
  25. #include "standard-headers/linux/virtio_blk.h"
  26. #include "vhost-user-blk.h"
  27. #define PCI_SLOT 0x04
  28. #define PCI_FN 0x00
  29. /* virtio-blk-device */
  30. static void *qvhost_user_blk_get_driver(QVhostUserBlk *v_blk,
  31. const char *interface)
  32. {
  33. if (!g_strcmp0(interface, "vhost-user-blk")) {
  34. return v_blk;
  35. }
  36. if (!g_strcmp0(interface, "virtio")) {
  37. return v_blk->vdev;
  38. }
  39. fprintf(stderr, "%s not present in vhost-user-blk-device\n", interface);
  40. g_assert_not_reached();
  41. }
  42. static void *qvhost_user_blk_device_get_driver(void *object,
  43. const char *interface)
  44. {
  45. QVhostUserBlkDevice *v_blk = object;
  46. return qvhost_user_blk_get_driver(&v_blk->blk, interface);
  47. }
  48. static void *vhost_user_blk_device_create(void *virtio_dev,
  49. QGuestAllocator *t_alloc,
  50. void *addr)
  51. {
  52. QVhostUserBlkDevice *vhost_user_blk = g_new0(QVhostUserBlkDevice, 1);
  53. QVhostUserBlk *interface = &vhost_user_blk->blk;
  54. interface->vdev = virtio_dev;
  55. vhost_user_blk->obj.get_driver = qvhost_user_blk_device_get_driver;
  56. return &vhost_user_blk->obj;
  57. }
  58. /* virtio-blk-pci */
  59. static void *qvhost_user_blk_pci_get_driver(void *object, const char *interface)
  60. {
  61. QVhostUserBlkPCI *v_blk = object;
  62. if (!g_strcmp0(interface, "pci-device")) {
  63. return v_blk->pci_vdev.pdev;
  64. }
  65. return qvhost_user_blk_get_driver(&v_blk->blk, interface);
  66. }
  67. static void *vhost_user_blk_pci_create(void *pci_bus, QGuestAllocator *t_alloc,
  68. void *addr)
  69. {
  70. QVhostUserBlkPCI *vhost_user_blk = g_new0(QVhostUserBlkPCI, 1);
  71. QVhostUserBlk *interface = &vhost_user_blk->blk;
  72. QOSGraphObject *obj = &vhost_user_blk->pci_vdev.obj;
  73. virtio_pci_init(&vhost_user_blk->pci_vdev, pci_bus, addr);
  74. interface->vdev = &vhost_user_blk->pci_vdev.vdev;
  75. g_assert_cmphex(interface->vdev->device_type, ==, VIRTIO_ID_BLOCK);
  76. obj->get_driver = qvhost_user_blk_pci_get_driver;
  77. return obj;
  78. }
  79. static void vhost_user_blk_register_nodes(void)
  80. {
  81. /*
  82. * FIXME: every test using these two nodes needs to setup a
  83. * -drive,id=drive0 otherwise QEMU is not going to start.
  84. * Therefore, we do not include "produces" edge for virtio
  85. * and pci-device yet.
  86. */
  87. char *arg = g_strdup_printf("id=drv0,chardev=char1,addr=%x.%x",
  88. PCI_SLOT, PCI_FN);
  89. QPCIAddress addr = {
  90. .devfn = QPCI_DEVFN(PCI_SLOT, PCI_FN),
  91. };
  92. QOSGraphEdgeOptions opts = { };
  93. /* virtio-blk-device */
  94. /** opts.extra_device_opts = "drive=drive0"; */
  95. qos_node_create_driver("vhost-user-blk-device",
  96. vhost_user_blk_device_create);
  97. qos_node_consumes("vhost-user-blk-device", "virtio-bus", &opts);
  98. qos_node_produces("vhost-user-blk-device", "vhost-user-blk");
  99. /* virtio-blk-pci */
  100. opts.extra_device_opts = arg;
  101. add_qpci_address(&opts, &addr);
  102. qos_node_create_driver("vhost-user-blk-pci", vhost_user_blk_pci_create);
  103. qos_node_consumes("vhost-user-blk-pci", "pci-bus", &opts);
  104. qos_node_produces("vhost-user-blk-pci", "vhost-user-blk");
  105. g_free(arg);
  106. }
  107. libqos_init(vhost_user_blk_register_nodes);