2023-07-26 11:03:32

by Petr Tesarik

[permalink] [raw]
Subject: [PATCH v2 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 an additional relocation types, removes the need
to implement a Global Offset Table (GOT) for the purgatory and fixes the
placement of initrd.

Changelog
=========

Changes from v1:
- Replace memcmp() with a for loop.
- Drop handling of 16-bit add/subtract relocations. They were used only
by alternatives in strcmp(), which was referenced only by string.o.
- Add the initrd placement fix.

Petr Tesarik (1):
riscv/purgatory: do not link with string.o and its dependencies

Torsten Duwe (2):
riscv/kexec: handle R_RISCV_CALL_PLT relocation type
riscv/kexec: load initrd high in available memory

arch/riscv/kernel/elf_kexec.c | 3 ++-
arch/riscv/purgatory/Makefile | 26 +-------------------------
arch/riscv/purgatory/purgatory.c | 6 ++++--
3 files changed, 7 insertions(+), 28 deletions(-)

--
2.25.1



2023-07-26 11:04:51

by Petr Tesarik

[permalink] [raw]
Subject: [PATCH v2 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-26 11:23:45

by Petr Tesarik

[permalink] [raw]
Subject: [PATCH v2 3/3] riscv/kexec: load initrd high in available memory

From: Torsten Duwe <[email protected]>

When initrd is loaded low, the secondary kernel fails like this:

INITRD: 0xdc581000+0x00eef000 overlaps in-use memory region

This initrd load address corresponds to the _end symbol, but the
reservation is aligned on PMD_SIZE, as explained by a comment in
setup_bootmem().

It is technically possible to align the initrd load address accordingly,
leaving a hole between the end of kernel and the initrd, but it is much
simpler to allocate the initrd top-down.

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

diff --git a/arch/riscv/kernel/elf_kexec.c b/arch/riscv/kernel/elf_kexec.c
index 38390d3bdcac..c08bb5c3b385 100644
--- a/arch/riscv/kernel/elf_kexec.c
+++ b/arch/riscv/kernel/elf_kexec.c
@@ -281,7 +281,7 @@ static void *elf_kexec_load(struct kimage *image, char *kernel_buf,
kbuf.buffer = initrd;
kbuf.bufsz = kbuf.memsz = initrd_len;
kbuf.buf_align = PAGE_SIZE;
- kbuf.top_down = false;
+ kbuf.top_down = true;
kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
ret = kexec_add_buffer(&kbuf);
if (ret)
--
2.25.1


2023-07-26 16:45:30

by Conor Dooley

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

On Wed, Jul 26, 2023 at 11:53:59AM +0200, Petr Tesarik 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

Ideally, these would be Link: tags, but that's certainly not worth a
respin. This looks fine to me,
Reviewed-by: Conor Dooley <[email protected]>

Thanks,
Conor.


Attachments:
(No filename) (683.00 B)
signature.asc (235.00 B)
Download all attachments

2023-07-26 16:59:06

by Conor Dooley

[permalink] [raw]
Subject: Re: [PATCH v2 3/3] riscv/kexec: load initrd high in available memory

On Wed, Jul 26, 2023 at 11:54:01AM +0200, Petr Tesarik wrote:
> From: Torsten Duwe <[email protected]>
>
> When initrd is loaded low, the secondary kernel fails like this:
>
> INITRD: 0xdc581000+0x00eef000 overlaps in-use memory region
>
> This initrd load address corresponds to the _end symbol, but the
> reservation is aligned on PMD_SIZE, as explained by a comment in
> setup_bootmem().
>
> It is technically possible to align the initrd load address accordingly,
> leaving a hole between the end of kernel and the initrd, but it is much
> simpler to allocate the initrd top-down.
>
> Fixes: 838b3e28488f ("RISC-V: Load purgatory in kexec_file")
> Signed-off-by: Torsten Duwe <[email protected]>
> Signed-off-by: Petr Tesarik <[email protected]>
> Cc: [email protected]

Trying to align it might be worthwhile, but the simple fix makes sense
for now & w.r.t backporting.

Reviewed-by: Conor Dooley <[email protected]>

Thanks,
Conor.


Attachments:
(No filename) (985.00 B)
signature.asc (235.00 B)
Download all attachments

2023-07-26 18:47:40

by Petr Tesarik

[permalink] [raw]
Subject: Re: [PATCH v2 3/3] riscv/kexec: load initrd high in available memory

On 7/26/2023 6:38 PM, Conor Dooley wrote:
> On Wed, Jul 26, 2023 at 11:54:01AM +0200, Petr Tesarik wrote:
>> From: Torsten Duwe <[email protected]>
>>
>> When initrd is loaded low, the secondary kernel fails like this:
>>
>> INITRD: 0xdc581000+0x00eef000 overlaps in-use memory region
>>
>> This initrd load address corresponds to the _end symbol, but the
>> reservation is aligned on PMD_SIZE, as explained by a comment in
>> setup_bootmem().
>>
>> It is technically possible to align the initrd load address accordingly,
>> leaving a hole between the end of kernel and the initrd, but it is much
>> simpler to allocate the initrd top-down.
>>
>> Fixes: 838b3e28488f ("RISC-V: Load purgatory in kexec_file")
>> Signed-off-by: Torsten Duwe <[email protected]>
>> Signed-off-by: Petr Tesarik <[email protected]>
>> Cc: [email protected]
>
> Trying to align it might be worthwhile, but the simple fix makes sense
> for now & w.r.t backporting.

On a second thought, allocating the initrd at the top of the range is
probably even better, because the kernel can unpack to low addresses,
resulting in less fragmented memory. See diagrams.

Top-down initrd:

+----------+ +----------+
| initrd | | |
+----------+ | free |
| | | |
| | unpack +----------+
| free | -----> | unpacked |
| | | initrd |
+----------+ +----------+
| kernel | | kernel |
+----------+ +----------+


Aligned initrd:

+----------+ +----------+
| | | free |
| | +----------|
| free | | unpacked |
| | | initrd |
+----------+ unpack +----------+
| initrd | -----> | free |
+----------+ +----------+
| kernel | | kernel |
+----------+ +----------+

Petr T


2023-08-01 10:11:51

by Petr Tesarik

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

Hi,

On 7/26/2023 11:53 AM, Petr Tesarik wrote:
> 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 an additional relocation types, removes the need
> to implement a Global Offset Table (GOT) for the purgatory and fixes the
> placement of initrd.

It seems there are no objections, but what is the plan here? Take it
into 6.5 as a fix, or let it go through for-next?

Petr T

> Changelog
> =========
>
> Changes from v1:
> - Replace memcmp() with a for loop.
> - Drop handling of 16-bit add/subtract relocations. They were used only
> by alternatives in strcmp(), which was referenced only by string.o.
> - Add the initrd placement fix.
>
> Petr Tesarik (1):
> riscv/purgatory: do not link with string.o and its dependencies
>
> Torsten Duwe (2):
> riscv/kexec: handle R_RISCV_CALL_PLT relocation type
> riscv/kexec: load initrd high in available memory
>
> arch/riscv/kernel/elf_kexec.c | 3 ++-
> arch/riscv/purgatory/Makefile | 26 +-------------------------
> arch/riscv/purgatory/purgatory.c | 6 ++++--
> 3 files changed, 7 insertions(+), 28 deletions(-)
>


Subject: Re: [PATCH v2 0/3] RISC-V: Fix a few kexec_file_load(2) failures

Hello:

This series was applied to riscv/linux.git (fixes)
by Palmer Dabbelt <[email protected]>:

On Wed, 26 Jul 2023 11:53:58 +0200 you wrote:
> 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
>
> [...]

Here is the summary with links:
- [v2,1/3] riscv/kexec: handle R_RISCV_CALL_PLT relocation type
https://git.kernel.org/riscv/c/1be0b05b3a80
- [v2,2/3] riscv/purgatory: do not link with string.o and its dependencies
(no matching commit)
- [v2,3/3] riscv/kexec: load initrd high in available memory
https://git.kernel.org/riscv/c/0ccd2e803745

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



2023-08-09 16:20:17

by Palmer Dabbelt

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


On Wed, 26 Jul 2023 11:53:58 +0200, Petr Tesarik wrote:
> 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
>
> [...]

Applied, thanks!

[1/3] riscv/kexec: handle R_RISCV_CALL_PLT relocation type
https://git.kernel.org/palmer/c/d0b4f95a5103
[3/3] riscv/kexec: load initrd high in available memory
https://git.kernel.org/palmer/c/49af7a2cd5f6

Best regards,
--
Palmer Dabbelt <[email protected]>