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