From: "huangjie.albert" <[email protected]>

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 <[email protected]>
---
 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
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

Reply via email to