Live Patching
 help / color / mirror / Atom feed
* Re: [PATCH kbuild v2] kbuild: Reduce the number of compiler-generated suffixes for clang thin-lto build
From: Nathan Chancellor @ 2026-03-10  3:14 UTC (permalink / raw)
  To: Yonghong Song
  Cc: linux-kbuild, live-patching, Josh Poimboeuf, kernel-team,
	Nicolas Schier, Song Liu
In-Reply-To: <20260307050250.3767489-1-yonghong.song@linux.dev>

On Fri, Mar 06, 2026 at 09:02:50PM -0800, Yonghong Song wrote:
> The current clang thin-lto build often produces lots of symbols with
> suffix. The following is a partial list of such function call symbols:
>     ...
>     ethnl_module_fw_flash_ntf.llvm.7631589765585346066
>     __nf_conntrack_alloc.llvm.6438426151906658917
>     tcp_can_early_drop.llvm.11937612064648250727
>     tcp_print_conntrack.llvm.11937612064648250727
>     ...
> 
> In my particular build with current bpf-next, the number of '*.llvm.<hash>'
> function calls is 1212. As the side effect of cross-file inlining,
> some static variables may be promoted with '*.llvm.<hash>' as well.
> In my same setup, the number of variables with such suffixes is 9.
> 
> Such symbols make kernel live patching difficult since
>   - a minor code change will change the hash and then the '*.llvm.<hash>'
>     symbol becomes another one with a different hash. Sometimes, maybe
>     the suffix is gone.
>   - a previous source-level symbol may become a one with suffix after live
>     patching code.
> 
> In [1], Song Liu suggested to reduce the number of '*.llvm.<hash>' functions
> to make live patch easier. In respond of this, I implemented this
> in llvm ([2]). The same thin-lto build with [2] only has two symbols with
> suffix:
>     m_stop.llvm.14460341347352036579
>     m_next.llvm.14460341347352036579
> This should make live patch much easier.
> 
> To support suffix symbol reduction, two lld flags are necessary to enable
> this feature in kernel:
>     - Flag '--lto-whole-program-visibility' is needed as it ensures that all
>       non-assembly files are available in the same thin-lto lld, which is true
>       for kernel.
>     - Flag '-mllvm -always-rename-promoted-locals=false' is needed to enable
>       suffix reduction. Currently in llvm [1], only process mode is supported.
>       There is another distributed mode (across different processes or even
>       different machines) which is not supported yet ([2]). The kernel uses
>       process mode so it should work.
> 
> The assembly files may have some global functions/data which may potentially
> conflict with thin-lto global symbols after the above two flags. But such assembly
> global symbols are limited and tend to be uniquely named for its context.
> Hence the conflict with globals in non-assembly codes is rare. If indeed the
> conflict happens, we can rename either of them to avoid conflicts.
> 
> Nathan Chancellor suggested the following under thin-lto:
>   KBUILD_LDFLAGS += $(call ld-option,--lto-whole-program-visibility -mllvm -always-rename-promoted-locals=false)
> The '-mllvm -always-rename-promoted-locals=false' flag is only available for llvm23.
> So for llvm22 or earlier, the above KBUILD_LDFLAGS will ignore those two flags.
> For llvm23 and later, two flags will be added to KBUILD_LDFLAGS.
> 
>   [1] https://lpc.events/event/19/contributions/2212
>   [2] https://github.com/llvm/llvm-project/pull/178587
> 
> Signed-off-by: Yonghong Song <yonghong.song@linux.dev>

Reviewed-by: Nathan Chancellor <nathan@kernel.org>
Tested-by: Nathan Chancellor <nathan@kernel.org> # build

Thanks!

> ---
>  Makefile | 1 +
>  1 file changed, 1 insertion(+)
> 
> Changelog:
>   v1 -> v2:
>     - v1: https://lore.kernel.org/linux-kbuild/20260306034325.3605301-1-yonghong.song@linux.dev/
>     - Removed the new config option and use ld-option to check whether new flags
>       will be used or not.
> 
> diff --git a/Makefile b/Makefile
> index e944c6e71e81..e4385af16985 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -1034,6 +1034,7 @@ endif
>  ifdef CONFIG_LTO_CLANG
>  ifdef CONFIG_LTO_CLANG_THIN
>  CC_FLAGS_LTO	:= -flto=thin -fsplit-lto-unit
> +KBUILD_LDFLAGS += $(call ld-option,--lto-whole-program-visibility -mllvm -always-rename-promoted-locals=false)
>  else
>  CC_FLAGS_LTO	:= -flto
>  endif
> -- 
> 2.47.3
> 

^ permalink raw reply

* Re: [PATCH kbuild] kbuild: Allow to reduce the number of suffixes for clang thin-lto build
From: Yonghong Song @ 2026-03-07  5:14 UTC (permalink / raw)
  To: Nathan Chancellor
  Cc: Josh Poimboeuf, linux-kbuild, live-patching, kernel-team,
	Nicolas Schier, Song Liu
In-Reply-To: <20260306224522.GA2746259@ax162>



On 3/6/26 2:45 PM, Nathan Chancellor wrote:
> On Fri, Mar 06, 2026 at 02:12:44PM -0800, Yonghong Song wrote:
>> So you mean we do not need a new config. Should just check clang and
>> clang versionn like below?
>>
>> diff --git a/Makefile b/Makefile
>> index e944c6e71e81..9bd3990024c5 100644
>> --- a/Makefile
>> +++ b/Makefile
>> @@ -1034,6 +1034,11 @@ endif
>>   ifdef CONFIG_LTO_CLANG
>>   ifdef CONFIG_LTO_CLANG_THIN
>>   CC_FLAGS_LTO   := -flto=thin -fsplit-lto-unit
>> +ifdef CONFIG_CC_IS_CLANG
>> +ifeq ($(shell test $(CONFIG_CLANG_VERSION) -ge 230000; echo $$?),0)
> This is the same as
>
>    ifeq ($(call clang-min-version,230000),y)
>
> That being said, could we not just do a dynamic check so that it always
> works when these flags are supported?

Thanks for the suggestion! What you had below with 'call ld-option' is perfect
to satisfy this requirement: <= llvm22, two flags will be ignored, and
>= llvm23, two flags will be used.

v2: https://lore.kernel.org/linux-kbuild/20260307050250.3767489-1-yonghong.song@linux.dev/

>
>> +KBUILD_LDFLAGS += --lto-whole-program-visibility -mllvm -always-rename-promoted-locals=false
>    KBUILD_LDFLAGS += $(call ld-option,--lto-whole-program-visibility -mllvm -always-rename-promoted-locals=false)
>
>> +endif
>> +endif
>>   else
>>   CC_FLAGS_LTO   := -flto
>>   endif
>>
>> I think this should work. In rare case, renaming the function should
>> solve the problem.
> I agree with Josh that having this be the default behavior with the
> workarounds that we have available to us to avoid problems from it is
> worth it. Thanks for chasing this after the discussions at LPC.
>
> Cheers,
> Nathan


^ permalink raw reply

* [PATCH kbuild v2] kbuild: Reduce the number of compiler-generated suffixes for clang thin-lto build
From: Yonghong Song @ 2026-03-07  5:02 UTC (permalink / raw)
  To: linux-kbuild, live-patching
  Cc: Josh Poimboeuf, kernel-team, Nathan Chancellor, Nicolas Schier,
	Song Liu

The current clang thin-lto build often produces lots of symbols with
suffix. The following is a partial list of such function call symbols:
    ...
    ethnl_module_fw_flash_ntf.llvm.7631589765585346066
    __nf_conntrack_alloc.llvm.6438426151906658917
    tcp_can_early_drop.llvm.11937612064648250727
    tcp_print_conntrack.llvm.11937612064648250727
    ...

In my particular build with current bpf-next, the number of '*.llvm.<hash>'
function calls is 1212. As the side effect of cross-file inlining,
some static variables may be promoted with '*.llvm.<hash>' as well.
In my same setup, the number of variables with such suffixes is 9.

Such symbols make kernel live patching difficult since
  - a minor code change will change the hash and then the '*.llvm.<hash>'
    symbol becomes another one with a different hash. Sometimes, maybe
    the suffix is gone.
  - a previous source-level symbol may become a one with suffix after live
    patching code.

In [1], Song Liu suggested to reduce the number of '*.llvm.<hash>' functions
to make live patch easier. In respond of this, I implemented this
in llvm ([2]). The same thin-lto build with [2] only has two symbols with
suffix:
    m_stop.llvm.14460341347352036579
    m_next.llvm.14460341347352036579
This should make live patch much easier.

To support suffix symbol reduction, two lld flags are necessary to enable
this feature in kernel:
    - Flag '--lto-whole-program-visibility' is needed as it ensures that all
      non-assembly files are available in the same thin-lto lld, which is true
      for kernel.
    - Flag '-mllvm -always-rename-promoted-locals=false' is needed to enable
      suffix reduction. Currently in llvm [1], only process mode is supported.
      There is another distributed mode (across different processes or even
      different machines) which is not supported yet ([2]). The kernel uses
      process mode so it should work.

The assembly files may have some global functions/data which may potentially
conflict with thin-lto global symbols after the above two flags. But such assembly
global symbols are limited and tend to be uniquely named for its context.
Hence the conflict with globals in non-assembly codes is rare. If indeed the
conflict happens, we can rename either of them to avoid conflicts.

Nathan Chancellor suggested the following under thin-lto:
  KBUILD_LDFLAGS += $(call ld-option,--lto-whole-program-visibility -mllvm -always-rename-promoted-locals=false)
The '-mllvm -always-rename-promoted-locals=false' flag is only available for llvm23.
So for llvm22 or earlier, the above KBUILD_LDFLAGS will ignore those two flags.
For llvm23 and later, two flags will be added to KBUILD_LDFLAGS.

  [1] https://lpc.events/event/19/contributions/2212
  [2] https://github.com/llvm/llvm-project/pull/178587

Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
---
 Makefile | 1 +
 1 file changed, 1 insertion(+)

Changelog:
  v1 -> v2:
    - v1: https://lore.kernel.org/linux-kbuild/20260306034325.3605301-1-yonghong.song@linux.dev/
    - Removed the new config option and use ld-option to check whether new flags
      will be used or not.

diff --git a/Makefile b/Makefile
index e944c6e71e81..e4385af16985 100644
--- a/Makefile
+++ b/Makefile
@@ -1034,6 +1034,7 @@ endif
 ifdef CONFIG_LTO_CLANG
 ifdef CONFIG_LTO_CLANG_THIN
 CC_FLAGS_LTO	:= -flto=thin -fsplit-lto-unit
+KBUILD_LDFLAGS += $(call ld-option,--lto-whole-program-visibility -mllvm -always-rename-promoted-locals=false)
 else
 CC_FLAGS_LTO	:= -flto
 endif
-- 
2.47.3


^ permalink raw reply related

* Re: [PATCH kbuild] kbuild: Allow to reduce the number of suffixes for clang thin-lto build
From: Nathan Chancellor @ 2026-03-06 22:45 UTC (permalink / raw)
  To: Yonghong Song
  Cc: Josh Poimboeuf, linux-kbuild, live-patching, kernel-team,
	Nicolas Schier, Song Liu
In-Reply-To: <f0c037e6-d498-41c3-8d71-0597a2e1d68d@linux.dev>

On Fri, Mar 06, 2026 at 02:12:44PM -0800, Yonghong Song wrote:
> So you mean we do not need a new config. Should just check clang and
> clang versionn like below?
> 
> diff --git a/Makefile b/Makefile
> index e944c6e71e81..9bd3990024c5 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -1034,6 +1034,11 @@ endif
>  ifdef CONFIG_LTO_CLANG
>  ifdef CONFIG_LTO_CLANG_THIN
>  CC_FLAGS_LTO   := -flto=thin -fsplit-lto-unit
> +ifdef CONFIG_CC_IS_CLANG
> +ifeq ($(shell test $(CONFIG_CLANG_VERSION) -ge 230000; echo $$?),0)

This is the same as

  ifeq ($(call clang-min-version,230000),y)

That being said, could we not just do a dynamic check so that it always
works when these flags are supported?

> +KBUILD_LDFLAGS += --lto-whole-program-visibility -mllvm -always-rename-promoted-locals=false

  KBUILD_LDFLAGS += $(call ld-option,--lto-whole-program-visibility -mllvm -always-rename-promoted-locals=false)

> +endif
> +endif
>  else
>  CC_FLAGS_LTO   := -flto
>  endif
> 
> I think this should work. In rare case, renaming the function should
> solve the problem.

I agree with Josh that having this be the default behavior with the
workarounds that we have available to us to avoid problems from it is
worth it. Thanks for chasing this after the discussions at LPC.

Cheers,
Nathan

^ permalink raw reply

* Re: [PATCH kbuild] kbuild: Allow to reduce the number of suffixes for clang thin-lto build
From: Yonghong Song @ 2026-03-06 22:12 UTC (permalink / raw)
  To: Josh Poimboeuf
  Cc: linux-kbuild, live-patching, kernel-team, Nathan Chancellor,
	Nicolas Schier, Song Liu, yonghong.song
In-Reply-To: <lmj53l5djuipucmuxwr563n6ty7hobduzg4vvy4pjnw4yz5t56@he3wiioegzhy>



On 3/6/26 12:57 PM, Josh Poimboeuf wrote:
> On Fri, Mar 06, 2026 at 12:55:02PM -0800, Josh Poimboeuf wrote:
>> On Fri, Mar 06, 2026 at 11:40:21AM -0800, Yonghong Song wrote:
>>>> Thanks!  Would there be any downsides to enabling this feature
>>>> unconditionally in the kernel when the compiler supports it?
>>> The only downside is for the following case:
>>>
>>> C   file: static function foo()
>>> Asm file: global function foo()
>>>
>>> The thin-lto will collect all C files and with the above llvm patch,
>>> the static function foo() may be promoted to global function foo()
>>> if there is no other pre-existing global function foo() in all C files.
>>>
>>> In such cases, there will be a conflict since
>>> there are two global function foo() (one from C file, another from Asm file).
>>> In such cases, the build will fail.
>>>
>>> How do you think we could hit such issues in linux kernel?
>>> Maybe should have default no for the new config?
>>>
>>> I think the chance should be very low. The following is a grab for x86
>>> for global symbols in asm code:
>>>
>>> [~/work/others/linux/arch/x86 (master)]$ egrep -r globl
>> There are actually quite a bit more than that, see SYM_CODE_START:
>>
>>    $ git grep 'SYM_CODE_START(' |wc -l
>>    169
>>
>> But still, I agree the chance of a conflict would be very low.  And
>> global assembly functions tend to be rather uniquely named.
>>
>>> Maybe we could collect all global symbols in asm codes before lld,
>>> and then we add an option in lld to feed those global symbols (with a file?),
>>> then we can be sure there won't be any conflict?
>> That wouldn't be worth the effort in my opinion.
>>
>> I think we should just unconditionally enable
>> -always-rename-promoted-locals=false when it's available.  While that
>> will implicitly enforce that global asm functions be uniquely named
>> across the tree, I don't see that as a problem.  In the rare case of a
>> conflict, we can just rename the function.

So you mean we do not need a new config. Should just check clang and
clang versionn like below?

diff --git a/Makefile b/Makefile
index e944c6e71e81..9bd3990024c5 100644
--- a/Makefile
+++ b/Makefile
@@ -1034,6 +1034,11 @@ endif
  ifdef CONFIG_LTO_CLANG
  ifdef CONFIG_LTO_CLANG_THIN
  CC_FLAGS_LTO   := -flto=thin -fsplit-lto-unit
+ifdef CONFIG_CC_IS_CLANG
+ifeq ($(shell test $(CONFIG_CLANG_VERSION) -ge 230000; echo $$?),0)
+KBUILD_LDFLAGS += --lto-whole-program-visibility -mllvm -always-rename-promoted-locals=false
+endif
+endif
  else
  CC_FLAGS_LTO   := -flto
  endif

I think this should work. In rare case, renaming the function should
solve the problem.

> BTW, reading this again I realize that this would affect not only global
> asm *functions*, but also global asm *data*.  But asm global data is
> quite rare and also tends to be uniquely named, so my conclusion is the
> same.
>
With thin-lto, the cross-file data inlining is a side effect of
cross-file function inlining. So the number of cross-file data inlining
is small. Compared to 1212 number of functions with suffix .llvm.<hash>,
the number of data with suffix only 9:

ffffffff84e8ad09 d __func__.net_ratelimit.llvm.12310750674033017485
ffffffff84f1d569 d .str.llvm.11541892489833206993
ffffffff87f42d40 b __cfs_bandwidth_used.llvm.9245315756205243639
ffffffff87f457c0 b __sched_clock_stable.llvm.13183765431478218167
ffffffff881968d0 b lock_chains_in_use.llvm.17116087415131265585
ffffffff88bba180 b timekeeper_data.llvm.4127123038948722377
ffffffff88bd0eb0 b slab_debugfs_root.llvm.537776758349482510
ffffffff88c0b300 b __acpi_os_prepare_sleep.llvm.3969442148434754585
ffffffff88c63b00 b handshake_rhashtbl.llvm.12810142853876704317

With newly added KBUILD_LDFLAGS flags, none of them have suffixes.
Again, the conflict for data variable should be rare too.

I will repost the patch with Makefile change once llvm23 release
is cut.

Thanks!


^ permalink raw reply related

* Re: [PATCH kbuild] kbuild: Allow to reduce the number of suffixes for clang thin-lto build
From: Josh Poimboeuf @ 2026-03-06 20:57 UTC (permalink / raw)
  To: Yonghong Song
  Cc: linux-kbuild, live-patching, kernel-team, Nathan Chancellor,
	Nicolas Schier, Song Liu
In-Reply-To: <bt7t2452h27o7bf27f7ljs2xhn7venhvslynq3a77jbtwi7hqk@cgobhbhi5y2r>

On Fri, Mar 06, 2026 at 12:55:02PM -0800, Josh Poimboeuf wrote:
> On Fri, Mar 06, 2026 at 11:40:21AM -0800, Yonghong Song wrote:
> > > Thanks!  Would there be any downsides to enabling this feature
> > > unconditionally in the kernel when the compiler supports it?
> > 
> > The only downside is for the following case:
> > 
> > C   file: static function foo()
> > Asm file: global function foo()
> > 
> > The thin-lto will collect all C files and with the above llvm patch,
> > the static function foo() may be promoted to global function foo()
> > if there is no other pre-existing global function foo() in all C files.
> > 
> > In such cases, there will be a conflict since
> > there are two global function foo() (one from C file, another from Asm file).
> > In such cases, the build will fail.
> > 
> > How do you think we could hit such issues in linux kernel?
> > Maybe should have default no for the new config?
> > 
> > I think the chance should be very low. The following is a grab for x86
> > for global symbols in asm code:
> > 
> > [~/work/others/linux/arch/x86 (master)]$ egrep -r globl
> 
> There are actually quite a bit more than that, see SYM_CODE_START:
> 
>   $ git grep 'SYM_CODE_START(' |wc -l
>   169
> 
> But still, I agree the chance of a conflict would be very low.  And
> global assembly functions tend to be rather uniquely named.
> 
> > Maybe we could collect all global symbols in asm codes before lld,
> > and then we add an option in lld to feed those global symbols (with a file?),
> > then we can be sure there won't be any conflict?
> 
> That wouldn't be worth the effort in my opinion.
> 
> I think we should just unconditionally enable
> -always-rename-promoted-locals=false when it's available.  While that
> will implicitly enforce that global asm functions be uniquely named
> across the tree, I don't see that as a problem.  In the rare case of a
> conflict, we can just rename the function.

BTW, reading this again I realize that this would affect not only global
asm *functions*, but also global asm *data*.  But asm global data is
quite rare and also tends to be uniquely named, so my conclusion is the
same.

-- 
Josh

^ permalink raw reply

* Re: [PATCH kbuild] kbuild: Allow to reduce the number of suffixes for clang thin-lto build
From: Josh Poimboeuf @ 2026-03-06 20:54 UTC (permalink / raw)
  To: Yonghong Song
  Cc: linux-kbuild, live-patching, kernel-team, Nathan Chancellor,
	Nicolas Schier, Song Liu
In-Reply-To: <f1afe1e8-0dfd-47b0-8ca4-f09d4fda13eb@linux.dev>

On Fri, Mar 06, 2026 at 11:40:21AM -0800, Yonghong Song wrote:
> 
> 
> On 3/6/26 10:32 AM, Josh Poimboeuf wrote:
> > On Thu, Mar 05, 2026 at 07:43:25PM -0800, Yonghong Song wrote:
> > > The current clang thin-lto build often produces lots of symbols with
> > > suffix. The following is a partial list of such function call symbols:
> > >      ...
> > >      ethnl_module_fw_flash_ntf.llvm.7631589765585346066
> > >      __nf_conntrack_alloc.llvm.6438426151906658917
> > >      tcp_can_early_drop.llvm.11937612064648250727
> > >      tcp_print_conntrack.llvm.11937612064648250727
> > >      ...
> > > 
> > > In my particular build with current bpf-next, the number of '*.llvm.<hash>'
> > > function calls is 1212. Such symbols make kernel live patching
> > > difficult since
> > >    - a minor code change will change the hash and then the '*.llvm.<hash>'
> > >      symbol becomes another one with a different hash or no hash, and
> > >    - a previous source-level symbol may become an one with suffix after live
> > >      patching code.
> > > 
> > > In [1], Song Liu suggested to reduce the number of '*.llvm.<hash>' functions
> > > to make live patch easier. In respond of this, I implemented this
> > > in llvm ([2]). The same thin-lto build with [2] only has two symbols with
> > > suffix:
> > >      m_stop.llvm.14460341347352036579
> > >      m_next.llvm.14460341347352036579
> > > This should make live patch much easier.
> > > 
> > > To support suffix symbol reduction, a new config
> > >      LTO_CLANG_THIN_SUFFIX_REDUCTION
> > > is introduced and the config depends on thin-lto and llvm23 or higher.
> > > 
> > > Two lld flags are necessary to enable this feature in kernel:
> > >      - Flag '--lto-whole-program-visibility' is needed as it ensures that all
> > >        modules are available in the same process, which is true for kernel at
> > >        thin-lto lld.
> > >      - Flag '-mllvm -always-rename-promoted-locals=false' is needed to enable
> > >        suffix reduction. Currently in llvm [1], only process mode is supported.
> > >        There is another distributed mode (across different processes or even
> > >        different machines) which is not supported yet ([2]).
> > > 
> > >    [1] https://lpc.events/event/19/contributions/2212
> > >    [2] https://github.com/llvm/llvm-project/pull/178587
> > > 
> > > Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
> > > ---
> > >   Makefile     |  3 +++
> > >   arch/Kconfig | 15 +++++++++++++++
> > >   2 files changed, 18 insertions(+)
> > > 
> > > diff --git a/Makefile b/Makefile
> > > index e944c6e71e81..9d6033595615 100644
> > > --- a/Makefile
> > > +++ b/Makefile
> > > @@ -1034,6 +1034,9 @@ endif
> > >   ifdef CONFIG_LTO_CLANG
> > >   ifdef CONFIG_LTO_CLANG_THIN
> > >   CC_FLAGS_LTO	:= -flto=thin -fsplit-lto-unit
> > > +ifdef CONFIG_LTO_CLANG_THIN_SUFFIX_REDUCTION
> > > +KBUILD_LDFLAGS += --lto-whole-program-visibility -mllvm -always-rename-promoted-locals=false
> > > +endif
> > >   else
> > >   CC_FLAGS_LTO	:= -flto
> > >   endif
> > > diff --git a/arch/Kconfig b/arch/Kconfig
> > > index 102ddbd4298e..e1db64a3284e 100644
> > > --- a/arch/Kconfig
> > > +++ b/arch/Kconfig
> > > @@ -861,8 +861,23 @@ config LTO_CLANG_THIN
> > >   	    https://clang.llvm.org/docs/ThinLTO.html
> > >   	  If unsure, say Y.
> > > +
> > >   endchoice
> > > +config LTO_CLANG_THIN_SUFFIX_REDUCTION
> > > +	bool "Clang ThinLTO Suffix Reduction (EXPERIMENTAL)"
> > > +	depends on LTO_CLANG_THIN
> > > +	depends on CLANG_VERSION >= 230000
> > > +	default y
> > > +	help
> > > +	  This option allows to reduce the number of symbols with
> > > +	  '.llvm.<hash' suffixes. This can help KLP (kernel living
> > > +	  patch) as symbol name can stay stable in most cases.
> > > +
> > > +	  See https://github.com/llvm/llvm-project/pull/178587
> > > +
> > > +	  If unsure, say N.
> > > +
> > Thanks!  Would there be any downsides to enabling this feature
> > unconditionally in the kernel when the compiler supports it?
> 
> The only downside is for the following case:
> 
> C   file: static function foo()
> Asm file: global function foo()
> 
> The thin-lto will collect all C files and with the above llvm patch,
> the static function foo() may be promoted to global function foo()
> if there is no other pre-existing global function foo() in all C files.
> 
> In such cases, there will be a conflict since
> there are two global function foo() (one from C file, another from Asm file).
> In such cases, the build will fail.
> 
> How do you think we could hit such issues in linux kernel?
> Maybe should have default no for the new config?
> 
> I think the chance should be very low. The following is a grab for x86
> for global symbols in asm code:
> 
> [~/work/others/linux/arch/x86 (master)]$ egrep -r globl

There are actually quite a bit more than that, see SYM_CODE_START:

  $ git grep 'SYM_CODE_START(' |wc -l
  169

But still, I agree the chance of a conflict would be very low.  And
global assembly functions tend to be rather uniquely named.

> Maybe we could collect all global symbols in asm codes before lld,
> and then we add an option in lld to feed those global symbols (with a file?),
> then we can be sure there won't be any conflict?

That wouldn't be worth the effort in my opinion.

I think we should just unconditionally enable
-always-rename-promoted-locals=false when it's available.  While that
will implicitly enforce that global asm functions be uniquely named
across the tree, I don't see that as a problem.  In the rare case of a
conflict, we can just rename the function.

-- 
Josh

^ permalink raw reply

* Re: [PATCH kbuild] kbuild: Allow to reduce the number of suffixes for clang thin-lto build
From: Yonghong Song @ 2026-03-06 19:40 UTC (permalink / raw)
  To: Josh Poimboeuf
  Cc: linux-kbuild, live-patching, kernel-team, Nathan Chancellor,
	Nicolas Schier, Song Liu
In-Reply-To: <pat2b5nibiik6nua6ls7cu7eqy5qgrugo4gnel32bz6vpcrmz3@f7ynsbvnxcaj>



On 3/6/26 10:32 AM, Josh Poimboeuf wrote:
> On Thu, Mar 05, 2026 at 07:43:25PM -0800, Yonghong Song wrote:
>> The current clang thin-lto build often produces lots of symbols with
>> suffix. The following is a partial list of such function call symbols:
>>      ...
>>      ethnl_module_fw_flash_ntf.llvm.7631589765585346066
>>      __nf_conntrack_alloc.llvm.6438426151906658917
>>      tcp_can_early_drop.llvm.11937612064648250727
>>      tcp_print_conntrack.llvm.11937612064648250727
>>      ...
>>
>> In my particular build with current bpf-next, the number of '*.llvm.<hash>'
>> function calls is 1212. Such symbols make kernel live patching
>> difficult since
>>    - a minor code change will change the hash and then the '*.llvm.<hash>'
>>      symbol becomes another one with a different hash or no hash, and
>>    - a previous source-level symbol may become an one with suffix after live
>>      patching code.
>>
>> In [1], Song Liu suggested to reduce the number of '*.llvm.<hash>' functions
>> to make live patch easier. In respond of this, I implemented this
>> in llvm ([2]). The same thin-lto build with [2] only has two symbols with
>> suffix:
>>      m_stop.llvm.14460341347352036579
>>      m_next.llvm.14460341347352036579
>> This should make live patch much easier.
>>
>> To support suffix symbol reduction, a new config
>>      LTO_CLANG_THIN_SUFFIX_REDUCTION
>> is introduced and the config depends on thin-lto and llvm23 or higher.
>>
>> Two lld flags are necessary to enable this feature in kernel:
>>      - Flag '--lto-whole-program-visibility' is needed as it ensures that all
>>        modules are available in the same process, which is true for kernel at
>>        thin-lto lld.
>>      - Flag '-mllvm -always-rename-promoted-locals=false' is needed to enable
>>        suffix reduction. Currently in llvm [1], only process mode is supported.
>>        There is another distributed mode (across different processes or even
>>        different machines) which is not supported yet ([2]).
>>
>>    [1] https://lpc.events/event/19/contributions/2212
>>    [2] https://github.com/llvm/llvm-project/pull/178587
>>
>> Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
>> ---
>>   Makefile     |  3 +++
>>   arch/Kconfig | 15 +++++++++++++++
>>   2 files changed, 18 insertions(+)
>>
>> diff --git a/Makefile b/Makefile
>> index e944c6e71e81..9d6033595615 100644
>> --- a/Makefile
>> +++ b/Makefile
>> @@ -1034,6 +1034,9 @@ endif
>>   ifdef CONFIG_LTO_CLANG
>>   ifdef CONFIG_LTO_CLANG_THIN
>>   CC_FLAGS_LTO	:= -flto=thin -fsplit-lto-unit
>> +ifdef CONFIG_LTO_CLANG_THIN_SUFFIX_REDUCTION
>> +KBUILD_LDFLAGS += --lto-whole-program-visibility -mllvm -always-rename-promoted-locals=false
>> +endif
>>   else
>>   CC_FLAGS_LTO	:= -flto
>>   endif
>> diff --git a/arch/Kconfig b/arch/Kconfig
>> index 102ddbd4298e..e1db64a3284e 100644
>> --- a/arch/Kconfig
>> +++ b/arch/Kconfig
>> @@ -861,8 +861,23 @@ config LTO_CLANG_THIN
>>   	    https://clang.llvm.org/docs/ThinLTO.html
>>   
>>   	  If unsure, say Y.
>> +
>>   endchoice
>>   
>> +config LTO_CLANG_THIN_SUFFIX_REDUCTION
>> +	bool "Clang ThinLTO Suffix Reduction (EXPERIMENTAL)"
>> +	depends on LTO_CLANG_THIN
>> +	depends on CLANG_VERSION >= 230000
>> +	default y
>> +	help
>> +	  This option allows to reduce the number of symbols with
>> +	  '.llvm.<hash' suffixes. This can help KLP (kernel living
>> +	  patch) as symbol name can stay stable in most cases.
>> +
>> +	  See https://github.com/llvm/llvm-project/pull/178587
>> +
>> +	  If unsure, say N.
>> +
> Thanks!  Would there be any downsides to enabling this feature
> unconditionally in the kernel when the compiler supports it?

The only downside is for the following case:

C   file: static function foo()
Asm file: global function foo()

The thin-lto will collect all C files and with the above llvm patch,
the static function foo() may be promoted to global function foo()
if there is no other pre-existing global function foo() in all C files.

In such cases, there will be a conflict since
there are two global function foo() (one from C file, another from Asm file).
In such cases, the build will fail.

How do you think we could hit such issues in linux kernel?
Maybe should have default no for the new config?

I think the chance should be very low. The following is a grab for x86
for global symbols in asm code:

[~/work/others/linux/arch/x86 (master)]$ egrep -r globl
egrep: warning: egrep is obsolescent; using grep -E
boot/compressed/mkpiggy.c:      printf(".globl z_input_len\n");
boot/compressed/mkpiggy.c:      printf(".globl z_output_len\n");
boot/compressed/mkpiggy.c:      printf(".globl input_data, input_data_end\n");
boot/compressed/mkpiggy.c:      printf(".globl input_len\n");
boot/compressed/mkpiggy.c:      printf(".globl output_len\n");
boot/compressed/head_64.S:      .globl  verify_cpu
boot/bioscall.S:        .globl  intcall
boot/header.S:  .globl  pecompat_fstart
boot/header.S:  .globl  sentinel
boot/header.S:  .globl  hdr
boot/header.S:  .globl  _start
boot/header.S:          .globl realmode_swtch
boot/header.S:  .globl  die
entry/vdso/vdso32/sigreturn.S:  .globl __kernel_sigreturn
entry/vdso/vdso32/sigreturn.S:  .globl __kernel_rt_sigreturn
entry/vdso/vdso32/system_call.S:        .globl __kernel_vsyscall
entry/vsyscall/vsyscall_emu_64.S:       .globl __vsyscall_page
entry/entry_32.S:       .globl __irqentry_text_start
entry/entry_32.S:       .globl __irqentry_text_end
entry/entry_64.S:       .globl __irqentry_text_start
entry/entry_64.S:       .globl __irqentry_text_end
include/asm/paravirt_types.h:       ".globl " PV_THUNK_NAME(func) ";"                           \
include/asm/static_call.h:          ".globl " STATIC_CALL_TRAMP_STR(name) "             \n"     \
kernel/cpu/amd.c:       ".globl vide\n"
kernel/ftrace_32.S:.globl ftrace_call
kernel/ftrace_32.S:.globl ftrace_graph_call
kernel/ftrace_32.S:.globl return_to_handler
kernel/relocate_kernel_32.S:    .globl kexec_control_code_size
kernel/head_32.S:.globl initial_pg_pmd
kernel/head_32.S:.globl initial_page_table
kernel/head_32.S:.globl swapper_pg_dir
kernel/head_32.S:.globl empty_zero_page
lib/error-inject.c:     ".globl just_return_func\n"
math-emu/reg_round.S:.globl fpu_reg_round
math-emu/reg_round.S:.globl fpu_Arith_exit
purgatory/kexec-purgatory.S:    .globl  kexec_purgatory
purgatory/kexec-purgatory.S:    .globl  kexec_purgatory_size
um/setjmp_32.S: .globl kernel_setjmp
um/setjmp_32.S: .globl kernel_longjmp
um/setjmp_64.S: .globl kernel_setjmp
um/setjmp_64.S: .globl kernel_longjmp
xen/xen-head.S: ELFNOTE(Xen, XEN_ELFNOTE_ENTRY,          .globl xen_elfnote_entry;
[~/work/others/linux/arch/x86 (master)]$

Maybe we could collect all global symbols in asm codes before lld,
and then we add an option in lld to feed those global symbols (with a file?),
then we can be sure there won't be any conflict?



^ permalink raw reply

* Re: [PATCH kbuild] kbuild: Allow to reduce the number of suffixes for clang thin-lto build
From: Josh Poimboeuf @ 2026-03-06 18:32 UTC (permalink / raw)
  To: Yonghong Song
  Cc: linux-kbuild, live-patching, kernel-team, Nathan Chancellor,
	Nicolas Schier, Song Liu
In-Reply-To: <20260306034325.3605301-1-yonghong.song@linux.dev>

On Thu, Mar 05, 2026 at 07:43:25PM -0800, Yonghong Song wrote:
> The current clang thin-lto build often produces lots of symbols with
> suffix. The following is a partial list of such function call symbols:
>     ...
>     ethnl_module_fw_flash_ntf.llvm.7631589765585346066
>     __nf_conntrack_alloc.llvm.6438426151906658917
>     tcp_can_early_drop.llvm.11937612064648250727
>     tcp_print_conntrack.llvm.11937612064648250727
>     ...
> 
> In my particular build with current bpf-next, the number of '*.llvm.<hash>'
> function calls is 1212. Such symbols make kernel live patching
> difficult since
>   - a minor code change will change the hash and then the '*.llvm.<hash>'
>     symbol becomes another one with a different hash or no hash, and
>   - a previous source-level symbol may become an one with suffix after live
>     patching code.
> 
> In [1], Song Liu suggested to reduce the number of '*.llvm.<hash>' functions
> to make live patch easier. In respond of this, I implemented this
> in llvm ([2]). The same thin-lto build with [2] only has two symbols with
> suffix:
>     m_stop.llvm.14460341347352036579
>     m_next.llvm.14460341347352036579
> This should make live patch much easier.
> 
> To support suffix symbol reduction, a new config
>     LTO_CLANG_THIN_SUFFIX_REDUCTION
> is introduced and the config depends on thin-lto and llvm23 or higher.
> 
> Two lld flags are necessary to enable this feature in kernel:
>     - Flag '--lto-whole-program-visibility' is needed as it ensures that all
>       modules are available in the same process, which is true for kernel at
>       thin-lto lld.
>     - Flag '-mllvm -always-rename-promoted-locals=false' is needed to enable
>       suffix reduction. Currently in llvm [1], only process mode is supported.
>       There is another distributed mode (across different processes or even
>       different machines) which is not supported yet ([2]).
> 
>   [1] https://lpc.events/event/19/contributions/2212
>   [2] https://github.com/llvm/llvm-project/pull/178587
> 
> Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
> ---
>  Makefile     |  3 +++
>  arch/Kconfig | 15 +++++++++++++++
>  2 files changed, 18 insertions(+)
> 
> diff --git a/Makefile b/Makefile
> index e944c6e71e81..9d6033595615 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -1034,6 +1034,9 @@ endif
>  ifdef CONFIG_LTO_CLANG
>  ifdef CONFIG_LTO_CLANG_THIN
>  CC_FLAGS_LTO	:= -flto=thin -fsplit-lto-unit
> +ifdef CONFIG_LTO_CLANG_THIN_SUFFIX_REDUCTION
> +KBUILD_LDFLAGS += --lto-whole-program-visibility -mllvm -always-rename-promoted-locals=false
> +endif
>  else
>  CC_FLAGS_LTO	:= -flto
>  endif
> diff --git a/arch/Kconfig b/arch/Kconfig
> index 102ddbd4298e..e1db64a3284e 100644
> --- a/arch/Kconfig
> +++ b/arch/Kconfig
> @@ -861,8 +861,23 @@ config LTO_CLANG_THIN
>  	    https://clang.llvm.org/docs/ThinLTO.html
>  
>  	  If unsure, say Y.
> +
>  endchoice
>  
> +config LTO_CLANG_THIN_SUFFIX_REDUCTION
> +	bool "Clang ThinLTO Suffix Reduction (EXPERIMENTAL)"
> +	depends on LTO_CLANG_THIN
> +	depends on CLANG_VERSION >= 230000
> +	default y
> +	help
> +	  This option allows to reduce the number of symbols with
> +	  '.llvm.<hash' suffixes. This can help KLP (kernel living
> +	  patch) as symbol name can stay stable in most cases.
> +
> +	  See https://github.com/llvm/llvm-project/pull/178587
> +
> +	  If unsure, say N.
> +

Thanks!  Would there be any downsides to enabling this feature
unconditionally in the kernel when the compiler supports it?

-- 
Josh

^ permalink raw reply

* Re: [PATCH v4 0/7] objtool/klp: klp-build LTO support
From: Josh Poimboeuf @ 2026-03-06 16:09 UTC (permalink / raw)
  To: Song Liu; +Cc: live-patching, jikos, mbenes, pmladek, joe.lawrence, kernel-team
In-Reply-To: <20260305231531.3847295-1-song@kernel.org>

On Thu, Mar 05, 2026 at 03:15:24PM -0800, Song Liu wrote:
> Add support for LTO in klp-build toolchain. The key changes are to the
> symbol correlation logic.Basically, we want to:
> 
> 1. Match symbols with differerent .llvm.<hash> suffixes, e.g., foo.llvm.123
>    to foo.llvm.456.
> 2. Match local symbols with promoted global symbols, e.g., local foo
>    with global foo.llvm.123.
> 
> 1/7 and 2/7 are small cleanup/fix for existing code.
> 3/7 through 7/7 contains the core logic changes to correlate_symbols().
> 
> Changes v3 => v4:
> 1. Minor fixes in patches 1, 3, 7.
> 2. Only keep patches 1-7 for now, as there is ongoing discussion about the
>    test infrastructure.
> 
> Changes v2 => v3:
> 1. Fix a bug in global => local correlations (patch 7/8).
> 2. Remove a WARN().
> 3. Some empty line changes.
> 
> Changes v1 => v2:
> 1. Error out on ambiguous .llvm.<hash>
> 
> Song Liu (7):
>   objtool/klp: Remove redundant strcmp() in correlate_symbols()
>   objtool/klp: Remove trailing '_' in demangle_name()
>   objtool/klp: Use sym->demangled_name for symbol_name hash
>   objtool/klp: Also demangle global objects
>   objtool/klp: Remove .llvm suffix in demangle_name()
>   objtool/klp: Match symbols based on demangled_name for global
>     variables
>   objtool/klp: Correlate locals to globals
> 
>  tools/objtool/elf.c                 | 95 ++++++++++++++++++++++-------
>  tools/objtool/include/objtool/elf.h |  3 +
>  tools/objtool/klp-diff.c            | 89 ++++++++++++++++++++++++++-
>  3 files changed, 165 insertions(+), 22 deletions(-)

Thanks!  I will go ahead and queue these up.

-- 
Josh

^ permalink raw reply

* Re: [PATCH 2/2] selftests: livepatch: functions.sh: Workaround heredoc on older bash
From: Petr Mladek @ 2026-03-06 14:38 UTC (permalink / raw)
  To: Marcos Paulo de Souza
  Cc: Josh Poimboeuf, Jiri Kosina, Miroslav Benes, Joe Lawrence,
	Shuah Khan, live-patching, linux-kselftest, linux-kernel
In-Reply-To: <aark_LapcGkPjrLu@pathway.suse.cz>

On Fri 2026-03-06 15:30:20, Petr Mladek wrote:
> On Fri 2026-02-20 11:12:34, Marcos Paulo de Souza wrote:
> > When running current selftests on older distributions like SLE12-SP5 that
> > contains an older bash trips over heredoc. Convert it to plain echo
> > calls, which ends up with the same result.
> > 
> > Signed-off-by: Marcos Paulo de Souza <mpdesouza@suse.com>
> 
> JFYI, the patch has been committed into livepatch.git,
> branch for-7.1/ftrace-test.
> 
> I have fixed the typo reported by Joe, see
> https://git.kernel.org/pub/scm/linux/kernel/git/livepatching/livepatching.git/commit/?h=for-7.1/ftrace-test&id=920e5001f4beb38685d5b8cac061cb1d2760eeab

Grr, the above was meant for the 1st patch.
This 2nd patch was _not_ committed.

Best Regards,
Petr

^ permalink raw reply

* Re: [PATCH 2/2] selftests: livepatch: functions.sh: Workaround heredoc on older bash
From: Petr Mladek @ 2026-03-06 14:30 UTC (permalink / raw)
  To: Marcos Paulo de Souza
  Cc: Josh Poimboeuf, Jiri Kosina, Miroslav Benes, Joe Lawrence,
	Shuah Khan, live-patching, linux-kselftest, linux-kernel
In-Reply-To: <20260220-lp-test-trace-v1-2-4b6703cd01a6@suse.com>

On Fri 2026-02-20 11:12:34, Marcos Paulo de Souza wrote:
> When running current selftests on older distributions like SLE12-SP5 that
> contains an older bash trips over heredoc. Convert it to plain echo
> calls, which ends up with the same result.
> 
> Signed-off-by: Marcos Paulo de Souza <mpdesouza@suse.com>

JFYI, the patch has been committed into livepatch.git,
branch for-7.1/ftrace-test.

I have fixed the typo reported by Joe, see
https://git.kernel.org/pub/scm/linux/kernel/git/livepatching/livepatching.git/commit/?h=for-7.1/ftrace-test&id=920e5001f4beb38685d5b8cac061cb1d2760eeab

Best Regards,
Petr

^ permalink raw reply

* Re: [PATCH 1/2] selftests: livepatch: test-ftrace: livepatch a traced function
From: Petr Mladek @ 2026-03-06 13:45 UTC (permalink / raw)
  To: Marcos Paulo de Souza
  Cc: Josh Poimboeuf, Jiri Kosina, Miroslav Benes, Joe Lawrence,
	Shuah Khan, live-patching, linux-kselftest, linux-kernel
In-Reply-To: <20260220-lp-test-trace-v1-1-4b6703cd01a6@suse.com>

On Fri 2026-02-20 11:12:33, Marcos Paulo de Souza wrote:
> This is basically the inverse case of commit 474eecc882ae
> ("selftests: livepatch: test if ftrace can trace a livepatched function")
> but ensuring that livepatch would work on a traced function.
> 
> Signed-off-by: Marcos Paulo de Souza <mpdesouza@suse.com>

Looks and works fine to me:

Reviewed-by: Petr Mladek <pmladek@suse.com>
Tested-by: Petr Mladek <pmladek@suse.com>

Best Regards,
Petr

PS: I am going to fix the typo mentioned by Joe and push this patch.

^ permalink raw reply

* Re: [PATCH] kernel/trace/ftrace: introduce ftrace module notifier
From: Petr Mladek @ 2026-03-06  9:57 UTC (permalink / raw)
  To: Song Chen
  Cc: Steven Rostedt, Miroslav Benes, mcgrof, petr.pavlu, da.gomez,
	samitolvanen, atomlin, mhiramat, mark.rutland, mathieu.desnoyers,
	linux-modules, linux-kernel, linux-trace-kernel, live-patching
In-Reply-To: <321d4670-27cb-453f-a50d-426c83894074@189.cn>

On Fri 2026-02-27 09:34:59, Song Chen wrote:
> Hi,
> 
> 在 2026/2/27 01:30, Steven Rostedt 写道:
> > On Thu, 26 Feb 2026 11:51:53 +0100 (CET)
> > Miroslav Benes <mbenes@suse.cz> wrote:
> > 
> > > > Let me see if there is any way to use notifier and remain below calling
> > > > sequence:
> > > > 
> > > > ftrace_module_enable
> > > > klp_module_coming
> > > > blocking_notifier_call_chain_robust(MODULE_STATE_COMING)
> > > > 
> > > > blocking_notifier_call_chain(MODULE_STATE_GOING)
> > > > klp_module_going
> > > > ftrace_release_mod
> > > 
> > > Both klp and ftrace used module notifiers in the past. We abandoned that
> > > and opted for direct calls due to issues with ordering at the time. I do
> > > not have the list of problems at hand but I remember it was very fragile.
> > > 
> > > See commits 7dcd182bec27 ("ftrace/module: remove ftrace module
> > > notifier"), 7e545d6eca20 ("livepatch/module: remove livepatch module
> > > notifier") and their surroundings.
> > > 
> > > So unless there is a reason for the change (which should be then carefully
> > > reviewed and properly tested), I would prefer to keep it as is. What is
> > > the motivation? I am failing to find it in the commit log.
> 
> There is no special motivation, i just read btf initialization in module
> loading and found direct calls of ftrace and klp, i thought they were just
> forgotten to use notifier and i even didn't search git log to verify, sorry
> about that.
> 
> > 
> > Honestly, I do think just decoupling ftrace and live kernel patching from
> > modules is rationale enough, as it makes the code a bit cleaner. But to do
> > so, we really need to make sure there is absolutely no regressions.
> > 
> > Thus, to allow such a change, I would ask those that are proposing it, show
> > a full work flow of how ftrace, live kernel patching, and modules work with
> > each other and why those functions are currently injected in the module code.
> > 
> > As Miroslav stated, we tried to do it via notifiers in the past and it
> > failed. I don't want to find out why they failed by just adding them back
> > to notifiers again. Instead, the reasons must be fully understood and
> > updates made to make sure they will not fail in the future.
> 
> Yes, you are right, i read commit msg of 7dcd182bec27, this patch just
> reverses it simply and will introduce order issue back. I will try to find
> out the problem in the past at first.

AFAIK, the root of the problem is that livepatch uses the ftrace
framework. It means that:

   + ftrace must be initialized before livepatch gets enabled
   + livepatch must be disabled before ftrace support gets removed

My understanding is that this can't be achieved by notifiers easily
because they are always proceed in the same order.

An elegant solution would be to introduce  notifier_reverse_call_chain()
which would process the callbacks in the reverse order. But it might
be non-trivial:

  + We would need to make sure that it does not break some
    existing "hidden" dependencies.

  + notifier_call_chain() uses RCU to process the list of registered
    callbacks. I am not sure how complicated would be to make it safe
    in both directions.

Best Regards,
Petr

^ permalink raw reply

* Re: [PATCH v3 8/8] livepatch: Add tests for klp-build toolchain
From: Petr Mladek @ 2026-03-06  9:13 UTC (permalink / raw)
  To: Josh Poimboeuf
  Cc: Joe Lawrence, Miroslav Benes, Song Liu, live-patching, jikos,
	kernel-team
In-Reply-To: <i7i5tbrk5au3udsoigqzwhjwziiiylehaxhauz3pfgongk56hf@dz56fniz7w2a>

On Thu 2026-03-05 10:50:53, Josh Poimboeuf wrote:
> On Wed, Mar 04, 2026 at 02:33:03PM -0500, Joe Lawrence wrote:
> Thanks Song and Joe, these are some great ideas.  Testing will be
> extremely important for the success of klp-build.
> 
>   - I like Song's idea of adding a fake (yet stable) test component in vmlinux for which we can create .patch files to test

Yeah, it simplifies writing and maintaining the test cases.

Also it helps to isolate the tests at runtime. I mean that it might
help to integrate the tests into some higher level testing framework.
I always wondered whether changing some interface might confuse
monitoring or debug output on machines used by misc QA teams.

Best Regards,
Petr

^ permalink raw reply

* [PATCH kbuild] kbuild: Allow to reduce the number of suffixes for clang thin-lto build
From: Yonghong Song @ 2026-03-06  3:43 UTC (permalink / raw)
  To: linux-kbuild, live-patching
  Cc: Josh Poimboeuf, kernel-team, Nathan Chancellor, Nicolas Schier,
	Song Liu

The current clang thin-lto build often produces lots of symbols with
suffix. The following is a partial list of such function call symbols:
    ...
    ethnl_module_fw_flash_ntf.llvm.7631589765585346066
    __nf_conntrack_alloc.llvm.6438426151906658917
    tcp_can_early_drop.llvm.11937612064648250727
    tcp_print_conntrack.llvm.11937612064648250727
    ...

In my particular build with current bpf-next, the number of '*.llvm.<hash>'
function calls is 1212. Such symbols make kernel live patching
difficult since
  - a minor code change will change the hash and then the '*.llvm.<hash>'
    symbol becomes another one with a different hash or no hash, and
  - a previous source-level symbol may become an one with suffix after live
    patching code.

In [1], Song Liu suggested to reduce the number of '*.llvm.<hash>' functions
to make live patch easier. In respond of this, I implemented this
in llvm ([2]). The same thin-lto build with [2] only has two symbols with
suffix:
    m_stop.llvm.14460341347352036579
    m_next.llvm.14460341347352036579
This should make live patch much easier.

To support suffix symbol reduction, a new config
    LTO_CLANG_THIN_SUFFIX_REDUCTION
is introduced and the config depends on thin-lto and llvm23 or higher.

Two lld flags are necessary to enable this feature in kernel:
    - Flag '--lto-whole-program-visibility' is needed as it ensures that all
      modules are available in the same process, which is true for kernel at
      thin-lto lld.
    - Flag '-mllvm -always-rename-promoted-locals=false' is needed to enable
      suffix reduction. Currently in llvm [1], only process mode is supported.
      There is another distributed mode (across different processes or even
      different machines) which is not supported yet ([2]).

  [1] https://lpc.events/event/19/contributions/2212
  [2] https://github.com/llvm/llvm-project/pull/178587

Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
---
 Makefile     |  3 +++
 arch/Kconfig | 15 +++++++++++++++
 2 files changed, 18 insertions(+)

diff --git a/Makefile b/Makefile
index e944c6e71e81..9d6033595615 100644
--- a/Makefile
+++ b/Makefile
@@ -1034,6 +1034,9 @@ endif
 ifdef CONFIG_LTO_CLANG
 ifdef CONFIG_LTO_CLANG_THIN
 CC_FLAGS_LTO	:= -flto=thin -fsplit-lto-unit
+ifdef CONFIG_LTO_CLANG_THIN_SUFFIX_REDUCTION
+KBUILD_LDFLAGS += --lto-whole-program-visibility -mllvm -always-rename-promoted-locals=false
+endif
 else
 CC_FLAGS_LTO	:= -flto
 endif
diff --git a/arch/Kconfig b/arch/Kconfig
index 102ddbd4298e..e1db64a3284e 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -861,8 +861,23 @@ config LTO_CLANG_THIN
 	    https://clang.llvm.org/docs/ThinLTO.html
 
 	  If unsure, say Y.
+
 endchoice
 
+config LTO_CLANG_THIN_SUFFIX_REDUCTION
+	bool "Clang ThinLTO Suffix Reduction (EXPERIMENTAL)"
+	depends on LTO_CLANG_THIN
+	depends on CLANG_VERSION >= 230000
+	default y
+	help
+	  This option allows to reduce the number of symbols with
+	  '.llvm.<hash' suffixes. This can help KLP (kernel living
+	  patch) as symbol name can stay stable in most cases.
+
+	  See https://github.com/llvm/llvm-project/pull/178587
+
+	  If unsure, say N.
+
 config ARCH_SUPPORTS_AUTOFDO_CLANG
 	bool
 
-- 
2.47.3


^ permalink raw reply related

* [PATCH v4 7/7] objtool/klp: Correlate locals to globals
From: Song Liu @ 2026-03-05 23:15 UTC (permalink / raw)
  To: live-patching
  Cc: jpoimboe, jikos, mbenes, pmladek, joe.lawrence, kernel-team,
	Song Liu
In-Reply-To: <20260305231531.3847295-1-song@kernel.org>

Allow correlating original locals to patched globals, and vice versa.
This is needed when:

1. User adds/removes "static" for a function.
2. CONFIG_LTO_CLANG_THIN promotes local functions and objects to global
   and add .llvm.<hash> suffix.

Signed-off-by: Song Liu <song@kernel.org>
---
 tools/objtool/klp-diff.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
index 92043da0ed0b..7bdb2a417096 100644
--- a/tools/objtool/klp-diff.c
+++ b/tools/objtool/klp-diff.c
@@ -517,6 +517,36 @@ static int correlate_symbols(struct elfs *e)
 		}
 	}
 
+	/* Correlate original locals with patched globals */
+	for_each_sym(e->orig, sym1) {
+		if (sym1->twin || dont_correlate(sym1) || !is_local_sym(sym1))
+			continue;
+
+		sym2 = find_global_symbol_by_name(e->patched, sym1->name);
+		if (!sym2 && find_global_symbol_by_demangled_name(e->patched, sym1, &sym2))
+			return -1;
+
+		if (sym2 && !sym2->twin) {
+			sym1->twin = sym2;
+			sym2->twin = sym1;
+		}
+	}
+
+	/* Correlate original globals with patched locals */
+	for_each_sym(e->patched, sym2) {
+		if (sym2->twin || dont_correlate(sym2) || !is_local_sym(sym2))
+			continue;
+
+		sym1 = find_global_symbol_by_name(e->orig, sym2->name);
+		if (!sym1 && find_global_symbol_by_demangled_name(e->orig, sym2, &sym1))
+			return -1;
+
+		if (sym1 && !sym1->twin) {
+			sym2->twin = sym1;
+			sym1->twin = sym2;
+		}
+	}
+
 	for_each_sym(e->orig, sym1) {
 		if (sym1->twin || dont_correlate(sym1))
 			continue;
-- 
2.52.0


^ permalink raw reply related

* [PATCH v4 6/7] objtool/klp: Match symbols based on demangled_name for global variables
From: Song Liu @ 2026-03-05 23:15 UTC (permalink / raw)
  To: live-patching
  Cc: jpoimboe, jikos, mbenes, pmladek, joe.lawrence, kernel-team,
	Song Liu
In-Reply-To: <20260305231531.3847295-1-song@kernel.org>

correlate_symbols() will always try to match full name first. If there is
no match, try match only demangled_name.

In very rare cases, it is possible to have multiple foo.llvm.<hash> in
the same kernel. Whenever there is ambiguity like this, fail the klp diff.

Signed-off-by: Song Liu <song@kernel.org>
---
 tools/objtool/elf.c                 | 13 +++++++
 tools/objtool/include/objtool/elf.h |  3 ++
 tools/objtool/klp-diff.c            | 57 +++++++++++++++++++++++++++++
 3 files changed, 73 insertions(+)

diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
index 51e6267cdf8d..ef4affd6e45e 100644
--- a/tools/objtool/elf.c
+++ b/tools/objtool/elf.c
@@ -323,6 +323,19 @@ struct symbol *find_global_symbol_by_name(const struct elf *elf, const char *nam
 	return NULL;
 }
 
+void iterate_global_symbol_by_demangled_name(const struct elf *elf,
+					     const char *demangled_name,
+					     void (*process)(struct symbol *sym, void *data),
+					     void *data)
+{
+	struct symbol *sym;
+
+	elf_hash_for_each_possible(symbol_name, sym, name_hash, str_hash(demangled_name)) {
+		if (!strcmp(sym->demangled_name, demangled_name) && !is_local_sym(sym))
+			process(sym, data);
+	}
+}
+
 struct reloc *find_reloc_by_dest_range(const struct elf *elf, struct section *sec,
 				     unsigned long offset, unsigned int len)
 {
diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/objtool/elf.h
index e12c516bd320..25573e5af76e 100644
--- a/tools/objtool/include/objtool/elf.h
+++ b/tools/objtool/include/objtool/elf.h
@@ -186,6 +186,9 @@ struct symbol *find_func_by_offset(struct section *sec, unsigned long offset);
 struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset);
 struct symbol *find_symbol_by_name(const struct elf *elf, const char *name);
 struct symbol *find_global_symbol_by_name(const struct elf *elf, const char *name);
+void iterate_global_symbol_by_demangled_name(const struct elf *elf, const char *demangled_name,
+					     void (*process)(struct symbol *sym, void *data),
+					     void *data);
 struct symbol *find_symbol_containing(const struct section *sec, unsigned long offset);
 int find_symbol_hole_containing(const struct section *sec, unsigned long offset);
 struct reloc *find_reloc_by_dest(const struct elf *elf, struct section *sec, unsigned long offset);
diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
index 57606bc3390a..92043da0ed0b 100644
--- a/tools/objtool/klp-diff.c
+++ b/tools/objtool/klp-diff.c
@@ -355,6 +355,46 @@ static bool dont_correlate(struct symbol *sym)
 	       strstarts(sym->name, "__initcall__");
 }
 
+struct process_demangled_name_data {
+	struct symbol *ret;
+	int count;
+};
+
+static void process_demangled_name(struct symbol *sym, void *d)
+{
+	struct process_demangled_name_data *data = d;
+
+	if (sym->twin)
+		return;
+
+	data->count++;
+	data->ret = sym;
+}
+
+/*
+ * When there is no full name match, try match demangled_name. This would
+ * match original foo.llvm.123 to patched foo.llvm.456.
+ *
+ * Note that, in very rare cases, it is possible to have multiple
+ * foo.llvm.<hash> in the same kernel. When this happens, report error and
+ * fail the diff.
+ */
+static int find_global_symbol_by_demangled_name(struct elf *elf, struct symbol *sym,
+						struct symbol **out_sym)
+{
+	struct process_demangled_name_data data = {};
+
+	iterate_global_symbol_by_demangled_name(elf, sym->demangled_name,
+						process_demangled_name,
+						&data);
+	if (data.count > 1) {
+		ERROR("Multiple (%d) correlation candidates for %s", data.count, sym->name);
+		return -1;
+	}
+	*out_sym = data.ret;
+	return 0;
+}
+
 /*
  * For each symbol in the original kernel, find its corresponding "twin" in the
  * patched kernel.
@@ -453,6 +493,23 @@ static int correlate_symbols(struct elfs *e)
 			continue;
 
 		sym2 = find_global_symbol_by_name(e->patched, sym1->name);
+		if (sym2 && !sym2->twin) {
+			sym1->twin = sym2;
+			sym2->twin = sym1;
+		}
+	}
+
+	/*
+	 * Correlate globals with demangled_name.
+	 * A separate loop is needed because we want to finish all the
+	 * full name correlations first.
+	 */
+	for_each_sym(e->orig, sym1) {
+		if (sym1->bind == STB_LOCAL || sym1->twin)
+			continue;
+
+		if (find_global_symbol_by_demangled_name(e->patched, sym1, &sym2))
+			return -1;
 
 		if (sym2 && !sym2->twin) {
 			sym1->twin = sym2;
-- 
2.52.0


^ permalink raw reply related

* [PATCH v4 5/7] objtool/klp: Remove .llvm suffix in demangle_name()
From: Song Liu @ 2026-03-05 23:15 UTC (permalink / raw)
  To: live-patching
  Cc: jpoimboe, jikos, mbenes, pmladek, joe.lawrence, kernel-team,
	Song Liu
In-Reply-To: <20260305231531.3847295-1-song@kernel.org>

Remove .llvm suffix, so that we can correlate foo.llvm.<hash 1> and
foo.llvm.<hash 2>.

Signed-off-by: Song Liu <song@kernel.org>
---
 tools/objtool/elf.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
index 78db51ebbed4..51e6267cdf8d 100644
--- a/tools/objtool/elf.c
+++ b/tools/objtool/elf.c
@@ -455,6 +455,11 @@ static int read_sections(struct elf *elf)
 static ssize_t demangled_name_len(const char *name)
 {
 	ssize_t idx;
+	const char *p;
+
+	p = strstr(name, ".llvm.");
+	if (p)
+		return p - name;
 
 	if (!strstarts(name, "__UNIQUE_ID_") && !strchr(name, '.'))
 		return strlen(name);
@@ -482,6 +487,9 @@ static ssize_t demangled_name_len(const char *name)
  *   __UNIQUE_ID_addressable___UNIQUE_ID_pci_invalid_bar_694_695
  *
  * to remove both trailing numbers, also remove trailing '_'.
+ *
+ * For symbols with llvm suffix, i.e., foo.llvm.<hash>, remove the
+ * .llvm.<hash> part.
  */
 static const char *demangle_name(struct symbol *sym)
 {
-- 
2.52.0


^ permalink raw reply related

* [PATCH v4 4/7] objtool/klp: Also demangle global objects
From: Song Liu @ 2026-03-05 23:15 UTC (permalink / raw)
  To: live-patching
  Cc: jpoimboe, jikos, mbenes, pmladek, joe.lawrence, kernel-team,
	Song Liu
In-Reply-To: <20260305231531.3847295-1-song@kernel.org>

With CONFIG_LTO_CLANG_THIN, it is possible to have global __UNIQUE_ID,
such as:

   FUNC    GLOBAL HIDDEN  19745 __UNIQUE_ID_quirk_amd_nb_node_458

Also demangle global objects.

Signed-off-by: Song Liu <song@kernel.org>
---
 tools/objtool/elf.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
index d9f883f7cff8..78db51ebbed4 100644
--- a/tools/objtool/elf.c
+++ b/tools/objtool/elf.c
@@ -488,9 +488,6 @@ static const char *demangle_name(struct symbol *sym)
 	char *str;
 	ssize_t len;
 
-	if (!is_local_sym(sym))
-		return sym->name;
-
 	if (!is_func_sym(sym) && !is_object_sym(sym))
 		return sym->name;
 
-- 
2.52.0


^ permalink raw reply related

* [PATCH v4 3/7] objtool/klp: Use sym->demangled_name for symbol_name hash
From: Song Liu @ 2026-03-05 23:15 UTC (permalink / raw)
  To: live-patching
  Cc: jpoimboe, jikos, mbenes, pmladek, joe.lawrence, kernel-team,
	Song Liu
In-Reply-To: <20260305231531.3847295-1-song@kernel.org>

For klp-build with LTO, it is necessary to correlate demangled symbols,
e.g., correlate foo.llvm.<num 1> and foo.llvm.<num 2>. However, these two
symbols do not have the same str_hash(name). To be able to correlate the
two symbols, calculate hash based on demanged_name, so that these two
symbols have the same hash.

No functional changes intended.

Signed-off-by: Song Liu <song@kernel.org>
---
 tools/objtool/elf.c | 58 +++++++++++++++++++++++++++++++--------------
 1 file changed, 40 insertions(+), 18 deletions(-)

diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
index 0d93e8496e8d..d9f883f7cff8 100644
--- a/tools/objtool/elf.c
+++ b/tools/objtool/elf.c
@@ -26,11 +26,18 @@
 #include <objtool/elf.h>
 #include <objtool/warn.h>
 
+static ssize_t demangled_name_len(const char *name);
+
 static inline u32 str_hash(const char *str)
 {
 	return jhash(str, strlen(str), 0);
 }
 
+static inline u32 str_hash_demangled(const char *str)
+{
+	return jhash(str, demangled_name_len(str), 0);
+}
+
 #define __elf_table(name)	(elf->name##_hash)
 #define __elf_bits(name)	(elf->name##_bits)
 
@@ -294,7 +301,7 @@ static struct symbol *find_local_symbol_by_file_and_name(const struct elf *elf,
 {
 	struct symbol *sym;
 
-	elf_hash_for_each_possible(symbol_name, sym, name_hash, str_hash(name)) {
+	elf_hash_for_each_possible(symbol_name, sym, name_hash, str_hash_demangled(name)) {
 		if (sym->bind == STB_LOCAL && sym->file == file &&
 		    !strcmp(sym->name, name)) {
 			return sym;
@@ -308,7 +315,7 @@ struct symbol *find_global_symbol_by_name(const struct elf *elf, const char *nam
 {
 	struct symbol *sym;
 
-	elf_hash_for_each_possible(symbol_name, sym, name_hash, str_hash(name)) {
+	elf_hash_for_each_possible(symbol_name, sym, name_hash, str_hash_demangled(name)) {
 		if (!strcmp(sym->name, name) && !is_local_sym(sym))
 			return sym;
 	}
@@ -441,6 +448,28 @@ static int read_sections(struct elf *elf)
 	return 0;
 }
 
+/*
+ * Returns desired length of the demangled name.
+ * If name doesn't need demangling, return strlen(name).
+ */
+static ssize_t demangled_name_len(const char *name)
+{
+	ssize_t idx;
+
+	if (!strstarts(name, "__UNIQUE_ID_") && !strchr(name, '.'))
+		return strlen(name);
+
+	for (idx = strlen(name) - 1; idx >= 0; idx--) {
+		char c = name[idx];
+
+		if (!isdigit(c) && c != '.' && c != '_')
+			break;
+	}
+	if (idx <= 0)
+		return strlen(name);
+	return idx + 1;
+}
+
 /*
  * Remove number suffix of a symbol.
  *
@@ -457,6 +486,7 @@ static int read_sections(struct elf *elf)
 static const char *demangle_name(struct symbol *sym)
 {
 	char *str;
+	ssize_t len;
 
 	if (!is_local_sym(sym))
 		return sym->name;
@@ -464,24 +494,16 @@ static const char *demangle_name(struct symbol *sym)
 	if (!is_func_sym(sym) && !is_object_sym(sym))
 		return sym->name;
 
-	if (!strstarts(sym->name, "__UNIQUE_ID_") && !strchr(sym->name, '.'))
+	len = demangled_name_len(sym->name);
+	if (len == strlen(sym->name))
 		return sym->name;
 
-	str = strdup(sym->name);
+	str = strndup(sym->name, len);
 	if (!str) {
 		ERROR_GLIBC("strdup");
 		return NULL;
 	}
 
-	for (int i = strlen(str) - 1; i >= 0; i--) {
-		char c = str[i];
-
-		if (!isdigit(c) && c != '.' && c != '_') {
-			str[i + 1] = '\0';
-			break;
-		}
-	}
-
 	return str;
 }
 
@@ -517,9 +539,13 @@ static int elf_add_symbol(struct elf *elf, struct symbol *sym)
 		entry = &sym->sec->symbol_list;
 	list_add(&sym->list, entry);
 
+	sym->demangled_name = demangle_name(sym);
+	if (!sym->demangled_name)
+		return -1;
+
 	list_add_tail(&sym->global_list, &elf->symbols);
 	elf_hash_add(symbol, &sym->hash, sym->idx);
-	elf_hash_add(symbol_name, &sym->name_hash, str_hash(sym->name));
+	elf_hash_add(symbol_name, &sym->name_hash, str_hash(sym->demangled_name));
 
 	if (is_func_sym(sym) &&
 	    (strstarts(sym->name, "__pfx_") ||
@@ -543,10 +569,6 @@ static int elf_add_symbol(struct elf *elf, struct symbol *sym)
 
 	sym->pfunc = sym->cfunc = sym;
 
-	sym->demangled_name = demangle_name(sym);
-	if (!sym->demangled_name)
-		return -1;
-
 	return 0;
 }
 
-- 
2.52.0


^ permalink raw reply related

* [PATCH v4 2/7] objtool/klp: Remove trailing '_' in demangle_name()
From: Song Liu @ 2026-03-05 23:15 UTC (permalink / raw)
  To: live-patching
  Cc: jpoimboe, jikos, mbenes, pmladek, joe.lawrence, kernel-team,
	Song Liu
In-Reply-To: <20260305231531.3847295-1-song@kernel.org>

With CONFIG_LTO_CLANG_THIN, it is possible to have nested __UNIQUE_ID_,
such as:

  __UNIQUE_ID_addressable___UNIQUE_ID_pci_invalid_bar_694_695

To remove both trailing numbers, also remove trailing '_'.

Also add comments to demangle_name().

Signed-off-by: Song Liu <song@kernel.org>
---
 tools/objtool/elf.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
index 2c02c7b49265..0d93e8496e8d 100644
--- a/tools/objtool/elf.c
+++ b/tools/objtool/elf.c
@@ -441,6 +441,19 @@ static int read_sections(struct elf *elf)
 	return 0;
 }
 
+/*
+ * Remove number suffix of a symbol.
+ *
+ * Specifically, remove trailing numbers for "__UNIQUE_ID_" symbols and
+ * symbols with '.'.
+ *
+ * With CONFIG_LTO_CLANG_THIN, it is possible to have nested __UNIQUE_ID_,
+ * such as
+ *
+ *   __UNIQUE_ID_addressable___UNIQUE_ID_pci_invalid_bar_694_695
+ *
+ * to remove both trailing numbers, also remove trailing '_'.
+ */
 static const char *demangle_name(struct symbol *sym)
 {
 	char *str;
@@ -463,7 +476,7 @@ static const char *demangle_name(struct symbol *sym)
 	for (int i = strlen(str) - 1; i >= 0; i--) {
 		char c = str[i];
 
-		if (!isdigit(c) && c != '.') {
+		if (!isdigit(c) && c != '.' && c != '_') {
 			str[i + 1] = '\0';
 			break;
 		}
-- 
2.52.0


^ permalink raw reply related

* [PATCH v4 1/7] objtool/klp: Remove redundant strcmp() in correlate_symbols()
From: Song Liu @ 2026-03-05 23:15 UTC (permalink / raw)
  To: live-patching
  Cc: jpoimboe, jikos, mbenes, pmladek, joe.lawrence, kernel-team,
	Song Liu
In-Reply-To: <20260305231531.3847295-1-song@kernel.org>

find_global_symbol_by_name() already compares names of the two symbols,
so there is no need to compare them again.

Signed-off-by: Song Liu <song@kernel.org>
---
 tools/objtool/klp-diff.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
index a3198a63c2f0..57606bc3390a 100644
--- a/tools/objtool/klp-diff.c
+++ b/tools/objtool/klp-diff.c
@@ -454,7 +454,7 @@ static int correlate_symbols(struct elfs *e)
 
 		sym2 = find_global_symbol_by_name(e->patched, sym1->name);
 
-		if (sym2 && !sym2->twin && !strcmp(sym1->name, sym2->name)) {
+		if (sym2 && !sym2->twin) {
 			sym1->twin = sym2;
 			sym2->twin = sym1;
 		}
-- 
2.52.0


^ permalink raw reply related

* [PATCH v4 0/7] objtool/klp: klp-build LTO support
From: Song Liu @ 2026-03-05 23:15 UTC (permalink / raw)
  To: live-patching
  Cc: jpoimboe, jikos, mbenes, pmladek, joe.lawrence, kernel-team,
	Song Liu

Add support for LTO in klp-build toolchain. The key changes are to the
symbol correlation logic.Basically, we want to:

1. Match symbols with differerent .llvm.<hash> suffixes, e.g., foo.llvm.123
   to foo.llvm.456.
2. Match local symbols with promoted global symbols, e.g., local foo
   with global foo.llvm.123.

1/7 and 2/7 are small cleanup/fix for existing code.
3/7 through 7/7 contains the core logic changes to correlate_symbols().

Changes v3 => v4:
1. Minor fixes in patches 1, 3, 7.
2. Only keep patches 1-7 for now, as there is ongoing discussion about the
   test infrastructure.

Changes v2 => v3:
1. Fix a bug in global => local correlations (patch 7/8).
2. Remove a WARN().
3. Some empty line changes.

Changes v1 => v2:
1. Error out on ambiguous .llvm.<hash>

Song Liu (7):
  objtool/klp: Remove redundant strcmp() in correlate_symbols()
  objtool/klp: Remove trailing '_' in demangle_name()
  objtool/klp: Use sym->demangled_name for symbol_name hash
  objtool/klp: Also demangle global objects
  objtool/klp: Remove .llvm suffix in demangle_name()
  objtool/klp: Match symbols based on demangled_name for global
    variables
  objtool/klp: Correlate locals to globals

 tools/objtool/elf.c                 | 95 ++++++++++++++++++++++-------
 tools/objtool/include/objtool/elf.h |  3 +
 tools/objtool/klp-diff.c            | 89 ++++++++++++++++++++++++++-
 3 files changed, 165 insertions(+), 22 deletions(-)

--
2.52.0

^ permalink raw reply

* Re: [PATCH v3 7/8] objtool/klp: Correlate locals to globals
From: Song Liu @ 2026-03-05 23:10 UTC (permalink / raw)
  To: Josh Poimboeuf
  Cc: live-patching, jikos, mbenes, pmladek, joe.lawrence, kernel-team
In-Reply-To: <4j5chvfnlugrpycrehextkinzfle7mokkos4ooa2ali2susov7@ncunycnjajtu>

On Thu, Mar 5, 2026 at 11:51 AM Josh Poimboeuf <jpoimboe@kernel.org> wrote:
>
> On Wed, Feb 25, 2026 at 04:54:35PM -0800, Song Liu wrote:
> > Allow correlating original locals to patched globals, and vice versa.
> > This is needed when:
> >
> > 1. User adds/removes "static" for a function.
> > 2. CONFIG_LTO_CLANG_THIN promotes local functions and objects to global
> >    and add .llvm.<hash> suffix.
> >
> > Given this is a less common scenario, show warnings when this is needed.
> >
> > Signed-off-by: Song Liu <song@kernel.org>
> > ---
> >  tools/objtool/klp-diff.c | 34 ++++++++++++++++++++++++++++++++++
> >  1 file changed, 34 insertions(+)
> >
> > diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
> > index 92043da0ed0b..5cda965807a5 100644
> > --- a/tools/objtool/klp-diff.c
> > +++ b/tools/objtool/klp-diff.c
> > @@ -517,6 +517,40 @@ static int correlate_symbols(struct elfs *e)
> >               }
> >       }
> >
> > +     /* Correlate original locals with patched globals */
> > +     for_each_sym(e->orig, sym1) {
> > +             if (sym1->twin || dont_correlate(sym1) || !is_local_sym(sym1))
> > +                     continue;
> > +
> > +             sym2 = find_global_symbol_by_name(e->patched, sym1->name);
> > +             if (!sym2 && find_global_symbol_by_demangled_name(e->patched, sym1, &sym2))
> > +                     return -1;
> > +
> > +             if (sym2 && !sym2->twin) {
> > +                     sym1->twin = sym2;
> > +                     sym2->twin = sym1;
> > +                     WARN("correlate LOCAL %s (original) to GLOBAL %s (patched)",
> > +                          sym1->name, sym2->name);
>
> I think this correlation is deterministic so there's no need for the
> warning?

Yes, we can remove this.

I also fixed 1/8 and 3/8. I will send v4 of patch 1/8 to 7/8, as we discuss
more with 8/8.

Thanks,
Song

^ permalink raw reply


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