On Wed, 13 Mar 2019 at 06:15, Eric Biggers <ebiggers@xxxxxxxxxx> wrote: > > From: Eric Biggers <ebiggers@xxxxxxxxxx> > > So that the no-SIMD fallback code can be tested by the crypto > self-tests, add a macro crypto_simd_usable() which wraps may_use_simd(), > but also returns false if the crypto self-tests have set a per-CPU bool > to disable SIMD in crypto code on the current CPU. > > Signed-off-by: Eric Biggers <ebiggers@xxxxxxxxxx> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@xxxxxxxxxx> > --- > crypto/testmgr.c | 26 +++++++++++++++++++++++++- > include/crypto/internal/simd.h | 24 ++++++++++++++++++++++++ > 2 files changed, 49 insertions(+), 1 deletion(-) > > diff --git a/crypto/testmgr.c b/crypto/testmgr.c > index 5d56b2990762..52417dde811f 100644 > --- a/crypto/testmgr.c > +++ b/crypto/testmgr.c > @@ -37,6 +37,7 @@ > #include <crypto/akcipher.h> > #include <crypto/kpp.h> > #include <crypto/acompress.h> > +#include <crypto/internal/simd.h> > > #include "internal.h" > > @@ -52,6 +53,9 @@ MODULE_PARM_DESC(noextratests, "disable expensive crypto self-tests"); > static unsigned int fuzz_iterations = 100; > module_param(fuzz_iterations, uint, 0644); > MODULE_PARM_DESC(fuzz_iterations, "number of fuzz test iterations"); > + > +DEFINE_PER_CPU(bool, crypto_simd_disabled_for_test); > +EXPORT_PER_CPU_SYMBOL_GPL(crypto_simd_disabled_for_test); > #endif > > #ifdef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS > @@ -838,7 +842,27 @@ static void generate_random_testvec_config(struct testvec_config *cfg, > > WARN_ON_ONCE(!valid_testvec_config(cfg)); > } > -#endif /* CONFIG_CRYPTO_MANAGER_EXTRA_TESTS */ > + > +static void crypto_disable_simd_for_test(void) > +{ > + preempt_disable(); > + __this_cpu_write(crypto_simd_disabled_for_test, true); > +} > + > +static void crypto_reenable_simd_for_test(void) > +{ > + __this_cpu_write(crypto_simd_disabled_for_test, false); > + preempt_enable(); > +} > +#else /* !CONFIG_CRYPTO_MANAGER_EXTRA_TESTS */ > +static void crypto_disable_simd_for_test(void) > +{ > +} > + > +static void crypto_reenable_simd_for_test(void) > +{ > +} > +#endif /* !CONFIG_CRYPTO_MANAGER_EXTRA_TESTS */ > > static int check_nonfinal_hash_op(const char *op, int err, > u8 *result, unsigned int digestsize, > diff --git a/include/crypto/internal/simd.h b/include/crypto/internal/simd.h > index a23b18b6ad61..d2316242a988 100644 > --- a/include/crypto/internal/simd.h > +++ b/include/crypto/internal/simd.h > @@ -6,6 +6,9 @@ > #ifndef _CRYPTO_INTERNAL_SIMD_H > #define _CRYPTO_INTERNAL_SIMD_H > > +#include <linux/percpu.h> > +#include <linux/types.h> > + > /* skcipher support */ > > struct simd_skcipher_alg; > @@ -42,4 +45,25 @@ int simd_register_aeads_compat(struct aead_alg *algs, int count, > void simd_unregister_aeads(struct aead_alg *algs, int count, > struct simd_aead_alg **simd_algs); > > +/* > + * crypto_simd_usable() - is it allowed at this time to use SIMD instructions or > + * access the SIMD register file? > + * > + * This delegates to may_use_simd(), except that this also returns false if SIMD > + * in crypto code has been temporarily disabled on this CPU by the crypto > + * self-tests, in order to test the no-SIMD fallback code. This override is > + * currently limited to configurations where the extra self-tests are enabled, > + * because it might be a bit too invasive to be part of the regular self-tests. > + * > + * This is a macro so that <asm/simd.h>, which some architectures don't have, > + * doesn't have to be included directly here. > + */ > +#ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS > +DECLARE_PER_CPU(bool, crypto_simd_disabled_for_test); > +#define crypto_simd_usable() \ > + (may_use_simd() && !this_cpu_read(crypto_simd_disabled_for_test)) > +#else > +#define crypto_simd_usable() may_use_simd() > +#endif > + > #endif /* _CRYPTO_INTERNAL_SIMD_H */ > -- > 2.21.0 >