virtio_pmem.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * virtio_pmem.c: Virtio pmem Driver
  4. *
  5. * Discovers persistent memory range information
  6. * from host and registers the virtual pmem device
  7. * with libnvdimm core.
  8. */
  9. #include "virtio_pmem.h"
  10. #include "nd.h"
  11. static struct virtio_device_id id_table[] = {
  12. { VIRTIO_ID_PMEM, VIRTIO_DEV_ANY_ID },
  13. { 0 },
  14. };
  15. /* Initialize virt queue */
  16. static int init_vq(struct virtio_pmem *vpmem)
  17. {
  18. /* single vq */
  19. vpmem->req_vq = virtio_find_single_vq(vpmem->vdev,
  20. virtio_pmem_host_ack, "flush_queue");
  21. if (IS_ERR(vpmem->req_vq))
  22. return PTR_ERR(vpmem->req_vq);
  23. spin_lock_init(&vpmem->pmem_lock);
  24. INIT_LIST_HEAD(&vpmem->req_list);
  25. return 0;
  26. };
  27. static int virtio_pmem_validate(struct virtio_device *vdev)
  28. {
  29. struct virtio_shm_region shm_reg;
  30. if (virtio_has_feature(vdev, VIRTIO_PMEM_F_SHMEM_REGION) &&
  31. !virtio_get_shm_region(vdev, &shm_reg, (u8)VIRTIO_PMEM_SHMEM_REGION_ID)
  32. ) {
  33. dev_notice(&vdev->dev, "failed to get shared memory region %d\n",
  34. VIRTIO_PMEM_SHMEM_REGION_ID);
  35. __virtio_clear_bit(vdev, VIRTIO_PMEM_F_SHMEM_REGION);
  36. }
  37. return 0;
  38. }
  39. static int virtio_pmem_probe(struct virtio_device *vdev)
  40. {
  41. struct nd_region_desc ndr_desc = {};
  42. struct nd_region *nd_region;
  43. struct virtio_pmem *vpmem;
  44. struct resource res;
  45. struct virtio_shm_region shm_reg;
  46. int err = 0;
  47. if (!vdev->config->get) {
  48. dev_err(&vdev->dev, "%s failure: config access disabled\n",
  49. __func__);
  50. return -EINVAL;
  51. }
  52. vpmem = devm_kzalloc(&vdev->dev, sizeof(*vpmem), GFP_KERNEL);
  53. if (!vpmem) {
  54. err = -ENOMEM;
  55. goto out_err;
  56. }
  57. mutex_init(&vpmem->flush_lock);
  58. vpmem->vdev = vdev;
  59. vdev->priv = vpmem;
  60. err = init_vq(vpmem);
  61. if (err) {
  62. dev_err(&vdev->dev, "failed to initialize virtio pmem vq's\n");
  63. goto out_err;
  64. }
  65. if (virtio_has_feature(vdev, VIRTIO_PMEM_F_SHMEM_REGION)) {
  66. virtio_get_shm_region(vdev, &shm_reg, (u8)VIRTIO_PMEM_SHMEM_REGION_ID);
  67. vpmem->start = shm_reg.addr;
  68. vpmem->size = shm_reg.len;
  69. } else {
  70. virtio_cread_le(vpmem->vdev, struct virtio_pmem_config,
  71. start, &vpmem->start);
  72. virtio_cread_le(vpmem->vdev, struct virtio_pmem_config,
  73. size, &vpmem->size);
  74. }
  75. res.start = vpmem->start;
  76. res.end = vpmem->start + vpmem->size - 1;
  77. vpmem->nd_desc.provider_name = "virtio-pmem";
  78. vpmem->nd_desc.module = THIS_MODULE;
  79. vpmem->nvdimm_bus = nvdimm_bus_register(&vdev->dev,
  80. &vpmem->nd_desc);
  81. if (!vpmem->nvdimm_bus) {
  82. dev_err(&vdev->dev, "failed to register device with nvdimm_bus\n");
  83. err = -ENXIO;
  84. goto out_vq;
  85. }
  86. dev_set_drvdata(&vdev->dev, vpmem->nvdimm_bus);
  87. ndr_desc.res = &res;
  88. ndr_desc.numa_node = memory_add_physaddr_to_nid(res.start);
  89. ndr_desc.target_node = phys_to_target_node(res.start);
  90. if (ndr_desc.target_node == NUMA_NO_NODE) {
  91. ndr_desc.target_node = ndr_desc.numa_node;
  92. dev_dbg(&vdev->dev, "changing target node from %d to %d",
  93. NUMA_NO_NODE, ndr_desc.target_node);
  94. }
  95. ndr_desc.flush = async_pmem_flush;
  96. ndr_desc.provider_data = vdev;
  97. set_bit(ND_REGION_PAGEMAP, &ndr_desc.flags);
  98. set_bit(ND_REGION_ASYNC, &ndr_desc.flags);
  99. /*
  100. * The NVDIMM region could be available before the
  101. * virtio_device_ready() that is called by
  102. * virtio_dev_probe(), so we set device ready here.
  103. */
  104. virtio_device_ready(vdev);
  105. nd_region = nvdimm_pmem_region_create(vpmem->nvdimm_bus, &ndr_desc);
  106. if (!nd_region) {
  107. dev_err(&vdev->dev, "failed to create nvdimm region\n");
  108. err = -ENXIO;
  109. goto out_nd;
  110. }
  111. return 0;
  112. out_nd:
  113. virtio_reset_device(vdev);
  114. nvdimm_bus_unregister(vpmem->nvdimm_bus);
  115. out_vq:
  116. vdev->config->del_vqs(vdev);
  117. out_err:
  118. return err;
  119. }
  120. static void virtio_pmem_remove(struct virtio_device *vdev)
  121. {
  122. struct nvdimm_bus *nvdimm_bus = dev_get_drvdata(&vdev->dev);
  123. nvdimm_bus_unregister(nvdimm_bus);
  124. vdev->config->del_vqs(vdev);
  125. virtio_reset_device(vdev);
  126. }
  127. static int virtio_pmem_freeze(struct virtio_device *vdev)
  128. {
  129. vdev->config->del_vqs(vdev);
  130. virtio_reset_device(vdev);
  131. return 0;
  132. }
  133. static int virtio_pmem_restore(struct virtio_device *vdev)
  134. {
  135. int ret;
  136. ret = init_vq(vdev->priv);
  137. if (ret) {
  138. dev_err(&vdev->dev, "failed to initialize virtio pmem's vq\n");
  139. return ret;
  140. }
  141. virtio_device_ready(vdev);
  142. return 0;
  143. }
  144. static unsigned int features[] = {
  145. VIRTIO_PMEM_F_SHMEM_REGION,
  146. };
  147. static struct virtio_driver virtio_pmem_driver = {
  148. .feature_table = features,
  149. .feature_table_size = ARRAY_SIZE(features),
  150. .driver.name = KBUILD_MODNAME,
  151. .id_table = id_table,
  152. .validate = virtio_pmem_validate,
  153. .probe = virtio_pmem_probe,
  154. .remove = virtio_pmem_remove,
  155. .freeze = virtio_pmem_freeze,
  156. .restore = virtio_pmem_restore,
  157. };
  158. module_virtio_driver(virtio_pmem_driver);
  159. MODULE_DEVICE_TABLE(virtio, id_table);
  160. MODULE_DESCRIPTION("Virtio pmem driver");
  161. MODULE_LICENSE("GPL");