arch/x86/include/asm/page_64.h | 3 +++ 1 file changed, 3 insertions(+)
When building with CONFIG_CFI=y and CONFIG_LTO_CLANG_FULL=y, there is a
series of errors from the various versions of clear_page() not having
__kcfi_typeid_ symbols.
$ cat kernel/configs/repro.config
CONFIG_CFI=y
# CONFIG_LTO_NONE is not set
CONFIG_LTO_CLANG_FULL=y
$ make -skj"$(nproc)" ARCH=x86_64 LLVM=1 clean defconfig repro.config bzImage
ld.lld: error: undefined symbol: __kcfi_typeid_clear_page_rep
>>> referenced by ld-temp.o
>>> vmlinux.o:(__cfi_clear_page_rep)
ld.lld: error: undefined symbol: __kcfi_typeid_clear_page_orig
>>> referenced by ld-temp.o
>>> vmlinux.o:(__cfi_clear_page_orig)
ld.lld: error: undefined symbol: __kcfi_typeid_clear_page_erms
>>> referenced by ld-temp.o
>>> vmlinux.o:(__cfi_clear_page_erms)
With full LTO, it is possible for LLVM to realize that these functions
never have their address taken (as they are only used within an
alternative, which will make them a direct call) across the whole kernel
and either drop or skip generating their kCFI type identification
symbols.
clear_page_{rep,orig,erms}() are defined in clear_page_64.S with
SYM_TYPED_FUNC_START as a result of commit 2981557cb040 ("x86,kcfi: Fix
EXPORT_SYMBOL vs kCFI"), as exported functions are free to be called
indirectly thus need kCFI type identifiers.
Use KCFI_REFERENCE with these clear_page() functions to force LLVM to
see these functions as address-taken and generate then keep the kCFI
type identifiers.
Fixes: 2981557cb040 ("x86,kcfi: Fix EXPORT_SYMBOL vs kCFI")
Closes: https://github.com/ClangBuiltLinux/linux/issues/2128
Signed-off-by: Nathan Chancellor <nathan@kernel.org>
---
Alternatively, these functions could move back to SYM_FUNC_START with a
comment that they need to be exported to be called via the alternative
in clear_page() but they are never expected to be called indirectly.
---
arch/x86/include/asm/page_64.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/x86/include/asm/page_64.h b/arch/x86/include/asm/page_64.h
index 015d23f3e01f..53f4089333f2 100644
--- a/arch/x86/include/asm/page_64.h
+++ b/arch/x86/include/asm/page_64.h
@@ -43,6 +43,9 @@ extern unsigned long __phys_addr_symbol(unsigned long);
void clear_page_orig(void *page);
void clear_page_rep(void *page);
void clear_page_erms(void *page);
+KCFI_REFERENCE(clear_page_orig);
+KCFI_REFERENCE(clear_page_rep);
+KCFI_REFERENCE(clear_page_erms);
static inline void clear_page(void *page)
{
---
base-commit: 3a8660878839faadb4f1a6dd72c3179c1df56787
change-id: 20251013-x86-fix-clear_page-cfi-full-lto-errors-173faa536840
Best regards,
--
Nathan Chancellor <nathan@kernel.org>
Hey Nathan,
On Mon, Oct 13, 2025 at 02:27:36PM -0700, Nathan Chancellor wrote:
> When building with CONFIG_CFI=y and CONFIG_LTO_CLANG_FULL=y, there is a
> series of errors from the various versions of clear_page() not having
> __kcfi_typeid_ symbols.
might wanna wait with this one - those are going away except one:
https://lore.kernel.org/r/20251027202109.678022-5-ankur.a.arora@oracle.com
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
Hey Boris, On Thu, Oct 30, 2025 at 08:28:19PM +0100, Borislav Petkov wrote: > On Mon, Oct 13, 2025 at 02:27:36PM -0700, Nathan Chancellor wrote: > > When building with CONFIG_CFI=y and CONFIG_LTO_CLANG_FULL=y, there is a > > series of errors from the various versions of clear_page() not having > > __kcfi_typeid_ symbols. > > might wanna wait with this one - those are going away except one: > > https://lore.kernel.org/r/20251027202109.678022-5-ankur.a.arora@oracle.com These errors occur in Linus's tree so could this go before that one then it could just update the instances of KCFI_ADDRESSABLE? I don't have a strong opinion, I found these series of errors tangentially but this feels like something that could go via x86/urgent and that series could just rebase on it. Cheers, Nathan
On Fri, Oct 31, 2025 at 10:20:44AM -0400, Nathan Chancellor wrote:
> These errors occur in Linus's tree so could this go before that one then
> it could just update the instances of KCFI_ADDRESSABLE? I don't have a
> strong opinion, I found these series of errors tangentially but this
> feels like something that could go via x86/urgent and that series could
> just rebase on it.
Sure, that works too.
I guess we want that in stable too, considering where the Fixes: tag commit
landed...?
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
On Fri, Oct 31, 2025 at 03:46:24PM +0100, Borislav Petkov wrote: > On Fri, Oct 31, 2025 at 10:20:44AM -0400, Nathan Chancellor wrote: > > These errors occur in Linus's tree so could this go before that one then > > it could just update the instances of KCFI_ADDRESSABLE? I don't have a > > strong opinion, I found these series of errors tangentially but this > > feels like something that could go via x86/urgent and that series could > > just rebase on it. > > Sure, that works too. > > I guess we want that in stable too, considering where the Fixes: tag commit > landed...? Yeah, I should have explicitly tagged this change for stable but I have been a little lazy since AUTOSEL often picks up the slack :) If you want a resend with that adjusted, let me know. Cheers, Nathan
On Fri, Oct 31, 2025 at 04:22:26PM -0400, Nathan Chancellor wrote:
> Yeah, I should have explicitly tagged this change for stable but I have
> been a little lazy since AUTOSEL often picks up the slack :) If you want
> a resend with that adjusted, let me know.
Nah, that's fine.
I'm asking explicitly because we have this basic rule:
stable material => urgent branch and goes to Linus now
So it basically determines where I route it to.
Lemme take care of it.
Thx.
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
Hi Nathan,
On Mon, Oct 13, 2025 at 2:27 PM Nathan Chancellor <nathan@kernel.org> wrote:
>
> When building with CONFIG_CFI=y and CONFIG_LTO_CLANG_FULL=y, there is a
> series of errors from the various versions of clear_page() not having
> __kcfi_typeid_ symbols.
>
> $ cat kernel/configs/repro.config
> CONFIG_CFI=y
> # CONFIG_LTO_NONE is not set
> CONFIG_LTO_CLANG_FULL=y
>
> $ make -skj"$(nproc)" ARCH=x86_64 LLVM=1 clean defconfig repro.config bzImage
> ld.lld: error: undefined symbol: __kcfi_typeid_clear_page_rep
> >>> referenced by ld-temp.o
> >>> vmlinux.o:(__cfi_clear_page_rep)
>
> ld.lld: error: undefined symbol: __kcfi_typeid_clear_page_orig
> >>> referenced by ld-temp.o
> >>> vmlinux.o:(__cfi_clear_page_orig)
>
> ld.lld: error: undefined symbol: __kcfi_typeid_clear_page_erms
> >>> referenced by ld-temp.o
> >>> vmlinux.o:(__cfi_clear_page_erms)
>
> With full LTO, it is possible for LLVM to realize that these functions
> never have their address taken (as they are only used within an
> alternative, which will make them a direct call) across the whole kernel
> and either drop or skip generating their kCFI type identification
> symbols.
>
> clear_page_{rep,orig,erms}() are defined in clear_page_64.S with
> SYM_TYPED_FUNC_START as a result of commit 2981557cb040 ("x86,kcfi: Fix
> EXPORT_SYMBOL vs kCFI"), as exported functions are free to be called
> indirectly thus need kCFI type identifiers.
>
> Use KCFI_REFERENCE with these clear_page() functions to force LLVM to
> see these functions as address-taken and generate then keep the kCFI
> type identifiers.
>
> Fixes: 2981557cb040 ("x86,kcfi: Fix EXPORT_SYMBOL vs kCFI")
> Closes: https://github.com/ClangBuiltLinux/linux/issues/2128
> Signed-off-by: Nathan Chancellor <nathan@kernel.org>
> ---
> Alternatively, these functions could move back to SYM_FUNC_START with a
> comment that they need to be exported to be called via the alternative
> in clear_page() but they are never expected to be called indirectly.
Right, this might be a cleaner solution if we don't actually expect
these to be indirectly called.
> ---
> arch/x86/include/asm/page_64.h | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/arch/x86/include/asm/page_64.h b/arch/x86/include/asm/page_64.h
> index 015d23f3e01f..53f4089333f2 100644
> --- a/arch/x86/include/asm/page_64.h
> +++ b/arch/x86/include/asm/page_64.h
> @@ -43,6 +43,9 @@ extern unsigned long __phys_addr_symbol(unsigned long);
> void clear_page_orig(void *page);
> void clear_page_rep(void *page);
> void clear_page_erms(void *page);
> +KCFI_REFERENCE(clear_page_orig);
> +KCFI_REFERENCE(clear_page_rep);
> +KCFI_REFERENCE(clear_page_erms);
In any case,
Reviewed-by: Sami Tolvanen <samitolvanen@google.com>
Sami
© 2016 - 2025 Red Hat, Inc.