From: "huangjie.albert" <huangjie.albert@xxxxxxxxxxxxx> 1、if kernel is uncompressed. we do not need to relocate kernel image for decompression 2、if kaslr is disabled, we do not need to do a memory copy before prase_elf. Two memory copies can be skipped with this patch. this can save aboat 20ms during booting. Signed-off-by: huangjie.albert <huangjie.albert@xxxxxxxxxxxxx> --- arch/x86/boot/compressed/head_64.S | 8 ++++++-- arch/x86/boot/compressed/misc.c | 22 +++++++++++++++++----- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S index d33f060900d2..9e7770c7047b 100644 --- a/arch/x86/boot/compressed/head_64.S +++ b/arch/x86/boot/compressed/head_64.S @@ -398,10 +398,13 @@ SYM_CODE_START(startup_64) 1: /* Target address to relocate to for decompression */ +#ifdef CONFIG_KERNEL_UNCOMPRESSED + movq %rbp, %rbx +#else movl BP_init_size(%rsi), %ebx subl $ rva(_end), %ebx addq %rbp, %rbx - +#endif /* Set up the stack */ leaq rva(boot_stack_end)(%rbx), %rsp @@ -522,6 +525,7 @@ trampoline_return: * Copy the compressed kernel to the end of our buffer * where decompression in place becomes safe. */ +#ifndef CONFIG_KERNEL_UNCOMPRESSED pushq %rsi leaq (_bss-8)(%rip), %rsi leaq rva(_bss-8)(%rbx), %rdi @@ -531,7 +535,7 @@ trampoline_return: rep movsq cld popq %rsi - +#endif /* * The GDT may get overwritten either during the copy we just did or * during extract_kernel below. To avoid any issues, repoint the GDTR diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c index c23c0f525d93..d8445562d4e9 100644 --- a/arch/x86/boot/compressed/misc.c +++ b/arch/x86/boot/compressed/misc.c @@ -290,7 +290,7 @@ static inline void handle_relocations(void *output, unsigned long output_len, { } #endif -static void parse_elf(void *output) +static void parse_elf(void *output, void *input) { #ifdef CONFIG_X86_64 Elf64_Ehdr ehdr; @@ -302,7 +302,7 @@ static void parse_elf(void *output) void *dest; int i; - memcpy(&ehdr, output, sizeof(ehdr)); + memcpy(&ehdr, input, sizeof(ehdr)); if (ehdr.e_ident[EI_MAG0] != ELFMAG0 || ehdr.e_ident[EI_MAG1] != ELFMAG1 || ehdr.e_ident[EI_MAG2] != ELFMAG2 || @@ -317,7 +317,7 @@ static void parse_elf(void *output) if (!phdrs) error("Failed to allocate space for phdrs"); - memcpy(phdrs, output + ehdr.e_phoff, sizeof(*phdrs) * ehdr.e_phnum); + memcpy(phdrs, input + ehdr.e_phoff, sizeof(*phdrs) * ehdr.e_phnum); for (i = 0; i < ehdr.e_phnum; i++) { phdr = &phdrs[i]; @@ -334,7 +334,7 @@ static void parse_elf(void *output) #else dest = (void *)(phdr->p_paddr); #endif - memmove(dest, output + phdr->p_offset, phdr->p_filesz); + memmove(dest, input + phdr->p_offset, phdr->p_filesz); break; default: /* Ignore other PT_* */ break; } @@ -467,9 +467,21 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap, #endif debug_putstr("\nDecompressing Linux... "); + +#ifdef CONFIG_KERNEL_UNCOMPRESSED + if (cmdline_find_option_bool("nokaslr")) { + parse_elf(output, input_data); + } else { + __decompress(input_data, input_len, NULL, NULL, output, output_len, + NULL, error); + parse_elf(output, output); + } +#else __decompress(input_data, input_len, NULL, NULL, output, output_len, NULL, error); - parse_elf(output); + parse_elf(output, output); +#endif + handle_relocations(output, output_len, virt_addr); debug_putstr("done.\nBooting the kernel.\n"); -- 2.31.1 _______________________________________________ kexec mailing list kexec@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/kexec