[RFC UKL 01/10] kbuild: Add sections and symbols to linker script for UKL support

From: Ali Raza
Date: Mon Oct 03 2022 - 18:22:08 EST


In order to link a user space executable we will need access to a few
section that are not normally used when linking the kernel. Add these
sections when we have selected CONFIG_UNIKERNEL_LINUX.

Add case to not throw warnings for COMMON symbols from application code.

Make the KBUILD_VMLINUX_OBJS contain the application library when UKL is
enabled.

Cc: Jonathan Corbet <corbet@xxxxxxx>
Cc: Masahiro Yamada <masahiroy@xxxxxxxxxx>
Cc: Michal Marek <michal.lkml@xxxxxxxxxxx>
Cc: Nick Desaulniers <ndesaulniers@xxxxxxxxxx>
Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
Cc: Ingo Molnar <mingo@xxxxxxxxxx>
Cc: Borislav Petkov <bp@xxxxxxxxx>
Cc: Dave Hansen <dave.hansen@xxxxxxxxxxxxxxx>
Cc: "H. Peter Anvin" <hpa@xxxxxxxxx>
Cc: Andy Lutomirski <luto@xxxxxxxxxx>
Cc: Eric Biederman <ebiederm@xxxxxxxxxxxx>
Cc: Kees Cook <keescook@xxxxxxxxxxxx>
Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx>
Cc: Alexander Viro <viro@xxxxxxxxxxxxxxxxxx>
Cc: Arnd Bergmann <arnd@xxxxxxxx>
Cc: Juri Lelli <juri.lelli@xxxxxxxxxx>
Cc: Vincent Guittot <vincent.guittot@xxxxxxxxxx>
Cc: Dietmar Eggemann <dietmar.eggemann@xxxxxxx>
Cc: Steven Rostedt <rostedt@xxxxxxxxxxx>
Cc: Ben Segall <bsegall@xxxxxxxxxx>
Cc: Mel Gorman <mgorman@xxxxxxx>
Cc: Daniel Bristot de Oliveira <bristot@xxxxxxxxxx>
Cc: Valentin Schneider <vschneid@xxxxxxxxxx>
Cc: Paolo Bonzini <pbonzini@xxxxxxxxxx>
Cc: Josh Poimboeuf <jpoimboe@xxxxxxxxxx>

Co-developed-by: Thomas Unger <tommyu@xxxxxx>
Signed-off-by: Thomas Unger <tommyu@xxxxxx>
Co-developed-by: Matthew Boyd <mboydmcse@xxxxxxxxx>
Signed-off-by: Matthew Boyd <mboydmcse@xxxxxxxxx>
Co-developed-by: Eric B Munson <munsoner@xxxxxx>
Signed-off-by: Eric B Munson <munsoner@xxxxxx>
Co-developed-by: Ali Raza <aliraza@xxxxxx>
Signed-off-by: Ali Raza <aliraza@xxxxxx>
---
Makefile | 4 ++
arch/x86/kernel/vmlinux.lds.S | 98 +++++++++++++++++++++++++++++++
include/asm-generic/sections.h | 4 ++
include/asm-generic/vmlinux.lds.h | 32 +++++++++-
scripts/mod/modpost.c | 4 ++
5 files changed, 141 insertions(+), 1 deletion(-)

diff --git a/Makefile b/Makefile
index 8478e13e9424..d072a52ed856 100644
--- a/Makefile
+++ b/Makefile
@@ -1129,6 +1129,10 @@ KBUILD_VMLINUX_LIBS := $(patsubst %/,%/lib.a, $(libs-y))
endif
KBUILD_VMLINUX_OBJS += $(patsubst %/,%/built-in.a, $(drivers-y))

+ifdef CONFIG_UNIKERNEL_LINUX
+KBUILD_VMLINUX_OBJS += $(CONFIG_UKL_ARCHIVE_PATH)
+endif
+
export KBUILD_VMLINUX_OBJS KBUILD_VMLINUX_LIBS
export KBUILD_LDS := arch/$(SRCARCH)/kernel/vmlinux.lds
# used by scripts/Makefile.package
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index 15f29053cec4..cb8b33955969 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -101,6 +101,9 @@ jiffies = jiffies_64;

PHDRS {
text PT_LOAD FLAGS(5); /* R_E */
+#if defined(CONFIG_UNIKERNEL_LINUX) && defined(CONFIG_UKL_TLS)
+ tls PT_TLS FLAGS(6); /* RW_ */
+#endif
data PT_LOAD FLAGS(6); /* RW_ */
#ifdef CONFIG_X86_64
#ifdef CONFIG_SMP
@@ -146,6 +149,71 @@ SECTIONS
#endif
} :text =0xcccc

+#ifdef CONFIG_UNIKERNEL_LINUX
+ /* Added to preserve page alignment */
+ . = ALIGN(PAGE_SIZE);
+
+ /* */
+ .rela.plt :
+ {
+ *(.rela.plt)
+ PROVIDE_HIDDEN (__rela_iplt_start = .);
+ *(.rela.iplt)
+ PROVIDE_HIDDEN (__rela_iplt_end = .);
+ } :text =0xcccc
+ .preinit_array :
+ {
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ } :text =0xcccc
+ .init_array :
+ {
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
+ KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o
+ *crtend.o *crtend?.o ) .ctors))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ } :text =0xcccc
+ .fini_array :
+ {
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
+ KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o
+ *crtend.o *crtend?.o ) .dtors))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+ } :text =0xcccc
+ .ctors :
+ {
+ /* gcc uses crtbegin.o to find the start of
+ the constructors, so we make sure it is
+ first. Because this is a wildcard, it
+ doesn't matter if the user does not
+ actually link against crtbegin.o; the
+ linker won't look for a file to match a
+ wildcard. The wildcard also means that it
+ doesn't matter which directory crtbegin.o
+ is in. */
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*crtbegin?.o(.ctors))
+ /* We don't want to include the .ctor section from
+ the crtend.o file until after the sorted ctors.
+ The .ctor section from the crtend file contains the
+ end of ctors marker and it must be last */
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ } :text =0xcccc
+ .dtors :
+ {
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*crtbegin?.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ } :text =0xcccc
+#endif
+
/* End of text section, which should occupy whole number of pages */
_etext = .;
. = ALIGN(PAGE_SIZE);
@@ -208,6 +276,29 @@ SECTIONS

. = ALIGN(__vvar_page + PAGE_SIZE, PAGE_SIZE);

+#ifdef CONFIG_UNIKERNEL_LINUX
+#ifdef CONFIG_UKL_TLS
+ /* Thread Local Storage sections */
+ . = ALIGN(PAGE_SIZE);
+ .tdata : ALIGN(0x200000){
+ __tls_data_start = .;
+ *(.tdata .tdata.* .gnu.linkonce.td.*)
+ __tls_data_end = .;
+ } :tls
+ .tbss : {
+ __tls_bss_start = .;
+ *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon)
+ __tls_bss_end = .;
+ } :tls
+#else
+ . = ALIGN(PAGE_SIZE);
+ __tls_data_start = .;
+ __tls_data_end = .;
+ __tls_bss_start = .;
+ __tls_bss_end = .;
+#endif
+#endif
+
/* Init code and data - will be freed after init */
. = ALIGN(PAGE_SIZE);
.init.begin : AT(ADDR(.init.begin) - LOAD_OFFSET) {
@@ -380,8 +471,13 @@ SECTIONS
*(BSS_MAIN)
BSS_DECRYPTED
. = ALIGN(PAGE_SIZE);
+#ifdef CONFIG_UNIKERNEL_LINUX
+ }
+ __bss_stop = .;
+#else
__bss_stop = .;
}
+#endif

/*
* The memory occupied from _text to here, __end_of_kernel_reserve, is
@@ -446,6 +542,7 @@ SECTIONS
#endif
"Unexpected GOT/PLT entries detected!")

+#ifndef CONFIG_UNIKERNEL_LINUX
/*
* Sections that should stay zero sized, which is safer to
* explicitly check instead of blindly discarding.
@@ -469,6 +566,7 @@ SECTIONS
*(.rela.*) *(.rela_*)
}
ASSERT(SIZEOF(.rela.dyn) == 0, "Unexpected run-time relocations (.rela) detected!")
+#endif
}

/*
diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
index db13bb620f52..42ebf251903c 100644
--- a/include/asm-generic/sections.h
+++ b/include/asm-generic/sections.h
@@ -35,6 +35,10 @@
extern char _text[], _stext[], _etext[];
extern char _data[], _sdata[], _edata[];
extern char __bss_start[], __bss_stop[];
+#ifdef CONFIG_UNIKERNEL_LINUX
+extern char __tls_data_start[], __tls_data_end[];
+extern char __tls_bss_start[], __tls_bss_end[];
+#endif
extern char __init_begin[], __init_end[];
extern char _sinittext[], _einittext[];
extern char __start_ro_after_init[], __end_ro_after_init[];
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 7c90b1ab3e00..4b0e4f3d4c39 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -568,6 +568,24 @@
* code elimination is enabled, so these sections should be converted
* to use ".." first.
*/
+#ifdef CONFIG_UNIKERNEL_LINUX
+#define TEXT_TEXT \
+ ALIGN_FUNCTION(); \
+ *(.text.hot .text.hot.*) \
+ *(TEXT_MAIN .text.fixup) \
+ *(.stub .text.* .gnu.linkonce.t.*) \
+ *(.text.unlikely .text.*_unlikely .text.unlikely.*) \
+ *(.text.exit .text.exit.*) \
+ *(.text.startup .text.startup.*) \
+ *(.text.unknown .text.unknown.*) \
+ NOINSTR_TEXT \
+ *(.text..refcount) \
+ *(.ref.text) \
+ *(.text.asan.* .text.tsan.*) \
+ TEXT_CFI_JT \
+ MEM_KEEP(init.text*) \
+ MEM_KEEP(exit.text*)
+#else
#define TEXT_TEXT \
ALIGN_FUNCTION(); \
*(.text.hot .text.hot.*) \
@@ -580,7 +598,8 @@
*(.text.asan.* .text.tsan.*) \
TEXT_CFI_JT \
MEM_KEEP(init.text*) \
- MEM_KEEP(exit.text*) \
+ MEM_KEEP(exit.text*)
+#endif


/* sched.text is aling to function alignment to secure we have same
@@ -1029,12 +1048,23 @@
/* ld.bfd warns about .gnu.version* even when not emitted */ \
*(.gnu.version*) \

+#ifdef CONFIG_UNIKERNEL_LINUX
+#define DISCARDS \
+ /DISCARD/ : { \
+ EXIT_DISCARDS \
+ EXIT_CALL \
+ COMMON_DISCARDS \
+ *(.gnu.glibc-stub.*) \
+ *(.gnu.warning.*) \
+ }
+#else
#define DISCARDS \
/DISCARD/ : { \
EXIT_DISCARDS \
EXIT_CALL \
COMMON_DISCARDS \
}
+#endif

/**
* PERCPU_INPUT - the percpu input sections
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 2c80da0220c3..a6023db6b630 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -626,6 +626,8 @@ static void handle_symbol(struct module *mod, struct elf_info *info,
case SHN_COMMON:
if (strstarts(symname, "__gnu_lto_")) {
/* Should warn here, but modpost runs before the linker */
+ } else if (strstarts(symname, "ukl_")) {
+ /* User code can have common symbols */
} else
warn("\"%s\" [%s] is COMMON symbol\n", symname, mod->name);
break;
@@ -774,6 +776,8 @@ static const char *const section_white_list[] =
".fmt_slot*", /* EZchip */
".gnu.lto*",
".discard.*",
+ ".gnu.warning.*",
+ ".gnu.glibc-stub.*",
NULL
};

--
2.21.3