Re: [PATCH v3 04/12] livepatch/klp-build: build LoongArch with -fPIC to keep GOT-indirect symbol references

Joe Lawrence <[email protected]>
Newsgroups dev.linux.lists.llvm,dev.linux.lists.loongarch,org.kernel.vger.linux-kernel,org.kernel.vger.live-patching
Message-ID <[email protected]>
On Tue, Jul 07, 2026 at 03:20:23PM +0800, George Guo wrote:
> From: George Guo <[email protected]>
> 
> On LoongArch, klp-build livepatch modules panic when a patched function
> references a global defined in the same compilation unit (e.g.
> SYSCALL_DEFINE1(newuname) -> 'uts_sem' in kernel/sys.c).
> 
> With CONFIG_RELOCATABLE=y the kernel is already -fPIE, so this is not
> absolute addressing; the problem is GOT indirection. For a same-unit
> global, -fPIE emits a direct PC-relative reference (R_LARCH_PCALA_*) and
> skips the GOT, while -fPIC routes it through the GOT (R_LARCH_GOT_PC_*).
> klp-build extracts the patched function into a separate module while
> 'uts_sem' stays in the core kernel, and the klp relocation machinery can
> only redirect such a cross-object reference through a GOT entry. The
> direct -fPIE reference has no GOT slot to fix up, so once the function is
> relocated its target is wrong and it faults.
> 
> Force -fPIC for LoongArch KLP builds; -fPIE is not enough, as it
> optimizes away the very GOT indirection KLP relies on.
> 
> This depends on the preceding patch: -fPIC is passed via KCFLAGS, but the
> arch adds -fPIE via KBUILD_CFLAGS_KERNEL, which kbuild applies after
> KCFLAGS (so -fPIE would win). That patch's command-line
> KBUILD_CFLAGS_KERNEL= assignment replaces the arch value and drops -fPIE,
> letting -fPIC take effect. The two patches must stay together.
> 

This might be my personal preference, but I think it would be quicker to
review patches: ("livepatch/klp-build: disable direct-extern-access for
LoongArch to fix kernel panic") ("livepatch/klp-build: build LoongArch
with -fPIC to keep GOT-indirect symbol references") if they were
squashed into one patch.

With that, the commit messages can drop the forward/backward references,
while the combined commit remains complete thought, i.e. for LoongArch
KLP builds, replace the arch's KBUILD_CFLAGS_KERNEL (dropping -fPIE and
-mdirect-extern-access) and add -fPIC via KCFLAGS instead.

> Co-developed-by: Kexin Liu <[email protected]>
> Signed-off-by: Kexin Liu <[email protected]>
> Signed-off-by: George Guo <[email protected]>
> ---
>  scripts/livepatch/klp-build | 19 +++++++++++++++++--
>  1 file changed, 17 insertions(+), 2 deletions(-)
> 
> diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build
> index 27fe8824ef12..42cd58aff3d8 100755
> --- a/scripts/livepatch/klp-build
> +++ b/scripts/livepatch/klp-build
> @@ -557,8 +557,15 @@ build_kernel() {
>  	local cmd=()
>  
>  	local ARCH_KBUILD_CFLAGS_KERNEL=""
> +	local ARCH_KCFLAGS=""
>  
>  	if [[ -v CONFIG_LOONGARCH && "$CONFIG_LOONGARCH" == "y" ]]; then
> +		# -fPIC replaces the kernel's -fPIE (added under CONFIG_RELOCATABLE);
> +		# without that config there is no -fPIE to replace.
> +		[[ "${CONFIG_RELOCATABLE:-}" == "y" ]] || \
> +			die "LoongArch klp-build requires CONFIG_RELOCATABLE=y"
> +		ARCH_KCFLAGS="-fPIC"
> +
>  		# -mdirect-extern-access only exists under explicit relocs, and this
>  		# function replaces KBUILD_CFLAGS_KERNEL wholesale (safe only then;
>  		# the non-explicit build puts -Wa,-mla-global-with-pcrel there).
> @@ -599,8 +606,16 @@ build_kernel() {
>  		cmd+=("-s")
>  	fi
>  	cmd+=("-j$JOBS")
> -	cmd+=("KCFLAGS=-ffunction-sections -fdata-sections")
> -	cmd+=("KBUILD_CFLAGS_KERNEL=$ARCH_KBUILD_CFLAGS_KERNEL")
> +	cmd+=("KCFLAGS=-ffunction-sections -fdata-sections${ARCH_KCFLAGS:+ $ARCH_KCFLAGS}")
> +	# -fPIC is added for KLP via KCFLAGS above; the arch adds -fPIE via
> +	# KBUILD_CFLAGS_KERNEL, which kbuild places after KCFLAGS on the
> +	# built-in compile line.  -fPIC/-fPIE is last-one-wins, so -fPIE would
> +	# win.  Setting KBUILD_CFLAGS_KERNEL on the command line replaces the
> +	# arch value (not append), which drops -fPIE and lets -fPIC win.  Only
> +	# do this when an arch needs it (LoongArch).
> +	if [[ -n "$ARCH_KBUILD_CFLAGS_KERNEL" ]]; then
> +		cmd+=("KBUILD_CFLAGS_KERNEL=$ARCH_KBUILD_CFLAGS_KERNEL")
> +	fi
>  	cmd+=("vmlinux")
>  	cmd+=("modules")
>  

I'd also pull out the configuration checks into validate_config() to be
consistent:

  if [[ -v CONFIG_LOONGARCH ]]; then
       [[ -v CONFIG_AS_HAS_EXPLICIT_RELOCS ]] || \
           die "LoongArch klp-build requires CONFIG_AS_HAS_EXPLICIT_RELOCS=y"
       [[ -v CONFIG_RELOCATABLE ]] || \
           die "LoongArch klp-build requires CONFIG_RELOCATABLE=y"
  fi

and then build_kernel() only needs to adjust the cmd / flags accordingly.

--
Joe
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.