From: Alexander Egorenkov Date: Wed, 30 Jun 2021 15:17:53 +0000 (+0200) Subject: s390/boot: make stacks part of the decompressor's image X-Git-Tag: v5.15-rc1~206^2~103 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=256d78d08177d72ae27621378699c9b35231d524;p=thirdparty%2Fkernel%2Flinux.git s390/boot: make stacks part of the decompressor's image Instead of using constant addresses for the normal and dump-info stacks, allocate both stacks in the decompressor's image and load the stack register in a position-independent manner. This will allow loading and entering the decompressor at an arbitrary memory address without corrupting the content at the fixed addresses used until now for both stacks. This is one of the prerequisites for being able to kexec the decompressor from its load address without relocating it first. Signed-off-by: Alexander Egorenkov Acked-by: Heiko Carstens Reviewed-by: Vasily Gorbik Signed-off-by: Heiko Carstens --- diff --git a/arch/s390/boot/boot.h b/arch/s390/boot/boot.h index 937dbdd0ef435..3d7d5ef4d1690 100644 --- a/arch/s390/boot/boot.h +++ b/arch/s390/boot/boot.h @@ -2,13 +2,8 @@ #ifndef BOOT_BOOT_H #define BOOT_BOOT_H -#include - -#define BOOT_STACK_OFFSET 0x8000 - -#ifndef __ASSEMBLY__ - #include +#include void startup_kernel(void); unsigned long detect_memory(void); @@ -35,8 +30,8 @@ extern char _stext_dma[], _etext_dma[]; extern struct exception_table_entry _start_dma_ex_table[]; extern struct exception_table_entry _stop_dma_ex_table[]; extern char _decompressor_syms_start[], _decompressor_syms_end[]; +extern char _stack_start[], _stack_end[]; unsigned long read_ipl_report(unsigned long safe_offset); -#endif /* __ASSEMBLY__ */ #endif /* BOOT_BOOT_H */ diff --git a/arch/s390/boot/compressed/vmlinux.lds.S b/arch/s390/boot/compressed/vmlinux.lds.S index 27a09c1c78f6a..0bd8aaaa4b332 100644 --- a/arch/s390/boot/compressed/vmlinux.lds.S +++ b/arch/s390/boot/compressed/vmlinux.lds.S @@ -1,6 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0 */ #include #include +#include +#include OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390") OUTPUT_ARCH(s390:64-bit) @@ -69,6 +71,17 @@ SECTIONS *(.bss) *(.bss.*) *(COMMON) + /* + * Stacks for the decompressor + */ + . = ALIGN(PAGE_SIZE); + _dump_info_stack_start = .; + . += PAGE_SIZE; + _dump_info_stack_end = .; + . = ALIGN(PAGE_SIZE); + _stack_start = .; + . += BOOT_STACK_SIZE; + _stack_end = .; _ebss = .; } diff --git a/arch/s390/boot/head.S b/arch/s390/boot/head.S index 51693cfb65c2c..cafe454703b82 100644 --- a/arch/s390/boot/head.S +++ b/arch/s390/boot/head.S @@ -25,10 +25,8 @@ #include #include #include -#include #include #include -#include "boot.h" #define ARCH_OFFSET 4 @@ -320,13 +318,11 @@ SYM_CODE_START_LOCAL(startup_normal) mvc __LC_LAST_UPDATE_CLOCK(8),__LC_BOOT_CLOCK+1 spt 6f-.LPG0(%r13) mvc __LC_LAST_UPDATE_TIMER(8),6f-.LPG0(%r13) - l %r15,.Lstack-.LPG0(%r13) + larl %r15,_stack_end-STACK_FRAME_OVERHEAD brasl %r14,verify_facilities brasl %r14,startup_kernel SYM_CODE_END(startup_normal) -.Lstack: - .long BOOT_STACK_OFFSET + BOOT_STACK_SIZE - STACK_FRAME_OVERHEAD .align 8 6: .long 0x7fffffff,0xffffffff .Lext_new_psw: @@ -386,15 +382,13 @@ SYM_CODE_START_LOCAL(startup_pgm_check_handler) oi __LC_RETURN_PSW+1,0x2 # set wait state bit larl %r9,.Lold_psw_disabled_wait stg %r9,__LC_PGM_NEW_PSW+8 - l %r15,.Ldump_info_stack-.Lold_psw_disabled_wait(%r9) + larl %r15,_dump_info_stack_end-STACK_FRAME_OVERHEAD brasl %r14,print_pgm_check_info .Lold_psw_disabled_wait: la %r8,4095 lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r8) lpswe __LC_RETURN_PSW # disabled wait SYM_CODE_END(startup_pgm_check_handler) -.Ldump_info_stack: - .long 0x5000 + PAGE_SIZE - STACK_FRAME_OVERHEAD # # params at 10400 (setup.h) diff --git a/arch/s390/boot/pgm_check_info.c b/arch/s390/boot/pgm_check_info.c index 7126a1b3293de..209f6ae5a1972 100644 --- a/arch/s390/boot/pgm_check_info.c +++ b/arch/s390/boot/pgm_check_info.c @@ -125,8 +125,8 @@ out: static noinline void print_stacktrace(void) { - struct stack_info boot_stack = { STACK_TYPE_TASK, BOOT_STACK_OFFSET, - BOOT_STACK_OFFSET + BOOT_STACK_SIZE }; + struct stack_info boot_stack = { STACK_TYPE_TASK, (unsigned long)_stack_start, + (unsigned long)_stack_end }; unsigned long sp = S390_lowcore.gpregs_save_area[15]; bool first = true;