mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] crypto: x86/aria - Take the address of each asm function in one file
@ 2026-10-12  3:19 Kees Cook
  0 siblings, 0 replies; only message in thread
From: Kees Cook @ 2026-10-12  3:19 UTC (permalink / raw)
  To: Herbert Xu
  Cc: Kees Cook, Taehee Yoo, Nathan Chancellor, Sami Tolvanen,
	linux-crypto, llvm, kernel test robot, linux-kernel,
	linux-hardening

A Clang Full LTO bug[1] was fixed in Clang 23 where multiple .o files
performing an address-take of the same asm-originating typeid weak symbols
would have those symbols get completely removed instead of just keeping
one, seen at link time:

  ld.lld: error: undefined symbol: __kcfi_typeid_aria_aesni_avx_encrypt_16way
  >>> referenced by aria-aesni-avx-asm_64.S:962
  >>>               vmlinux.o:(__cfi_aria_aesni_avx_encrypt_16way)

As a work-around for earlier Clang, add aria_avx_setup_16way_ops() and
aria_avx2_setup_32way_ops(), exported by the glue that owns each tier's
asm functions, and fill all three tables with them, so that each asm
function has its address taken in only one file.

Build tested ARCH=x86_64 with the kernel test robot's randconfig
(CONFIG_LTO_CLANG_FULL=y, CONFIG_CFI=y, and all three ARIA drivers built
in) and W=1, with Clang 22.1.8 and Clang 24.0.0git: vmlinux.o defines all
fifteen __kcfi_typeid_aria_* symbols, and vmlinux links. Without this
change, Clang 22.1.8 fails to link it as above, and Clang 24.0.0git,
which has the LLVM fix, links it.

Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202606041643.GyTZgCk1-lkp@intel.com/
Closes: https://lore.kernel.org/oe-kbuild-all/202606122021.pA9TozrA-lkp@intel.com/
Closes: https://lore.kernel.org/oe-kbuild-all/202608100432.yIX7TckM-lkp@intel.com/
Closes: https://lore.kernel.org/oe-kbuild-all/202610112311.o9XQsWsa-lkp@intel.com/
Link: https://github.com/llvm/llvm-project/pull/204025 [1]
Assisted-by: LLM
Signed-off-by: Kees Cook <kees@kernel.org>
---
 arch/x86/crypto/aria-avx.h              |  3 +++
 arch/x86/crypto/aria_aesni_avx2_glue.c  | 35 ++++++++++++++-----------
 arch/x86/crypto/aria_aesni_avx_glue.c   | 29 +++++++++++++-------
 arch/x86/crypto/aria_gfni_avx512_glue.c |  8 ++----
 4 files changed, 45 insertions(+), 30 deletions(-)

diff --git a/arch/x86/crypto/aria-avx.h b/arch/x86/crypto/aria-avx.h
index 6e1b2d8a31ed..0fff24861088 100644
--- a/arch/x86/crypto/aria-avx.h
+++ b/arch/x86/crypto/aria-avx.h
@@ -59,4 +59,7 @@ struct aria_avx_ops {
 
 
 };
+
+void aria_avx_setup_16way_ops(struct aria_avx_ops *ops, bool use_gfni);
+void aria_avx2_setup_32way_ops(struct aria_avx_ops *ops, bool use_gfni);
 #endif
diff --git a/arch/x86/crypto/aria_aesni_avx2_glue.c b/arch/x86/crypto/aria_aesni_avx2_glue.c
index 1487a49bfbac..65c850601f49 100644
--- a/arch/x86/crypto/aria_aesni_avx2_glue.c
+++ b/arch/x86/crypto/aria_aesni_avx2_glue.c
@@ -37,6 +37,24 @@ asmlinkage void aria_aesni_avx2_gfni_ctr_crypt_32way(const void *ctx, u8 *dst,
 						     u8 *keystream, u8 *iv);
 EXPORT_SYMBOL_GPL(aria_aesni_avx2_gfni_ctr_crypt_32way);
 
+/*
+ * Set up function pointers for the AVX 32-way asm functions for both this
+ * module and the the higher-tier modules.
+ */
+void aria_avx2_setup_32way_ops(struct aria_avx_ops *ops, bool use_gfni)
+{
+	if (use_gfni) {
+		ops->aria_encrypt_32way = aria_aesni_avx2_gfni_encrypt_32way;
+		ops->aria_decrypt_32way = aria_aesni_avx2_gfni_decrypt_32way;
+		ops->aria_ctr_crypt_32way = aria_aesni_avx2_gfni_ctr_crypt_32way;
+	} else {
+		ops->aria_encrypt_32way = aria_aesni_avx2_encrypt_32way;
+		ops->aria_decrypt_32way = aria_aesni_avx2_decrypt_32way;
+		ops->aria_ctr_crypt_32way = aria_aesni_avx2_ctr_crypt_32way;
+	}
+}
+EXPORT_SYMBOL_GPL(aria_avx2_setup_32way_ops);
+
 static struct aria_avx_ops aria_ops;
 
 struct aria_avx2_request_ctx {
@@ -211,21 +229,8 @@ static int __init aria_avx2_init(void)
 		return -ENODEV;
 	}
 
-	if (boot_cpu_has(X86_FEATURE_GFNI)) {
-		aria_ops.aria_encrypt_16way = aria_aesni_avx_gfni_encrypt_16way;
-		aria_ops.aria_decrypt_16way = aria_aesni_avx_gfni_decrypt_16way;
-		aria_ops.aria_ctr_crypt_16way = aria_aesni_avx_gfni_ctr_crypt_16way;
-		aria_ops.aria_encrypt_32way = aria_aesni_avx2_gfni_encrypt_32way;
-		aria_ops.aria_decrypt_32way = aria_aesni_avx2_gfni_decrypt_32way;
-		aria_ops.aria_ctr_crypt_32way = aria_aesni_avx2_gfni_ctr_crypt_32way;
-	} else {
-		aria_ops.aria_encrypt_16way = aria_aesni_avx_encrypt_16way;
-		aria_ops.aria_decrypt_16way = aria_aesni_avx_decrypt_16way;
-		aria_ops.aria_ctr_crypt_16way = aria_aesni_avx_ctr_crypt_16way;
-		aria_ops.aria_encrypt_32way = aria_aesni_avx2_encrypt_32way;
-		aria_ops.aria_decrypt_32way = aria_aesni_avx2_decrypt_32way;
-		aria_ops.aria_ctr_crypt_32way = aria_aesni_avx2_ctr_crypt_32way;
-	}
+	aria_avx_setup_16way_ops(&aria_ops, boot_cpu_has(X86_FEATURE_GFNI));
+	aria_avx2_setup_32way_ops(&aria_ops, boot_cpu_has(X86_FEATURE_GFNI));
 
 	return crypto_register_skciphers(aria_algs, ARRAY_SIZE(aria_algs));
 }
diff --git a/arch/x86/crypto/aria_aesni_avx_glue.c b/arch/x86/crypto/aria_aesni_avx_glue.c
index e4e3d78915a5..07baf5a27143 100644
--- a/arch/x86/crypto/aria_aesni_avx_glue.c
+++ b/arch/x86/crypto/aria_aesni_avx_glue.c
@@ -39,6 +39,25 @@ EXPORT_SYMBOL_GPL(aria_aesni_avx_gfni_ctr_crypt_16way);
 
 static struct aria_avx_ops aria_ops;
 
+/*
+ * Set up function pointers for the AVX 16-way asm functions for both this
+ * module's own dispatch table and the higher-tier (AVX2, GFNI/AVX-512)
+ * modules.
+ */
+void aria_avx_setup_16way_ops(struct aria_avx_ops *ops, bool use_gfni)
+{
+	if (use_gfni) {
+		ops->aria_encrypt_16way = aria_aesni_avx_gfni_encrypt_16way;
+		ops->aria_decrypt_16way = aria_aesni_avx_gfni_decrypt_16way;
+		ops->aria_ctr_crypt_16way = aria_aesni_avx_gfni_ctr_crypt_16way;
+	} else {
+		ops->aria_encrypt_16way = aria_aesni_avx_encrypt_16way;
+		ops->aria_decrypt_16way = aria_aesni_avx_decrypt_16way;
+		ops->aria_ctr_crypt_16way = aria_aesni_avx_ctr_crypt_16way;
+	}
+}
+EXPORT_SYMBOL_GPL(aria_avx_setup_16way_ops);
+
 struct aria_avx_request_ctx {
 	u8 keystream[ARIA_AESNI_PARALLEL_BLOCK_SIZE];
 };
@@ -197,15 +216,7 @@ static int __init aria_avx_init(void)
 		return -ENODEV;
 	}
 
-	if (boot_cpu_has(X86_FEATURE_GFNI)) {
-		aria_ops.aria_encrypt_16way = aria_aesni_avx_gfni_encrypt_16way;
-		aria_ops.aria_decrypt_16way = aria_aesni_avx_gfni_decrypt_16way;
-		aria_ops.aria_ctr_crypt_16way = aria_aesni_avx_gfni_ctr_crypt_16way;
-	} else {
-		aria_ops.aria_encrypt_16way = aria_aesni_avx_encrypt_16way;
-		aria_ops.aria_decrypt_16way = aria_aesni_avx_decrypt_16way;
-		aria_ops.aria_ctr_crypt_16way = aria_aesni_avx_ctr_crypt_16way;
-	}
+	aria_avx_setup_16way_ops(&aria_ops, boot_cpu_has(X86_FEATURE_GFNI));
 
 	return crypto_register_skciphers(aria_algs, ARRAY_SIZE(aria_algs));
 }
diff --git a/arch/x86/crypto/aria_gfni_avx512_glue.c b/arch/x86/crypto/aria_gfni_avx512_glue.c
index 363cbf4399cc..1eccfceae314 100644
--- a/arch/x86/crypto/aria_gfni_avx512_glue.c
+++ b/arch/x86/crypto/aria_gfni_avx512_glue.c
@@ -214,12 +214,8 @@ static int __init aria_avx512_init(void)
 		return -ENODEV;
 	}
 
-	aria_ops.aria_encrypt_16way = aria_aesni_avx_gfni_encrypt_16way;
-	aria_ops.aria_decrypt_16way = aria_aesni_avx_gfni_decrypt_16way;
-	aria_ops.aria_ctr_crypt_16way = aria_aesni_avx_gfni_ctr_crypt_16way;
-	aria_ops.aria_encrypt_32way = aria_aesni_avx2_gfni_encrypt_32way;
-	aria_ops.aria_decrypt_32way = aria_aesni_avx2_gfni_decrypt_32way;
-	aria_ops.aria_ctr_crypt_32way = aria_aesni_avx2_gfni_ctr_crypt_32way;
+	aria_avx_setup_16way_ops(&aria_ops, true);
+	aria_avx2_setup_32way_ops(&aria_ops, true);
 	aria_ops.aria_encrypt_64way = aria_gfni_avx512_encrypt_64way;
 	aria_ops.aria_decrypt_64way = aria_gfni_avx512_decrypt_64way;
 	aria_ops.aria_ctr_crypt_64way = aria_gfni_avx512_ctr_crypt_64way;
-- 
2.55.0


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2026-10-12  3:19 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-12  3:19 [PATCH] crypto: x86/aria - Take the address of each asm function in one file Kees Cook

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®