From: chenmiao chenmiao.ku@gmail.com
[ Upstream commit 9d0cb6d00be891586261a35da7f8c3c956825c39 ]
To ensure the proper functioning of the jump_label test module, this patch adds support for the R_OR1K_32_PCREL relocation type for any modules. The implementation calculates the PC-relative offset by subtracting the instruction location from the target value and stores the result at the specified location.
Signed-off-by: chenmiao chenmiao.ku@gmail.com Signed-off-by: Stafford Horne shorne@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
YES
- What it fixes - Adds missing relocation handling for OpenRISC modules: `R_OR1K_32_PCREL` now computes a proper PC-relative value, enabling modules that use this relocation (e.g., the jump_label test module) to load and run correctly. - Before this change, such relocations fell into the default case and were left un-applied while only logging an error, which risks loading a broken module without failing the load explicitly (see `arch/openrisc/kernel/module.c:72` and the unconditional `return 0` at `arch/openrisc/kernel/module.c:79`).
- Change details - New case computes S + A − P for 32-bit PC-relative relocations and writes the result directly: - `arch/openrisc/kernel/module.c:58`: `case R_OR1K_32_PCREL:` - `arch/openrisc/kernel/module.c:59`: `value -= (uint32_t)location;` - `arch/openrisc/kernel/module.c:60`: `*location = value;` - This mirrors established semantics for 32-bit PC-relative relocations, consistent with other architectures’ module loaders (e.g., `arch/hexagon/kernel/module.c:132` uses `*location = value - (uint32_t)location;`). - It fits alongside existing relocation handling already present for OpenRISC: - Absolute 32-bit relocations written directly (`arch/openrisc/kernel/module.c:42`). - Branch-style PC-relative relocations (`R_OR1K_INSN_REL_26`) that subtract P, then encode into a 26-bit field (`arch/openrisc/kernel/module.c:51`–`56`). - Other recently added relocations such as `R_OR1K_AHI16` and `R_OR1K_SLO16` (`arch/openrisc/kernel/module.c:62`–`71`).
- Impact and scope - The change is small and contained to a single switch case in the OpenRISC module loader (`arch/openrisc/kernel/module.c`). - It only affects module relocation handling, which is invoked during module loading via the generic path in `kernel/module/main.c:1617` (SHT_RELA → `apply_relocate_add`). - No API or architectural changes; no effect on other subsystems or architectures.
- Risk assessment - Very low risk: - The operation is a straightforward, canonical PC-relative computation (S + A − P). - It aligns with existing patterns for other architectures and with OpenRISC’s own existing PC-relative branch relocation handling. - High user value for OpenRISC users: - Fixes module load-time correctness for modules emitting `R_OR1K_32_PCREL`, including the jump_label test module.
- Backport considerations - Suitable for stable: it’s a clear bug fix, minimal, and architecture-local. - If older stable trees predate `R_OR1K_*` relocation renaming, the backport may need to map to the legacy names; otherwise the change is mechanically the addition of this single case.
Conclusion: This is a small, targeted, correctness fix to the OpenRISC module loader that prevents silently broken module loads and aligns with standard relocation semantics. It should be backported.
arch/openrisc/kernel/module.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/arch/openrisc/kernel/module.c b/arch/openrisc/kernel/module.c index c9ff4c4a0b29b..4ac4fbaa827c1 100644 --- a/arch/openrisc/kernel/module.c +++ b/arch/openrisc/kernel/module.c @@ -55,6 +55,10 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, value |= *location & 0xfc000000; *location = value; break; + case R_OR1K_32_PCREL: + value -= (uint32_t)location; + *location = value; + break; case R_OR1K_AHI16: /* Adjust the operand to match with a signed LO16. */ value += 0x8000;