Skip to content

Commit 8652d44

Browse files
ribaldaakpm00
authored andcommitted
kexec: support purgatories with .text.hot sections
Patch series "kexec: Fix kexec_file_load for llvm16 with PGO", v7. When upreving llvm I realised that kexec stopped working on my test platform. The reason seems to be that due to PGO there are multiple .text sections on the purgatory, and kexec does not supports that. This patch (of 4): Clang16 links the purgatory text in two sections when PGO is in use: [ 1] .text PROGBITS 0000000000000000 00000040 00000000000011a1 0000000000000000 AX 0 0 16 [ 2] .rela.text RELA 0000000000000000 00003498 0000000000000648 0000000000000018 I 24 1 8 ... [17] .text.hot. PROGBITS 0000000000000000 00003220 000000000000020b 0000000000000000 AX 0 0 1 [18] .rela.text.hot. RELA 0000000000000000 00004428 0000000000000078 0000000000000018 I 24 17 8 And both of them have their range [sh_addr ... sh_addr+sh_size] on the area pointed by `e_entry`. This causes that image->start is calculated twice, once for .text and another time for .text.hot. The second calculation leaves image->start in a random location. Because of this, the system crashes immediately after: kexec_core: Starting new kernel Link: https://lkml.kernel.org/r/[email protected] Link: https://lkml.kernel.org/r/[email protected] Fixes: 9304570 ("kernel/kexec_file.c: split up __kexec_load_puragory") Signed-off-by: Ricardo Ribalda <[email protected]> Reviewed-by: Ross Zwisler <[email protected]> Reviewed-by: Steven Rostedt (Google) <[email protected]> Reviewed-by: Philipp Rudo <[email protected]> Cc: Albert Ou <[email protected]> Cc: Baoquan He <[email protected]> Cc: Borislav Petkov (AMD) <[email protected]> Cc: Christophe Leroy <[email protected]> Cc: Dave Hansen <[email protected]> Cc: Dave Young <[email protected]> Cc: Eric W. Biederman <[email protected]> Cc: "H. Peter Anvin" <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Michael Ellerman <[email protected]> Cc: Nathan Chancellor <[email protected]> Cc: Nicholas Piggin <[email protected]> Cc: Nick Desaulniers <[email protected]> Cc: Palmer Dabbelt <[email protected]> Cc: Palmer Dabbelt <[email protected]> Cc: Paul Walmsley <[email protected]> Cc: Simon Horman <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Tom Rix <[email protected]> Cc: <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 5543d3c commit 8652d44

File tree

1 file changed

+13
-1
lines changed

1 file changed

+13
-1
lines changed

kernel/kexec_file.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -901,10 +901,22 @@ static int kexec_purgatory_setup_sechdrs(struct purgatory_info *pi,
901901
}
902902

903903
offset = ALIGN(offset, align);
904+
905+
/*
906+
* Check if the segment contains the entry point, if so,
907+
* calculate the value of image->start based on it.
908+
* If the compiler has produced more than one .text section
909+
* (Eg: .text.hot), they are generally after the main .text
910+
* section, and they shall not be used to calculate
911+
* image->start. So do not re-calculate image->start if it
912+
* is not set to the initial value, and warn the user so they
913+
* have a chance to fix their purgatory's linker script.
914+
*/
904915
if (sechdrs[i].sh_flags & SHF_EXECINSTR &&
905916
pi->ehdr->e_entry >= sechdrs[i].sh_addr &&
906917
pi->ehdr->e_entry < (sechdrs[i].sh_addr
907-
+ sechdrs[i].sh_size)) {
918+
+ sechdrs[i].sh_size) &&
919+
!WARN_ON(kbuf->image->start != pi->ehdr->e_entry)) {
908920
kbuf->image->start -= sechdrs[i].sh_addr;
909921
kbuf->image->start += kbuf->mem + offset;
910922
}

0 commit comments

Comments
 (0)