2023-07-25 09:07:08

by Petr Tesarik

[permalink] [raw]
Subject: [PATCH v1 0/3] RISC-V: Fix a few kexec_file_load(2) failures

From: Petr Tesarik <[email protected]>

The kexec_file_load(2) syscall does not work at least in some kernel
builds. For details see the relevant section in this blog post:

https://sigillatum.tesarici.cz/2023-07-21-state-of-riscv64-kdump.html

This patch series handles additional relocation types and removes the need
to implement a Global Offset Table (GOT) for the purgatory.

Petr Tesarik (2):
riscv/kexec: handle R_RISCV_ADD16 and R_RISCV_SUB16 relocation types
riscv/purgatory: do not link with string.o

Torsten Duwe (1):
riscv/kexec: handle R_RISCV_CALL_PLT relocation type

arch/riscv/kernel/elf_kexec.c | 7 +++++++
arch/riscv/purgatory/Makefile | 9 +--------
2 files changed, 8 insertions(+), 8 deletions(-)

--
2.25.1



2023-07-25 09:17:48

by Petr Tesarik

[permalink] [raw]
Subject: [PATCH v1 1/3] riscv/kexec: handle R_RISCV_CALL_PLT relocation type

From: Torsten Duwe <[email protected]>

R_RISCV_CALL has been deprecated and replaced by R_RISCV_CALL_PLT. See Enum
18-19 in Table 3. Relocation types here:

https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc

It was deprecated in ("Deprecated R_RISCV_CALL, prefer R_RISCV_CALL_PLT"):

https://github.com/riscv-non-isa/riscv-elf-psabi-doc/commit/a0dced85018d7a0ec17023c9389cbd70b1dbc1b0

Recent tools (at least GNU binutils-2.40) already use R_RISCV_CALL_PLT.
Kernels built with such binutils fail kexec_load_file(2) with:

kexec_image: Unknown rela relocation: 19
kexec_image: Error loading purgatory ret=-8

The binary code at the call site remains the same, so tell
arch_kexec_apply_relocations_add() to handle _PLT alike.

Fixes: 838b3e28488f ("RISC-V: Load purgatory in kexec_file")
Signed-off-by: Torsten Duwe <[email protected]>
Signed-off-by: Petr Tesarik <[email protected]>
Cc: Li Zhengyu <[email protected]>
Cc: [email protected]
---
arch/riscv/kernel/elf_kexec.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/arch/riscv/kernel/elf_kexec.c b/arch/riscv/kernel/elf_kexec.c
index 5372b708fae2..38390d3bdcac 100644
--- a/arch/riscv/kernel/elf_kexec.c
+++ b/arch/riscv/kernel/elf_kexec.c
@@ -425,6 +425,7 @@ int arch_kexec_apply_relocations_add(struct purgatory_info *pi,
* sym, instead of searching the whole relsec.
*/
case R_RISCV_PCREL_HI20:
+ case R_RISCV_CALL_PLT:
case R_RISCV_CALL:
*(u64 *)loc = CLEAN_IMM(UITYPE, *(u64 *)loc) |
ENCODE_UJTYPE_IMM(val - addr);
--
2.25.1


2023-07-25 09:26:04

by Petr Tesarik

[permalink] [raw]
Subject: [PATCH v1 3/3] riscv/purgatory: do not link with string.o

From: Petr Tesarik <[email protected]>

Linking with this object file it makes kexec_file_load(2) fail with:

kexec_image: Unknown rela relocation: 20
kexec_image: Error loading purgatory ret=-8

This is R_RISCV_GOT_HI20, generated by the linker to handle references to
the global variable _ctype from strcasecmp() and strncasecmp().

Rather than implementing GOT for the purgatory, remove the object file,
because it is not needed by the purgatory code.

Fixes: 838b3e28488f ("RISC-V: Load purgatory in kexec_file")
Signed-off-by: Petr Tesarik <[email protected]>
Cc: Li Zhengyu <[email protected]>
Cc: [email protected]
---
arch/riscv/purgatory/Makefile | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/arch/riscv/purgatory/Makefile b/arch/riscv/purgatory/Makefile
index dc20e166983e..497bb72b6ba8 100644
--- a/arch/riscv/purgatory/Makefile
+++ b/arch/riscv/purgatory/Makefile
@@ -1,15 +1,12 @@
# SPDX-License-Identifier: GPL-2.0
OBJECT_FILES_NON_STANDARD := y

-purgatory-y := purgatory.o sha256.o entry.o string.o ctype.o memcpy.o memset.o
+purgatory-y := purgatory.o sha256.o entry.o ctype.o memcpy.o memset.o
purgatory-y += strcmp.o strlen.o strncmp.o

targets += $(purgatory-y)
PURGATORY_OBJS = $(addprefix $(obj)/,$(purgatory-y))

-$(obj)/string.o: $(srctree)/lib/string.c FORCE
- $(call if_changed_rule,cc_o_c)
-
$(obj)/ctype.o: $(srctree)/lib/ctype.c FORCE
$(call if_changed_rule,cc_o_c)

@@ -32,7 +29,6 @@ $(obj)/sha256.o: $(srctree)/lib/crypto/sha256.c FORCE
$(call if_changed_rule,cc_o_c)

CFLAGS_sha256.o := -D__DISABLE_EXPORTS -D__NO_FORTIFY
-CFLAGS_string.o := -D__DISABLE_EXPORTS
CFLAGS_ctype.o := -D__DISABLE_EXPORTS

# When profile-guided optimization is enabled, llvm emits two different
@@ -83,9 +79,6 @@ CFLAGS_purgatory.o += $(PURGATORY_CFLAGS)
CFLAGS_REMOVE_sha256.o += $(PURGATORY_CFLAGS_REMOVE)
CFLAGS_sha256.o += $(PURGATORY_CFLAGS)

-CFLAGS_REMOVE_string.o += $(PURGATORY_CFLAGS_REMOVE)
-CFLAGS_string.o += $(PURGATORY_CFLAGS)
-
CFLAGS_REMOVE_ctype.o += $(PURGATORY_CFLAGS_REMOVE)
CFLAGS_ctype.o += $(PURGATORY_CFLAGS)

--
2.25.1


2023-07-25 10:52:02

by Petr Tesařík

[permalink] [raw]
Subject: Re: [PATCH v1 1/3] riscv/kexec: handle R_RISCV_CALL_PLT relocation type

+Cc Torsten (somehow missed from the original Cc list).

Petr T

On Tue, 25 Jul 2023 10:44:25 +0200
Petr Tesarik <[email protected]> wrote:

> From: Torsten Duwe <[email protected]>
>
> R_RISCV_CALL has been deprecated and replaced by R_RISCV_CALL_PLT. See Enum
> 18-19 in Table 3. Relocation types here:
>
> https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc
>
> It was deprecated in ("Deprecated R_RISCV_CALL, prefer R_RISCV_CALL_PLT"):
>
> https://github.com/riscv-non-isa/riscv-elf-psabi-doc/commit/a0dced85018d7a0ec17023c9389cbd70b1dbc1b0
>
> Recent tools (at least GNU binutils-2.40) already use R_RISCV_CALL_PLT.
> Kernels built with such binutils fail kexec_load_file(2) with:
>
> kexec_image: Unknown rela relocation: 19
> kexec_image: Error loading purgatory ret=-8
>
> The binary code at the call site remains the same, so tell
> arch_kexec_apply_relocations_add() to handle _PLT alike.
>
> Fixes: 838b3e28488f ("RISC-V: Load purgatory in kexec_file")
> Signed-off-by: Torsten Duwe <[email protected]>
> Signed-off-by: Petr Tesarik <[email protected]>
> Cc: Li Zhengyu <[email protected]>
> Cc: [email protected]
> ---
> arch/riscv/kernel/elf_kexec.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/arch/riscv/kernel/elf_kexec.c b/arch/riscv/kernel/elf_kexec.c
> index 5372b708fae2..38390d3bdcac 100644
> --- a/arch/riscv/kernel/elf_kexec.c
> +++ b/arch/riscv/kernel/elf_kexec.c
> @@ -425,6 +425,7 @@ int arch_kexec_apply_relocations_add(struct purgatory_info *pi,
> * sym, instead of searching the whole relsec.
> */
> case R_RISCV_PCREL_HI20:
> + case R_RISCV_CALL_PLT:
> case R_RISCV_CALL:
> *(u64 *)loc = CLEAN_IMM(UITYPE, *(u64 *)loc) |
> ENCODE_UJTYPE_IMM(val - addr);


2023-07-25 19:50:23

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH v1 3/3] riscv/purgatory: do not link with string.o

Hi Petr,

kernel test robot noticed the following build errors:

[auto build test ERROR on kees/for-next/pstore]
[also build test ERROR on kees/for-next/kspp linus/master v6.5-rc3 next-20230725]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/Petr-Tesarik/riscv-kexec-handle-R_RISCV_CALL_PLT-relocation-type/20230725-165116
base: https://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/pstore
patch link: https://lore.kernel.org/r/a083f38c7c3acd6ac9542228e36947be30b58188.1690274483.git.petr.tesarik.ext%40huawei.com
patch subject: [PATCH v1 3/3] riscv/purgatory: do not link with string.o
config: riscv-randconfig-r001-20230725 (https://download.01.org/0day-ci/archive/20230726/[email protected]/config)
compiler: clang version 17.0.0 (https://github.com/llvm/llvm-project.git 4a5ac14ee968ff0ad5d2cc1ffa0299048db4c88a)
reproduce: (https://download.01.org/0day-ci/archive/20230726/[email protected]/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/

All errors (new ones prefixed by >>):

>> ld.lld: error: undefined symbol: memcmp
>>> referenced by ctype.c
>>> arch/riscv/purgatory/purgatory.ro:(purgatory)

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

2023-07-25 20:44:54

by Petr Tesařík

[permalink] [raw]
Subject: Re: [PATCH v1 3/3] riscv/purgatory: do not link with string.o

On Wed, 26 Jul 2023 03:36:39 +0800
kernel test robot <[email protected]> wrote:

> Hi Petr,
>
> kernel test robot noticed the following build errors:
>
> [auto build test ERROR on kees/for-next/pstore]
> [also build test ERROR on kees/for-next/kspp linus/master v6.5-rc3 next-20230725]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch#_base_tree_information]
>
> url: https://github.com/intel-lab-lkp/linux/commits/Petr-Tesarik/riscv-kexec-handle-R_RISCV_CALL_PLT-relocation-type/20230725-165116
> base: https://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/pstore
> patch link: https://lore.kernel.org/r/a083f38c7c3acd6ac9542228e36947be30b58188.1690274483.git.petr.tesarik.ext%40huawei.com
> patch subject: [PATCH v1 3/3] riscv/purgatory: do not link with string.o
> config: riscv-randconfig-r001-20230725 (https://download.01.org/0day-ci/archive/20230726/[email protected]/config)
> compiler: clang version 17.0.0 (https://github.com/llvm/llvm-project.git 4a5ac14ee968ff0ad5d2cc1ffa0299048db4c88a)
> reproduce: (https://download.01.org/0day-ci/archive/20230726/[email protected]/reproduce)
>
> If you fix the issue in a separate patch/commit (i.e. not just a new version of
> the same patch/commit), kindly add following tags
> | Reported-by: kernel test robot <[email protected]>
> | Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
>
> All errors (new ones prefixed by >>):
>
> >> ld.lld: error: undefined symbol: memcmp
> >>> referenced by ctype.c
> >>> arch/riscv/purgatory/purgatory.ro:(purgatory)

Ah, I see... In my build, it was inlined by gcc (GCC-13), but I cannot
rely on that. Too bad...

OTOH I don't think it's worth implementing full support for GOT,
especially for functions that are not needed. I would rather either
write a RISC-V implementation of memcmp(), or split memcmp() from
lib/string.c.

Stay tuned for v2.

Petr T