virtio_crypto_mgr.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. /* Management for virtio crypto devices (refer to adf_dev_mgr.c)
  2. *
  3. * Copyright 2016 HUAWEI TECHNOLOGIES CO., LTD.
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include <linux/mutex.h>
  19. #include <linux/list.h>
  20. #include <linux/module.h>
  21. #include <uapi/linux/virtio_crypto.h>
  22. #include "virtio_crypto_common.h"
  23. static LIST_HEAD(virtio_crypto_table);
  24. static uint32_t num_devices;
  25. /* The table_lock protects the above global list and num_devices */
  26. static DEFINE_MUTEX(table_lock);
  27. #define VIRTIO_CRYPTO_MAX_DEVICES 32
  28. /*
  29. * virtcrypto_devmgr_add_dev() - Add vcrypto_dev to the acceleration
  30. * framework.
  31. * @vcrypto_dev: Pointer to virtio crypto device.
  32. *
  33. * Function adds virtio crypto device to the global list.
  34. * To be used by virtio crypto device specific drivers.
  35. *
  36. * Return: 0 on success, error code othewise.
  37. */
  38. int virtcrypto_devmgr_add_dev(struct virtio_crypto *vcrypto_dev)
  39. {
  40. struct list_head *itr;
  41. mutex_lock(&table_lock);
  42. if (num_devices == VIRTIO_CRYPTO_MAX_DEVICES) {
  43. pr_info("virtio_crypto: only support up to %d devices\n",
  44. VIRTIO_CRYPTO_MAX_DEVICES);
  45. mutex_unlock(&table_lock);
  46. return -EFAULT;
  47. }
  48. list_for_each(itr, &virtio_crypto_table) {
  49. struct virtio_crypto *ptr =
  50. list_entry(itr, struct virtio_crypto, list);
  51. if (ptr == vcrypto_dev) {
  52. mutex_unlock(&table_lock);
  53. return -EEXIST;
  54. }
  55. }
  56. atomic_set(&vcrypto_dev->ref_count, 0);
  57. list_add_tail(&vcrypto_dev->list, &virtio_crypto_table);
  58. vcrypto_dev->dev_id = num_devices++;
  59. mutex_unlock(&table_lock);
  60. return 0;
  61. }
  62. struct list_head *virtcrypto_devmgr_get_head(void)
  63. {
  64. return &virtio_crypto_table;
  65. }
  66. /*
  67. * virtcrypto_devmgr_rm_dev() - Remove vcrypto_dev from the acceleration
  68. * framework.
  69. * @vcrypto_dev: Pointer to virtio crypto device.
  70. *
  71. * Function removes virtio crypto device from the acceleration framework.
  72. * To be used by virtio crypto device specific drivers.
  73. *
  74. * Return: void
  75. */
  76. void virtcrypto_devmgr_rm_dev(struct virtio_crypto *vcrypto_dev)
  77. {
  78. mutex_lock(&table_lock);
  79. list_del(&vcrypto_dev->list);
  80. num_devices--;
  81. mutex_unlock(&table_lock);
  82. }
  83. /*
  84. * virtcrypto_devmgr_get_first()
  85. *
  86. * Function returns the first virtio crypto device from the acceleration
  87. * framework.
  88. *
  89. * To be used by virtio crypto device specific drivers.
  90. *
  91. * Return: pointer to vcrypto_dev or NULL if not found.
  92. */
  93. struct virtio_crypto *virtcrypto_devmgr_get_first(void)
  94. {
  95. struct virtio_crypto *dev = NULL;
  96. mutex_lock(&table_lock);
  97. if (!list_empty(&virtio_crypto_table))
  98. dev = list_first_entry(&virtio_crypto_table,
  99. struct virtio_crypto,
  100. list);
  101. mutex_unlock(&table_lock);
  102. return dev;
  103. }
  104. /*
  105. * virtcrypto_dev_in_use() - Check whether vcrypto_dev is currently in use
  106. * @vcrypto_dev: Pointer to virtio crypto device.
  107. *
  108. * To be used by virtio crypto device specific drivers.
  109. *
  110. * Return: 1 when device is in use, 0 otherwise.
  111. */
  112. int virtcrypto_dev_in_use(struct virtio_crypto *vcrypto_dev)
  113. {
  114. return atomic_read(&vcrypto_dev->ref_count) != 0;
  115. }
  116. /*
  117. * virtcrypto_dev_get() - Increment vcrypto_dev reference count
  118. * @vcrypto_dev: Pointer to virtio crypto device.
  119. *
  120. * Increment the vcrypto_dev refcount and if this is the first time
  121. * incrementing it during this period the vcrypto_dev is in use,
  122. * increment the module refcount too.
  123. * To be used by virtio crypto device specific drivers.
  124. *
  125. * Return: 0 when successful, EFAULT when fail to bump module refcount
  126. */
  127. int virtcrypto_dev_get(struct virtio_crypto *vcrypto_dev)
  128. {
  129. if (atomic_add_return(1, &vcrypto_dev->ref_count) == 1)
  130. if (!try_module_get(vcrypto_dev->owner))
  131. return -EFAULT;
  132. return 0;
  133. }
  134. /*
  135. * virtcrypto_dev_put() - Decrement vcrypto_dev reference count
  136. * @vcrypto_dev: Pointer to virtio crypto device.
  137. *
  138. * Decrement the vcrypto_dev refcount and if this is the last time
  139. * decrementing it during this period the vcrypto_dev is in use,
  140. * decrement the module refcount too.
  141. * To be used by virtio crypto device specific drivers.
  142. *
  143. * Return: void
  144. */
  145. void virtcrypto_dev_put(struct virtio_crypto *vcrypto_dev)
  146. {
  147. if (atomic_sub_return(1, &vcrypto_dev->ref_count) == 0)
  148. module_put(vcrypto_dev->owner);
  149. }
  150. /*
  151. * virtcrypto_dev_started() - Check whether device has started
  152. * @vcrypto_dev: Pointer to virtio crypto device.
  153. *
  154. * To be used by virtio crypto device specific drivers.
  155. *
  156. * Return: 1 when the device has started, 0 otherwise
  157. */
  158. int virtcrypto_dev_started(struct virtio_crypto *vcrypto_dev)
  159. {
  160. return (vcrypto_dev->status & VIRTIO_CRYPTO_S_HW_READY);
  161. }
  162. /*
  163. * virtcrypto_get_dev_node() - Get vcrypto_dev on the node.
  164. * @node: Node id the driver works.
  165. *
  166. * Function returns the virtio crypto device used fewest on the node.
  167. *
  168. * To be used by virtio crypto device specific drivers.
  169. *
  170. * Return: pointer to vcrypto_dev or NULL if not found.
  171. */
  172. struct virtio_crypto *virtcrypto_get_dev_node(int node)
  173. {
  174. struct virtio_crypto *vcrypto_dev = NULL, *tmp_dev;
  175. unsigned long best = ~0;
  176. unsigned long ctr;
  177. mutex_lock(&table_lock);
  178. list_for_each_entry(tmp_dev, virtcrypto_devmgr_get_head(), list) {
  179. if ((node == dev_to_node(&tmp_dev->vdev->dev) ||
  180. dev_to_node(&tmp_dev->vdev->dev) < 0) &&
  181. virtcrypto_dev_started(tmp_dev)) {
  182. ctr = atomic_read(&tmp_dev->ref_count);
  183. if (best > ctr) {
  184. vcrypto_dev = tmp_dev;
  185. best = ctr;
  186. }
  187. }
  188. }
  189. if (!vcrypto_dev) {
  190. pr_info("virtio_crypto: Could not find a device on node %d\n",
  191. node);
  192. /* Get any started device */
  193. list_for_each_entry(tmp_dev,
  194. virtcrypto_devmgr_get_head(), list) {
  195. if (virtcrypto_dev_started(tmp_dev)) {
  196. vcrypto_dev = tmp_dev;
  197. break;
  198. }
  199. }
  200. }
  201. mutex_unlock(&table_lock);
  202. if (!vcrypto_dev)
  203. return NULL;
  204. virtcrypto_dev_get(vcrypto_dev);
  205. return vcrypto_dev;
  206. }
  207. /*
  208. * virtcrypto_dev_start() - Start virtio crypto device
  209. * @vcrypto: Pointer to virtio crypto device.
  210. *
  211. * Function notifies all the registered services that the virtio crypto device
  212. * is ready to be used.
  213. * To be used by virtio crypto device specific drivers.
  214. *
  215. * Return: 0 on success, EFAULT when fail to register algorithms
  216. */
  217. int virtcrypto_dev_start(struct virtio_crypto *vcrypto)
  218. {
  219. if (virtio_crypto_algs_register()) {
  220. pr_err("virtio_crypto: Failed to register crypto algs\n");
  221. return -EFAULT;
  222. }
  223. return 0;
  224. }
  225. /*
  226. * virtcrypto_dev_stop() - Stop virtio crypto device
  227. * @vcrypto: Pointer to virtio crypto device.
  228. *
  229. * Function notifies all the registered services that the virtio crypto device
  230. * is ready to be used.
  231. * To be used by virtio crypto device specific drivers.
  232. *
  233. * Return: void
  234. */
  235. void virtcrypto_dev_stop(struct virtio_crypto *vcrypto)
  236. {
  237. virtio_crypto_algs_unregister();
  238. }