llvm.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
From: Ard Biesheuvel <ardb+git@google.com>
To: linux-kernel@vger.kernel.org
Cc: Ard Biesheuvel <ardb@kernel.org>,
	x86@kernel.org, "H. Peter Anvin" <hpa@zytor.com>,
	 Andy Lutomirski <luto@kernel.org>,
	Peter Zijlstra <peterz@infradead.org>,
	Uros Bizjak <ubizjak@gmail.com>,  Dennis Zhou <dennis@kernel.org>,
	Tejun Heo <tj@kernel.org>, Christoph Lameter <cl@linux.com>,
	 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>,
	Paolo Bonzini <pbonzini@redhat.com>,
	 Vitaly Kuznetsov <vkuznets@redhat.com>,
	Juergen Gross <jgross@suse.com>,
	 Boris Ostrovsky <boris.ostrovsky@oracle.com>,
	 Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Arnd Bergmann <arnd@arndb.de>,
	 Masahiro Yamada <masahiroy@kernel.org>,
	Kees Cook <kees@kernel.org>,
	 Nathan Chancellor <nathan@kernel.org>,
	Keith Packard <keithp@keithp.com>,
	 Justin Stitt <justinstitt@google.com>,
	Josh Poimboeuf <jpoimboe@kernel.org>,
	 Arnaldo Carvalho de Melo <acme@kernel.org>,
	Namhyung Kim <namhyung@kernel.org>, Jiri Olsa <jolsa@kernel.org>,
	 Ian Rogers <irogers@google.com>,
	Adrian Hunter <adrian.hunter@intel.com>,
	 Kan Liang <kan.liang@linux.intel.com>,
	linux-doc@vger.kernel.org,  linux-pm@vger.kernel.org,
	kvm@vger.kernel.org, xen-devel@lists.xenproject.org,
	 linux-efi@vger.kernel.org, linux-arch@vger.kernel.org,
	 linux-sparse@vger.kernel.org, linux-kbuild@vger.kernel.org,
	 linux-perf-users@vger.kernel.org,
	rust-for-linux@vger.kernel.org,  llvm@lists.linux.dev
Subject: [RFC PATCH 26/28] x86/boot: Implement support for ELF RELA/RELR relocations
Date: Wed, 25 Sep 2024 17:01:26 +0200	[thread overview]
Message-ID: <20240925150059.3955569-56-ardb+git@google.com> (raw)
In-Reply-To: <20240925150059.3955569-30-ardb+git@google.com>

From: Ard Biesheuvel <ardb@kernel.org>

Add support for standard dynamic ELF relocations to perform the virtual
relocation of the core kernel at boot. The RELR format results in a 10x
reduction in memory footprint of the relocation data, and can be
generated by the linker directly. This removes the need for
a) a host tool 'relocs' and a bespoke, clunky relocation table format
   where the table is simply concatenated to the vmlinux payload when
   building the decompressor;
b) dependence on the --emit-relocs linker switch, which dumps static,
   intermediate build time relocations into the ELF binary, to be
   subsequently used as runtime relocations.

The latter is especially problematic, as linkers may apply relaxations
that result in the code going out of sync with the static relocation
that annotated it in the input. This requires additional work on the
part of the linker to update the static relocation, which is not even
possible in all cases. Therefore, it is much better to consume a
runtime, dynamic relocation format in the way it was intended.

This will require switching to linking vmlinux in PIE mode - this is
implemented in a subsequent patch.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 Documentation/arch/x86/zero-page.rst  |  3 +-
 arch/x86/Kconfig                      |  1 +
 arch/x86/include/asm/setup.h          |  1 +
 arch/x86/include/uapi/asm/bootparam.h |  2 +-
 arch/x86/kernel/head64.c              | 36 ++++++++++++++++++++
 arch/x86/kernel/head_64.S             |  5 +++
 arch/x86/kernel/vmlinux.lds.S         | 24 +++++++++----
 7 files changed, 64 insertions(+), 8 deletions(-)

diff --git a/Documentation/arch/x86/zero-page.rst b/Documentation/arch/x86/zero-page.rst
index 45aa9cceb4f1..fd18b77113e2 100644
--- a/Documentation/arch/x86/zero-page.rst
+++ b/Documentation/arch/x86/zero-page.rst
@@ -3,7 +3,7 @@
 =========
 Zero Page
 =========
-The additional fields in struct boot_params as a part of 32-bit boot
+The additional fields in struct boot_params as a part of 32/64-bit boot
 protocol of kernel. These should be filled by bootloader or 16-bit
 real-mode setup code of the kernel. References/settings to it mainly
 are in::
@@ -20,6 +20,7 @@ Offset/Size	Proto	Name			Meaning
 060/010		ALL	ist_info		Intel SpeedStep (IST) BIOS support information
 						(struct ist_info)
 070/008		ALL	acpi_rsdp_addr		Physical address of ACPI RSDP table
+078/008		64-bit	kaslr_va_shift		Virtual kASLR displacement of the core kernel
 080/010		ALL	hd0_info		hd0 disk parameter, OBSOLETE!!
 090/010		ALL	hd1_info		hd1 disk parameter, OBSOLETE!!
 0A0/010		ALL	sys_desc_table		System description table (struct sys_desc_table),
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 2852fcd82cbd..54cb1f14218b 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -26,6 +26,7 @@ config X86_64
 	depends on 64BIT
 	# Options that are inherently 64-bit kernel only:
 	select ARCH_HAS_GIGANTIC_PAGE
+	select ARCH_HAS_RELR
 	select ARCH_SUPPORTS_INT128 if CC_HAS_INT128
 	select ARCH_SUPPORTS_PER_VMA_LOCK
 	select ARCH_SUPPORTS_HUGE_PFNMAP if TRANSPARENT_HUGEPAGE
diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h
index 85f4fde3515c..a4d7dd81f773 100644
--- a/arch/x86/include/asm/setup.h
+++ b/arch/x86/include/asm/setup.h
@@ -51,6 +51,7 @@ extern void reserve_standard_io_resources(void);
 extern void i386_reserve_resources(void);
 extern unsigned long __startup_64(unsigned long p2v_offset, struct boot_params *bp);
 extern void startup_64_setup_gdt_idt(void);
+extern void startup_64_apply_relocations(struct boot_params *bp);
 extern void early_setup_idt(void);
 extern void __init do_early_exception(struct pt_regs *regs, int trapnr);
 
diff --git a/arch/x86/include/uapi/asm/bootparam.h b/arch/x86/include/uapi/asm/bootparam.h
index 9b82eebd7add..3389b1be234c 100644
--- a/arch/x86/include/uapi/asm/bootparam.h
+++ b/arch/x86/include/uapi/asm/bootparam.h
@@ -120,7 +120,7 @@ struct boot_params {
 	__u64  tboot_addr;				/* 0x058 */
 	struct ist_info ist_info;			/* 0x060 */
 	__u64 acpi_rsdp_addr;				/* 0x070 */
-	__u8  _pad3[8];					/* 0x078 */
+	__u64 kaslr_va_shift;				/* 0x078 */
 	__u8  hd0_info[16];	/* obsolete! */		/* 0x080 */
 	__u8  hd1_info[16];	/* obsolete! */		/* 0x090 */
 	struct sys_desc_table sys_desc_table; /* obsolete! */	/* 0x0a0 */
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
index 49e8ba1c0d34..6609e1012f2f 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -20,6 +20,7 @@
 #include <linux/io.h>
 #include <linux/memblock.h>
 #include <linux/cc_platform.h>
+#include <linux/elf.h>
 #include <linux/pgtable.h>
 
 #include <asm/asm.h>
@@ -588,3 +589,38 @@ void __head startup_64_setup_gdt_idt(void)
 
 	startup_64_load_idt(handler);
 }
+
+#ifdef CONFIG_RELOCATABLE
+void __head startup_64_apply_relocations(struct boot_params *bp)
+{
+	extern const Elf64_Rela __rela_start[], __rela_end[];
+	extern const u64 __relr_start[], __relr_end[];
+	u64 va_offset = (u64)RIP_REL_REF(_text) - __START_KERNEL;
+	u64 va_shift = bp->kaslr_va_shift;
+	u64 *place = NULL;
+
+	if (!va_shift)
+		return;
+
+	for (const Elf64_Rela *r = __rela_start; r < __rela_end; r++) {
+		if (ELF64_R_TYPE(r->r_info) != R_X86_64_RELATIVE)
+			continue;
+
+		place = (u64 *)(r->r_offset + va_offset);
+		*place += va_shift;
+	}
+
+	for (const u64 *rel = __relr_start; rel < __relr_end; rel++) {
+		if ((*rel & 1) == 0) {
+			place = (u64 *)(*rel + va_offset);
+			*place++ += va_shift;
+			continue;
+		}
+
+		for (u64 *p = place, r = *rel >> 1; r; p++, r >>= 1)
+			if (r & 1)
+				*p += va_shift;
+		place += 63;
+	}
+}
+#endif
diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S
index cc2fec3de4b7..88cdc5a0c7a3 100644
--- a/arch/x86/kernel/head_64.S
+++ b/arch/x86/kernel/head_64.S
@@ -74,6 +74,11 @@ SYM_CODE_START_NOALIGN(startup_64)
 	cdq
 	wrmsr
 
+#ifdef CONFIG_RELOCATABLE
+	movq	%r15, %rdi
+	call	startup_64_apply_relocations
+#endif
+
 	call	startup_64_setup_gdt_idt
 
 	/* Now switch to __KERNEL_CS so IRET works reliably */
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index 52b8db931d0f..f7e832c2ac61 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -240,6 +240,18 @@ xen_elfnote_phys32_entry_offset =
 	:init
 #endif
 
+	.init.rela : {
+		__rela_start = .;
+		*(.rela.*) *(.rela_*)
+		__rela_end = .;
+	}
+
+	.init.relr : {
+		__relr_start = .;
+		*(.relr.*)
+		__relr_end = .;
+	}
+
 	/*
 	 * Section for code used exclusively before alternatives are run. All
 	 * references to such code must be patched out by alternatives, normally
@@ -469,12 +481,6 @@ xen_elfnote_phys32_entry_offset =
 		*(.got) *(.igot.*)
 	}
 	ASSERT(SIZEOF(.got) == 0, "Unexpected GOT entries detected!")
-#endif
-
-	.plt : {
-		*(.plt) *(.plt.*) *(.iplt)
-	}
-	ASSERT(SIZEOF(.plt) == 0, "Unexpected run-time procedure linkages detected!")
 
 	.rel.dyn : {
 		*(.rel.*) *(.rel_*)
@@ -485,6 +491,12 @@ xen_elfnote_phys32_entry_offset =
 		*(.rela.*) *(.rela_*)
 	}
 	ASSERT(SIZEOF(.rela.dyn) == 0, "Unexpected run-time relocations (.rela) detected!")
+#endif
+
+	.plt : {
+		*(.plt) *(.plt.*) *(.iplt)
+	}
+	ASSERT(SIZEOF(.plt) == 0, "Unexpected run-time procedure linkages detected!")
 }
 
 /*
-- 
2.46.0.792.g87dc391469-goog


  parent reply	other threads:[~2024-09-25 15:02 UTC|newest]

Thread overview: 73+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-09-25 15:01 [RFC PATCH 00/28] x86: Rely on toolchain for relocatable code Ard Biesheuvel
2024-09-25 15:01 ` [RFC PATCH 01/28] x86/pvh: Call C code via the kernel virtual mapping Ard Biesheuvel
2024-09-25 21:12   ` Jason Andryuk
2024-09-25 15:01 ` [RFC PATCH 02/28] Documentation: Bump minimum GCC version to 8.1 Ard Biesheuvel
2024-09-25 15:58   ` Arnd Bergmann
2024-12-19 11:53     ` Mark Rutland
2024-12-19 12:02       ` Arnd Bergmann
2024-09-26 21:35   ` Miguel Ojeda
2024-09-27 16:22   ` Mark Rutland
2024-09-25 15:01 ` [RFC PATCH 03/28] x86/tools: Use mmap() to simplify relocs host tool Ard Biesheuvel
2024-09-25 15:01 ` [RFC PATCH 04/28] x86/boot: Permit GOTPCREL relocations for x86_64 builds Ard Biesheuvel
2024-10-01  5:33   ` Josh Poimboeuf
2024-10-01  6:56     ` Ard Biesheuvel
2024-09-25 15:01 ` [RFC PATCH 05/28] x86: Define the stack protector guard symbol explicitly Ard Biesheuvel
2024-09-25 15:53   ` Ian Rogers
2024-09-25 17:43     ` Ard Biesheuvel
2024-09-25 17:48       ` Ian Rogers
2024-09-25 18:32   ` Uros Bizjak
2024-09-28 13:41     ` Brian Gerst
2024-10-04 13:15       ` Ard Biesheuvel
2024-10-08 14:36         ` Brian Gerst
2024-10-04 10:01   ` Uros Bizjak
2024-09-25 15:01 ` [RFC PATCH 06/28] x86/percpu: Get rid of absolute per-CPU variable placement Ard Biesheuvel
2024-09-25 17:56   ` Christoph Lameter (Ampere)
2024-09-25 15:01 ` [RFC PATCH 07/28] scripts/kallsyms: Avoid 0x0 as the relative base Ard Biesheuvel
2024-09-25 15:01 ` [RFC PATCH 08/28] scripts/kallsyms: Remove support for absolute per-CPU variables Ard Biesheuvel
2024-09-25 15:01 ` [RFC PATCH 09/28] x86/tools: Remove special relocation handling for " Ard Biesheuvel
2024-09-25 15:01 ` [RFC PATCH 10/28] x86/xen: Avoid relocatable quantities in Xen ELF notes Ard Biesheuvel
2024-09-25 15:01 ` [RFC PATCH 11/28] x86/pvh: Avoid absolute symbol references in .head.text Ard Biesheuvel
2024-09-25 21:10   ` Jason Andryuk
2024-09-25 21:50     ` Ard Biesheuvel
2024-09-25 22:40       ` Jason Andryuk
2024-09-25 15:01 ` [RFC PATCH 12/28] x86/pm-trace: Use RIP-relative accesses for .tracedata Ard Biesheuvel
2024-09-25 15:01 ` [RFC PATCH 13/28] x86/kvm: Use RIP-relative addressing Ard Biesheuvel
2024-09-25 15:01 ` [RFC PATCH 14/28] x86/rethook: Use RIP-relative reference for return address Ard Biesheuvel
2024-09-25 16:39   ` Linus Torvalds
2024-09-25 16:45     ` Ard Biesheuvel
2024-09-25 15:01 ` [RFC PATCH 15/28] x86/sync_core: Use RIP-relative addressing Ard Biesheuvel
2024-09-25 15:01 ` [RFC PATCH 16/28] x86/entry_64: " Ard Biesheuvel
2024-09-25 15:01 ` [RFC PATCH 17/28] x86/hibernate: Prefer RIP-relative accesses Ard Biesheuvel
2024-09-25 15:01 ` [RFC PATCH 18/28] x86/boot/64: Determine VA/PA offset before entering C code Ard Biesheuvel
2024-09-25 15:01 ` [RFC PATCH 19/28] x86/boot/64: Avoid intentional absolute symbol references in .head.text Ard Biesheuvel
2024-09-25 15:01 ` [RFC PATCH 20/28] x64/acpi: Use PIC-compatible references in wakeup_64.S Ard Biesheuvel
2024-09-25 15:01 ` [RFC PATCH 21/28] x86/head: Use PIC-compatible symbol references in startup code Ard Biesheuvel
2024-09-25 15:01 ` [RFC PATCH 22/28] asm-generic: Treat PIC .data.rel.ro sections as .rodata Ard Biesheuvel
2024-09-25 15:01 ` [RFC PATCH 23/28] tools/objtool: Mark generated sections as writable Ard Biesheuvel
2024-09-25 15:01 ` [RFC PATCH 24/28] tools/objtool: Treat indirect ftrace calls as direct calls Ard Biesheuvel
2024-10-01  7:18   ` Josh Poimboeuf
2024-10-01  7:39     ` Ard Biesheuvel
2024-09-25 15:01 ` [RFC PATCH 25/28] x86: Use PIE codegen for the core kernel Ard Biesheuvel
2024-10-01 21:13   ` H. Peter Anvin
2024-10-02 15:25     ` Ard Biesheuvel
2024-10-02 20:01       ` Linus Torvalds
2024-10-03 11:13         ` Ard Biesheuvel
2024-10-04 21:06           ` H. Peter Anvin
2024-10-05  8:31             ` Uros Bizjak
2024-10-05 23:36               ` H. Peter Anvin
2024-10-06  0:00                 ` Linus Torvalds
2024-10-06  8:06                   ` Uros Bizjak
2024-10-06  7:59                 ` Uros Bizjak
2024-10-06 18:00                   ` David Laight
2024-10-06 19:17                     ` Uros Bizjak
2024-10-06 19:38                       ` H. Peter Anvin
2024-09-25 15:01 ` Ard Biesheuvel [this message]
2024-09-25 15:01 ` [RFC PATCH 27/28] x86/kernel: Switch to PIE linking " Ard Biesheuvel
2024-09-25 18:54   ` Uros Bizjak
2024-09-25 19:14     ` Ard Biesheuvel
2024-09-25 19:39       ` Uros Bizjak
2024-09-25 20:01         ` Ard Biesheuvel
2024-09-25 20:22           ` Uros Bizjak
2024-09-25 20:24   ` Vegard Nossum
2024-09-26 13:38     ` Ard Biesheuvel
2024-09-25 15:01 ` [RFC PATCH 28/28] x86/tools: Drop x86_64 support from 'relocs' tool Ard Biesheuvel

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=20240925150059.3955569-56-ardb+git@google.com \
    --to=ardb+git@google.com \
    --cc=acme@kernel.org \
    --cc=adrian.hunter@intel.com \
    --cc=ardb@kernel.org \
    --cc=arnd@arndb.de \
    --cc=boris.ostrovsky@oracle.com \
    --cc=cl@linux.com \
    --cc=dennis@kernel.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=hpa@zytor.com \
    --cc=irogers@google.com \
    --cc=jgross@suse.com \
    --cc=jolsa@kernel.org \
    --cc=jpoimboe@kernel.org \
    --cc=justinstitt@google.com \
    --cc=kan.liang@linux.intel.com \
    --cc=kees@kernel.org \
    --cc=keithp@keithp.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-efi@vger.kernel.org \
    --cc=linux-kbuild@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=linux-sparse@vger.kernel.org \
    --cc=llvm@lists.linux.dev \
    --cc=luto@kernel.org \
    --cc=masahiroy@kernel.org \
    --cc=mathieu.desnoyers@efficios.com \
    --cc=namhyung@kernel.org \
    --cc=nathan@kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=peterz@infradead.org \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=tj@kernel.org \
    --cc=ubizjak@gmail.com \
    --cc=vkuznets@redhat.com \
    --cc=x86@kernel.org \
    --cc=xen-devel@lists.xenproject.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;
as well as URLs for NNTP newsgroup(s).