summaryrefslogtreecommitdiff
path: root/arch/s390/boot
diff options
context:
space:
mode:
authorVasily Gorbik <gor@linux.ibm.com>2018-07-19 13:11:28 +0200
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2018-10-09 11:21:02 +0200
commit8f75582a2fb6e2c5afc5252b6d6932f61a79c939 (patch)
treece09a3124eabde2b2e88f03d030f2a54ecbe450a /arch/s390/boot
parent32ce55a6592fc3e117e70953001a9ea1931f7941 (diff)
s390: remove decompressor's head.S
Decompressor's head.S provided "data mover" sole purpose of which has been to safely move uncompressed kernel at 0x100000 and jump to it. With current bzImage layout entire decompressor's code guaranteed to be in a safe location under 0x100000, and hence could not be overwritten during kernel move. For that reason head.S could be replaced with simple memmove function. To do so introduce early boot code phase which is executed from arch/s390/boot/head.S after "verify_facilities" and takes care of optional kernel image decompression and transition to it. Reviewed-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/boot')
-rw-r--r--arch/s390/boot/Makefile2
-rw-r--r--arch/s390/boot/boot.h7
-rw-r--r--arch/s390/boot/compressed/Makefile5
-rw-r--r--arch/s390/boot/compressed/decompressor.h11
-rw-r--r--arch/s390/boot/compressed/head.S52
-rw-r--r--arch/s390/boot/compressed/misc.c7
-rw-r--r--arch/s390/boot/head.S6
-rw-r--r--arch/s390/boot/startup.c17
8 files changed, 43 insertions, 64 deletions
diff --git a/arch/s390/boot/Makefile b/arch/s390/boot/Makefile
index 9e6668ee93de..1b5a95b1ab09 100644
--- a/arch/s390/boot/Makefile
+++ b/arch/s390/boot/Makefile
@@ -27,7 +27,7 @@ endif
CFLAGS_sclp_early_core.o += -I$(srctree)/drivers/s390/char
-obj-y := head.o als.o ebcdic.o sclp_early_core.o mem.o
+obj-y := head.o als.o startup.o ebcdic.o sclp_early_core.o mem.o
targets := bzImage startup.a $(obj-y)
subdir- := compressed
diff --git a/arch/s390/boot/boot.h b/arch/s390/boot/boot.h
new file mode 100644
index 000000000000..36c93e6cbc3f
--- /dev/null
+++ b/arch/s390/boot/boot.h
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef BOOT_BOOT_H
+#define BOOT_BOOT_H
+
+void startup_kernel(void);
+
+#endif /* BOOT_BOOT_H */
diff --git a/arch/s390/boot/compressed/Makefile b/arch/s390/boot/compressed/Makefile
index 04609478d18b..c16ded8a35be 100644
--- a/arch/s390/boot/compressed/Makefile
+++ b/arch/s390/boot/compressed/Makefile
@@ -9,7 +9,7 @@ KCOV_INSTRUMENT := n
GCOV_PROFILE := n
UBSAN_SANITIZE := n
-obj-y := $(if $(CONFIG_KERNEL_UNCOMPRESSED),,head.o misc.o) piggy.o
+obj-y := $(if $(CONFIG_KERNEL_UNCOMPRESSED),,misc.o) piggy.o
targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2
targets += vmlinux.bin.xz vmlinux.bin.lzma vmlinux.bin.lzo vmlinux.bin.lz4
targets += vmlinux.scr.lds $(obj-y) $(if $(CONFIG_KERNEL_UNCOMPRESSED),,sizes.h)
@@ -32,9 +32,6 @@ quiet_cmd_sizes = GEN $@
$(obj)/sizes.h: vmlinux
$(call if_changed,sizes)
-AFLAGS_head.o += -I$(objtree)/$(obj)
-$(obj)/head.o: $(obj)/sizes.h
-
CFLAGS_misc.o += -I$(objtree)/$(obj)
$(obj)/misc.o: $(obj)/sizes.h
diff --git a/arch/s390/boot/compressed/decompressor.h b/arch/s390/boot/compressed/decompressor.h
new file mode 100644
index 000000000000..0dd0b84679c4
--- /dev/null
+++ b/arch/s390/boot/compressed/decompressor.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef BOOT_COMPRESSED_DECOMPRESSOR_H
+#define BOOT_COMPRESSED_DECOMPRESSOR_H
+
+#ifdef CONFIG_KERNEL_UNCOMPRESSED
+static inline void *decompress_kernel(unsigned long *uncompressed_size) {}
+#else
+void *decompress_kernel(unsigned long *uncompressed_size);
+#endif
+
+#endif /* BOOT_COMPRESSED_DECOMPRESSOR_H */
diff --git a/arch/s390/boot/compressed/head.S b/arch/s390/boot/compressed/head.S
deleted file mode 100644
index 4041fcfd8980..000000000000
--- a/arch/s390/boot/compressed/head.S
+++ /dev/null
@@ -1,52 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Startup glue code to uncompress the kernel
- *
- * Copyright IBM Corp. 2010
- *
- * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
- */
-
-#include <linux/init.h>
-#include <linux/linkage.h>
-#include <asm/asm-offsets.h>
-#include <asm/thread_info.h>
-#include <asm/page.h>
-#include <asm/ptrace.h>
-#include "sizes.h"
-
-__HEAD
-ENTRY(startup_decompressor)
- basr %r13,0 # get base
-.LPG1:
- # setup stack
- lg %r15,.Lstack-.LPG1(%r13)
- brasl %r14,decompress_kernel
- # Set up registers for memory mover. We move the decompressed image to
- # 0x100000, where startup_continue of the decompressed image is supposed
- # to be.
- lgr %r4,%r2
- lg %r2,.Loffset-.LPG1(%r13)
- lg %r3,.Lmvsize-.LPG1(%r13)
- lgr %r5,%r3
- # Move the memory mover someplace safe so it doesn't overwrite itself.
- la %r1,0x200
- mvc 0(mover_end-mover,%r1),mover-.LPG1(%r13)
- # When the memory mover is done we pass control to
- # arch/s390/kernel/head64.S:startup_continue which lives at 0x100000 in
- # the decompressed image.
- lgr %r6,%r2
- br %r1
-mover:
- mvcle %r2,%r4,0
- jo mover
- br %r6
-mover_end:
-
- .align 8
-.Lstack:
- .quad 0x8000 + THREAD_SIZE - STACK_FRAME_OVERHEAD
-.Loffset:
- .quad 0x100000
-.Lmvsize:
- .quad SZ__bss_start
diff --git a/arch/s390/boot/compressed/misc.c b/arch/s390/boot/compressed/misc.c
index f66ad73c205b..321f6151ded9 100644
--- a/arch/s390/boot/compressed/misc.c
+++ b/arch/s390/boot/compressed/misc.c
@@ -12,6 +12,7 @@
#include <asm/sclp.h>
#include <asm/ipl.h>
#include "sizes.h"
+#include "decompressor.h"
/*
* gzip declarations
@@ -82,7 +83,7 @@ static void error(char *x)
asm volatile("lpsw %0" : : "Q" (psw));
}
-unsigned long decompress_kernel(void)
+void *decompress_kernel(unsigned long *uncompressed_size)
{
void *output, *kernel_end;
@@ -111,6 +112,8 @@ unsigned long decompress_kernel(void)
free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
__decompress(input_data, input_len, NULL, NULL, output, 0, NULL, error);
- return (unsigned long) output;
+ if (uncompressed_size)
+ *uncompressed_size = SZ__bss_start;
+ return output;
}
diff --git a/arch/s390/boot/head.S b/arch/s390/boot/head.S
index d0736a05bc7f..e209cfe69bb9 100644
--- a/arch/s390/boot/head.S
+++ b/arch/s390/boot/head.S
@@ -312,11 +312,7 @@ ENTRY(startup_kdump)
mvc __LC_LAST_UPDATE_TIMER(8),6f-.LPG0(%r13)
l %r15,.Lstack-.LPG0(%r13)
brasl %r14,verify_facilities
-#ifdef CONFIG_KERNEL_UNCOMPRESSED
- jg startup_continue
-#else
- jg startup_decompressor
-#endif
+ brasl %r14,startup_kernel
.Lstack:
.long 0x8000 + THREAD_SIZE - STACK_FRAME_OVERHEAD
diff --git a/arch/s390/boot/startup.c b/arch/s390/boot/startup.c
new file mode 100644
index 000000000000..2a9ce355f8e6
--- /dev/null
+++ b/arch/s390/boot/startup.c
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/string.h>
+#include "compressed/decompressor.h"
+#include "boot.h"
+
+void startup_kernel(void)
+{
+ void (*startup_continue)(void) = (void *)0x100000;
+ unsigned long uncompressed_size;
+ void *uncompressed_img;
+
+ if (!IS_ENABLED(CONFIG_KERNEL_UNCOMPRESSED)) {
+ uncompressed_img = decompress_kernel(&uncompressed_size);
+ memmove(startup_continue, uncompressed_img, uncompressed_size);
+ }
+ startup_continue();
+}