From: ard.biesheuvel@linaro.org (Ard Biesheuvel)
To: linux-arm-kernel@lists.infradead.org
Subject: [RFC PATCH 2/3] arm64: add support for relocatable kernel
Date: Mon, 16 Mar 2015 16:23:42 +0100 [thread overview]
Message-ID: <1426519423-28263-3-git-send-email-ard.biesheuvel@linaro.org> (raw)
In-Reply-To: <1426519423-28263-1-git-send-email-ard.biesheuvel@linaro.org>
This adds support for runtime relocation of the kernel Image, by
building it as a PIE (ET_DYN) executable and applying the relocations
in the early boot code.
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
arch/arm64/Kconfig | 3 +++
arch/arm64/Makefile | 4 +++
arch/arm64/kernel/head.S | 58 ++++++++++++++++++++++++++++++++++++++++-
arch/arm64/kernel/image.h | 8 +++++-
arch/arm64/kernel/vmlinux.lds.S | 12 +++++++++
scripts/sortextable.c | 4 +--
6 files changed, 85 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 1b8e97331ffb..cc6504998f2c 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -143,6 +143,9 @@ config KERNEL_MODE_NEON
config FIX_EARLYCON_MEM
def_bool y
+config RELOCATABLE_KERNEL
+ def_bool y
+
source "init/Kconfig"
source "kernel/Kconfig.freezer"
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index 69ceedc982a5..e3914049c389 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -15,6 +15,10 @@ CPPFLAGS_vmlinux.lds = -DTEXT_OFFSET=$(TEXT_OFFSET)
OBJCOPYFLAGS :=-O binary -R .note -R .note.gnu.build-id -R .comment -S
GZFLAGS :=-9
+ifneq ($(CONFIG_RELOCATABLE_KERNEL),)
+LDFLAGS_vmlinux += -pie
+endif
+
KBUILD_DEFCONFIG := defconfig
KBUILD_CFLAGS += -mgeneral-regs-only
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 1ea3cd2aba34..874754794b25 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -239,6 +239,7 @@ section_table:
ENTRY(stext)
mov x21, x0 // x21=FDT
+ mov x23, x1 // x23=image offset
bl el2_setup // Drop to EL1, w20=cpu_boot_mode
bl __calc_phys_offset // x24=PHYS_OFFSET, x28=PHYS_OFFSET-PAGE_OFFSET
bl set_cpu_boot_mode_flag
@@ -249,8 +250,12 @@ ENTRY(stext)
* On return, the CPU will be ready for the MMU to be turned on and
* the TCR will have been set.
*/
+#ifndef CONFIG_RELOCATABLE_KERNEL
ldr x27, =__mmap_switched // address to jump to after
// MMU has been enabled
+#else
+ adr x27, __relocate_kernel
+#endif
adrp lr, __enable_mmu // return (PIC) address
add lr, lr, #:lo12:__enable_mmu
b __cpu_setup // initialise processor
@@ -397,9 +402,10 @@ __create_page_tables:
*/
mov x0, x26 // swapper_pg_dir
mov x5, #PAGE_OFFSET
+ add x5, x5, x23 // __va(KERNEL_START)
create_pgd_entry x0, x5, x3, x6
adr_l x6, KERNEL_END
- mov x3, x24 // phys offset
+ add x3, x23, x24 // phys offset + image offset
sub x6, x6, x3 // kernel memsize
add x6, x6, x5 // __va(KERNEL_END)
create_block_map x0, x7, x3, x5, x6
@@ -438,6 +444,55 @@ __mmap_switched:
b start_kernel
ENDPROC(__mmap_switched)
+#ifdef CONFIG_RELOCATABLE_KERNEL
+
+#define R_AARCH64_RELATIVE 0x403
+#define R_AARCH64_ABS64 0x101
+
+ /*
+ * Iterate over each entry in the relocation table, and apply the
+ * relocations in place.
+ */
+__relocate_kernel:
+ adr_l x8, __dynsym_start // start of symbol table
+ adr_l x9, __reloc_start // start of reloc table
+ adr_l x10, __reloc_end // end of reloc table
+0: cmp x9, x10
+ b.hs 2f
+ ldp x11, x12, [x9], #24
+ cmp x12, #R_AARCH64_RELATIVE
+ b.ne 1f
+ ldr x12, [x9, #-8]
+ add x12, x12, x23 // relocate
+ str x12, [x11, x28]
+ b 0b
+
+1: ubfx x13, x12, #0, #32
+ cmp x13, #R_AARCH64_ABS64
+ b.ne 0b
+ lsr x13, x12, #32 // symbol index
+ ldr x12, [x9, #-8]
+ add x13, x13, x13, lsl #1 // x 3
+ add x13, x8, x13, lsl #3 // x 8
+ ldrsh w14, [x13, #6] // Elf64_Sym::st_shndx
+ ldr x15, [x13, #8] // Elf64_Sym::st_value
+ cmp w14, #-0xf // SHN_ABS (0xfff1) ?
+ add x14, x15, x23 // relocate
+ csel x15, x14, x15, ne
+ add x15, x12, x15
+ str x15, [x11, x28]
+ b 0b
+
+2: ldr x8, =vectors // reload VBAR_EL1 with
+ msr vbar_el1, x8 // relocated address
+ isb
+
+ ldr x9, =__mmap_switched
+ br x9
+ENDPROC(__relocate_kernel)
+
+#endif
+
/*
* end early head section, begin head code that is also used for
* hotplug and needs to have the same protections as the text region
@@ -657,6 +712,7 @@ __calc_phys_offset:
mov x2, PAGE_OFFSET
sub x28, x0, x1 // x28 = PHYS_OFFSET - PAGE_OFFSET
add x24, x2, x28 // x24 = PHYS_OFFSET
+ sub x24, x24, x23 // subtract image offset
ret
ENDPROC(__calc_phys_offset)
diff --git a/arch/arm64/kernel/image.h b/arch/arm64/kernel/image.h
index 8fae0756e175..8b1e9fa8fc8c 100644
--- a/arch/arm64/kernel/image.h
+++ b/arch/arm64/kernel/image.h
@@ -47,7 +47,13 @@
#define __HEAD_FLAG_BE 0
#endif
-#define __HEAD_FLAGS (__HEAD_FLAG_BE << 0)
+#ifdef CONFIG_RELOCATABLE_KERNEL
+#define __HEAD_FLAG_RELOC 1
+#else
+#define __HEAD_FLAG_RELOC 0
+#endif
+
+#define __HEAD_FLAGS (__HEAD_FLAG_BE << 0) | (__HEAD_FLAG_RELOC << 1)
/*
* These will output as part of the Image header, which should be little-endian
diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
index a2c29865c3fe..df706a8c22f1 100644
--- a/arch/arm64/kernel/vmlinux.lds.S
+++ b/arch/arm64/kernel/vmlinux.lds.S
@@ -131,6 +131,18 @@ SECTIONS
PERCPU_SECTION(64)
+ .rela : {
+ . = ALIGN(8);
+ __reloc_start = .;
+ *(.rela .rela*)
+ __reloc_end = .;
+ }
+ .dynsym : {
+ . = ALIGN(8);
+ __dynsym_start = .;
+ *(.dynsym)
+ }
+
. = ALIGN(PAGE_SIZE);
__init_end = .;
diff --git a/scripts/sortextable.c b/scripts/sortextable.c
index 1052d4834a44..77fcc1a80011 100644
--- a/scripts/sortextable.c
+++ b/scripts/sortextable.c
@@ -262,9 +262,9 @@ do_file(char const *const fname)
break;
} /* end switch */
if (memcmp(ELFMAG, ehdr->e_ident, SELFMAG) != 0
- || r2(&ehdr->e_type) != ET_EXEC
+ || (r2(&ehdr->e_type) != ET_EXEC && r2(&ehdr->e_type) != ET_DYN)
|| ehdr->e_ident[EI_VERSION] != EV_CURRENT) {
- fprintf(stderr, "unrecognized ET_EXEC file %s\n", fname);
+ fprintf(stderr, "unrecognized ET_EXEC/ET_DYN file %s\n", fname);
fail_file();
}
--
1.8.3.2
next prev parent reply other threads:[~2015-03-16 15:23 UTC|newest]
Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-03-16 15:23 [RFC PATCH 0/3] arm64: relocatable kernel proof of concept Ard Biesheuvel
2015-03-16 15:23 ` [RFC PATCH 1/3] arm64: head.S: replace early literals with constant immediates Ard Biesheuvel
2015-03-16 17:14 ` Mark Rutland
2015-03-17 7:01 ` Ard Biesheuvel
2015-03-16 15:23 ` Ard Biesheuvel [this message]
2015-03-16 15:23 ` [RFC PATCH 3/3] arm64/efi: use relocated kernel Ard Biesheuvel
2015-03-16 16:09 ` [RFC PATCH 0/3] arm64: relocatable kernel proof of concept Mark Rutland
2015-03-16 16:45 ` Ard Biesheuvel
2015-03-16 17:33 ` Mark Rutland
2015-03-16 17:43 ` Ard Biesheuvel
2015-03-17 16:20 ` Mark Rutland
2015-03-16 23:19 ` Kees Cook
2015-03-17 7:38 ` Ard Biesheuvel
2015-03-17 16:35 ` Mark Rutland
2015-03-17 16:40 ` Ard Biesheuvel
2015-03-17 16:43 ` Mark Rutland
2015-03-23 15:36 ` [PATCH 0/4] RFC: split text and linear mappings using tagged pointers Ard Biesheuvel
2015-03-23 15:36 ` [PATCH 1/4] arm64: use tagged pointers to distinguish kernel text from the linear mapping Ard Biesheuvel
2015-03-25 14:04 ` Catalin Marinas
2015-03-26 1:27 ` Mark Rutland
2015-03-23 15:36 ` [PATCH 2/4] arm64: fixmap: move translation tables to dedicated region Ard Biesheuvel
2015-03-26 1:28 ` Mark Rutland
2015-03-26 6:20 ` Ard Biesheuvel
2015-03-30 14:34 ` Mark Rutland
2015-03-23 15:36 ` [PATCH 3/4] arm64: move kernel text below PAGE_OFFSET Ard Biesheuvel
2015-03-25 14:10 ` Catalin Marinas
2015-03-23 15:36 ` [PATCH 4/4] arm64: align PHYS_OFFSET to block size Ard Biesheuvel
2015-03-25 14:14 ` Catalin Marinas
2015-03-26 6:23 ` Ard Biesheuvel
2015-03-25 14:59 ` Catalin Marinas
2015-03-26 6:22 ` Ard Biesheuvel
2015-03-27 13:16 ` Ard Biesheuvel
2015-03-30 13:49 ` Catalin Marinas
2015-03-30 14:00 ` Ard Biesheuvel
2015-03-30 14:55 ` Mark Rutland
2015-03-30 15:00 ` Catalin Marinas
2015-03-30 18:08 ` Ard Biesheuvel
2015-03-31 14:49 ` Catalin Marinas
2015-03-31 16:19 ` Catalin Marinas
2015-03-31 16:46 ` Catalin Marinas
2015-03-26 1:26 ` [PATCH 0/4] RFC: split text and linear mappings using tagged pointers Mark Rutland
2015-03-26 6:09 ` 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=1426519423-28263-3-git-send-email-ard.biesheuvel@linaro.org \
--to=ard.biesheuvel@linaro.org \
--cc=linux-arm-kernel@lists.infradead.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).