Skip to content

Commit

Permalink
s390/boot: make stacks part of the decompressor's image
Browse files Browse the repository at this point in the history
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 <[email protected]>
Acked-by: Heiko Carstens <[email protected]>
Reviewed-by: Vasily Gorbik <[email protected]>
Signed-off-by: Heiko Carstens <[email protected]>
  • Loading branch information
eaibmz authored and hcahca committed Jul 27, 2021
1 parent 7fadcc0 commit 256d78d
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 17 deletions.
9 changes: 2 additions & 7 deletions arch/s390/boot/boot.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,8 @@
#ifndef BOOT_BOOT_H
#define BOOT_BOOT_H

#include <linux/types.h>

#define BOOT_STACK_OFFSET 0x8000

#ifndef __ASSEMBLY__

#include <asm/extable.h>
#include <linux/types.h>

void startup_kernel(void);
unsigned long detect_memory(void);
Expand All @@ -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 */
13 changes: 13 additions & 0 deletions arch/s390/boot/compressed/vmlinux.lds.S
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0 */
#include <asm-generic/vmlinux.lds.h>
#include <asm/vmlinux.lds.h>
#include <asm/thread_info.h>
#include <asm/page.h>

OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390")
OUTPUT_ARCH(s390:64-bit)
Expand Down Expand Up @@ -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 = .;
}

Expand Down
10 changes: 2 additions & 8 deletions arch/s390/boot/head.S
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,8 @@
#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 "boot.h"

#define ARCH_OFFSET 4

Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions arch/s390/boot/pgm_check_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ void decompressor_printk(const char *fmt, ...)

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;

Expand Down

0 comments on commit 256d78d

Please sign in to comment.