Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0-or-later 2 : /* Management for virtio crypto devices (refer to adf_dev_mgr.c) 3 : * 4 : * Copyright 2016 HUAWEI TECHNOLOGIES CO., LTD. 5 : */ 6 : 7 : #include <linux/mutex.h> 8 : #include <linux/list.h> 9 : #include <linux/module.h> 10 : 11 : #include <uapi/linux/virtio_crypto.h> 12 : #include "virtio_crypto_common.h" 13 : 14 : static LIST_HEAD(virtio_crypto_table); 15 : static uint32_t num_devices; 16 : 17 : /* The table_lock protects the above global list and num_devices */ 18 : static DEFINE_MUTEX(table_lock); 19 : 20 : #define VIRTIO_CRYPTO_MAX_DEVICES 32 21 : 22 : 23 : /* 24 : * virtcrypto_devmgr_add_dev() - Add vcrypto_dev to the acceleration 25 : * framework. 26 : * @vcrypto_dev: Pointer to virtio crypto device. 27 : * 28 : * Function adds virtio crypto device to the global list. 29 : * To be used by virtio crypto device specific drivers. 30 : * 31 : * Return: 0 on success, error code othewise. 32 : */ 33 0 : int virtcrypto_devmgr_add_dev(struct virtio_crypto *vcrypto_dev) 34 : { 35 0 : struct list_head *itr; 36 : 37 0 : mutex_lock(&table_lock); 38 0 : if (num_devices == VIRTIO_CRYPTO_MAX_DEVICES) { 39 0 : pr_info("virtio_crypto: only support up to %d devices\n", 40 : VIRTIO_CRYPTO_MAX_DEVICES); 41 0 : mutex_unlock(&table_lock); 42 0 : return -EFAULT; 43 : } 44 : 45 0 : list_for_each(itr, &virtio_crypto_table) { 46 0 : struct virtio_crypto *ptr = 47 0 : list_entry(itr, struct virtio_crypto, list); 48 : 49 0 : if (ptr == vcrypto_dev) { 50 0 : mutex_unlock(&table_lock); 51 0 : return -EEXIST; 52 : } 53 : } 54 0 : atomic_set(&vcrypto_dev->ref_count, 0); 55 0 : list_add_tail(&vcrypto_dev->list, &virtio_crypto_table); 56 0 : vcrypto_dev->dev_id = num_devices++; 57 0 : mutex_unlock(&table_lock); 58 0 : return 0; 59 : } 60 : 61 0 : struct list_head *virtcrypto_devmgr_get_head(void) 62 : { 63 0 : return &virtio_crypto_table; 64 : } 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 0 : void virtcrypto_devmgr_rm_dev(struct virtio_crypto *vcrypto_dev) 77 : { 78 0 : mutex_lock(&table_lock); 79 0 : list_del(&vcrypto_dev->list); 80 0 : num_devices--; 81 0 : mutex_unlock(&table_lock); 82 0 : } 83 : 84 : /* 85 : * virtcrypto_devmgr_get_first() 86 : * 87 : * Function returns the first virtio crypto device from the acceleration 88 : * framework. 89 : * 90 : * To be used by virtio crypto device specific drivers. 91 : * 92 : * Return: pointer to vcrypto_dev or NULL if not found. 93 : */ 94 0 : struct virtio_crypto *virtcrypto_devmgr_get_first(void) 95 : { 96 0 : struct virtio_crypto *dev = NULL; 97 : 98 0 : mutex_lock(&table_lock); 99 0 : if (!list_empty(&virtio_crypto_table)) 100 0 : dev = list_first_entry(&virtio_crypto_table, 101 : struct virtio_crypto, 102 : list); 103 0 : mutex_unlock(&table_lock); 104 0 : return dev; 105 : } 106 : 107 : /* 108 : * virtcrypto_dev_in_use() - Check whether vcrypto_dev is currently in use 109 : * @vcrypto_dev: Pointer to virtio crypto device. 110 : * 111 : * To be used by virtio crypto device specific drivers. 112 : * 113 : * Return: 1 when device is in use, 0 otherwise. 114 : */ 115 0 : int virtcrypto_dev_in_use(struct virtio_crypto *vcrypto_dev) 116 : { 117 0 : return atomic_read(&vcrypto_dev->ref_count) != 0; 118 : } 119 : 120 : /* 121 : * virtcrypto_dev_get() - Increment vcrypto_dev reference count 122 : * @vcrypto_dev: Pointer to virtio crypto device. 123 : * 124 : * Increment the vcrypto_dev refcount and if this is the first time 125 : * incrementing it during this period the vcrypto_dev is in use, 126 : * increment the module refcount too. 127 : * To be used by virtio crypto device specific drivers. 128 : * 129 : * Return: 0 when successful, EFAULT when fail to bump module refcount 130 : */ 131 0 : int virtcrypto_dev_get(struct virtio_crypto *vcrypto_dev) 132 : { 133 0 : if (atomic_add_return(1, &vcrypto_dev->ref_count) == 1) 134 : if (!try_module_get(vcrypto_dev->owner)) 135 : return -EFAULT; 136 0 : return 0; 137 : } 138 : 139 : /* 140 : * virtcrypto_dev_put() - Decrement vcrypto_dev reference count 141 : * @vcrypto_dev: Pointer to virtio crypto device. 142 : * 143 : * Decrement the vcrypto_dev refcount and if this is the last time 144 : * decrementing it during this period the vcrypto_dev is in use, 145 : * decrement the module refcount too. 146 : * To be used by virtio crypto device specific drivers. 147 : * 148 : * Return: void 149 : */ 150 0 : void virtcrypto_dev_put(struct virtio_crypto *vcrypto_dev) 151 : { 152 0 : if (atomic_sub_return(1, &vcrypto_dev->ref_count) == 0) 153 0 : module_put(vcrypto_dev->owner); 154 0 : } 155 : 156 : /* 157 : * virtcrypto_dev_started() - Check whether device has started 158 : * @vcrypto_dev: Pointer to virtio crypto device. 159 : * 160 : * To be used by virtio crypto device specific drivers. 161 : * 162 : * Return: 1 when the device has started, 0 otherwise 163 : */ 164 0 : int virtcrypto_dev_started(struct virtio_crypto *vcrypto_dev) 165 : { 166 0 : return (vcrypto_dev->status & VIRTIO_CRYPTO_S_HW_READY); 167 : } 168 : 169 : /* 170 : * virtcrypto_get_dev_node() - Get vcrypto_dev on the node. 171 : * @node: Node id the driver works. 172 : * @service: Crypto service that needs to be supported by the 173 : * dev 174 : * @algo: The algorithm number that needs to be supported by the 175 : * dev 176 : * 177 : * Function returns the virtio crypto device used fewest on the node, 178 : * and supports the given crypto service and algorithm. 179 : * 180 : * To be used by virtio crypto device specific drivers. 181 : * 182 : * Return: pointer to vcrypto_dev or NULL if not found. 183 : */ 184 0 : struct virtio_crypto *virtcrypto_get_dev_node(int node, uint32_t service, 185 : uint32_t algo) 186 : { 187 0 : struct virtio_crypto *vcrypto_dev = NULL, *tmp_dev; 188 0 : unsigned long best = ~0; 189 0 : unsigned long ctr; 190 : 191 0 : mutex_lock(&table_lock); 192 0 : list_for_each_entry(tmp_dev, virtcrypto_devmgr_get_head(), list) { 193 : 194 0 : if ((node == dev_to_node(&tmp_dev->vdev->dev) || 195 0 : dev_to_node(&tmp_dev->vdev->dev) < 0) && 196 0 : virtcrypto_dev_started(tmp_dev) && 197 0 : virtcrypto_algo_is_supported(tmp_dev, service, algo)) { 198 0 : ctr = atomic_read(&tmp_dev->ref_count); 199 0 : if (best > ctr) { 200 0 : vcrypto_dev = tmp_dev; 201 0 : best = ctr; 202 : } 203 : } 204 : } 205 : 206 0 : if (!vcrypto_dev) { 207 0 : pr_info("virtio_crypto: Could not find a device on node %d\n", 208 : node); 209 : /* Get any started device */ 210 0 : list_for_each_entry(tmp_dev, 211 : virtcrypto_devmgr_get_head(), list) { 212 0 : if (virtcrypto_dev_started(tmp_dev) && 213 0 : virtcrypto_algo_is_supported(tmp_dev, 214 : service, algo)) { 215 : vcrypto_dev = tmp_dev; 216 : break; 217 : } 218 : } 219 : } 220 0 : mutex_unlock(&table_lock); 221 0 : if (!vcrypto_dev) 222 : return NULL; 223 : 224 0 : virtcrypto_dev_get(vcrypto_dev); 225 0 : return vcrypto_dev; 226 : } 227 : 228 : /* 229 : * virtcrypto_dev_start() - Start virtio crypto device 230 : * @vcrypto: Pointer to virtio crypto device. 231 : * 232 : * Function notifies all the registered services that the virtio crypto device 233 : * is ready to be used. 234 : * To be used by virtio crypto device specific drivers. 235 : * 236 : * Return: 0 on success, EFAULT when fail to register algorithms 237 : */ 238 0 : int virtcrypto_dev_start(struct virtio_crypto *vcrypto) 239 : { 240 0 : if (virtio_crypto_algs_register(vcrypto)) { 241 0 : pr_err("virtio_crypto: Failed to register crypto algs\n"); 242 0 : return -EFAULT; 243 : } 244 : 245 : return 0; 246 : } 247 : 248 : /* 249 : * virtcrypto_dev_stop() - Stop virtio crypto device 250 : * @vcrypto: Pointer to virtio crypto device. 251 : * 252 : * Function notifies all the registered services that the virtio crypto device 253 : * is ready to be used. 254 : * To be used by virtio crypto device specific drivers. 255 : * 256 : * Return: void 257 : */ 258 0 : void virtcrypto_dev_stop(struct virtio_crypto *vcrypto) 259 : { 260 0 : virtio_crypto_algs_unregister(vcrypto); 261 0 : } 262 : 263 : /* 264 : * vcrypto_algo_is_supported() 265 : * @vcrypto: Pointer to virtio crypto device. 266 : * @service: The bit number for service validate. 267 : * See VIRTIO_CRYPTO_SERVICE_* 268 : * @algo : The bit number for the algorithm to validate. 269 : * 270 : * 271 : * Validate if the virtio crypto device supports a service and 272 : * algo. 273 : * 274 : * Return true if device supports a service and algo. 275 : */ 276 : 277 0 : bool virtcrypto_algo_is_supported(struct virtio_crypto *vcrypto, 278 : uint32_t service, 279 : uint32_t algo) 280 : { 281 0 : uint32_t service_mask = 1u << service; 282 0 : uint32_t algo_mask = 0; 283 0 : bool low = true; 284 : 285 0 : if (algo > 31) { 286 0 : algo -= 32; 287 0 : low = false; 288 : } 289 : 290 0 : if (!(vcrypto->crypto_services & service_mask)) 291 : return false; 292 : 293 0 : switch (service) { 294 0 : case VIRTIO_CRYPTO_SERVICE_CIPHER: 295 0 : if (low) 296 0 : algo_mask = vcrypto->cipher_algo_l; 297 : else 298 0 : algo_mask = vcrypto->cipher_algo_h; 299 : break; 300 : 301 0 : case VIRTIO_CRYPTO_SERVICE_HASH: 302 0 : algo_mask = vcrypto->hash_algo; 303 0 : break; 304 : 305 0 : case VIRTIO_CRYPTO_SERVICE_MAC: 306 0 : if (low) 307 0 : algo_mask = vcrypto->mac_algo_l; 308 : else 309 0 : algo_mask = vcrypto->mac_algo_h; 310 : break; 311 : 312 0 : case VIRTIO_CRYPTO_SERVICE_AEAD: 313 0 : algo_mask = vcrypto->aead_algo; 314 0 : break; 315 : } 316 : 317 0 : if (!(algo_mask & (1u << algo))) 318 0 : return false; 319 : 320 : return true; 321 : }