Commit 996f7f29 authored by Ilya Leoshkevich's avatar Ilya Leoshkevich Committed by Alexander Gordeev
Browse files

s390/boot: Introduce jump_to_kernel() function



Introduce a global function that jumps from the decompressor to the
decompressed kernel. Put its address into svc_old_psw, from where GDB
can take it without loading decompressor symbols. It should be
available throughout the entire decompressor execution, because it's
placed there statically, and nothing in the decompressor uses the SVC
instruction.

Acked-by: default avatarHeiko Carstens <hca@linux.ibm.com>
Signed-off-by: default avatarIlya Leoshkevich <iii@linux.ibm.com>
Tested-by: default avatarAlexander Gordeev <agordeev@linux.ibm.com>
Link: https://lore.kernel.org/r/20250625154220.75300-2-iii@linux.ibm.com


Signed-off-by: default avatarAlexander Gordeev <agordeev@linux.ibm.com>
parent b367017c
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -27,7 +27,7 @@ CFLAGS_sclp_early_core.o += -I$(srctree)/drivers/s390/char
obj-y	:= head.o als.o startup.o physmem_info.o ipl_parm.o ipl_report.o vmem.o
obj-y	+= string.o ebcdic.o sclp_early_core.o mem.o ipl_vmparm.o cmdline.o
obj-y	+= version.o pgm_check.o ctype.o ipl_data.o relocs.o alternative.o
obj-y	+= uv.o printk.o
obj-y	+= uv.o printk.o trampoline.o
obj-$(CONFIG_RANDOMIZE_BASE)	+= kaslr.o
obj-y	+= $(if $(CONFIG_KERNEL_UNCOMPRESSED),,decompressor.o) info.o
obj-$(CONFIG_KERNEL_ZSTD) += clz_ctz.o
+1 −0
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ void print_stacktrace(unsigned long sp);
void error(char *m);
int get_random(unsigned long limit, unsigned long *value);
void boot_rb_dump(void);
void __noreturn jump_to_kernel(psw_t *psw);

#ifndef boot_fmt
#define boot_fmt(fmt)	fmt
+8 −1
Original line number Diff line number Diff line
@@ -16,7 +16,9 @@ struct ipl_lowcore {
	struct ccw0	ccwpgm[2];			/* 0x0008 */
	u8		fill[56];			/* 0x0018 */
	struct ccw0	ccwpgmcc[20];			/* 0x0050 */
	u8		pad_0xf0[0x01a0-0x00f0];	/* 0x00f0 */
	u8		pad_0xf0[0x0140-0x00f0];	/* 0x00f0 */
	psw_t		svc_old_psw;			/* 0x0140 */
	u8		pad_0x150[0x01a0-0x0150];	/* 0x0150 */
	psw_t		restart_psw;			/* 0x01a0 */
	psw_t		external_new_psw;		/* 0x01b0 */
	psw_t		svc_new_psw;			/* 0x01c0 */
@@ -75,6 +77,11 @@ static struct ipl_lowcore ipl_lowcore __used __section(".ipldata") = {
		[18] = CCW0(CCW_CMD_READ_IPL, 0x690, 0x50, CCW_FLAG_SLI | CCW_FLAG_CC),
		[19] = CCW0(CCW_CMD_READ_IPL, 0x6e0, 0x50, CCW_FLAG_SLI),
	},
	/*
	 * Let the GDB's lx-symbols command find the jump_to_kernel symbol
	 * without having to load decompressor symbols.
	 */
	.svc_old_psw	  = { .mask = 0, .addr = (unsigned long)jump_to_kernel },
	.restart_psw	  = { .mask = 0, .addr = IPL_START, },
	.external_new_psw = { .mask = PSW_MASK_DISABLED, .addr = __LC_EXT_NEW_PSW, },
	.svc_new_psw	  = { .mask = PSW_MASK_DISABLED, .addr = __LC_SVC_NEW_PSW, },
+1 −1
Original line number Diff line number Diff line
@@ -642,5 +642,5 @@ void startup_kernel(void)
	psw.addr = __kaslr_offset + vmlinux.entry;
	psw.mask = PSW_KERNEL_BITS;
	boot_debug("Starting kernel at:  0x%016lx\n", psw.addr);
	__load_psw(psw);
	jump_to_kernel(&psw);
}
+9 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */

#include <linux/linkage.h>

# This function is identical to __load_psw(), but the lx-symbols GDB command
# puts a breakpoint on it, so it needs to be kept separate.
SYM_CODE_START(jump_to_kernel)
	lpswe 0(%r2)
SYM_CODE_END(jump_to_kernel)