Commit 256d78d0 authored by Alexander Egorenkov's avatar Alexander Egorenkov Committed by Heiko Carstens
Browse files

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: default avatarAlexander Egorenkov <egorenar@linux.ibm.com>
Acked-by: default avatarHeiko Carstens <hca@linux.ibm.com>
Reviewed-by: default avatarVasily Gorbik <gor@linux.ibm.com>
Signed-off-by: default avatarHeiko Carstens <hca@linux.ibm.com>
parent 7fadcc07
Loading
Loading
Loading
Loading
+2 −7
Original line number Diff line number Diff line
@@ -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);
@@ -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 −0
Original line number Diff line number Diff line
/* 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)
@@ -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 = .;
	}

+2 −8
Original line number Diff line number Diff line
@@ -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

@@ -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)
+2 −2
Original line number Diff line number Diff line
@@ -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;