[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CABKxMyNcuHE4iEWLHdGZw-O4g8zaj9CvXWNQ7fqBkZV0mNWVfQ@mail.gmail.com>
Date: Mon, 25 Jul 2022 20:55:39 +0800
From: 黄杰 <huangjie.albert@...edance.com>
To: linux-kernel <linux-kernel@...r.kernel.org>
Subject: Fwd: [PATCH 4/4] x86: boot: avoid memory copy if kernel is uncompressed
---------- Forwarded message ---------
发件人: Albert Huang <huangjie.albert@...edance.com>
Date: 2022年7月25日周一 16:40
Subject: [PATCH 4/4] x86: boot: avoid memory copy if kernel is uncompressed
To:
Cc: huangjie.albert <huangjie.albert@...edance.com>, Thomas Gleixner
<tglx@...utronix.de>, Ingo Molnar <mingo@...hat.com>, Borislav Petkov
<bp@...en8.de>, Dave Hansen <dave.hansen@...ux.intel.com>,
<x86@...nel.org>, H. Peter Anvin <hpa@...or.com>, Eric Biederman
<ebiederm@...ssion.com>, Masahiro Yamada <masahiroy@...nel.org>,
Michal Marek <michal.lkml@...kovi.net>, Nick Desaulniers
<ndesaulniers@...gle.com>, Kirill A. Shutemov
<kirill.shutemov@...ux.intel.com>, Kuppuswamy Sathyanarayanan
<sathyanarayanan.kuppuswamy@...ux.intel.com>, Michael Roth
<michael.roth@....com>, Nathan Chancellor <nathan@...nel.org>, Ard
Biesheuvel <ardb@...nel.org>, Mark Rutland <mark.rutland@....com>,
Sean Christopherson <seanjc@...gle.com>, Peter Zijlstra
<peterz@...radead.org>, Kees Cook <keescook@...omium.org>, Tony Luck
<tony.luck@...el.com>, <linux-kernel@...r.kernel.org>,
<kexec@...ts.infradead.org>, <linux-kbuild@...r.kernel.org>
From: "huangjie.albert" <huangjie.albert@...edance.com>
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@...edance.com>
---
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
Powered by blists - more mailing lists