mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-23 23:32:14 +00:00
crypto: api - Fix built-in testing dependency failures
When complex algorithms that depend on other algorithms are built into the kernel, the order of registration must be done such that the underlying algorithms are ready before the ones on top are registered. As otherwise they would fail during the self-test which is required during registration. In the past we have used subsystem initialisation ordering to guarantee this. The number of such precedence levels are limited and they may cause ripple effects in other subsystems. This patch solves this problem by delaying all self-tests during boot-up for built-in algorithms. They will be tested either when something else in the kernel requests for them, or when we have finished registering all built-in algorithms, whichever comes earlier. Reported-by: Vladis Dronov <vdronov@redhat.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
parent
7c5329697e
commit
adad556efc
3 changed files with 108 additions and 27 deletions
52
crypto/api.c
52
crypto/api.c
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include <linux/err.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/jump_label.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/kmod.h>
|
||||
#include <linux/module.h>
|
||||
|
@ -30,6 +31,8 @@ EXPORT_SYMBOL_GPL(crypto_alg_sem);
|
|||
BLOCKING_NOTIFIER_HEAD(crypto_chain);
|
||||
EXPORT_SYMBOL_GPL(crypto_chain);
|
||||
|
||||
DEFINE_STATIC_KEY_FALSE(crypto_boot_test_finished);
|
||||
|
||||
static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg);
|
||||
|
||||
struct crypto_alg *crypto_mod_get(struct crypto_alg *alg)
|
||||
|
@ -47,11 +50,6 @@ void crypto_mod_put(struct crypto_alg *alg)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(crypto_mod_put);
|
||||
|
||||
static inline int crypto_is_test_larval(struct crypto_larval *larval)
|
||||
{
|
||||
return larval->alg.cra_driver_name[0];
|
||||
}
|
||||
|
||||
static struct crypto_alg *__crypto_alg_lookup(const char *name, u32 type,
|
||||
u32 mask)
|
||||
{
|
||||
|
@ -163,11 +161,55 @@ void crypto_larval_kill(struct crypto_alg *alg)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(crypto_larval_kill);
|
||||
|
||||
void crypto_wait_for_test(struct crypto_larval *larval)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = crypto_probing_notify(CRYPTO_MSG_ALG_REGISTER, larval->adult);
|
||||
if (err != NOTIFY_STOP) {
|
||||
if (WARN_ON(err != NOTIFY_DONE))
|
||||
goto out;
|
||||
crypto_alg_tested(larval->alg.cra_driver_name, 0);
|
||||
}
|
||||
|
||||
err = wait_for_completion_killable(&larval->completion);
|
||||
WARN_ON(err);
|
||||
if (!err)
|
||||
crypto_notify(CRYPTO_MSG_ALG_LOADED, larval);
|
||||
|
||||
out:
|
||||
crypto_larval_kill(&larval->alg);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(crypto_wait_for_test);
|
||||
|
||||
static void crypto_start_test(struct crypto_larval *larval)
|
||||
{
|
||||
if (!crypto_is_test_larval(larval))
|
||||
return;
|
||||
|
||||
if (larval->test_started)
|
||||
return;
|
||||
|
||||
down_write(&crypto_alg_sem);
|
||||
if (larval->test_started) {
|
||||
up_write(&crypto_alg_sem);
|
||||
return;
|
||||
}
|
||||
|
||||
larval->test_started = true;
|
||||
up_write(&crypto_alg_sem);
|
||||
|
||||
crypto_wait_for_test(larval);
|
||||
}
|
||||
|
||||
static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg)
|
||||
{
|
||||
struct crypto_larval *larval = (void *)alg;
|
||||
long timeout;
|
||||
|
||||
if (!static_branch_likely(&crypto_boot_test_finished))
|
||||
crypto_start_test(larval);
|
||||
|
||||
timeout = wait_for_completion_killable_timeout(
|
||||
&larval->completion, 60 * HZ);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue