* [PATCH v2 1/8] objtool/LoongArch: Add arch_adjusted_addend() for KLP support
2026-06-08 10:08 [PATCH v2 0/8] LoongArch: Add livepatch build (KLP) support George Guo
@ 2026-06-08 10:08 ` George Guo
2026-06-08 10:08 ` [PATCH v2 2/8] LoongArch: Mark special sections " George Guo
` (7 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: George Guo @ 2026-06-08 10:08 UTC (permalink / raw)
To: chenhuacai, jpoimboe, peterz, jikos, mbenes, pmladek
Cc: kernel, joe.lawrence, rostedt, ardb, nathan,
nick.desaulniers+lkml, yangtiezhu, jiaxun.yang, liukexin,
guodongtai, xry111, wangyuli, loongarch, live-patching, llvm,
linux-kernel
From: George Guo <guodongtai@kylinos.cn>
Implement arch_adjusted_addend() to return the relocation addend value.
Co-developed-by: Kexin Liu <liukexin@kylinos.cn>
Signed-off-by: Kexin Liu <liukexin@kylinos.cn>
Signed-off-by: George Guo <guodongtai@kylinos.cn>
---
tools/objtool/arch/loongarch/decode.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/tools/objtool/arch/loongarch/decode.c b/tools/objtool/arch/loongarch/decode.c
index 6cd288150f49..674e4efd138f 100644
--- a/tools/objtool/arch/loongarch/decode.c
+++ b/tools/objtool/arch/loongarch/decode.c
@@ -34,6 +34,11 @@ s64 arch_insn_adjusted_addend(struct instruction *insn, struct reloc *reloc)
return reloc_addend(reloc);
}
+u64 arch_adjusted_addend(struct reloc *reloc)
+{
+ return reloc_addend(reloc);
+}
+
bool arch_pc_relative_reloc(struct reloc *reloc)
{
return false;
--
2.25.1
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH v2 2/8] LoongArch: Mark special sections for KLP support
2026-06-08 10:08 [PATCH v2 0/8] LoongArch: Add livepatch build (KLP) support George Guo
2026-06-08 10:08 ` [PATCH v2 1/8] objtool/LoongArch: Add arch_adjusted_addend() for KLP support George Guo
@ 2026-06-08 10:08 ` George Guo
2026-07-01 23:06 ` Joe Lawrence
2026-06-08 10:08 ` [PATCH v2 3/8] livepatch/klp-build: disable direct-extern-access for LoongArch to fix kernel panic George Guo
` (6 subsequent siblings)
8 siblings, 1 reply; 11+ messages in thread
From: George Guo @ 2026-06-08 10:08 UTC (permalink / raw)
To: chenhuacai, jpoimboe, peterz, jikos, mbenes, pmladek
Cc: kernel, joe.lawrence, rostedt, ardb, nathan,
nick.desaulniers+lkml, yangtiezhu, jiaxun.yang, liukexin,
guodongtai, xry111, wangyuli, loongarch, live-patching, llvm,
linux-kernel
From: George Guo <guodongtai@kylinos.cn>
objtool needs to split the kernel's special sections into per-entry
symbols when generating livepatch modules. Mark them so it can:
- .altinstructions and __ex_table are read-only, so set an explicit
entry size via SHF_MERGE (ALT_INSTR_SIZE / EXTABLE_SIZE).
- __bug_table and __jump_table are writable. SHF_MERGE cannot be
combined with SHF_WRITE (Clang rejects it), so annotate each entry
with ANNOTATE_DATA_SPECIAL instead, mirroring x86/arm64.
Co-developed-by: Kexin Liu <liukexin@kylinos.cn>
Signed-off-by: Kexin Liu <liukexin@kylinos.cn>
Signed-off-by: George Guo <guodongtai@kylinos.cn>
---
arch/loongarch/include/asm/alternative-asm.h | 5 +++--
arch/loongarch/include/asm/alternative.h | 6 ++++--
arch/loongarch/include/asm/asm-extable.h | 10 ++++++++--
arch/loongarch/include/asm/bug.h | 1 +
arch/loongarch/include/asm/jump_label.h | 2 ++
arch/loongarch/kernel/asm-offsets.c | 20 ++++++++++++++++++++
6 files changed, 38 insertions(+), 6 deletions(-)
diff --git a/arch/loongarch/include/asm/alternative-asm.h b/arch/loongarch/include/asm/alternative-asm.h
index 7dc29bd9b2f0..d940d9d2c0e1 100644
--- a/arch/loongarch/include/asm/alternative-asm.h
+++ b/arch/loongarch/include/asm/alternative-asm.h
@@ -5,6 +5,7 @@
#ifdef __ASSEMBLER__
#include <asm/asm.h>
+#include <generated/asm-offsets.h>
/*
* Issue one struct alt_instr descriptor entry (need to put it into
@@ -33,7 +34,7 @@
.fill - (((144f-143f)-(141b-140b)) > 0) * ((144f-143f)-(141b-140b)) / 4, 4, 0x03400000
142 :
- .pushsection .altinstructions, "a"
+ .pushsection .altinstructions, "aM", @progbits, ALT_INSTR_SIZE
altinstruction_entry 140b, 143f, \feature, 142b-140b, 144f-143f
.popsection
@@ -63,7 +64,7 @@
(alt_max_short(new_len1, new_len2) - (old_len)) / 4, 4, 0x03400000
142 :
- .pushsection .altinstructions, "a"
+ .pushsection .altinstructions, "aM", @progbits, ALT_INSTR_SIZE
altinstruction_entry 140b, 143f, \feature1, 142b-140b, 144f-143f, 142b-141b
altinstruction_entry 140b, 144f, \feature2, 142b-140b, 145f-144f, 142b-141b
.popsection
diff --git a/arch/loongarch/include/asm/alternative.h b/arch/loongarch/include/asm/alternative.h
index b5bae21fb3c8..8f7712ed2f4e 100644
--- a/arch/loongarch/include/asm/alternative.h
+++ b/arch/loongarch/include/asm/alternative.h
@@ -70,7 +70,8 @@ extern void apply_alternatives(struct alt_instr *start, struct alt_instr *end);
/* alternative assembly primitive: */
#define ALTERNATIVE(oldinstr, newinstr, feature) \
OLDINSTR(oldinstr, 1) \
- ".pushsection .altinstructions,\"a\"\n" \
+ ".pushsection .altinstructions, \"aM\", @progbits, " \
+ __stringify(ALT_INSTR_SIZE) "\n" \
ALTINSTR_ENTRY(feature, 1) \
".popsection\n" \
".subsection 1\n" \
@@ -79,7 +80,8 @@ extern void apply_alternatives(struct alt_instr *start, struct alt_instr *end);
#define ALTERNATIVE_2(oldinstr, newinstr1, feature1, newinstr2, feature2)\
OLDINSTR_2(oldinstr, 1, 2) \
- ".pushsection .altinstructions,\"a\"\n" \
+ ".pushsection .altinstructions, \"aM\", @progbits, " \
+ __stringify(ALT_INSTR_SIZE) "\n" \
ALTINSTR_ENTRY(feature1, 1) \
ALTINSTR_ENTRY(feature2, 2) \
".popsection\n" \
diff --git a/arch/loongarch/include/asm/asm-extable.h b/arch/loongarch/include/asm/asm-extable.h
index d60bdf2e6377..2d7eef7c0b39 100644
--- a/arch/loongarch/include/asm/asm-extable.h
+++ b/arch/loongarch/include/asm/asm-extable.h
@@ -7,10 +7,15 @@
#define EX_TYPE_UACCESS_ERR_ZERO 2
#define EX_TYPE_BPF 3
+#ifndef COMPILE_OFFSETS
+#include <asm/asm-offsets.h>
+#endif
+
#ifdef __ASSEMBLER__
#define __ASM_EXTABLE_RAW(insn, fixup, type, data) \
- .pushsection __ex_table, "a"; \
+ .pushsection __ex_table, "aM", @progbits, \
+ EXTABLE_SIZE; \
.balign 4; \
.long ((insn) - .); \
.long ((fixup) - .); \
@@ -29,7 +34,8 @@
#include <asm/gpr-num.h>
#define __ASM_EXTABLE_RAW(insn, fixup, type, data) \
- ".pushsection __ex_table, \"a\"\n" \
+ ".pushsection __ex_table, \"aM\", @progbits, "\
+ __stringify(EXTABLE_SIZE) "\n" \
".balign 4\n" \
".long ((" insn ") - .)\n" \
".long ((" fixup ") - .)\n" \
diff --git a/arch/loongarch/include/asm/bug.h b/arch/loongarch/include/asm/bug.h
index d090a5bec5eb..14e3acbaad8d 100644
--- a/arch/loongarch/include/asm/bug.h
+++ b/arch/loongarch/include/asm/bug.h
@@ -25,6 +25,7 @@
#define __BUG_ENTRY(cond_str, flags) \
.pushsection __bug_table, "aw"; \
.align 2; \
+ __ANNOTATE_DATA_SPECIAL; \
10000: .long 10001f - .; \
_BUGVERBOSE_LOCATION(WARN_CONDITION_STR(cond_str) __FILE__, __LINE__) \
.short flags; \
diff --git a/arch/loongarch/include/asm/jump_label.h b/arch/loongarch/include/asm/jump_label.h
index 7ef4ae3abf08..d20f0fa24b6b 100644
--- a/arch/loongarch/include/asm/jump_label.h
+++ b/arch/loongarch/include/asm/jump_label.h
@@ -12,6 +12,7 @@
#include <linux/types.h>
#include <linux/stringify.h>
#include <asm/asm.h>
+#include <linux/objtool.h>
#define HAVE_JUMP_LABEL_BATCH
@@ -27,6 +28,7 @@
#define JUMP_TABLE_ENTRY(key, label) \
".pushsection __jump_table, \"aw\" \n\t" \
".align " __stringify(PTRLOG) " \n\t" \
+ ANNOTATE_DATA_SPECIAL "\n\t" \
".long 1b - ., " label " - . \n\t" \
JUMP_LABEL_TYPE key " - . \n\t" \
".popsection \n\t"
diff --git a/arch/loongarch/kernel/asm-offsets.c b/arch/loongarch/kernel/asm-offsets.c
index 2cc953f113ac..470323aa022c 100644
--- a/arch/loongarch/kernel/asm-offsets.c
+++ b/arch/loongarch/kernel/asm-offsets.c
@@ -18,6 +18,8 @@
#include <asm/ftrace.h>
#include <asm/sigframe.h>
#include <vdso/datapage.h>
+#include <asm/alternative.h>
+#include <asm/extable.h>
static void __used output_ptreg_defines(void)
{
@@ -323,3 +325,21 @@ static void __used output_vdso_defines(void)
DEFINE(__VDSO_PAGES, VDSO_NR_PAGES);
BLANK();
}
+
+static void __used output_extable_defines(void)
+{
+ COMMENT("LoongArch exception table entry offsets.");
+
+ DEFINE(EXTABLE_SIZE, sizeof(struct exception_table_entry));
+ BLANK();
+}
+
+static void __used output_alt_instr_defines(void)
+{
+ COMMENT("LoongArch alternative instructions offsets.");
+
+ DEFINE(ALT_INSTR_SIZE, sizeof(struct alt_instr));
+ BLANK();
+}
+
+
--
2.25.1
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCH v2 2/8] LoongArch: Mark special sections for KLP support
2026-06-08 10:08 ` [PATCH v2 2/8] LoongArch: Mark special sections " George Guo
@ 2026-07-01 23:06 ` Joe Lawrence
0 siblings, 0 replies; 11+ messages in thread
From: Joe Lawrence @ 2026-07-01 23:06 UTC (permalink / raw)
To: George Guo
Cc: chenhuacai, jpoimboe, peterz, jikos, mbenes, pmladek, kernel,
rostedt, ardb, nathan, nick.desaulniers+lkml, yangtiezhu,
jiaxun.yang, liukexin, guodongtai, xry111, wangyuli, loongarch,
live-patching, llvm, linux-kernel
On Mon, Jun 08, 2026 at 06:08:46PM +0800, George Guo wrote:
> From: George Guo <guodongtai@kylinos.cn>
>
> objtool needs to split the kernel's special sections into per-entry
> symbols when generating livepatch modules. Mark them so it can:
>
> - .altinstructions and __ex_table are read-only, so set an explicit
> entry size via SHF_MERGE (ALT_INSTR_SIZE / EXTABLE_SIZE).
>
> - __bug_table and __jump_table are writable. SHF_MERGE cannot be
> combined with SHF_WRITE (Clang rejects it), so annotate each entry
> with ANNOTATE_DATA_SPECIAL instead, mirroring x86/arm64.
>
> Co-developed-by: Kexin Liu <liukexin@kylinos.cn>
> Signed-off-by: Kexin Liu <liukexin@kylinos.cn>
> Signed-off-by: George Guo <guodongtai@kylinos.cn>
> ---
Hi George,
Disclaimer: I don't have LoongArch hardware, so the best I can do with
this patchset is to read and poke at it with (cross) compilation.
For the special sections, said cross compiler (loongarch64-linux-gnu-gcc
(GCC) 15.2.1 20250808 (Red Hat Cross 15.2.1-1)) is interesting as it
appears to emit relocs in special sections (__ex_table,
.altinstructions, __bug_table, __jump_table) that point to local
assembler labels in the function's text section rather than the section
symbol + offset.
An example gcc / loongarch .rela__ex_table section looks like:
Relocation section '.rela__ex_table' at offset 0x6a28 contains 10 entries:
Offset Info Type Symbol's Value Symbol's Name + Addend
0000000000000000 0000005d00000063 R_LARCH_32_PCREL 00000000000011f0 .L1^B4 + 0
0000000000000004 0000005e00000063 R_LARCH_32_PCREL 00000000000011f4 .L2^B1 + 0
[ ... snip ... ]
Unlike everywhere else ...
llvm / loongarch:
Relocation section '.rela__ex_table' at offset 0x5710 contains 10 entries:
Offset Info Type Symbol's Value Symbol's Name + Addend
0000000000000000 0000000200000063 R_LARCH_32_PCREL 0000000000000000 .text + 2a70
0000000000000004 0000000200000063 R_LARCH_32_PCREL 0000000000000000 .text + 2a74
gcc / x86:
Relocation section '.rela__ex_table' at offset 0x40f50 contains 2 entries:
Offset Info Type Symbol's Value Symbol's Name + Addend
0000000000000000 0000000200000002 R_X86_64_PC32 0000000000000000 .text + 1596
0000000000000004 0000000200000002 R_X86_64_PC32 0000000000000000 .text + 159b
llvm / x86:
Relocation section '.rela__ex_table' at offset 0x343d8 contains 2 entries:
Offset Info Type Symbol's Value Symbol's Name + Addend
0000000000000000 0000000200000002 R_X86_64_PC32 0000000000000000 .text + 231a
0000000000000004 0000000200000002 R_X86_64_PC32 0000000000000000 .text + 231f
gcc / aarch64:
Relocation section '.rela__ex_table' at offset 0x448c8 contains 10 entries:
Offset Info Type Symbol's Value Symbol's Name + Addend
0000000000000000 0000000200000105 R_AARCH64_PREL32 0000000000000000 .text + 24bc
0000000000000004 0000000200000105 R_AARCH64_PREL32 0000000000000000 .text + 2524
[ ... snip ... ]
llvm / aarch64 Relocation section '.rela__ex_table' at offset 0x37760 contains 10 entries:
Offset Info Type Symbol's Value Symbol's Name + Addend
0000000000000000 0000000200000105 R_AARCH64_PREL32 0000000000000000 .text + 2730
0000000000000004 0000000200000105 R_AARCH64_PREL32 0000000000000000 .text + 264c
[ ... snip ... ]
The objtool/klp-diff.c implications is that
convert_reloc_secsym_to_sym() doesn't handle such non-section symbol
relocs in special sections:
if (!is_sec_sym(sym))
return 0;
That early return leaves the reloc pointing at a .L* symbol that is
never cloned into the output livepatch object. When
clone_special_section() later calls should_keep_special_sym() to decide
whether to include each table entry, it cannot map the reloc to an
included function and silently drops it. In the __ex_table case above,
the patched function's entries are missing from the .ko. As far as I
can tell, this problem applies to other special sections (like
.altinstructions, etc.) as well.
If not GCC / GAS is to be supported, then klp-diff will need to handle
this alternate relocation format. Perhaps these could be pre-converted
in convert_reloc_secsym_to_sym() to the general form (func_sym +
(label_offset - func_offset)) that is expected? I don't know if that's
enough to keep everything hanging together, but might be a place to
start.
--
Joe
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v2 3/8] livepatch/klp-build: disable direct-extern-access for LoongArch to fix kernel panic
2026-06-08 10:08 [PATCH v2 0/8] LoongArch: Add livepatch build (KLP) support George Guo
2026-06-08 10:08 ` [PATCH v2 1/8] objtool/LoongArch: Add arch_adjusted_addend() for KLP support George Guo
2026-06-08 10:08 ` [PATCH v2 2/8] LoongArch: Mark special sections " George Guo
@ 2026-06-08 10:08 ` George Guo
2026-06-08 10:08 ` [PATCH v2 4/8] livepatch/klp-build: build LoongArch with -fPIC to keep GOT-indirect symbol references George Guo
` (5 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: George Guo @ 2026-06-08 10:08 UTC (permalink / raw)
To: chenhuacai, jpoimboe, peterz, jikos, mbenes, pmladek
Cc: kernel, joe.lawrence, rostedt, ardb, nathan,
nick.desaulniers+lkml, yangtiezhu, jiaxun.yang, liukexin,
guodongtai, xry111, wangyuli, loongarch, live-patching, llvm,
linux-kernel
From: George Guo <guodongtai@kylinos.cn>
On LoongArch systems, livepatch modules containing references to
EXTERNAL global variables trigger kernel panics when the core kernel is
built with the -mdirect-extern-access optimization.
Root cause:
The -mdirect-extern-access optimization replaces GOT-based external
symbol access with direct addressing for improved performance. However,
this breaks the kernel module loading mechanism, which relies on GOT
entries for proper relocation of EXTERNAL symbol references. Direct
access to global variables from livepatch modules causes invalid memory
accesses and kernel panics.
Solution:
For LoongArch klp builds, conditionally disable direct-extern-access by
adding:
- -mno-direct-extern-access for GCC builds
- -fno-direct-access-external-data for Clang builds
See also commit 38b10b269d04 ("LoongArch: Tweak CFLAGS for Clang
compatibility"), which added -mdirect-extern-access to the kernel as a
nice-to-have optimization that reduces GOT accesses.
Note this is passed as a command-line KBUILD_CFLAGS_KERNEL= assignment,
which replaces arch/loongarch/Makefile's KBUILD_CFLAGS_KERNEL wholesale
rather than appending to it. As a side effect it also drops the -fPIE
that the arch adds under CONFIG_RELOCATABLE. That is intentional and
relied upon by the next patch ("LoongArch: ... -fPIC ..."), which adds
-fPIC via KCFLAGS: kbuild applies KBUILD_CFLAGS_KERNEL after KCFLAGS for
built-in objects (see modkern_cflags in scripts/Makefile.lib), so a
retained -fPIE would otherwise win over that -fPIC. The two patches must
stay together.
Co-developed-by: Kexin Liu <liukexin@kylinos.cn>
Signed-off-by: Kexin Liu <liukexin@kylinos.cn>
Signed-off-by: George Guo <guodongtai@kylinos.cn>
---
scripts/livepatch/klp-build | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build
index e83973567c87..27fe8824ef12 100755
--- a/scripts/livepatch/klp-build
+++ b/scripts/livepatch/klp-build
@@ -556,6 +556,24 @@ build_kernel() {
local log="$TMP_DIR/build.log"
local cmd=()
+ local ARCH_KBUILD_CFLAGS_KERNEL=""
+
+ if [[ -v CONFIG_LOONGARCH && "$CONFIG_LOONGARCH" == "y" ]]; then
+ # -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).
+ [[ "${CONFIG_AS_HAS_EXPLICIT_RELOCS:-}" == "y" ]] || \
+ die "LoongArch klp-build requires CONFIG_AS_HAS_EXPLICIT_RELOCS=y"
+
+ if [[ "${CONFIG_CC_IS_CLANG:-}" == "y" ]]; then
+ ARCH_KBUILD_CFLAGS_KERNEL="-fno-direct-access-external-data"
+ else
+ ARCH_KBUILD_CFLAGS_KERNEL="-mno-direct-extern-access"
+ fi
+
+ status "LoongArch detected: adding $ARCH_KBUILD_CFLAGS_KERNEL to KBUILD_CFLAGS_KERNEL"
+ fi
+
cmd=("make")
# When a patch to a kernel module references a newly created unexported
@@ -582,6 +600,7 @@ build_kernel() {
fi
cmd+=("-j$JOBS")
cmd+=("KCFLAGS=-ffunction-sections -fdata-sections")
+ cmd+=("KBUILD_CFLAGS_KERNEL=$ARCH_KBUILD_CFLAGS_KERNEL")
cmd+=("vmlinux")
cmd+=("modules")
--
2.25.1
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH v2 4/8] livepatch/klp-build: build LoongArch with -fPIC to keep GOT-indirect symbol references
2026-06-08 10:08 [PATCH v2 0/8] LoongArch: Add livepatch build (KLP) support George Guo
` (2 preceding siblings ...)
2026-06-08 10:08 ` [PATCH v2 3/8] livepatch/klp-build: disable direct-extern-access for LoongArch to fix kernel panic George Guo
@ 2026-06-08 10:08 ` George Guo
2026-06-08 10:08 ` [PATCH v2 5/8] LoongArch: Fix EFI linking with -fdata-sections George Guo
` (4 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: George Guo @ 2026-06-08 10:08 UTC (permalink / raw)
To: chenhuacai, jpoimboe, peterz, jikos, mbenes, pmladek
Cc: kernel, joe.lawrence, rostedt, ardb, nathan,
nick.desaulniers+lkml, yangtiezhu, jiaxun.yang, liukexin,
guodongtai, xry111, wangyuli, loongarch, live-patching, llvm,
linux-kernel
From: George Guo <guodongtai@kylinos.cn>
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.
Co-developed-by: Kexin Liu <liukexin@kylinos.cn>
Signed-off-by: Kexin Liu <liukexin@kylinos.cn>
Signed-off-by: George Guo <guodongtai@kylinos.cn>
---
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")
--
2.25.1
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH v2 5/8] LoongArch: Fix EFI linking with -fdata-sections
2026-06-08 10:08 [PATCH v2 0/8] LoongArch: Add livepatch build (KLP) support George Guo
` (3 preceding siblings ...)
2026-06-08 10:08 ` [PATCH v2 4/8] livepatch/klp-build: build LoongArch with -fPIC to keep GOT-indirect symbol references George Guo
@ 2026-06-08 10:08 ` George Guo
2026-06-08 10:08 ` [PATCH v2 6/8] objtool/klp: Add LoongArch jump opcode bytes support George Guo
` (3 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: George Guo @ 2026-06-08 10:08 UTC (permalink / raw)
To: chenhuacai, jpoimboe, peterz, jikos, mbenes, pmladek
Cc: kernel, joe.lawrence, rostedt, ardb, nathan,
nick.desaulniers+lkml, yangtiezhu, jiaxun.yang, liukexin,
guodongtai, xry111, wangyuli, loongarch, live-patching, llvm,
linux-kernel
From: George Guo <guodongtai@kylinos.cn>
When building with func-fdata-sections, the .init.bss section gets split
up into a bunch of .init.bss.<var> sections. Make sure they get linked
into .init.data.
Co-developed-by: Kexin Liu <liukexin@kylinos.cn>
Signed-off-by: Kexin Liu <liukexin@kylinos.cn>
Signed-off-by: George Guo <guodongtai@kylinos.cn>
---
arch/loongarch/kernel/vmlinux.lds.S | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/loongarch/kernel/vmlinux.lds.S b/arch/loongarch/kernel/vmlinux.lds.S
index 840d944c2f73..dc5fa017db94 100644
--- a/arch/loongarch/kernel/vmlinux.lds.S
+++ b/arch/loongarch/kernel/vmlinux.lds.S
@@ -96,7 +96,7 @@ SECTIONS
#endif
.init.bss : {
- *(.init.bss)
+ *(.init.bss .init.bss.*)
}
. = ALIGN(PECOFF_SEGMENT_ALIGN);
__initdata_end = .;
--
2.25.1
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH v2 6/8] objtool/klp: Add LoongArch jump opcode bytes support
2026-06-08 10:08 [PATCH v2 0/8] LoongArch: Add livepatch build (KLP) support George Guo
` (4 preceding siblings ...)
2026-06-08 10:08 ` [PATCH v2 5/8] LoongArch: Fix EFI linking with -fdata-sections George Guo
@ 2026-06-08 10:08 ` George Guo
2026-06-08 10:08 ` [PATCH v2 7/8] klp-build: Add LoongArch syscall patching macro George Guo
` (2 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: George Guo @ 2026-06-08 10:08 UTC (permalink / raw)
To: chenhuacai, jpoimboe, peterz, jikos, mbenes, pmladek
Cc: kernel, joe.lawrence, rostedt, ardb, nathan,
nick.desaulniers+lkml, yangtiezhu, jiaxun.yang, liukexin,
guodongtai, xry111, wangyuli, loongarch, live-patching, llvm,
linux-kernel
From: George Guo <guodongtai@kylinos.cn>
Implement arch_jump_opcode_bytes() for LoongArch so that klp checksums
for jump/call instructions with non-relocated destination offsets are
position-independent, mirroring the x86 and arm64 implementations.
Mask out the embedded branch offset while preserving the opcode and the
register operands, which differ per instruction format:
- B/BL (reg0i26): no regs -> 0xfc000000
- BEQZ/BNEZ/BCEQZ/BCNEZ (reg1i21): keep rj/cj -> 0xfc0003e0
- JIRL/BEQ/BNE/.../BGEU (reg2i16): keep rj/rd -> 0xfc0003ff
Co-developed-by: Kexin Liu <liukexin@kylinos.cn>
Signed-off-by: Kexin Liu <liukexin@kylinos.cn>
Signed-off-by: George Guo <guodongtai@kylinos.cn>
---
tools/objtool/arch/loongarch/decode.c | 41 +++++++++++++++++++++++++++
1 file changed, 41 insertions(+)
diff --git a/tools/objtool/arch/loongarch/decode.c b/tools/objtool/arch/loongarch/decode.c
index 674e4efd138f..12facd0cc8d1 100644
--- a/tools/objtool/arch/loongarch/decode.c
+++ b/tools/objtool/arch/loongarch/decode.c
@@ -432,6 +432,47 @@ unsigned long arch_jump_table_sym_offset(struct reloc *reloc, struct reloc *tabl
}
}
+size_t arch_jump_opcode_bytes(struct objtool_file *file, struct instruction *insn,
+ unsigned char *buf)
+{
+ union loongarch_instruction *code;
+ u32 insn_word;
+
+ insn_word = le32toh(*(u32 *)(insn->sec->data->d_buf + insn->offset));
+ code = (union loongarch_instruction *)&insn_word;
+
+ switch (code->reg0i26_format.opcode) {
+ case b_op:
+ case bl_op:
+ /* reg0i26: 26-bit offset, no register operands */
+ insn_word &= 0xfc000000;
+ break;
+ case beqz_op:
+ case bnez_op:
+ case bceqz_op: /* == bcnez_op */
+ /* reg1i21: keep opcode + rj/cj at bits[9:5] */
+ insn_word &= 0xfc0003e0;
+ break;
+ case jirl_op:
+ case beq_op:
+ case bne_op:
+ case blt_op:
+ case bge_op:
+ case bltu_op:
+ case bgeu_op:
+ /* reg2i16: keep opcode + rj/rd at bits[9:0] */
+ insn_word &= 0xfc0003ff;
+ break;
+ default:
+ break;
+ }
+
+ insn_word = htole32(insn_word);
+ memcpy(buf, &insn_word, sizeof(insn_word));
+
+ return LOONGARCH_INSN_SIZE;
+}
+
#ifdef DISAS
int arch_disas_info_init(struct disassemble_info *dinfo)
--
2.25.1
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH v2 7/8] klp-build: Add LoongArch syscall patching macro
2026-06-08 10:08 [PATCH v2 0/8] LoongArch: Add livepatch build (KLP) support George Guo
` (5 preceding siblings ...)
2026-06-08 10:08 ` [PATCH v2 6/8] objtool/klp: Add LoongArch jump opcode bytes support George Guo
@ 2026-06-08 10:08 ` George Guo
2026-06-08 10:08 ` [PATCH v2 8/8] LoongArch: Add livepatch build (KLP) support George Guo
2026-07-02 20:00 ` [PATCH v2 0/8] " Joe Lawrence
8 siblings, 0 replies; 11+ messages in thread
From: George Guo @ 2026-06-08 10:08 UTC (permalink / raw)
To: chenhuacai, jpoimboe, peterz, jikos, mbenes, pmladek
Cc: kernel, joe.lawrence, rostedt, ardb, nathan,
nick.desaulniers+lkml, yangtiezhu, jiaxun.yang, liukexin,
guodongtai, xry111, wangyuli, loongarch, live-patching, llvm,
linux-kernel
From: George Guo <guodongtai@kylinos.cn>
Add LoongArch support for KLP_SYSCALL_DEFINEx(), mirroring the generic
__SYSCALL_DEFINEx() pattern from include/linux/syscalls.h.
Co-developed-by: Kexin Liu <liukexin@kylinos.cn>
Signed-off-by: Kexin Liu <liukexin@kylinos.cn>
Signed-off-by: George Guo <guodongtai@kylinos.cn>
---
include/linux/livepatch_helpers.h | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/include/linux/livepatch_helpers.h b/include/linux/livepatch_helpers.h
index 4b647b83865f..a8aad067177b 100644
--- a/include/linux/livepatch_helpers.h
+++ b/include/linux/livepatch_helpers.h
@@ -91,6 +91,28 @@
} \
static inline long __klp_do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))
+#elif defined(CONFIG_LOONGARCH)
+
+#define __KLP_SYSCALL_DEFINEx(x, name, ...) \
+ __diag_push(); \
+ __diag_ignore(GCC, 8, "-Wattribute-alias", \
+ "Type aliasing is used to sanitize syscall arguments");\
+ asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \
+ __attribute__((alias(__stringify(__se_sys##name)))); \
+ ALLOW_ERROR_INJECTION(sys##name, ERRNO); \
+ static inline long __klp_do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__));\
+ asmlinkage long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)); \
+ asmlinkage long __attribute__((optimize("-fno-optimize-sibling-calls")))\
+ __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \
+ { \
+ long ret = __klp_do_sys##name(__MAP(x,__SC_CAST,__VA_ARGS__));\
+ __MAP(x,__SC_TEST,__VA_ARGS__); \
+ __PROTECT(x, ret,__MAP(x,__SC_ARGS,__VA_ARGS__)); \
+ return ret; \
+ } \
+ __diag_pop(); \
+ static inline long __klp_do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))
+
#endif
#endif /* _LINUX_LIVEPATCH_HELPERS_H */
--
2.25.1
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH v2 8/8] LoongArch: Add livepatch build (KLP) support
2026-06-08 10:08 [PATCH v2 0/8] LoongArch: Add livepatch build (KLP) support George Guo
` (6 preceding siblings ...)
2026-06-08 10:08 ` [PATCH v2 7/8] klp-build: Add LoongArch syscall patching macro George Guo
@ 2026-06-08 10:08 ` George Guo
2026-07-02 20:00 ` [PATCH v2 0/8] " Joe Lawrence
8 siblings, 0 replies; 11+ messages in thread
From: George Guo @ 2026-06-08 10:08 UTC (permalink / raw)
To: chenhuacai, jpoimboe, peterz, jikos, mbenes, pmladek
Cc: kernel, joe.lawrence, rostedt, ardb, nathan,
nick.desaulniers+lkml, yangtiezhu, jiaxun.yang, liukexin,
guodongtai, xry111, wangyuli, loongarch, live-patching, llvm,
linux-kernel
From: George Guo <guodongtai@kylinos.cn>
This allows automated livepatch module generation using objtool.
Co-developed-by: Kexin Liu <liukexin@kylinos.cn>
Signed-off-by: Kexin Liu <liukexin@kylinos.cn>
Signed-off-by: George Guo <guodongtai@kylinos.cn>
---
arch/loongarch/Kconfig | 1 +
tools/objtool/Makefile | 3 ++-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
index 3b042dbb2c41..1dbf51ba9d6a 100644
--- a/arch/loongarch/Kconfig
+++ b/arch/loongarch/Kconfig
@@ -159,6 +159,7 @@ config LOONGARCH
select HAVE_IOREMAP_PROT
select HAVE_IRQ_EXIT_ON_IRQ_STACK
select HAVE_IRQ_TIME_ACCOUNTING
+ select HAVE_KLP_BUILD
select HAVE_KPROBES
select HAVE_KPROBES_ON_FTRACE
select HAVE_KRETPROBES
diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile
index 94aabeee9736..83d645675ed9 100644
--- a/tools/objtool/Makefile
+++ b/tools/objtool/Makefile
@@ -8,7 +8,8 @@ ifeq ($(SRCARCH),x86)
endif
ifeq ($(SRCARCH),loongarch)
- BUILD_ORC := y
+ BUILD_ORC := y
+ ARCH_HAS_KLP := y
endif
ifeq ($(SRCARCH),arm64)
--
2.25.1
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCH v2 0/8] LoongArch: Add livepatch build (KLP) support
2026-06-08 10:08 [PATCH v2 0/8] LoongArch: Add livepatch build (KLP) support George Guo
` (7 preceding siblings ...)
2026-06-08 10:08 ` [PATCH v2 8/8] LoongArch: Add livepatch build (KLP) support George Guo
@ 2026-07-02 20:00 ` Joe Lawrence
8 siblings, 0 replies; 11+ messages in thread
From: Joe Lawrence @ 2026-07-02 20:00 UTC (permalink / raw)
To: George Guo
Cc: chenhuacai, jpoimboe, peterz, jikos, mbenes, pmladek, kernel,
rostedt, ardb, nathan, nick.desaulniers+lkml, yangtiezhu,
jiaxun.yang, liukexin, guodongtai, xry111, wangyuli, loongarch,
live-patching, llvm, linux-kernel
On Mon, Jun 08, 2026 at 06:08:44PM +0800, George Guo wrote:
> This series adds LoongArch support for the klp-build livepatch tooling,
> enabling automated livepatch module generation using objtool on
> LoongArch.
>
> It is based on Josh Poimboeuf's klp-build series [1] (see base-commit
> below) and extends it with the LoongArch-specific objtool and build
> pieces, plus a few LoongArch toolchain/relocation fixes required to make
> livepatch modules load and run correctly.
>
Ok, what am I doing wrong here:
- Git tree is jpoimboe/klp-build-arm64 + this patchset
- Using clang v21.1.8 and a defconfig + CONFIG_LIVEPATCH requirements
- A simple patch to net/core/dev.c :: netif_rx_internal()
$ clang --version
clang version 21.1.8 (Fedora 21.1.8-4.fc43)
Target: x86_64-redhat-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Configuration file: /etc/clang/x86_64-redhat-linux-gnu-clang.cfg
Setup and build the reference kernel:
$ ARCH=loongarch LLVM=1 make defconfig
$ ./scripts/config --file .config \
--set-val CONFIG_FTRACE y \
--set-val CONFIG_KALLSYMS_ALL y \
--set-val CONFIG_FUNCTION_TRACER y \
--set-val CONFIG_DYNAMIC_FTRACE y \
--set-val CONFIG_DYNAMIC_DEBUG y \
--set-val CONFIG_LIVEPATCH y
$ ARCH=loongarch LLVM=1 make olddefconfig
$ grep LIVEPATCH .config
CONFIG_HAVE_LIVEPATCH=y
CONFIG_LIVEPATCH=y
$ ARCH=loongarch LLVM=1 make -j$(nproc)
...
Then provide this small patch:
$ cat test.patch
diff --git a/net/core/dev.c b/net/core/dev.c
index 06c195906231..14fd3d5f351a 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -5717,6 +5717,7 @@ static int netif_rx_internal(struct sk_buff *skb)
unsigned int qtail;
ret = enqueue_to_backlog(skb, smp_processor_id(), &qtail);
+ pr_info("test");
}
return ret;
}
to klp-build:
$ ARCH=loongarch LLVM=1 ./scripts/livepatch/klp-build -T test.patch
Validating patch(es)
Building original kernel
LoongArch detected: adding -fno-direct-access-external-data to KBUILD_CFLAGS_KERNEL
Cannot find symbol for section 5: .text.sched_clock.
kernel/sched/build_utility.o: failed
The "Cannot find symbol for section" error message comes out of the
recordmcount script.
What's strange is that arch/loongarch/Makefile wants to use patchable
function entry:
ifdef CONFIG_DYNAMIC_FTRACE
KBUILD_CPPFLAGS += -DCC_USING_PATCHABLE_FUNCTION_ENTRY
CC_FLAGS_FTRACE := -fpatchable-function-entry=2
endif
but Kconfig doesn't set it up for LoongArch. If I select when
DYNAMIC_FTRACE is turned on, like:
diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
index 1dbf51ba9d6a..6d9bc4a580d9 100644
--- a/arch/loongarch/Kconfig
+++ b/arch/loongarch/Kconfig
@@ -139,6 +139,7 @@ config LOONGARCH
select HAVE_DMA_CONTIGUOUS
select HAVE_DYNAMIC_FTRACE
select HAVE_DYNAMIC_FTRACE_WITH_ARGS
+ select FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY if DYNAMIC_FTRACE
select HAVE_FTRACE_REGS_HAVING_PT_REGS
select HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
select HAVE_DYNAMIC_FTRACE_WITH_REGS
then rebuild the kernel and retry klp-build, it at least completes the
original and patched kernel builds:
$ ARCH=loongarch LLVM=1 ./scripts/livepatch/klp-build -T test.patch
Validating patch(es)
Building original kernel
LoongArch detected: adding -fno-direct-access-external-data to KBUILD_CFLAGS_KERNEL
vmlinux.o: warning: objtool: __efistub_efi_boot_kernel(): unexpected end of section .init.text.efi_boot_kernel
Copying original object files
Fixing patch(es)
Building patched kernel
LoongArch detected: adding -fno-direct-access-external-data to KBUILD_CFLAGS_KERNEL
vmlinux.o: warning: objtool: __efistub_efi_boot_kernel(): unexpected end of section .init.text.efi_boot_kernel
Copying patched object files
Generating original checksums
Generating patched checksums
Diffing objects
vmlinux.o: changed function: netif_rx_internal
vmlinux.o: error: objtool: __jump_table_23683+0x8: duplicate reloc
error: klp-build: objtool klp diff failed
error: klp-build: line 829: '( cd "$ORIG_CSUM_DIR"; [[ -v VERBOSE ]] && echo "cd $ORIG_CSUM_DIR && ${cmd[*]}"; "${cmd[@]}" > >(tee -a "$log") 2> >(tee -a "$log" | "${filter[@]}" 1>&2) || die "objtool klp diff failed" )'
but ends with a new error on "duplicate reloc" out of klp-build.
What compiler / kernel config should I be trying with this patchset?
Thanks,
--
Joe
^ permalink raw reply [flat|nested] 11+ messages in thread