Skip to content

Fix module load issue for R_RISCV_32_PCREL#334

Open
xmzzz wants to merge 12 commits into
RVCK-Project:rvck-6.6from
xmzzz:add-relocations-6f2837b
Open

Fix module load issue for R_RISCV_32_PCREL#334
xmzzz wants to merge 12 commits into
RVCK-Project:rvck-6.6from
xmzzz:add-relocations-6f2837b

Conversation

@xmzzz

@xmzzz xmzzz commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator

fixed: #310

Backport the upstream RISC-V module relocation support to allow loading
kernel modules built with newer binutils (e.g. 2.42) that emit
R_RISCV_32_PCREL and other relocation types.

This fixes the "Unknown relocation type 57" error observed when loading
modules such as cambricon_drv compiled with newer toolchains.

Included patches:

  1. Revert "sg2042: riscv: kernel: Optimize apply_relocate_add()"
  2. riscv: Avoid unaligned access when relocating modules
  3. riscv: Add remaining module relocations
  4. RISC-V: Don't rely on positional structure initialization
  5. riscv: Safely remove entries from relocation list
  6. riscv: Correct type casting in module loading
  7. riscv: module: Allocate PLT entries for R_RISCV_PLT32
  8. riscv: Fix module loading free order
  9. riscv: Correctly free relocation hashtable on error
  10. riscv: Fix relocation hashtable size
  11. riscv: module: remove relocation_head rel_entry member allocation
  12. riscv: Use kvmalloc_array on relocation_hashtable

Test:

  • Built a minimal test module (pcrel_test.ko) that forces generation of
    an R_RISCV_32_PCREL relocation. Verified with readelf:

    $ riscv64-unknown-linux-gnu-readelf -r pcrel_test.ko | grep 32_PCREL
    000000000000 003600000039 R_RISCV_32_PCREL 0000000000000000 pcrel_target + 0

  • Loaded the module successfully on LicheePi 4A board.
    dmesg output:

$ sudo insmod ./pcrel_test.ko 
[sudo] password for openeuler: 
[  688.973056][ T1250] pcrel_test: loading out-of-tree module taints kernel.
[  688.979904][ T1250] pcrel_test: module verification failed: signature and/or required key missing - tainting kernel
[  688.991394][ T1250] R_RISCV_32_PCREL OK: value=0xffffdff8 expected=0xffffdff8

补充分析, 基于上游主线 master (by @unicornx):
解释为何要 backport 这些补丁,基本上是基于 “8fd6c5142395 riscv: Add remaining module relocations” 以及围绕它的后期的 fixes。

git log --oneline arch/riscv/kernel/module.c
189f164e573e Convert remaining multi-line kmalloc_obj/flex GFP_KERNEL uses
bf4afc53b77a Convert 'alloc_obj' family to use the new default GFP_KERNEL argument
69050f8d6d07 treewide: Replace kmalloc with kmalloc_obj for non-scalar types
0b4cce68efb9 riscv: module: Fix out-of-bounds relocation access
8578b2f7e1fb riscv: Use kvmalloc_array on relocation_hashtable         // backported by PR#344, Fixes: 8fd6c5142395 ("riscv: Add remaining module relocations")
03f0b548537f riscv: module: remove relocation_head rel_entry member    // backported by PR#344, Fixes: 8fd6c5142395 ("riscv: Add remaining module relocations")
3cc754c237e9 riscv: Use LIST_HEAD() to simplify code
0cc2dc4902f4 arch: make execmem setup available regardless of CONFIG_MODULES
4d7b321a9ce0 riscv: extend execmem_params for generated code allocations
f6bec26c0a73 mm/execmem, arch: convert simple overrides of module_alloc to execmem
080c4324fa5e riscv: optimize ELF relocation function in riscv
3a58275099b9 Merge patch series "riscv: modules: Fix module loading error handling"
a35551c7244d riscv: Fix relocation_hashtable size                      // backported by PR#344, Fixes: d8792a5734b0 ("riscv: Safely remove entries from relocation list")
4b38b36bfbd8 riscv: Correctly free relocation hashtable on error       // backported by PR#344, Fixes: d8792a5734b0 ("riscv: Safely remove entries from relocation list")
78996eee79eb riscv: Fix module loading free order                      // backported by PR#344, Fixes: d8792a5734b0 ("riscv: Safely remove entries from relocation list")
749b94b08005 riscv: Fix module_alloc() that did not reset the linear   // backported by 6.6.y as 8633e74002cd
4a92a87950c4 riscv: Correct type casting in module loading             // backported by PR#344, Fixes: 8fd6c5142395 ("riscv: Add remaining module relocations")
d8792a5734b0 riscv: Safely remove entries from relocation list         // backported by PR#344, Fixes: 8fd6c5142395 ("riscv: Add remaining module relocations")
28ea54bade76 RISC-V: Don't rely on positional structure initialization // backported by PR#344, Fixes: b51fc88cb35e ("Merge patch series "riscv: Add remaining module relocations and tests"")
8fd6c5142395 riscv: Add remaining module relocations				   // backported by PR#344, 这个是解决问题的主要补丁
8cbe0accc4a6 riscv: Avoid unaligned access when relocating modules     // backported by PR#344
1bc400ffb52b riscv: module: Add ADD16 and SUB16 rela types             // 6.6 包含的补丁到这里为止
......

xmzzz and others added 12 commits July 15, 2026 01:20
community inclusion
category: revert
bugzilla: RVCK-Project#310

-------------------------------------------------

This reverts commit 56d768f.

The relevant optimization is implemented in the upstream Linux kernel in
commit 080c432 (“riscv: optimize ELF relocation function in riscv”).
Before performing a backport, revert this vendor patch.

Signed-off-by: Mingzheng Xing <xingmingzheng@iscas.ac.cn>
mainline inclusion
from mainline-v6.7
commit 8cbe0ac
category: bugfix
bugzilla: RVCK-Project#310

--------------------------------

With the C-extension regular 32bit instructions are not
necessarily aligned on 4-byte boundaries. RISC-V instructions
are in fact an ordered list of 16bit little-endian
"parcels", so access the instruction as such.

This should also make the code work in case someone builds
a big-endian RISC-V machine.

Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
Signed-off-by: Charlie Jenkins <charlie@rivosinc.com>
Link: https://lore.kernel.org/r/20231101-module_relocations-v9-1-8dfa3483c400@rivosinc.com
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
Signed-off-by: Mingzheng Xing <xingmingzheng@iscas.ac.cn>
mainline inclusion
from mainline-v6.7
commit 8fd6c51
category: bugfix
bugzilla: RVCK-Project#310

--------------------------------

Add all final module relocations and add error logs explaining the ones
that are not supported. Implement overflow checks for
ADD/SUB/SET/ULEB128 relocations.

Signed-off-by: Charlie Jenkins <charlie@rivosinc.com>
Link: https://lore.kernel.org/r/20231101-module_relocations-v9-2-8dfa3483c400@rivosinc.com
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
Signed-off-by: Mingzheng Xing <xingmingzheng@iscas.ac.cn>
mainline inclusion
from mainline-v6.7
commit 28ea54b
category: bugfix
bugzilla: RVCK-Project#310

--------------------------------

Without this I get a bunch of warnings along the lines of

    arch/riscv/kernel/module.c:535:26: error: positional initialization of field in 'struct' declared with 'designated_init' attribute [-Werror=designated-init]
      535 |         [R_RISCV_32] = { apply_r_riscv_32_rela },

This just mades the member initializers explicit instead of positional.
I also aligned some of the table, but mostly just to make the batch
editing go faster.

Fixes: b51fc88 ("Merge patch series "riscv: Add remaining module relocations and tests"")
Reviewed-by: Charlie Jenkins <charlie@rivosinc.com>
Link: https://lore.kernel.org/r/20231107155529.8368-1-palmer@rivosinc.com
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
Signed-off-by: Mingzheng Xing <xingmingzheng@iscas.ac.cn>
mainline inclusion
from mainline-v6.7
commit d8792a5
category: bugfix
bugzilla: RVCK-Project#310

--------------------------------

Use the safe versions of list and hlist iteration to safely remove
entries from the module relocation lists. To allow mutliple threads to
load modules concurrently, move relocation list pointers onto the stack
rather than using global variables.

Fixes: 8fd6c51 ("riscv: Add remaining module relocations")
Reported-by: Ron Economos <re@w6rz.net>
Closes: https://lore.kernel.org/linux-riscv/444de86a-7e7c-4de7-5d1d-c1c40eefa4ba@w6rz.net
Signed-off-by: Charlie Jenkins <charlie@rivosinc.com>
Tested-by: Björn Töpel <bjorn@rivosinc.com>
Link: https://lore.kernel.org/r/20231127-module_linking_freeing-v4-1-a2ca1d7027d0@rivosinc.com
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
Signed-off-by: Mingzheng Xing <xingmingzheng@iscas.ac.cn>
mainline inclusion
from mainline-v6.7
commit 4a92a87
category: bugfix
bugzilla: RVCK-Project#310

--------------------------------

Use __le16 with le16_to_cpu.

Fixes: 8fd6c51 ("riscv: Add remaining module relocations")
Signed-off-by: Charlie Jenkins <charlie@rivosinc.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
Tested-by: Samuel Holland <samuel.holland@sifive.com>
Tested-by: Björn Töpel <bjorn@rivosinc.com>
Link: https://lore.kernel.org/r/20231127-module_linking_freeing-v4-2-a2ca1d7027d0@rivosinc.com
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
Signed-off-by: Mingzheng Xing <xingmingzheng@iscas.ac.cn>
mainline inclusion
from mainline-v6.15
commit 1ee1313
category: bugfix
bugzilla: RVCK-Project#310

--------------------------------

apply_r_riscv_plt32_rela() may need to emit a PLT entry for the
referenced symbol, so there must be space allocated in the PLT.

Fixes: 8fd6c51 ("riscv: Add remaining module relocations")
Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Link: https://lore.kernel.org/r/20250409171526.862481-2-samuel.holland@sifive.com
Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Signed-off-by: Mingzheng Xing <xingmingzheng@iscas.ac.cn>
mainline inclusion
from mainline-v6.8
commit 78996ee
category: bugfix
bugzilla: RVCK-Project#310

--------------------------------

Reverse order of kfree calls to resolve use-after-free error.

Signed-off-by: Charlie Jenkins <charlie@rivosinc.com>
Fixes: d8792a5 ("riscv: Safely remove entries from relocation list")
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Dan Carpenter <error27@gmail.com>
Closes: https://lore.kernel.org/r/202312132019.iYGTwW0L-lkp@intel.com/
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Julia Lawall <julia.lawall@inria.fr>
Closes: https://lore.kernel.org/r/202312120044.wTI1Uyaa-lkp@intel.com/
Reviewed-by: Dan Carpenter <dan.carpenter@linaro.org>
Link: https://lore.kernel.org/r/20240104-module_loading_fix-v3-1-a71f8de6ce0f@rivosinc.com
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
Signed-off-by: Mingzheng Xing <xingmingzheng@iscas.ac.cn>
mainline inclusion
from mainline-v6.8
commit 4b38b36
category: bugfix
bugzilla: RVCK-Project#310

--------------------------------

When there is not enough allocatable memory for the relocation
hashtable, module loading should exit gracefully. Previously, this was
attempted to be accomplished by checking if an unsigned number is less
than zero which does not work. Instead have the caller check if the
hashtable was correctly allocated and add a comment explaining that
hashtable_bits that is 0 is valid.

Signed-off-by: Charlie Jenkins <charlie@rivosinc.com>
Fixes: d8792a5 ("riscv: Safely remove entries from relocation list")
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
Closes: https://lore.kernel.org/r/202312132019.iYGTwW0L-lkp@intel.com/
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Julia Lawall <julia.lawall@inria.fr>
Closes: https://lore.kernel.org/r/202312120044.wTI1Uyaa-lkp@intel.com/
Reviewed-by: Dan Carpenter <dan.carpenter@linaro.org>
Link: https://lore.kernel.org/r/20240104-module_loading_fix-v3-2-a71f8de6ce0f@rivosinc.com
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
Signed-off-by: Mingzheng Xing <xingmingzheng@iscas.ac.cn>
mainline inclusion
from mainline-v6.8
commit a35551c
category: bugfix
bugzilla: RVCK-Project#310

--------------------------------

A second dereference is needed to get the accurate size of the
relocation_hashtable.

Signed-off-by: Charlie Jenkins <charlie@rivosinc.com>
Fixes: d8792a5 ("riscv: Safely remove entries from relocation list")
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Julia Lawall <julia.lawall@inria.fr>
Closes: https://lore.kernel.org/r/202312120044.wTI1Uyaa-lkp@intel.com/
Reviewed-by: Dan Carpenter <dan.carpenter@linaro.org>
Link: https://lore.kernel.org/r/20240104-module_loading_fix-v3-3-a71f8de6ce0f@rivosinc.com
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
Signed-off-by: Mingzheng Xing <xingmingzheng@iscas.ac.cn>
mainline inclusion
from mainline-v6.13
commit 03f0b54
category: bugfix
bugzilla: RVCK-Project#310

--------------------------------

relocation_head's list_head member, rel_entry, doesn't need to be
allocated, its storage can just be part of the allocated relocation_head.
Remove the pointer which allows to get rid of the allocation as well as
an existing memory leak found by Kai Zhang using kmemleak.

Fixes: 8fd6c51 ("riscv: Add remaining module relocations")
Reported-by: Kai Zhang <zhangkai@iscas.ac.cn>
Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Charlie Jenkins <charlie@rivosinc.com>
Tested-by: Charlie Jenkins <charlie@rivosinc.com>
Link: https://lore.kernel.org/r/20241128081636.3620468-1-cleger@rivosinc.com
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
Signed-off-by: Mingzheng Xing <xingmingzheng@iscas.ac.cn>
mainline inclusion
from mainline-v6.15
commit 8578b2f
category: bugfix
bugzilla: RVCK-Project#310

--------------------------------

The number of relocations may be a huge value that is unallocatable
by kmalloc. Use kvmalloc instead so that it does not fail.

Fixes: 8fd6c51 ("riscv: Add remaining module relocations")
Suggested-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Signed-off-by: Will Pierce <wgpierce17@gmail.com>
Link: https://lore.kernel.org/r/20250402081426.5197-1-wgpierce17@gmail.com
Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Signed-off-by: Mingzheng Xing <xingmingzheng@iscas.ac.cn>
@github-actions

github-actions Bot commented Jul 14, 2026

Copy link
Copy Markdown

开始测试 log: https://github.com/RVCK-Project/rvck/actions/runs/29353724774

参数解析结果
args value
repository RVCK-Project/rvck
head ref pull/334/head
base ref rvck-6.6
LAVA repo RVCK-Project/lavaci
LAVA hardware ['qemu']
LAVA Testcase path lava-testcases/common-test/ltp/ltp.yaml
need run job kunit-test,kernel-build,check-patch,lava-trigger

测试完成

详细结果:
check result
kunit-test success
kernel-build success
check-patch success
lava-trigger-qemu success
lava-trigger-sg2042 skipped
lava-trigger-k1 skipped
lava-trigger-lpi4a skipped

Kunit Test Result

[17:30:17] Testing complete. Ran 482 tests: passed: 465, skipped: 17

Kernel Build Result

Check Patch Result

Total Errors 0
Total Warnings 23

LAVA Check (qemu)

args value
testcase_repo RVCK-Project/lavaci
lava_template lava-job-template/qemu/qemu-ltp.yaml
testcase_path lava-testcases/common-test/ltp/ltp.yaml
kernel_download_url http://10.30.190.110/openEuler-RISC-V/RVCK/OERV-RVCI/RVCK-Project/rvck/334_29353724774_1/Image
initramfs_download_url http://10.30.190.110/openEuler-RISC-V/RVCK/OERV-RVCI/RVCK-Project/rvck/334_29353724774_1/initramfs.img
rootfs_download_url https://fast-mirror.isrc.ac.cn/openeuler-sig-riscv/openEuler-RISC-V/RVCK/openEuler24.03-LTS-SP1/openeuler-rootfs.img.zst
testcase_ref main
testitem_name RVCK-Project_rvck_pull_request_target_334__common-test_qemu

result: Lava check done!

@unicornx

unicornx commented Jul 15, 2026

Copy link
Copy Markdown

@xmzzz

Test:

  • Built a minimal test module (pcrel_test.ko) that forces generation of
    an R_RISCV_32_PCREL relocation. Verified with readelf:

请问如何制作出这种 ko?对工具链和编译选项有何要求,我这里想试一下。

$ riscv64-unknown-linux-gnu-readelf -r pcrel_test.ko | grep 32_PCREL
000000000000 003600000039 R_RISCV_32_PCREL 0000000000000000 pcrel_target + 0

  • Loaded the module successfully on LicheePi 4A board.

这个问题和硬件应该没有关系吧,我想基于 QEMU 测试一下,ok?

dmesg output:

$ sudo insmod ./pcrel_test.ko 
[sudo] password for openeuler: 
[  688.973056][ T1250] pcrel_test: loading out-of-tree module taints kernel.
[  688.979904][ T1250] pcrel_test: module verification failed: signature and/or required key missing - tainting kernel
[  688.991394][ T1250] R_RISCV_32_PCREL OK: value=0xffffdff8 expected=0xffffdff8

fix: #310

@xmzzz

xmzzz commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator Author

我在下面贴一下测试模块源码,包括C代码和汇编

测试模块通过汇编伪指令 .reloc 强制生成一个 type=57 的重定位项,所以理论上不依赖
高版本工具链,只要 assembler 能识别 R_RISCV_32_PCREL(若不能试试用数字 57 代替)。

编译方式和普通内核模块一致:

make KDIR=<kernel_build> ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu-

与硬件无关,qemu理论上可以测,因为是内核模块加载器对 ELF relocation 的处理逻辑。
(测试时如果遇到 module_layout 版本校验失败的问题,试下编译内核时关闭 CONFIG_MODVERSIONS)

~/test-module/pcrel_test_main.c

/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Minimal kernel module to verify R_RISCV_32_PCREL relocation handling.
 */

#include <linux/module.h>
#include <linux/kernel.h>

extern u32 pcrel_value;
extern void pcrel_target(void);

static int __init pcrel_init(void)
{
        u32 expected = (u32)((unsigned long)&pcrel_target -
                             (unsigned long)&pcrel_value);

        if (pcrel_value == expected)
                pr_info("R_RISCV_32_PCREL OK: value=0x%08x expected=0x%08x\n",
                        pcrel_value, expected);
        else
                pr_err("R_RISCV_32_PCREL FAIL: value=0x%08x expected=0x%08x\n",
                        pcrel_value, expected);

        return 0;
}

static void __exit pcrel_exit(void)
{
        pr_info("pcrel_test unloaded\n");
}

module_init(pcrel_init);
module_exit(pcrel_exit);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Test R_RISCV_32_PCREL relocation");

~/test-module/pcrel_test_asm.S

/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Force generation of an R_RISCV_32_PCREL relocation.
 *
 * R_RISCV_32_PCREL (type 57) is used by newer binutils (>= 2.42) for
 * 32-bit PC-relative data references.
 */

.section .data
.align 2
.globl pcrel_value
pcrel_value:
        .reloc pcrel_value, R_RISCV_32_PCREL, pcrel_target
        .long 0

.section .text
.globl pcrel_target
pcrel_target:
        ret

@unicornx

unicornx commented Jul 22, 2026

Copy link
Copy Markdown

Tested-by: Chen Wang wangchen20@iscas.ac.cn

Test with

Without this Patchset:

[u@localhost ~]$ sudo insmod ./test_pcrel.ko 
[sudo] password for u: 
[  135.174302] test_pcrel: loading out-of-tree module taints kernel.
[  135.174718] test_pcrel: module verification failed: signature and/or required key missing - tainting kernel
[  135.175147] test_pcrel: Unknown relocation type 57
insmod: ERROR: could not insert module ./test_pcrel.ko: Invalid parameters

Applied this patchset:

[u@localhost ~]$ sudo insmod ./test_pcrel.ko 
[sudo] password for u: 
[   89.766152] test_pcrel: loading out-of-tree module taints kernel.
[   89.766656] test_pcrel: module verification failed: signature and/or required key missing - tainting kernel
[   89.779364] R_RISCV_32_PCREL OK: value=0xffffdff8 expected=0xffffdff8

The test module source:
test_pcrel.tar.gz

@unicornx
unicornx self-requested a review July 22, 2026 08:28
@unicornx unicornx changed the title riscv: Add remaining module relocations Fix module load issue for R_RISCV_32_PCREL Jul 22, 2026
@unicornx

Copy link
Copy Markdown

针对 ”Revert "riscv: kernel: Optimize apply_relocate_add()"“ 这笔提交有个疑问:回退这个补丁会不会有什么副作用?当初加算能的这个补丁的改动已经被这次 pr 覆盖了吗?

@liuhj2023

Copy link
Copy Markdown

针对 ”Revert "riscv: kernel: Optimize apply_relocate_add()"“ 这笔提交有个疑问:回退这个补丁会不会有什么副作用?当初加算能的这个补丁的改动已经被这次 pr 覆盖了吗?

汪老师,riscv: kernel: Optimize apply_relocate_add() 这笔patch是我司同事为了加速模块加载所做的一次优化,回退不影响功能。

@unicornx unicornx left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Reviewed-by: Chen Wang wangchen20@iscas.ac.cn
Tested-by: Chen Wang wangchen20@iscas.ac.cn

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Port "riscv: Add remaining module relocations"

9 participants