diff options
| -rw-r--r-- | crypto/algapi.c | 65 | ||||
| -rw-r--r-- | include/crypto/algapi.h | 3 | 
2 files changed, 41 insertions, 27 deletions
diff --git a/crypto/algapi.c b/crypto/algapi.c index 1c2185b5b00..f137a432061 100644 --- a/crypto/algapi.c +++ b/crypto/algapi.c  | |||
| @@ -84,36 +84,47 @@ static void crypto_destroy_instance(struct crypto_alg *alg) | |||
| 84 | crypto_tmpl_put(tmpl); | 84 | crypto_tmpl_put(tmpl); | 
| 85 | } | 85 | } | 
| 86 | 86 | ||
| 87 | static void crypto_remove_spawns(struct list_head *spawns, | 87 | static void crypto_remove_spawn(struct crypto_spawn *spawn, | 
| 88 | struct list_head *list) | 88 | struct list_head *list, | 
| 89 | struct list_head *secondary_spawns) | ||
| 89 | { | 90 | { | 
| 90 | struct crypto_spawn *spawn, *n; | 91 | struct crypto_instance *inst = spawn->inst; | 
| 92 | struct crypto_template *tmpl = inst->tmpl; | ||
| 91 | 93 | ||
| 92 | list_for_each_entry_safe(spawn, n, spawns, list) { | 94 | list_del_init(&spawn->list); | 
| 93 | struct crypto_instance *inst = spawn->inst; | 95 | spawn->alg = NULL; | 
| 94 | struct crypto_template *tmpl = inst->tmpl; | ||
| 95 | 96 | ||
| 96 | list_del_init(&spawn->list); | 97 | if (crypto_is_dead(&inst->alg)) | 
| 97 | spawn->alg = NULL; | 98 | return; | 
| 98 | 99 | ||
| 99 | if (crypto_is_dead(&inst->alg)) | 100 | inst->alg.cra_flags |= CRYPTO_ALG_DEAD; | 
| 100 | continue; | 101 | if (!tmpl || !crypto_tmpl_get(tmpl)) | 
| 102 | return; | ||
| 103 | |||
| 104 | crypto_notify(CRYPTO_MSG_ALG_UNREGISTER, &inst->alg); | ||
| 105 | list_move(&inst->alg.cra_list, list); | ||
| 106 | hlist_del(&inst->list); | ||
| 107 | inst->alg.cra_destroy = crypto_destroy_instance; | ||
| 108 | |||
| 109 | list_splice(&inst->alg.cra_users, secondary_spawns); | ||
| 110 | } | ||
| 111 | |||
| 112 | static void crypto_remove_spawns(struct list_head *spawns, | ||
| 113 | struct list_head *list, u32 new_type) | ||
| 114 | { | ||
| 115 | struct crypto_spawn *spawn, *n; | ||
| 116 | LIST_HEAD(secondary_spawns); | ||
| 101 | 117 | ||
| 102 | inst->alg.cra_flags |= CRYPTO_ALG_DEAD; | 118 | list_for_each_entry_safe(spawn, n, spawns, list) { | 
| 103 | if (!tmpl || !crypto_tmpl_get(tmpl)) | 119 | if ((spawn->alg->cra_flags ^ new_type) & spawn->mask) | 
| 104 | continue; | 120 | continue; | 
| 105 | 121 | ||
| 106 | crypto_notify(CRYPTO_MSG_ALG_UNREGISTER, &inst->alg); | 122 | crypto_remove_spawn(spawn, list, &secondary_spawns); | 
| 107 | list_move(&inst->alg.cra_list, list); | 123 | } | 
| 108 | hlist_del(&inst->list); | ||
| 109 | inst->alg.cra_destroy = crypto_destroy_instance; | ||
| 110 | 124 | ||
| 111 | if (!list_empty(&inst->alg.cra_users)) { | 125 | while (!list_empty(&secondary_spawns)) { | 
| 112 | if (&n->list == spawns) | 126 | list_for_each_entry_safe(spawn, n, &secondary_spawns, list) | 
| 113 | n = list_entry(inst->alg.cra_users.next, | 127 | crypto_remove_spawn(spawn, list, &secondary_spawns); | 
| 114 | typeof(*n), list); | ||
| 115 | __list_splice(&inst->alg.cra_users, spawns->prev); | ||
| 116 | } | ||
| 117 | } | 128 | } | 
| 118 | } | 129 | } | 
| 119 | 130 | ||
| @@ -164,7 +175,7 @@ static int __crypto_register_alg(struct crypto_alg *alg, | |||
| 164 | q->cra_priority > alg->cra_priority) | 175 | q->cra_priority > alg->cra_priority) | 
| 165 | continue; | 176 | continue; | 
| 166 | 177 | ||
| 167 | crypto_remove_spawns(&q->cra_users, list); | 178 | crypto_remove_spawns(&q->cra_users, list, alg->cra_flags); | 
| 168 | } | 179 | } | 
| 169 | 180 | ||
| 170 | list_add(&alg->cra_list, &crypto_alg_list); | 181 | list_add(&alg->cra_list, &crypto_alg_list); | 
| @@ -214,7 +225,7 @@ static int crypto_remove_alg(struct crypto_alg *alg, struct list_head *list) | |||
| 214 | 225 | ||
| 215 | crypto_notify(CRYPTO_MSG_ALG_UNREGISTER, alg); | 226 | crypto_notify(CRYPTO_MSG_ALG_UNREGISTER, alg); | 
| 216 | list_del_init(&alg->cra_list); | 227 | list_del_init(&alg->cra_list); | 
| 217 | crypto_remove_spawns(&alg->cra_users, list); | 228 | crypto_remove_spawns(&alg->cra_users, list, alg->cra_flags); | 
| 218 | 229 | ||
| 219 | return 0; | 230 | return 0; | 
| 220 | } | 231 | } | 
| @@ -351,11 +362,12 @@ err: | |||
| 351 | EXPORT_SYMBOL_GPL(crypto_register_instance); | 362 | EXPORT_SYMBOL_GPL(crypto_register_instance); | 
| 352 | 363 | ||
| 353 | int crypto_init_spawn(struct crypto_spawn *spawn, struct crypto_alg *alg, | 364 | int crypto_init_spawn(struct crypto_spawn *spawn, struct crypto_alg *alg, | 
| 354 | struct crypto_instance *inst) | 365 | struct crypto_instance *inst, u32 mask) | 
| 355 | { | 366 | { | 
| 356 | int err = -EAGAIN; | 367 | int err = -EAGAIN; | 
| 357 | 368 | ||
| 358 | spawn->inst = inst; | 369 | spawn->inst = inst; | 
| 370 | spawn->mask = mask; | ||
| 359 | 371 | ||
| 360 | down_write(&crypto_alg_sem); | 372 | down_write(&crypto_alg_sem); | 
| 361 | if (!crypto_is_moribund(alg)) { | 373 | if (!crypto_is_moribund(alg)) { | 
| @@ -494,7 +506,8 @@ struct crypto_instance *crypto_alloc_instance(const char *name, | |||
| 494 | goto err_free_inst; | 506 | goto err_free_inst; | 
| 495 | 507 | ||
| 496 | spawn = crypto_instance_ctx(inst); | 508 | spawn = crypto_instance_ctx(inst); | 
| 497 | err = crypto_init_spawn(spawn, alg, inst); | 509 | err = crypto_init_spawn(spawn, alg, inst, | 
| 510 | CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC); | ||
| 498 | 511 | ||
| 499 | if (err) | 512 | if (err) | 
| 500 | goto err_free_inst; | 513 | goto err_free_inst; | 
diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h index 469f511315c..7847fc2a03f 100644 --- a/include/crypto/algapi.h +++ b/include/crypto/algapi.h  | |||
| @@ -51,6 +51,7 @@ struct crypto_spawn { | |||
| 51 | struct list_head list; | 51 | struct list_head list; | 
| 52 | struct crypto_alg *alg; | 52 | struct crypto_alg *alg; | 
| 53 | struct crypto_instance *inst; | 53 | struct crypto_instance *inst; | 
| 54 | u32 mask; | ||
| 54 | }; | 55 | }; | 
| 55 | 56 | ||
| 56 | struct crypto_queue { | 57 | struct crypto_queue { | 
| @@ -103,7 +104,7 @@ void crypto_unregister_template(struct crypto_template *tmpl); | |||
| 103 | struct crypto_template *crypto_lookup_template(const char *name); | 104 | struct crypto_template *crypto_lookup_template(const char *name); | 
| 104 | 105 | ||
| 105 | int crypto_init_spawn(struct crypto_spawn *spawn, struct crypto_alg *alg, | 106 | int crypto_init_spawn(struct crypto_spawn *spawn, struct crypto_alg *alg, | 
| 106 | struct crypto_instance *inst); | 107 | struct crypto_instance *inst, u32 mask); | 
| 107 | void crypto_drop_spawn(struct crypto_spawn *spawn); | 108 | void crypto_drop_spawn(struct crypto_spawn *spawn); | 
| 108 | struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn, u32 type, | 109 | struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn, u32 type, | 
| 109 | u32 mask); | 110 | u32 mask); | 
