s390/early: move functions which may not access bss section to extra file
authorHeiko Carstens <heiko.carstens@de.ibm.com>
Fri, 4 May 2018 11:22:12 +0000 (13:22 +0200)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Wed, 9 May 2018 08:55:01 +0000 (10:55 +0200)
Move functions which may not access bss section to extra file. This
makes it easier to verify that all early functions which may not rely
on an initialized bss section are not accessing it.

Reviewed-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
arch/s390/kernel/Makefile
arch/s390/kernel/early.c
arch/s390/kernel/early_nobss.c [new file with mode: 0644]
arch/s390/kernel/entry.h
arch/s390/kernel/head64.S

index f92dd8ed3884ae4dbd4bc2f47d30248e794241e1..b5146697ab501da8a9fe4dadef8f6819cc42703c 100644 (file)
@@ -6,22 +6,26 @@
 ifdef CONFIG_FUNCTION_TRACER
 
 # Do not trace tracer code
-CFLAGS_REMOVE_ftrace.o = $(CC_FLAGS_FTRACE)
+CFLAGS_REMOVE_ftrace.o         = $(CC_FLAGS_FTRACE)
 
 # Do not trace early setup code
-CFLAGS_REMOVE_als.o    = $(CC_FLAGS_FTRACE)
-CFLAGS_REMOVE_early.o  = $(CC_FLAGS_FTRACE)
+CFLAGS_REMOVE_als.o            = $(CC_FLAGS_FTRACE)
+CFLAGS_REMOVE_early.o          = $(CC_FLAGS_FTRACE)
+CFLAGS_REMOVE_early_nobss.o    = $(CC_FLAGS_FTRACE)
 
 endif
 
-GCOV_PROFILE_als.o     := n
-GCOV_PROFILE_early.o   := n
+GCOV_PROFILE_als.o             := n
+GCOV_PROFILE_early.o           := n
+GCOV_PROFILE_early_nobss.o     := n
 
-KCOV_INSTRUMENT_als.o  := n
-KCOV_INSTRUMENT_early.o        := n
+KCOV_INSTRUMENT_als.o          := n
+KCOV_INSTRUMENT_early.o                := n
+KCOV_INSTRUMENT_early_nobss.o  := n
 
-UBSAN_SANITIZE_als.o   := n
-UBSAN_SANITIZE_early.o := n
+UBSAN_SANITIZE_als.o           := n
+UBSAN_SANITIZE_early.o         := n
+UBSAN_SANITIZE_early_nobss.o   := n
 
 #
 # Use -march=z900 for als.c to be able to print an error
@@ -57,7 +61,7 @@ CFLAGS_ptrace.o               += -DUTS_MACHINE='"$(UTS_MACHINE)"'
 
 obj-y  := traps.o time.o process.o base.o early.o setup.o idle.o vtime.o
 obj-y  += processor.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o nmi.o
-obj-y  += debug.o irq.o ipl.o dis.o diag.o vdso.o als.o
+obj-y  += debug.o irq.o ipl.o dis.o diag.o vdso.o als.o early_nobss.o
 obj-y  += sysinfo.o jump_label.o lgr.o os_info.o machine_kexec.o pgm_check.o
 obj-y  += runtime_instr.o cache.o fpu.o dumpstack.o guarded_storage.o sthyi.o
 obj-y  += entry.o reipl.o relocate_kernel.o kdebugfs.o alternative.o
index 4f6527d4747b7476ad0f944f7f9dde5cfbd17d42..827699eb48fa98c7cbd869a62d1e8e303d293483 100644 (file)
 
 static void __init setup_boot_command_line(void);
 
-/*
- * Get the TOD clock running.
- */
-static void __init reset_tod_clock(void)
-{
-       u64 time;
-
-       if (store_tod_clock(&time) == 0)
-               return;
-       /* TOD clock not running. Set the clock to Unix Epoch. */
-       if (set_tod_clock(TOD_UNIX_EPOCH) != 0 || store_tod_clock(&time) != 0)
-               disabled_wait(0);
-
-       memset(tod_clock_base, 0, 16);
-       *(__u64 *) &tod_clock_base[1] = TOD_UNIX_EPOCH;
-       S390_lowcore.last_update_clock = TOD_UNIX_EPOCH;
-}
-
-/*
- * Clear bss memory
- */
-static noinline __init void clear_bss_section(void)
-{
-       memset(__bss_start, 0, __bss_stop - __bss_start);
-}
-
 /*
  * Initialize storage key for kernel pages
  */
@@ -310,26 +284,6 @@ static int __init cad_setup(char *str)
 }
 early_param("cad", cad_setup);
 
-static __init noinline void rescue_initrd(void)
-{
-       unsigned long min_initrd_addr = (unsigned long) _end + (4UL << 20);
-
-       /*
-        * Just like in case of IPL from VM reader we make sure there is a
-        * gap of 4MB between end of kernel and start of initrd.
-        * That way we can also be sure that saving an NSS will succeed,
-        * which however only requires different segments.
-        */
-       if (!IS_ENABLED(CONFIG_BLK_DEV_INITRD))
-               return;
-       if (!INITRD_START || !INITRD_SIZE)
-               return;
-       if (INITRD_START >= min_initrd_addr)
-               return;
-       memmove((void *) min_initrd_addr, (void *) INITRD_START, INITRD_SIZE);
-       INITRD_START = min_initrd_addr;
-}
-
 /* Set up boot command line */
 static void __init append_to_cmdline(size_t (*ipl_data)(char *, size_t))
 {
@@ -379,9 +333,6 @@ static void __init setup_boot_command_line(void)
 
 void __init startup_init(void)
 {
-       reset_tod_clock();
-       rescue_initrd();
-       clear_bss_section();
        time_early_init();
        init_kernel_storage_key();
        lockdep_off();
diff --git a/arch/s390/kernel/early_nobss.c b/arch/s390/kernel/early_nobss.c
new file mode 100644 (file)
index 0000000..2d84fc4
--- /dev/null
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *    Copyright IBM Corp. 2007, 2018
+ */
+
+/*
+ * Early setup functions which may not rely on an initialized bss
+ * section. The last thing that is supposed to happen here is
+ * initialization of the bss section.
+ */
+
+#include <linux/processor.h>
+#include <linux/string.h>
+#include <asm/sections.h>
+#include <asm/lowcore.h>
+#include <asm/setup.h>
+#include <asm/timex.h>
+#include "entry.h"
+
+static void __init reset_tod_clock(void)
+{
+       u64 time;
+
+       if (store_tod_clock(&time) == 0)
+               return;
+       /* TOD clock not running. Set the clock to Unix Epoch. */
+       if (set_tod_clock(TOD_UNIX_EPOCH) != 0 || store_tod_clock(&time) != 0)
+               disabled_wait(0);
+
+       memset(tod_clock_base, 0, 16);
+       *(__u64 *) &tod_clock_base[1] = TOD_UNIX_EPOCH;
+       S390_lowcore.last_update_clock = TOD_UNIX_EPOCH;
+}
+
+static void __init rescue_initrd(void)
+{
+       unsigned long min_initrd_addr = (unsigned long) _end + (4UL << 20);
+
+       /*
+        * Just like in case of IPL from VM reader we make sure there is a
+        * gap of 4MB between end of kernel and start of initrd.
+        * That way we can also be sure that saving an NSS will succeed,
+        * which however only requires different segments.
+        */
+       if (!IS_ENABLED(CONFIG_BLK_DEV_INITRD))
+               return;
+       if (!INITRD_START || !INITRD_SIZE)
+               return;
+       if (INITRD_START >= min_initrd_addr)
+               return;
+       memmove((void *) min_initrd_addr, (void *) INITRD_START, INITRD_SIZE);
+       INITRD_START = min_initrd_addr;
+}
+
+static void __init clear_bss_section(void)
+{
+       memset(__bss_start, 0, __bss_stop - __bss_start);
+}
+
+void __init startup_init_nobss(void)
+{
+       reset_tod_clock();
+       rescue_initrd();
+       clear_bss_section();
+}
index e87758f8fbdccfa9540989bef0984a360d7ed686..961abfac2c5fb0b39d6a11a21c1292c6138dbf6c 100644 (file)
@@ -58,6 +58,7 @@ void do_notify_resume(struct pt_regs *regs);
 void __init init_IRQ(void);
 void do_IRQ(struct pt_regs *regs, int irq);
 void do_restart(void);
+void __init startup_init_nobss(void);
 void __init startup_init(void);
 void die(struct pt_regs *regs, const char *str);
 int setup_profiling_timer(unsigned int multiplier);
index 38a973ccf50108b423683496ee4daa28ab2382d6..791cb9000e8658fdb6b17cce1550e88ddf1055cc 100644 (file)
@@ -40,8 +40,12 @@ ENTRY(startup_continue)
        stg     %r15,__LC_KERNEL_STACK  # set end of kernel stack
        aghi    %r15,-160
 #
-# Save ipl parameters, clear bss memory, initialize storage key for kernel pages,
-# and create a kernel NSS if the SAVESYS= parm is defined
+# Early setup functions that may not rely on an initialized bss section,
+# like moving the initrd. Returns with an initialized bss section.
+#
+       brasl   %r14,startup_init_nobss
+#
+# Early machine initialization and detection functions.
 #
        brasl   %r14,startup_init
        lpswe   .Lentry-.LPG1(13)       # jump to _stext in primary-space,