public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: "Jiri Slaby (SUSE)" <jirislaby@kernel.org>
To: linux-kernel@vger.kernel.org
Cc: Alexander Lobakin <alexandr.lobakin@intel.com>,
	Jiri Slaby <jirislaby@kernel.org>
Subject: [PATCH 01/46] x86/boot: robustify calling startup_{32,64}() from the decompressor code
Date: Mon, 14 Nov 2022 12:42:59 +0100	[thread overview]
Message-ID: <20221114114344.18650-2-jirislaby@kernel.org> (raw)
In-Reply-To: <20221114114344.18650-1-jirislaby@kernel.org>

From: Alexander Lobakin <alexandr.lobakin@intel.com>

After commit ce697ccee1a8 ("kbuild: remove head-y syntax"), I
started digging whether x86 is ready for removing this old cruft.
Removing its objects from the list makes the kernel unbootable.
This applies only to bzImage, vmlinux still works correctly.
The reason is that with no strict object order determined by the
linker arguments, not the linker script, startup_64 can be placed
not right at the beginning of the kernel.
Here's vmlinux.map's beginning before removing:

ffffffff81000000         vmlinux.o:(.head.text)
ffffffff81000000                 startup_64
ffffffff81000070                 secondary_startup_64
ffffffff81000075                 secondary_startup_64_no_verify
ffffffff81000160                 verify_cpu

and after:

ffffffff81000000         vmlinux.o:(.head.text)
ffffffff81000000                 pvh_start_xen
ffffffff81000080                 startup_64
ffffffff810000f0                 secondary_startup_64
ffffffff810000f5                 secondary_startup_64_no_verify

Not a problem itself, but the self-extractor code has the address of
that function hardcoded the beginning, not looking onto the ELF
header, which always contains the address of startup_{32,64}().

So, instead of doing an "act of blind faith", just take the address
from the ELF header and extract a relative offset to the entry
point. The decompressor function already returns a pointer to the
beginning of the kernel to the Asm code, which then jumps to it,
so add that offset to the return value.
This doesn't change anything for now, but allows to resign from the
"head object list" for x86 and makes sure valid Kbuild or any other
improvements won't break anything here in general.

Tested-by: Jiri Slaby <jirislaby@kernel.org>
Signed-off-by: Alexander Lobakin <alexandr.lobakin@intel.com>
Reviewed-by: Jiri Slaby <jirislaby@kernel.org>
Signed-off-by: Jiri Slaby (SUSE) <jirislaby@kernel.org>
---
 arch/x86/boot/compressed/head_32.S |  2 +-
 arch/x86/boot/compressed/head_64.S |  2 +-
 arch/x86/boot/compressed/misc.c    | 16 ++++++++++------
 3 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S
index 3b354eb9516d..56f9847e208b 100644
--- a/arch/x86/boot/compressed/head_32.S
+++ b/arch/x86/boot/compressed/head_32.S
@@ -187,7 +187,7 @@ SYM_FUNC_START_LOCAL_NOALIGN(.Lrelocated)
 	leal	boot_heap@GOTOFF(%ebx), %eax
 	pushl	%eax			/* heap area */
 	pushl	%esi			/* real mode pointer */
-	call	extract_kernel		/* returns kernel location in %eax */
+	call	extract_kernel		/* returns kernel entry point in %eax */
 	addl	$24, %esp
 
 /*
diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S
index d33f060900d2..aeba5aa3d26c 100644
--- a/arch/x86/boot/compressed/head_64.S
+++ b/arch/x86/boot/compressed/head_64.S
@@ -593,7 +593,7 @@ SYM_FUNC_START_LOCAL_NOALIGN(.Lrelocated)
 	movl	input_len(%rip), %ecx	/* input_len */
 	movq	%rbp, %r8		/* output target address */
 	movl	output_len(%rip), %r9d	/* decompressed length, end of relocs */
-	call	extract_kernel		/* returns kernel location in %rax */
+	call	extract_kernel		/* returns kernel entry point in %rax */
 	popq	%rsi
 
 /*
diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c
index cf690d8712f4..2548d7fb243e 100644
--- a/arch/x86/boot/compressed/misc.c
+++ b/arch/x86/boot/compressed/misc.c
@@ -277,7 +277,7 @@ static inline void handle_relocations(void *output, unsigned long output_len,
 { }
 #endif
 
-static void parse_elf(void *output)
+static size_t parse_elf(void *output)
 {
 #ifdef CONFIG_X86_64
 	Elf64_Ehdr ehdr;
@@ -287,16 +287,15 @@ static void parse_elf(void *output)
 	Elf32_Phdr *phdrs, *phdr;
 #endif
 	void *dest;
+	size_t off;
 	int i;
 
 	memcpy(&ehdr, output, sizeof(ehdr));
 	if (ehdr.e_ident[EI_MAG0] != ELFMAG0 ||
 	   ehdr.e_ident[EI_MAG1] != ELFMAG1 ||
 	   ehdr.e_ident[EI_MAG2] != ELFMAG2 ||
-	   ehdr.e_ident[EI_MAG3] != ELFMAG3) {
+	   ehdr.e_ident[EI_MAG3] != ELFMAG3)
 		error("Kernel is not a valid ELF file");
-		return;
-	}
 
 	debug_putstr("Parsing ELF... ");
 
@@ -305,6 +304,7 @@ static void parse_elf(void *output)
 		error("Failed to allocate space for phdrs");
 
 	memcpy(phdrs, output + ehdr.e_phoff, sizeof(*phdrs) * ehdr.e_phnum);
+	off = ehdr.e_entry - phdrs->p_paddr;
 
 	for (i = 0; i < ehdr.e_phnum; i++) {
 		phdr = &phdrs[i];
@@ -328,6 +328,8 @@ static void parse_elf(void *output)
 	}
 
 	free(phdrs);
+
+	return off;
 }
 
 /*
@@ -356,6 +358,7 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap,
 	const unsigned long kernel_total_size = VO__end - VO__text;
 	unsigned long virt_addr = LOAD_PHYSICAL_ADDR;
 	unsigned long needed_size;
+	size_t off;
 
 	/* Retain x86 boot parameters pointer passed from startup_32/64. */
 	boot_params = rmode;
@@ -456,14 +459,15 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap,
 	debug_putstr("\nDecompressing Linux... ");
 	__decompress(input_data, input_len, NULL, NULL, output, output_len,
 			NULL, error);
-	parse_elf(output);
+	off = parse_elf(output);
+	debug_putaddr(off);
 	handle_relocations(output, output_len, virt_addr);
 	debug_putstr("done.\nBooting the kernel.\n");
 
 	/* Disable exception handling before booting the kernel */
 	cleanup_exception_handling();
 
-	return output;
+	return output + off;
 }
 
 void fortify_panic(const char *name)
-- 
2.38.1


  reply	other threads:[~2022-11-14 11:44 UTC|newest]

Thread overview: 87+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-14 11:42 [PATCH 00/46] gcc-LTO support for the kernel Jiri Slaby (SUSE)
2022-11-14 11:42 ` Jiri Slaby (SUSE) [this message]
2022-11-14 11:43 ` [PATCH 02/46] kbuild: pass jobserver to cmd_ld_vmlinux.o Jiri Slaby (SUSE)
2022-11-14 17:57   ` Masahiro Yamada
2022-11-15  6:36     ` Jiri Slaby
2022-11-14 11:43 ` [PATCH 03/46] kbuild: lto: preserve MAKEFLAGS for module linking Jiri Slaby (SUSE)
2022-11-14 18:02   ` Masahiro Yamada
2022-11-14 11:43 ` [PATCH 04/46] compiler.h: introduce __visible_on_lto Jiri Slaby (SUSE)
2022-11-14 11:43 ` [PATCH 05/46] compiler.h: introduce __global_on_lto Jiri Slaby (SUSE)
2022-11-14 11:43 ` [PATCH 06/46] Compiler Attributes, lto: introduce __noreorder Jiri Slaby (SUSE)
2022-11-14 11:43 ` [PATCH 07/46] tracepoint, lto: Mark static call functions as __visible Jiri Slaby (SUSE)
2022-11-14 11:43 ` [PATCH 08/46] static_call, lto: Mark static keys " Jiri Slaby (SUSE)
2022-11-14 15:51   ` Peter Zijlstra
2022-11-14 18:52     ` Josh Poimboeuf
2022-11-14 20:34     ` Andi Kleen
2022-11-17  8:24       ` Peter Zijlstra
2022-11-14 18:57   ` Josh Poimboeuf
2022-11-14 11:43 ` [PATCH 09/46] static_call, lto: Mark static_call_return0() " Jiri Slaby (SUSE)
2022-11-14 11:43 ` [PATCH 10/46] static_call, lto: Mark func_a() as __visible_on_lto Jiri Slaby (SUSE)
2022-11-14 15:54   ` Peter Zijlstra
2022-11-14 20:29     ` Andi Kleen
2022-11-14 11:43 ` [PATCH 11/46] x86/alternative, lto: Mark int3_*() as global and __visible Jiri Slaby (SUSE)
2022-11-14 11:43 ` [PATCH 12/46] x86/paravirt, lto: Mark native_steal_clock() as __visible_on_lto Jiri Slaby (SUSE)
2022-11-14 15:58   ` Peter Zijlstra
2022-11-14 11:43 ` [PATCH 13/46] x86/preempt, lto: Mark preempt_schedule_*thunk() as __visible Jiri Slaby (SUSE)
2022-11-14 11:43 ` [PATCH 14/46] x86/sev, lto: Mark cpuid_table_copy as __visible_on_lto Jiri Slaby (SUSE)
2022-11-14 16:02   ` Peter Zijlstra
2022-11-14 11:43 ` [PATCH 15/46] x86/xen, lto: Mark xen_vcpu_stolen() as __visible Jiri Slaby (SUSE)
2022-11-14 11:43 ` [PATCH 16/46] x86, lto: Mark gdt_page and native_sched_clock() " Jiri Slaby (SUSE)
2022-11-14 11:43 ` [PATCH 17/46] amd, lto: Mark amd pmu and pstate functions as __visible_on_lto Jiri Slaby (SUSE)
2022-11-14 11:43 ` [PATCH 18/46] entry, lto: Mark raw_irqentry_exit_cond_resched() as __visible Jiri Slaby (SUSE)
2022-11-16 23:30   ` Thomas Gleixner
2022-11-17  8:40     ` Peter Zijlstra
2022-11-17 22:07       ` Andi Kleen
2022-11-18  1:28         ` Thomas Gleixner
2022-11-19  0:50           ` Andi Kleen
2022-11-19  8:50             ` Thomas Gleixner
2022-11-22  9:32     ` Jiri Slaby
2022-11-14 11:43 ` [PATCH 19/46] export, lto: Mark __kstrtab* in EXPORT_SYMBOL() as global and __visible Jiri Slaby (SUSE)
2022-11-14 11:43 ` [PATCH 20/46] softirq, lto: Mark irq_enter/exit_rcu() as __visible Jiri Slaby (SUSE)
2022-11-14 11:43 ` [PATCH 21/46] btf, lto: pass scope as strings Jiri Slaby (SUSE)
2022-11-14 11:43 ` [PATCH 22/46] btf, lto: Make all BTF IDs global on LTO Jiri Slaby (SUSE)
2022-11-14 11:43 ` [PATCH 23/46] init.h, lto: mark initcalls as __noreorder Jiri Slaby (SUSE)
2022-11-14 11:43 ` [PATCH 24/46] bpf, lto: mark interpreter jump table " Jiri Slaby (SUSE)
2022-11-14 11:43 ` [PATCH 25/46] sched, lto: mark sched classes " Jiri Slaby (SUSE)
2022-11-14 11:43 ` [PATCH 26/46] x86/apic, lto: Mark apic_driver*() " Jiri Slaby (SUSE)
2022-11-14 11:43 ` [PATCH 27/46] linkage, lto: use C version for SYSCALL_ALIAS() / cond_syscall() Jiri Slaby (SUSE)
2022-11-14 11:43 ` [PATCH 28/46] scripts, lto: re-add gcc-ld Jiri Slaby (SUSE)
2022-11-14 11:43 ` [PATCH 29/46] scripts, lto: use CONFIG_LTO for many LTO specific actions Jiri Slaby (SUSE)
2022-11-14 11:43 ` [PATCH 30/46] Kbuild, lto: Add Link Time Optimization support Jiri Slaby (SUSE)
2022-11-14 18:55   ` Josh Poimboeuf
2022-11-15 13:31     ` Martin Liška
2022-11-14 11:43 ` [PATCH 31/46] x86/purgatory, lto: Disable gcc LTO for purgatory Jiri Slaby (SUSE)
2022-11-14 11:43 ` [PATCH 32/46] x86/realmode, lto: Disable gcc LTO for real mode code Jiri Slaby (SUSE)
2022-11-14 11:43 ` [PATCH 33/46] x86/vdso, lto: Disable gcc LTO for the vdso Jiri Slaby (SUSE)
2022-11-14 11:43 ` [PATCH 34/46] scripts, lto: disable gcc LTO for some mod sources Jiri Slaby (SUSE)
2022-11-14 11:43 ` [PATCH 35/46] Kbuild, lto: disable gcc LTO for bounds+asm-offsets Jiri Slaby (SUSE)
2022-11-14 11:43 ` [PATCH 36/46] lib/string, lto: disable gcc LTO for string.o Jiri Slaby (SUSE)
2022-11-14 11:43 ` [PATCH 37/46] Compiler attributes, lto: disable __flatten with LTO Jiri Slaby (SUSE)
2022-11-14 17:01   ` Miguel Ojeda
2022-11-14 11:43 ` [PATCH 38/46] Kbuild, lto: don't include weak source file symbols in System.map Jiri Slaby (SUSE)
2022-11-14 11:43 ` [PATCH 39/46] x86, lto: Disable relative init pointers with gcc LTO Jiri Slaby (SUSE)
2022-11-14 11:43 ` [PATCH 40/46] x86/livepatch, lto: Disable live patching " Jiri Slaby (SUSE)
2022-11-14 19:07   ` Josh Poimboeuf
2022-11-14 20:28     ` Andi Kleen
2022-11-14 22:00       ` Josh Poimboeuf
2022-11-15 13:32         ` Martin Liška
2022-11-17 20:00   ` Song Liu
2022-11-14 11:43 ` [PATCH 41/46] x86/lib, lto: Mark 32bit mem{cpy,move,set} as __used Jiri Slaby (SUSE)
2022-11-14 11:43 ` [PATCH 42/46] mm/kasan, lto: Mark kasan " Jiri Slaby (SUSE)
2022-11-14 11:43 ` [PATCH 43/46] scripts, lto: check C symbols for modversions Jiri Slaby (SUSE)
2022-11-14 11:43 ` [PATCH 44/46] scripts/bloat-o-meter, lto: handle gcc LTO Jiri Slaby (SUSE)
2022-11-14 11:43 ` [PATCH 45/46] kasan, lto: remove extra BUILD_BUG() in memory_is_poisoned Jiri Slaby (SUSE)
2022-11-26 17:07   ` Andrey Konovalov
2022-11-14 11:43 ` [PATCH 46/46] x86, lto: Finally enable gcc LTO for x86 Jiri Slaby (SUSE)
2022-11-14 11:56 ` [PATCH 00/46] gcc-LTO support for the kernel Ard Biesheuvel
2022-11-14 12:04   ` Jiri Slaby
2022-11-14 19:40 ` Ard Biesheuvel
2022-11-17  8:28   ` Peter Zijlstra
2022-11-17  8:50     ` Richard Biener
2022-11-17 11:42       ` Peter Zijlstra
2022-11-17 11:49         ` Ard Biesheuvel
2022-11-17 13:55           ` Richard Biener
2022-11-17 14:32             ` Peter Zijlstra
2022-11-17 14:40               ` Richard Biener
2022-11-17 15:15             ` Ard Biesheuvel
2022-11-17 11:48       ` Thomas Gleixner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20221114114344.18650-2-jirislaby@kernel.org \
    --to=jirislaby@kernel.org \
    --cc=alexandr.lobakin@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox