@@ -288,6 +288,11 @@ static const struct x86_cpu_id module_cpu_ids[] = {
};
MODULE_DEVICE_TABLE(x86cpu, module_cpu_ids);
+static int missing_x86_features;
+module_param(missing_x86_features, int, 0444);
+MODULE_PARM_DESC(missing_x86_features,
+ "Missing x86 instruction set extensions (SSE2) and/or XSAVE features (SSE)");
+
static struct simd_aead_alg *simd_alg;
static int __init crypto_aegis128_aesni_module_init(void)
@@ -296,8 +301,10 @@ static int __init crypto_aegis128_aesni_module_init(void)
return -ENODEV;
if (!boot_cpu_has(X86_FEATURE_XMM2) ||
- !cpu_has_xfeatures(XFEATURE_MASK_SSE, NULL))
- return -ENODEV;
+ !cpu_has_xfeatures(XFEATURE_MASK_SSE, NULL)) {
+ missing_x86_features = 1;
+ return 0;
+ }
return simd_register_aeads_compat(&crypto_aegis128_aesni_alg, 1,
&simd_alg);
@@ -305,7 +312,9 @@ static int __init crypto_aegis128_aesni_module_init(void)
static void __exit crypto_aegis128_aesni_module_exit(void)
{
- simd_unregister_aeads(&crypto_aegis128_aesni_alg, 1, &simd_alg);
+ if (!missing_x86_features)
+ simd_unregister_aeads(&crypto_aegis128_aesni_alg, 1, &simd_alg);
+ missing_x86_features = 0;
}
module_init(crypto_aegis128_aesni_module_init);
@@ -176,23 +176,25 @@ static const struct x86_cpu_id module_cpu_ids[] = {
};
MODULE_DEVICE_TABLE(x86cpu, module_cpu_ids);
+static int missing_x86_features;
+module_param(missing_x86_features, int, 0444);
+MODULE_PARM_DESC(missing_x86_features,
+ "Missing x86 instruction set extensions (AES-NI, OSXSAVE) and/or XSAVE features (SSE, YMM)");
+
static int __init aria_avx_init(void)
{
- const char *feature_name;
-
if (!x86_match_cpu(module_cpu_ids))
return -ENODEV;
if (!boot_cpu_has(X86_FEATURE_AES) ||
!boot_cpu_has(X86_FEATURE_OSXSAVE)) {
- pr_info("AES or OSXSAVE instructions are not detected.\n");
- return -ENODEV;
+ missing_x86_features = 1;
+ return 0;
}
- if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM,
- &feature_name)) {
- pr_info("CPU feature '%s' is not supported.\n", feature_name);
- return -ENODEV;
+ if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, NULL)) {
+ missing_x86_features = 1;
+ return 0;
}
if (boot_cpu_has(X86_FEATURE_GFNI)) {
@@ -213,8 +215,10 @@ static int __init aria_avx_init(void)
static void __exit aria_avx_exit(void)
{
- simd_unregister_skciphers(aria_algs, ARRAY_SIZE(aria_algs),
- aria_simd_algs);
+ if (!missing_x86_features)
+ simd_unregister_skciphers(aria_algs, ARRAY_SIZE(aria_algs),
+ aria_simd_algs);
+ missing_x86_features = 0;
using_x86_gfni = 0;
}
@@ -105,26 +105,28 @@ static const struct x86_cpu_id module_cpu_ids[] = {
};
MODULE_DEVICE_TABLE(x86cpu, module_cpu_ids);
+static int missing_x86_features;
+module_param(missing_x86_features, int, 0444);
+MODULE_PARM_DESC(missing_x86_features,
+ "Missing x86 instruction set extensions (AES-NI, AVX, OSXSAVE) and/or XSAVE features (SSE, YMM)");
+
static struct simd_skcipher_alg *camellia_simd_algs[ARRAY_SIZE(camellia_algs)];
static int __init camellia_aesni_init(void)
{
- const char *feature_name;
-
if (!x86_match_cpu(module_cpu_ids))
return -ENODEV;
if (!boot_cpu_has(X86_FEATURE_AES) ||
!boot_cpu_has(X86_FEATURE_AVX) ||
!boot_cpu_has(X86_FEATURE_OSXSAVE)) {
- pr_info("AES-NI, AVX, or OSXSAVE instructions are not detected.\n");
- return -ENODEV;
+ missing_x86_features = 1;
+ return 0;
}
- if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM,
- &feature_name)) {
- pr_info("CPU feature '%s' is not supported.\n", feature_name);
- return -ENODEV;
+ if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, NULL)) {
+ missing_x86_features = 1;
+ return 0;
}
return simd_register_skciphers_compat(camellia_algs,
@@ -134,8 +136,11 @@ static int __init camellia_aesni_init(void)
static void __exit camellia_aesni_fini(void)
{
- simd_unregister_skciphers(camellia_algs, ARRAY_SIZE(camellia_algs),
- camellia_simd_algs);
+ if (!missing_x86_features)
+ simd_unregister_skciphers(camellia_algs,
+ ARRAY_SIZE(camellia_algs),
+ camellia_simd_algs);
+ missing_x86_features = 0;
}
module_init(camellia_aesni_init);
@@ -105,25 +105,27 @@ static const struct x86_cpu_id module_cpu_ids[] = {
};
MODULE_DEVICE_TABLE(x86cpu, module_cpu_ids);
+static int missing_x86_features;
+module_param(missing_x86_features, int, 0444);
+MODULE_PARM_DESC(missing_x86_features,
+ "Missing x86 instruction set extensions (AES-NI, OSXSAVE) and/or XSAVE features (SSE, YMM)");
+
static struct simd_skcipher_alg *camellia_simd_algs[ARRAY_SIZE(camellia_algs)];
static int __init camellia_aesni_init(void)
{
- const char *feature_name;
-
if (!x86_match_cpu(module_cpu_ids))
return -ENODEV;
if (!boot_cpu_has(X86_FEATURE_AES) ||
!boot_cpu_has(X86_FEATURE_OSXSAVE)) {
- pr_info("AES-NI or OSXSAVE instructions are not detected.\n");
- return -ENODEV;
+ missing_x86_features = 1;
+ return 0;
}
- if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM,
- &feature_name)) {
- pr_info("CPU feature '%s' is not supported.\n", feature_name);
- return -ENODEV;
+ if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, NULL)) {
+ missing_x86_features = 1;
+ return 0;
}
return simd_register_skciphers_compat(camellia_algs,
@@ -133,8 +135,11 @@ static int __init camellia_aesni_init(void)
static void __exit camellia_aesni_fini(void)
{
- simd_unregister_skciphers(camellia_algs, ARRAY_SIZE(camellia_algs),
- camellia_simd_algs);
+ if (!missing_x86_features)
+ simd_unregister_skciphers(camellia_algs,
+ ARRAY_SIZE(camellia_algs),
+ camellia_simd_algs);
+ missing_x86_features = 0;
}
module_init(camellia_aesni_init);
@@ -100,19 +100,21 @@ static const struct x86_cpu_id module_cpu_ids[] = {
};
MODULE_DEVICE_TABLE(x86cpu, module_cpu_ids);
+static int missing_x86_features;
+module_param(missing_x86_features, int, 0444);
+MODULE_PARM_DESC(missing_x86_features,
+ "Missing x86 XSAVE features (SSE, YMM)");
+
static struct simd_skcipher_alg *cast5_simd_algs[ARRAY_SIZE(cast5_algs)];
static int __init cast5_init(void)
{
- const char *feature_name;
-
if (!x86_match_cpu(module_cpu_ids))
return -ENODEV;
- if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM,
- &feature_name)) {
- pr_info("CPU feature '%s' is not supported.\n", feature_name);
- return -ENODEV;
+ if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, NULL)) {
+ missing_x86_features = 1;
+ return 0;
}
return simd_register_skciphers_compat(cast5_algs,
@@ -122,8 +124,10 @@ static int __init cast5_init(void)
static void __exit cast5_exit(void)
{
- simd_unregister_skciphers(cast5_algs, ARRAY_SIZE(cast5_algs),
- cast5_simd_algs);
+ if (!missing_x86_features)
+ simd_unregister_skciphers(cast5_algs, ARRAY_SIZE(cast5_algs),
+ cast5_simd_algs);
+ missing_x86_features = 0;
}
module_init(cast5_init);
@@ -100,19 +100,21 @@ static const struct x86_cpu_id module_cpu_ids[] = {
};
MODULE_DEVICE_TABLE(x86cpu, module_cpu_ids);
+static int missing_x86_features;
+module_param(missing_x86_features, int, 0444);
+MODULE_PARM_DESC(missing_x86_features,
+ "Missing x86 XSAVE features (SSE, YMM)");
+
static struct simd_skcipher_alg *cast6_simd_algs[ARRAY_SIZE(cast6_algs)];
static int __init cast6_init(void)
{
- const char *feature_name;
-
if (!x86_match_cpu(module_cpu_ids))
return -ENODEV;
- if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM,
- &feature_name)) {
- pr_info("CPU feature '%s' is not supported.\n", feature_name);
- return -ENODEV;
+ if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, NULL)) {
+ missing_x86_features = 1;
+ return 0;
}
return simd_register_skciphers_compat(cast6_algs,
@@ -122,8 +124,10 @@ static int __init cast6_init(void)
static void __exit cast6_exit(void)
{
- simd_unregister_skciphers(cast6_algs, ARRAY_SIZE(cast6_algs),
- cast6_simd_algs);
+ if (!missing_x86_features)
+ simd_unregister_skciphers(cast6_algs, ARRAY_SIZE(cast6_algs),
+ cast6_simd_algs);
+ missing_x86_features = 0;
}
module_init(cast6_init);
@@ -1706,13 +1706,20 @@ static const struct x86_cpu_id module_cpu_ids[] = {
};
MODULE_DEVICE_TABLE(x86cpu, module_cpu_ids);
+static int missing_x86_features;
+module_param(missing_x86_features, int, 0444);
+MODULE_PARM_DESC(missing_x86_features,
+ "Missing x86 instruction set extensions (BMI2)");
+
static int __init curve25519_mod_init(void)
{
if (!x86_match_cpu(module_cpu_ids))
return -ENODEV;
- if (!boot_cpu_has(X86_FEATURE_BMI2))
- return -ENODEV;
+ if (!boot_cpu_has(X86_FEATURE_BMI2)) {
+ missing_x86_features = 1;
+ return 0;
+ }
static_branch_enable(&curve25519_use_bmi2_adx);
@@ -1725,6 +1732,7 @@ static void __exit curve25519_mod_exit(void)
if (IS_REACHABLE(CONFIG_CRYPTO_KPP) &&
static_branch_likely(&curve25519_use_bmi2_adx))
crypto_unregister_kpp(&curve25519_alg);
+ missing_x86_features = 0;
}
module_init(curve25519_mod_init);
@@ -67,20 +67,28 @@ static const struct x86_cpu_id module_cpu_ids[] = {
};
MODULE_DEVICE_TABLE(x86cpu, module_cpu_ids);
+static int missing_x86_features;
+module_param(missing_x86_features, int, 0444);
+MODULE_PARM_DESC(missing_x86_features,
+ "Missing x86 instruction set extensions (OSXSAVE)");
+
static int __init nhpoly1305_mod_init(void)
{
if (!x86_match_cpu(module_cpu_ids))
return -ENODEV;
- if (!boot_cpu_has(X86_FEATURE_OSXSAVE))
- return -ENODEV;
+ if (!boot_cpu_has(X86_FEATURE_OSXSAVE)) {
+ missing_x86_features = 1;
+ return 0;
+ }
return crypto_register_shash(&nhpoly1305_alg);
}
static void __exit nhpoly1305_mod_exit(void)
{
- crypto_unregister_shash(&nhpoly1305_alg);
+ if (!missing_x86_features)
+ crypto_unregister_shash(&nhpoly1305_alg);
}
module_init(nhpoly1305_mod_init);
@@ -182,20 +182,29 @@ static const struct x86_cpu_id module_cpu_ids[] = {
};
MODULE_DEVICE_TABLE(x86cpu, module_cpu_ids);
+static int missing_x86_features;
+module_param(missing_x86_features, int, 0444);
+MODULE_PARM_DESC(missing_x86_features,
+ "Missing x86 instruction set extensions (AVX)");
+
static int __init polyval_clmulni_mod_init(void)
{
if (!x86_match_cpu(module_cpu_ids))
return -ENODEV;
- if (!boot_cpu_has(X86_FEATURE_AVX))
- return -ENODEV;
+ if (!boot_cpu_has(X86_FEATURE_AVX)) {
+ missing_x86_features = 1;
+ return 0;
+ }
return crypto_register_shash(&polyval_alg);
}
static void __exit polyval_clmulni_mod_exit(void)
{
- crypto_unregister_shash(&polyval_alg);
+ if (!missing_x86_features)
+ crypto_unregister_shash(&polyval_alg);
+ missing_x86_features = 0;
}
module_init(polyval_clmulni_mod_init);
@@ -101,23 +101,25 @@ static const struct x86_cpu_id module_cpu_ids[] = {
};
MODULE_DEVICE_TABLE(x86cpu, module_cpu_ids);
+static int missing_x86_features;
+module_param(missing_x86_features, int, 0444);
+MODULE_PARM_DESC(missing_x86_features,
+ "Missing x86 instruction set extensions (OSXSAVE) and/or XSAVE features (SSE, YMM)");
+
static struct simd_skcipher_alg *serpent_simd_algs[ARRAY_SIZE(serpent_algs)];
static int __init serpent_avx2_init(void)
{
- const char *feature_name;
-
if (!x86_match_cpu(module_cpu_ids))
return -ENODEV;
if (!boot_cpu_has(X86_FEATURE_OSXSAVE)) {
- pr_info("OSXSAVE instructions are not detected.\n");
- return -ENODEV;
+ missing_x86_features = 1;
+ return 0;
}
- if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM,
- &feature_name)) {
- pr_info("CPU feature '%s' is not supported.\n", feature_name);
- return -ENODEV;
+ if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, NULL)) {
+ missing_x86_features = 1;
+ return 0;
}
return simd_register_skciphers_compat(serpent_algs,
@@ -127,8 +129,10 @@ static int __init serpent_avx2_init(void)
static void __exit serpent_avx2_fini(void)
{
- simd_unregister_skciphers(serpent_algs, ARRAY_SIZE(serpent_algs),
- serpent_simd_algs);
+ if (!missing_x86_features)
+ simd_unregister_skciphers(serpent_algs, ARRAY_SIZE(serpent_algs),
+ serpent_simd_algs);
+ missing_x86_features = 0;
}
module_init(serpent_avx2_init);
@@ -107,19 +107,21 @@ static const struct x86_cpu_id module_cpu_ids[] = {
};
MODULE_DEVICE_TABLE(x86cpu, module_cpu_ids);
+static int missing_x86_features;
+module_param(missing_x86_features, int, 0444);
+MODULE_PARM_DESC(missing_x86_features,
+ "Missing x86 XSAVE features (SSE, YMM)");
+
static struct simd_skcipher_alg *serpent_simd_algs[ARRAY_SIZE(serpent_algs)];
static int __init serpent_init(void)
{
- const char *feature_name;
-
if (!x86_match_cpu(module_cpu_ids))
return -ENODEV;
- if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM,
- &feature_name)) {
- pr_info("CPU feature '%s' is not supported.\n", feature_name);
- return -ENODEV;
+ if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, NULL)) {
+ missing_x86_features = 1;
+ return 0;
}
return simd_register_skciphers_compat(serpent_algs,
@@ -129,8 +131,11 @@ static int __init serpent_init(void)
static void __exit serpent_exit(void)
{
- simd_unregister_skciphers(serpent_algs, ARRAY_SIZE(serpent_algs),
- serpent_simd_algs);
+ if (!missing_x86_features)
+ simd_unregister_skciphers(serpent_algs,
+ ARRAY_SIZE(serpent_algs),
+ serpent_simd_algs);
+ missing_x86_features = 0;
}
module_init(serpent_init);
@@ -351,9 +351,17 @@ static const struct x86_cpu_id module_cpu_ids[] = {
};
MODULE_DEVICE_TABLE(x86cpu, module_cpu_ids);
+static int missing_x86_features_avx2;
+static int missing_x86_features_avx;
+module_param(missing_x86_features_avx2, int, 0444);
+module_param(missing_x86_features_avx, int, 0444);
+MODULE_PARM_DESC(missing_x86_features_avx2,
+ "Missing x86 instruction set extensions (BMI1, BMI2) to support AVX2");
+MODULE_PARM_DESC(missing_x86_features_avx,
+ "Missing x86 XSAVE features (SSE, YMM) to support AVX");
+
static int __init sha1_ssse3_mod_init(void)
{
- const char *feature_name;
int ret;
if (!x86_match_cpu(module_cpu_ids))
@@ -374,10 +382,11 @@ static int __init sha1_ssse3_mod_init(void)
if (boot_cpu_has(X86_FEATURE_BMI1) &&
boot_cpu_has(X86_FEATURE_BMI2)) {
-
ret = crypto_register_shash(&sha1_avx2_alg);
if (!ret)
using_x86_avx2 = 1;
+ } else {
+ missing_x86_features_avx2 = 1;
}
}
@@ -385,11 +394,12 @@ static int __init sha1_ssse3_mod_init(void)
if (boot_cpu_has(X86_FEATURE_AVX)) {
if (cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM,
- &feature_name)) {
-
+ NULL)) {
ret = crypto_register_shash(&sha1_avx_alg);
if (!ret)
using_x86_avx = 1;
+ } else {
+ missing_x86_features_avx = 1;
}
}
@@ -415,6 +425,8 @@ static void __exit sha1_ssse3_mod_fini(void)
unregister_sha1_avx2();
unregister_sha1_avx();
unregister_sha1_ssse3();
+ missing_x86_features_avx2 = 0;
+ missing_x86_features_avx = 0;
}
module_init(sha1_ssse3_mod_init);
@@ -413,9 +413,17 @@ static const struct x86_cpu_id module_cpu_ids[] = {
};
MODULE_DEVICE_TABLE(x86cpu, module_cpu_ids);
+static int missing_x86_features_avx2;
+static int missing_x86_features_avx;
+module_param(missing_x86_features_avx2, int, 0444);
+module_param(missing_x86_features_avx, int, 0444);
+MODULE_PARM_DESC(missing_x86_features_avx2,
+ "Missing x86 instruction set extensions (BMI2) to support AVX2");
+MODULE_PARM_DESC(missing_x86_features_avx,
+ "Missing x86 XSAVE features (SSE, YMM) to support AVX");
+
static int __init sha256_ssse3_mod_init(void)
{
- const char *feature_name;
int ret;
if (!x86_match_cpu(module_cpu_ids))
@@ -440,6 +448,8 @@ static int __init sha256_ssse3_mod_init(void)
ARRAY_SIZE(sha256_avx2_algs));
if (!ret)
using_x86_avx2 = 1;
+ } else {
+ missing_x86_features_avx2 = 1;
}
}
@@ -447,11 +457,13 @@ static int __init sha256_ssse3_mod_init(void)
if (boot_cpu_has(X86_FEATURE_AVX)) {
if (cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM,
- &feature_name)) {
+ NULL)) {
ret = crypto_register_shashes(sha256_avx_algs,
ARRAY_SIZE(sha256_avx_algs));
if (!ret)
using_x86_avx = 1;
+ } else {
+ missing_x86_features_avx = 1;
}
}
@@ -478,6 +490,8 @@ static void __exit sha256_ssse3_mod_fini(void)
unregister_sha256_avx2();
unregister_sha256_avx();
unregister_sha256_ssse3();
+ missing_x86_features_avx2 = 0;
+ missing_x86_features_avx = 0;
}
module_init(sha256_ssse3_mod_init);
@@ -319,6 +319,15 @@ static const struct x86_cpu_id module_cpu_ids[] = {
};
MODULE_DEVICE_TABLE(x86cpu, module_cpu_ids);
+static int missing_x86_features_avx2;
+static int missing_x86_features_avx;
+module_param(missing_x86_features_avx2, int, 0444);
+module_param(missing_x86_features_avx, int, 0444);
+MODULE_PARM_DESC(missing_x86_features_avx2,
+ "Missing x86 instruction set extensions (BMI2) to support AVX2");
+MODULE_PARM_DESC(missing_x86_features_avx,
+ "Missing x86 XSAVE features (SSE, YMM) to support AVX");
+
static void unregister_sha512_avx2(void)
{
if (using_x86_avx2) {
@@ -330,7 +339,6 @@ static void unregister_sha512_avx2(void)
static int __init sha512_ssse3_mod_init(void)
{
- const char *feature_name;
int ret;
if (!x86_match_cpu(module_cpu_ids))
@@ -343,6 +351,8 @@ static int __init sha512_ssse3_mod_init(void)
ARRAY_SIZE(sha512_avx2_algs));
if (!ret)
using_x86_avx2 = 1;
+ } else {
+ missing_x86_features_avx2 = 1;
}
}
@@ -350,11 +360,13 @@ static int __init sha512_ssse3_mod_init(void)
if (boot_cpu_has(X86_FEATURE_AVX)) {
if (cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM,
- &feature_name)) {
+ NULL)) {
ret = crypto_register_shashes(sha512_avx_algs,
ARRAY_SIZE(sha512_avx_algs));
if (!ret)
using_x86_avx = 1;
+ } else {
+ missing_x86_features_avx = 1;
}
}
@@ -376,6 +388,8 @@ static void __exit sha512_ssse3_mod_fini(void)
unregister_sha512_avx2();
unregister_sha512_avx();
unregister_sha512_ssse3();
+ missing_x86_features_avx2 = 0;
+ missing_x86_features_avx = 0;
}
module_init(sha512_ssse3_mod_init);
@@ -126,22 +126,24 @@ static const struct x86_cpu_id module_cpu_ids[] = {
};
MODULE_DEVICE_TABLE(x86cpu, module_cpu_ids);
+static int missing_x86_features;
+module_param(missing_x86_features, int, 0444);
+MODULE_PARM_DESC(missing_x86_features,
+ "Missing x86 instruction set extensions (BMI2) and/or XSAVE features (SSE, YMM)");
+
static int __init sm3_avx_mod_init(void)
{
- const char *feature_name;
-
if (!x86_match_cpu(module_cpu_ids))
return -ENODEV;
if (!boot_cpu_has(X86_FEATURE_BMI2)) {
- pr_info("BMI2 instruction are not detected.\n");
- return -ENODEV;
+ missing_x86_features = 1;
+ return 0;
}
- if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM,
- &feature_name)) {
- pr_info("CPU feature '%s' is not supported.\n", feature_name);
- return -ENODEV;
+ if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, NULL)) {
+ missing_x86_features = 1;
+ return 0;
}
return crypto_register_shash(&sm3_avx_alg);
@@ -149,7 +151,9 @@ static int __init sm3_avx_mod_init(void)
static void __exit sm3_avx_mod_exit(void)
{
- crypto_unregister_shash(&sm3_avx_alg);
+ if (!missing_x86_features)
+ crypto_unregister_shash(&sm3_avx_alg);
+ missing_x86_features = 0;
}
module_init(sm3_avx_mod_init);
@@ -133,27 +133,29 @@ static const struct x86_cpu_id module_cpu_ids[] = {
};
MODULE_DEVICE_TABLE(x86cpu, module_cpu_ids);
+static int missing_x86_features;
+module_param(missing_x86_features, int, 0444);
+MODULE_PARM_DESC(missing_x86_features,
+ "Missing x86 instruction set extensions (AES-NI, AVX, OSXSAVE) and/or XSAVE features (SSE, YMM)");
+
static struct simd_skcipher_alg *
simd_sm4_aesni_avx2_skciphers[ARRAY_SIZE(sm4_aesni_avx2_skciphers)];
static int __init sm4_init(void)
{
- const char *feature_name;
-
if (!x86_match_cpu(module_cpu_ids))
return -ENODEV;
if (!boot_cpu_has(X86_FEATURE_AVX) ||
!boot_cpu_has(X86_FEATURE_AES) ||
!boot_cpu_has(X86_FEATURE_OSXSAVE)) {
- pr_info("AVX, AES-NI, and/or OSXSAVE instructions are not detected.\n");
- return -ENODEV;
+ missing_x86_features = 1;
+ return 0;
}
- if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM,
- &feature_name)) {
- pr_info("CPU feature '%s' is not supported.\n", feature_name);
- return -ENODEV;
+ if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, NULL)) {
+ missing_x86_features = 1;
+ return 0;
}
return simd_register_skciphers_compat(sm4_aesni_avx2_skciphers,
@@ -163,9 +165,11 @@ static int __init sm4_init(void)
static void __exit sm4_exit(void)
{
- simd_unregister_skciphers(sm4_aesni_avx2_skciphers,
- ARRAY_SIZE(sm4_aesni_avx2_skciphers),
- simd_sm4_aesni_avx2_skciphers);
+ if (!missing_x86_features)
+ simd_unregister_skciphers(sm4_aesni_avx2_skciphers,
+ ARRAY_SIZE(sm4_aesni_avx2_skciphers),
+ simd_sm4_aesni_avx2_skciphers);
+ missing_x86_features = 0;
}
module_init(sm4_init);
@@ -452,26 +452,28 @@ static const struct x86_cpu_id module_cpu_ids[] = {
};
MODULE_DEVICE_TABLE(x86cpu, module_cpu_ids);
+static int missing_x86_features;
+module_param(missing_x86_features, int, 0444);
+MODULE_PARM_DESC(missing_x86_features,
+ "Missing x86 instruction set extensions (AES-NI, OSXSAVE) and/or XSAVE features (SSE, YMM)");
+
static struct simd_skcipher_alg *
simd_sm4_aesni_avx_skciphers[ARRAY_SIZE(sm4_aesni_avx_skciphers)];
static int __init sm4_init(void)
{
- const char *feature_name;
-
if (!x86_match_cpu(module_cpu_ids))
return -ENODEV;
if (!boot_cpu_has(X86_FEATURE_AES) ||
!boot_cpu_has(X86_FEATURE_OSXSAVE)) {
- pr_info("AES-NI or OSXSAVE instructions are not detected.\n");
- return -ENODEV;
+ missing_x86_features = 1;
+ return 0;
}
- if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM,
- &feature_name)) {
- pr_info("CPU feature '%s' is not supported.\n", feature_name);
- return -ENODEV;
+ if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, NULL)) {
+ missing_x86_features = 1;
+ return 0;
}
return simd_register_skciphers_compat(sm4_aesni_avx_skciphers,
@@ -481,9 +483,11 @@ static int __init sm4_init(void)
static void __exit sm4_exit(void)
{
- simd_unregister_skciphers(sm4_aesni_avx_skciphers,
- ARRAY_SIZE(sm4_aesni_avx_skciphers),
- simd_sm4_aesni_avx_skciphers);
+ if (!missing_x86_features)
+ simd_unregister_skciphers(sm4_aesni_avx_skciphers,
+ ARRAY_SIZE(sm4_aesni_avx_skciphers),
+ simd_sm4_aesni_avx_skciphers);
+ missing_x86_features = 0;
}
module_init(sm4_init);
@@ -110,18 +110,21 @@ static const struct x86_cpu_id module_cpu_ids[] = {
};
MODULE_DEVICE_TABLE(x86cpu, module_cpu_ids);
+static int missing_x86_features;
+module_param(missing_x86_features, int, 0444);
+MODULE_PARM_DESC(missing_x86_features,
+ "Missing x86 XSAVE features (SSE, YMM)");
+
static struct simd_skcipher_alg *twofish_simd_algs[ARRAY_SIZE(twofish_algs)];
static int __init twofish_init(void)
{
- const char *feature_name;
-
if (!x86_match_cpu(module_cpu_ids))
return -ENODEV;
- if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, &feature_name)) {
- pr_info("CPU feature '%s' is not supported.\n", feature_name);
- return -ENODEV;
+ if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, NULL)) {
+ missing_x86_features = 1;
+ return 0;
}
return simd_register_skciphers_compat(twofish_algs,
@@ -131,8 +134,10 @@ static int __init twofish_init(void)
static void __exit twofish_exit(void)
{
- simd_unregister_skciphers(twofish_algs, ARRAY_SIZE(twofish_algs),
- twofish_simd_algs);
+ if (!missing_x86_features)
+ simd_unregister_skciphers(twofish_algs, ARRAY_SIZE(twofish_algs),
+ twofish_simd_algs);
+ missing_x86_features = 0;
}
module_init(twofish_init);
Don't refuse to load modules based on missing additional x86 features (e.g., OSXSAVE) or x86 XSAVE features (e.g., YMM). Instead, load the module, but don't register any crypto drivers. Report the fact that one or more features are missing in a new missing_x86_features module parameter (0 = no problems, 1 = something is missing; each module parameter description lists all the features that it wants). For the SHA functions that register up to four drivers based on CPU features, report separate module parameters for each set: missing_x86_features_avx2 missing_x86_features_avx Signed-off-by: Robert Elliott <elliott@hpe.com> --- arch/x86/crypto/aegis128-aesni-glue.c | 15 ++++++++++--- arch/x86/crypto/aria_aesni_avx_glue.c | 24 +++++++++++--------- arch/x86/crypto/camellia_aesni_avx2_glue.c | 25 ++++++++++++--------- arch/x86/crypto/camellia_aesni_avx_glue.c | 25 ++++++++++++--------- arch/x86/crypto/cast5_avx_glue.c | 20 ++++++++++------- arch/x86/crypto/cast6_avx_glue.c | 20 ++++++++++------- arch/x86/crypto/curve25519-x86_64.c | 12 ++++++++-- arch/x86/crypto/nhpoly1305-avx2-glue.c | 14 +++++++++--- arch/x86/crypto/polyval-clmulni_glue.c | 15 ++++++++++--- arch/x86/crypto/serpent_avx2_glue.c | 24 +++++++++++--------- arch/x86/crypto/serpent_avx_glue.c | 21 ++++++++++------- arch/x86/crypto/sha1_ssse3_glue.c | 20 +++++++++++++---- arch/x86/crypto/sha256_ssse3_glue.c | 18 +++++++++++++-- arch/x86/crypto/sha512_ssse3_glue.c | 18 +++++++++++++-- arch/x86/crypto/sm3_avx_glue.c | 22 ++++++++++-------- arch/x86/crypto/sm4_aesni_avx2_glue.c | 26 +++++++++++++--------- arch/x86/crypto/sm4_aesni_avx_glue.c | 26 +++++++++++++--------- arch/x86/crypto/twofish_avx_glue.c | 19 ++++++++++------ 18 files changed, 243 insertions(+), 121 deletions(-)