Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

s390/boot: move sclp early buffer from fixed address in asm to C

To make the decompressor relocatable, the early SCLP buffer with a fixed
address must be replaced with a relocatable C buffer of the according size
and alignment as required by SCLP.

Introduce a new function sclp_early_set_buffer() into the SCLP driver
which enables the decompressor to change the SCLP early buffer at any time.
This will be useful when the decompressor becomes fully relocatable and
might need to change the SCLP early buffer to one with an address < 2G
as required by SCLP because it was loaded at an address >= 2G.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Acked-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>

authored by

Alexander Egorenkov and committed by
Heiko Carstens
f1d3c532 8b6bd6f2

+23 -8
+1
arch/s390/boot/boot.h
··· 13 13 void parse_boot_command_line(void); 14 14 void verify_facilities(void); 15 15 void print_missing_facilities(void); 16 + void sclp_early_setup_buffer(void); 16 17 void print_pgm_check_info(void); 17 18 unsigned long get_random_base(unsigned long safe_addr); 18 19 void __printf(1, 2) decompressor_printk(const char *fmt, ...);
+4 -1
arch/s390/boot/compressed/vmlinux.lds.S
··· 3 3 #include <asm/vmlinux.lds.h> 4 4 #include <asm/thread_info.h> 5 5 #include <asm/page.h> 6 + #include <asm/sclp.h> 6 7 7 8 OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390") 8 9 OUTPUT_ARCH(s390:64-bit) ··· 55 54 KEEP(*(.dma.ex_table)) 56 55 _stop_dma_ex_table = .; 57 56 } 58 - .dma.data : { *(.dma.data) } 57 + .dma.data : { 58 + *(.dma.data) 59 + } 59 60 . = ALIGN(PAGE_SIZE); 60 61 _edma = .; 61 62
+1 -3
arch/s390/boot/head.S
··· 320 320 spt 6f-.LPG0(%r13) 321 321 mvc __LC_LAST_UPDATE_TIMER(8),6f-.LPG0(%r13) 322 322 larl %r15,_stack_end-STACK_FRAME_OVERHEAD 323 + brasl %r14,sclp_early_setup_buffer 323 324 brasl %r14,verify_facilities 324 325 brasl %r14,startup_kernel 325 326 SYM_CODE_END(startup_normal) ··· 410 409 .byte 0 411 410 .org PARMAREA+__PARMAREA_SIZE 412 411 SYM_DATA_END(parmarea) 413 - 414 - .org EARLY_SCCB_OFFSET 415 - .fill EXT_SCCB_READ_SCP 416 412 417 413 .org HEAD_END
+9
arch/s390/boot/sclp_early_core.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 + #include "boot.h" 2 3 #include "../../../drivers/s390/char/sclp_early_core.c" 4 + 5 + /* SCLP early buffer must stay page-aligned and below 2GB */ 6 + static char __sclp_early_sccb[EXT_SCCB_READ_SCP] __aligned(PAGE_SIZE); 7 + 8 + void sclp_early_setup_buffer(void) 9 + { 10 + sclp_early_set_buffer(&__sclp_early_sccb); 11 + }
+1
arch/s390/include/asm/sclp.h
··· 115 115 u8 data[0]; /* Subsequent Data passed verbatim to SCLP ET 24 */ 116 116 } __packed; 117 117 118 + void sclp_early_set_buffer(void *sccb); 118 119 int sclp_early_read_info(void); 119 120 int sclp_early_read_storage_info(void); 120 121 int sclp_early_get_core_info(struct sclp_core_info *info);
+1 -3
arch/s390/include/asm/setup.h
··· 7 7 #define _ASM_S390_SETUP_H 8 8 9 9 #include <linux/bits.h> 10 - #include <asm/sclp.h> 11 10 #include <uapi/asm/setup.h> 12 11 #include <linux/build_bug.h> 13 12 14 13 #define EP_OFFSET 0x10008 15 14 #define EP_STRING "S390EP" 16 15 #define PARMAREA 0x10400 17 - #define EARLY_SCCB_OFFSET 0x11000 18 - #define HEAD_END (EARLY_SCCB_OFFSET + EXT_SCCB_READ_SCP) 16 + #define HEAD_END 0x11000 19 17 20 18 /* 21 19 * Machine features detected in early.c
+6 -1
drivers/s390/char/sclp_early_core.c
··· 17 17 18 18 static struct read_info_sccb __bootdata(sclp_info_sccb); 19 19 static int __bootdata(sclp_info_sccb_valid); 20 - char *sclp_early_sccb = (char *) EARLY_SCCB_OFFSET; 20 + char *__bootdata(sclp_early_sccb); 21 21 int sclp_init_state = sclp_init_state_uninitialized; 22 22 /* 23 23 * Used to keep track of the size of the event masks. Qemu until version 2.11 ··· 209 209 *have_linemode = sclp_early_con_check_linemode(sccb); 210 210 *have_vt220 = !!(sccb_get_send_mask(sccb) & EVTYP_VT220MSG_MASK); 211 211 return rc; 212 + } 213 + 214 + void sclp_early_set_buffer(void *sccb) 215 + { 216 + sclp_early_sccb = sccb; 212 217 } 213 218 214 219 /*