summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/s390/boot/Makefile3
-rw-r--r--arch/s390/boot/boot.h3
-rw-r--r--arch/s390/boot/cmdline.c2
-rw-r--r--arch/s390/boot/ctype.c2
-rw-r--r--arch/s390/boot/ipl_parm.c173
-rw-r--r--arch/s390/boot/ipl_vmparm.c2
-rw-r--r--arch/s390/boot/startup.c3
-rw-r--r--arch/s390/boot/string.c100
-rw-r--r--arch/s390/include/asm/boot_data.h11
-rw-r--r--arch/s390/include/asm/ipl.h4
-rw-r--r--arch/s390/kernel/Makefile2
-rw-r--r--arch/s390/kernel/early.c47
-rw-r--r--arch/s390/kernel/ipl.c117
-rw-r--r--arch/s390/kernel/ipl_vmparm.c36
-rw-r--r--arch/s390/kernel/setup.c26
15 files changed, 355 insertions, 176 deletions
diff --git a/arch/s390/boot/Makefile b/arch/s390/boot/Makefile
index b6903c47e0ac..f58edd8b2e34 100644
--- a/arch/s390/boot/Makefile
+++ b/arch/s390/boot/Makefile
@@ -27,7 +27,8 @@ endif
27 27
28CFLAGS_sclp_early_core.o += -I$(srctree)/drivers/s390/char 28CFLAGS_sclp_early_core.o += -I$(srctree)/drivers/s390/char
29 29
30obj-y := head.o als.o startup.o mem_detect.o ebcdic.o sclp_early_core.o mem.o 30obj-y := head.o als.o startup.o mem_detect.o ipl_parm.o string.o ebcdic.o
31obj-y += sclp_early_core.o mem.o ipl_vmparm.o cmdline.o ctype.o
31targets := bzImage startup.a section_cmp.boot.data $(obj-y) 32targets := bzImage startup.a section_cmp.boot.data $(obj-y)
32subdir- := compressed 33subdir- := compressed
33 34
diff --git a/arch/s390/boot/boot.h b/arch/s390/boot/boot.h
index 808154b99a5d..fc41e2277ea8 100644
--- a/arch/s390/boot/boot.h
+++ b/arch/s390/boot/boot.h
@@ -4,5 +4,8 @@
4 4
5void startup_kernel(void); 5void startup_kernel(void);
6void detect_memory(void); 6void detect_memory(void);
7void store_ipl_parmblock(void);
8void setup_boot_command_line(void);
9void setup_memory_end(void);
7 10
8#endif /* BOOT_BOOT_H */ 11#endif /* BOOT_BOOT_H */
diff --git a/arch/s390/boot/cmdline.c b/arch/s390/boot/cmdline.c
new file mode 100644
index 000000000000..73d826cdbdeb
--- /dev/null
+++ b/arch/s390/boot/cmdline.c
@@ -0,0 +1,2 @@
1// SPDX-License-Identifier: GPL-2.0
2#include "../../../lib/cmdline.c"
diff --git a/arch/s390/boot/ctype.c b/arch/s390/boot/ctype.c
new file mode 100644
index 000000000000..2495810b47e3
--- /dev/null
+++ b/arch/s390/boot/ctype.c
@@ -0,0 +1,2 @@
1// SPDX-License-Identifier: GPL-2.0
2#include "../../../lib/ctype.c"
diff --git a/arch/s390/boot/ipl_parm.c b/arch/s390/boot/ipl_parm.c
new file mode 100644
index 000000000000..7f8e546400a1
--- /dev/null
+++ b/arch/s390/boot/ipl_parm.c
@@ -0,0 +1,173 @@
1// SPDX-License-Identifier: GPL-2.0
2#include <linux/init.h>
3#include <linux/ctype.h>
4#include <asm/ebcdic.h>
5#include <asm/sclp.h>
6#include <asm/sections.h>
7#include <asm/boot_data.h>
8#include "boot.h"
9
10char __bootdata(early_command_line)[COMMAND_LINE_SIZE];
11struct ipl_parameter_block __bootdata(early_ipl_block);
12int __bootdata(early_ipl_block_valid);
13
14unsigned long __bootdata(memory_end);
15int __bootdata(memory_end_set);
16
17static inline int __diag308(unsigned long subcode, void *addr)
18{
19 register unsigned long _addr asm("0") = (unsigned long)addr;
20 register unsigned long _rc asm("1") = 0;
21 unsigned long reg1, reg2;
22 psw_t old = S390_lowcore.program_new_psw;
23
24 asm volatile(
25 " epsw %0,%1\n"
26 " st %0,%[psw_pgm]\n"
27 " st %1,%[psw_pgm]+4\n"
28 " larl %0,1f\n"
29 " stg %0,%[psw_pgm]+8\n"
30 " diag %[addr],%[subcode],0x308\n"
31 "1: nopr %%r7\n"
32 : "=&d" (reg1), "=&a" (reg2),
33 [psw_pgm] "=Q" (S390_lowcore.program_new_psw),
34 [addr] "+d" (_addr), "+d" (_rc)
35 : [subcode] "d" (subcode)
36 : "cc", "memory");
37 S390_lowcore.program_new_psw = old;
38 return _rc;
39}
40
41void store_ipl_parmblock(void)
42{
43 int rc;
44
45 rc = __diag308(DIAG308_STORE, &early_ipl_block);
46 if (rc == DIAG308_RC_OK &&
47 early_ipl_block.hdr.version <= IPL_MAX_SUPPORTED_VERSION)
48 early_ipl_block_valid = 1;
49}
50
51static size_t scpdata_length(const char *buf, size_t count)
52{
53 while (count) {
54 if (buf[count - 1] != '\0' && buf[count - 1] != ' ')
55 break;
56 count--;
57 }
58 return count;
59}
60
61static size_t ipl_block_get_ascii_scpdata(char *dest, size_t size,
62 const struct ipl_parameter_block *ipb)
63{
64 size_t count;
65 size_t i;
66 int has_lowercase;
67
68 count = min(size - 1, scpdata_length(ipb->ipl_info.fcp.scp_data,
69 ipb->ipl_info.fcp.scp_data_len));
70 if (!count)
71 goto out;
72
73 has_lowercase = 0;
74 for (i = 0; i < count; i++) {
75 if (!isascii(ipb->ipl_info.fcp.scp_data[i])) {
76 count = 0;
77 goto out;
78 }
79 if (!has_lowercase && islower(ipb->ipl_info.fcp.scp_data[i]))
80 has_lowercase = 1;
81 }
82
83 if (has_lowercase)
84 memcpy(dest, ipb->ipl_info.fcp.scp_data, count);
85 else
86 for (i = 0; i < count; i++)
87 dest[i] = tolower(ipb->ipl_info.fcp.scp_data[i]);
88out:
89 dest[count] = '\0';
90 return count;
91}
92
93static void append_ipl_block_parm(void)
94{
95 char *parm, *delim;
96 size_t len, rc = 0;
97
98 len = strlen(early_command_line);
99
100 delim = early_command_line + len; /* '\0' character position */
101 parm = early_command_line + len + 1; /* append right after '\0' */
102
103 switch (early_ipl_block.hdr.pbt) {
104 case DIAG308_IPL_TYPE_CCW:
105 rc = ipl_block_get_ascii_vmparm(
106 parm, COMMAND_LINE_SIZE - len - 1, &early_ipl_block);
107 break;
108 case DIAG308_IPL_TYPE_FCP:
109 rc = ipl_block_get_ascii_scpdata(
110 parm, COMMAND_LINE_SIZE - len - 1, &early_ipl_block);
111 break;
112 }
113 if (rc) {
114 if (*parm == '=')
115 memmove(early_command_line, parm + 1, rc);
116 else
117 *delim = ' '; /* replace '\0' with space */
118 }
119}
120
121static inline int has_ebcdic_char(const char *str)
122{
123 int i;
124
125 for (i = 0; str[i]; i++)
126 if (str[i] & 0x80)
127 return 1;
128 return 0;
129}
130
131void setup_boot_command_line(void)
132{
133 COMMAND_LINE[ARCH_COMMAND_LINE_SIZE - 1] = 0;
134 /* convert arch command line to ascii if necessary */
135 if (has_ebcdic_char(COMMAND_LINE))
136 EBCASC(COMMAND_LINE, ARCH_COMMAND_LINE_SIZE);
137 /* copy arch command line */
138 strcpy(early_command_line, strim(COMMAND_LINE));
139
140 /* append IPL PARM data to the boot command line */
141 if (early_ipl_block_valid)
142 append_ipl_block_parm();
143}
144
145static char command_line_buf[COMMAND_LINE_SIZE] __section(.data);
146static void parse_mem_opt(void)
147{
148 char *args;
149 char *param, *val;
150
151 args = strcpy(command_line_buf, early_command_line);
152 while (*args) {
153 args = next_arg(args, &param, &val);
154
155 if (!strcmp(param, "mem")) {
156 memory_end = memparse(val, NULL);
157 memory_end_set = 1;
158 }
159 }
160}
161
162void setup_memory_end(void)
163{
164 parse_mem_opt();
165#ifdef CONFIG_CRASH_DUMP
166 if (!OLDMEM_BASE && early_ipl_block_valid &&
167 early_ipl_block.hdr.pbt == DIAG308_IPL_TYPE_FCP &&
168 early_ipl_block.ipl_info.fcp.opt == DIAG308_IPL_OPT_DUMP) {
169 if (!sclp_early_get_hsa_size(&memory_end) && memory_end)
170 memory_end_set = 1;
171 }
172#endif
173}
diff --git a/arch/s390/boot/ipl_vmparm.c b/arch/s390/boot/ipl_vmparm.c
new file mode 100644
index 000000000000..8dacd5fadfd7
--- /dev/null
+++ b/arch/s390/boot/ipl_vmparm.c
@@ -0,0 +1,2 @@
1// SPDX-License-Identifier: GPL-2.0
2#include "../kernel/ipl_vmparm.c"
diff --git a/arch/s390/boot/startup.c b/arch/s390/boot/startup.c
index b0e9f4619203..4d441317cdeb 100644
--- a/arch/s390/boot/startup.c
+++ b/arch/s390/boot/startup.c
@@ -51,6 +51,9 @@ void startup_kernel(void)
51 51
52 rescue_initrd(); 52 rescue_initrd();
53 sclp_early_read_info(); 53 sclp_early_read_info();
54 store_ipl_parmblock();
55 setup_boot_command_line();
56 setup_memory_end();
54 detect_memory(); 57 detect_memory();
55 if (!IS_ENABLED(CONFIG_KERNEL_UNCOMPRESSED)) { 58 if (!IS_ENABLED(CONFIG_KERNEL_UNCOMPRESSED)) {
56 img = decompress_kernel(); 59 img = decompress_kernel();
diff --git a/arch/s390/boot/string.c b/arch/s390/boot/string.c
new file mode 100644
index 000000000000..09ca9130e73a
--- /dev/null
+++ b/arch/s390/boot/string.c
@@ -0,0 +1,100 @@
1// SPDX-License-Identifier: GPL-2.0
2#include <linux/ctype.h>
3#include <linux/kernel.h>
4#include "../lib/string.c"
5
6int strncmp(const char *cs, const char *ct, size_t count)
7{
8 unsigned char c1, c2;
9
10 while (count) {
11 c1 = *cs++;
12 c2 = *ct++;
13 if (c1 != c2)
14 return c1 < c2 ? -1 : 1;
15 if (!c1)
16 break;
17 count--;
18 }
19 return 0;
20}
21
22char *skip_spaces(const char *str)
23{
24 while (isspace(*str))
25 ++str;
26 return (char *)str;
27}
28
29char *strim(char *s)
30{
31 size_t size;
32 char *end;
33
34 size = strlen(s);
35 if (!size)
36 return s;
37
38 end = s + size - 1;
39 while (end >= s && isspace(*end))
40 end--;
41 *(end + 1) = '\0';
42
43 return skip_spaces(s);
44}
45
46/* Works only for digits and letters, but small and fast */
47#define TOLOWER(x) ((x) | 0x20)
48
49static unsigned int simple_guess_base(const char *cp)
50{
51 if (cp[0] == '0') {
52 if (TOLOWER(cp[1]) == 'x' && isxdigit(cp[2]))
53 return 16;
54 else
55 return 8;
56 } else {
57 return 10;
58 }
59}
60
61/**
62 * simple_strtoull - convert a string to an unsigned long long
63 * @cp: The start of the string
64 * @endp: A pointer to the end of the parsed string will be placed here
65 * @base: The number base to use
66 */
67
68unsigned long long simple_strtoull(const char *cp, char **endp,
69 unsigned int base)
70{
71 unsigned long long result = 0;
72
73 if (!base)
74 base = simple_guess_base(cp);
75
76 if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x')
77 cp += 2;
78
79 while (isxdigit(*cp)) {
80 unsigned int value;
81
82 value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10;
83 if (value >= base)
84 break;
85 result = result * base + value;
86 cp++;
87 }
88 if (endp)
89 *endp = (char *)cp;
90
91 return result;
92}
93
94long simple_strtol(const char *cp, char **endp, unsigned int base)
95{
96 if (*cp == '-')
97 return -simple_strtoull(cp + 1, endp, base);
98
99 return simple_strtoull(cp, endp, base);
100}
diff --git a/arch/s390/include/asm/boot_data.h b/arch/s390/include/asm/boot_data.h
new file mode 100644
index 000000000000..2d999ccb977a
--- /dev/null
+++ b/arch/s390/include/asm/boot_data.h
@@ -0,0 +1,11 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef _ASM_S390_BOOT_DATA_H
3
4#include <asm/setup.h>
5#include <asm/ipl.h>
6
7extern char early_command_line[COMMAND_LINE_SIZE];
8extern struct ipl_parameter_block early_ipl_block;
9extern int early_ipl_block_valid;
10
11#endif /* _ASM_S390_BOOT_DATA_H */
diff --git a/arch/s390/include/asm/ipl.h b/arch/s390/include/asm/ipl.h
index ae5135704616..a8389e2d2f03 100644
--- a/arch/s390/include/asm/ipl.h
+++ b/arch/s390/include/asm/ipl.h
@@ -89,8 +89,8 @@ void __init save_area_add_vxrs(struct save_area *, __vector128 *vxrs);
89 89
90extern void s390_reset_system(void); 90extern void s390_reset_system(void);
91extern void ipl_store_parameters(void); 91extern void ipl_store_parameters(void);
92extern size_t append_ipl_vmparm(char *, size_t); 92extern size_t ipl_block_get_ascii_vmparm(char *dest, size_t size,
93extern size_t append_ipl_scpdata(char *, size_t); 93 const struct ipl_parameter_block *ipb);
94 94
95enum ipl_type { 95enum ipl_type {
96 IPL_TYPE_UNKNOWN = 1, 96 IPL_TYPE_UNKNOWN = 1,
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
index dbfd1730e631..7ad6fa60a1f2 100644
--- a/arch/s390/kernel/Makefile
+++ b/arch/s390/kernel/Makefile
@@ -47,7 +47,7 @@ obj-y += debug.o irq.o ipl.o dis.o diag.o vdso.o early_nobss.o
47obj-y += sysinfo.o jump_label.o lgr.o os_info.o machine_kexec.o pgm_check.o 47obj-y += sysinfo.o jump_label.o lgr.o os_info.o machine_kexec.o pgm_check.o
48obj-y += runtime_instr.o cache.o fpu.o dumpstack.o guarded_storage.o sthyi.o 48obj-y += runtime_instr.o cache.o fpu.o dumpstack.o guarded_storage.o sthyi.o
49obj-y += entry.o reipl.o relocate_kernel.o kdebugfs.o alternative.o 49obj-y += entry.o reipl.o relocate_kernel.o kdebugfs.o alternative.o
50obj-y += nospec-branch.o 50obj-y += nospec-branch.o ipl_vmparm.o
51 51
52extra-y += head64.o vmlinux.lds 52extra-y += head64.o vmlinux.lds
53 53
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index 5b28b434f8a1..af5c2b3f7065 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -29,10 +29,9 @@
29#include <asm/cpcmd.h> 29#include <asm/cpcmd.h>
30#include <asm/sclp.h> 30#include <asm/sclp.h>
31#include <asm/facility.h> 31#include <asm/facility.h>
32#include <asm/boot_data.h>
32#include "entry.h" 33#include "entry.h"
33 34
34static void __init setup_boot_command_line(void);
35
36/* 35/*
37 * Initialize storage key for kernel pages 36 * Initialize storage key for kernel pages
38 */ 37 */
@@ -284,51 +283,11 @@ static int __init cad_setup(char *str)
284} 283}
285early_param("cad", cad_setup); 284early_param("cad", cad_setup);
286 285
287/* Set up boot command line */ 286char __bootdata(early_command_line)[COMMAND_LINE_SIZE];
288static void __init append_to_cmdline(size_t (*ipl_data)(char *, size_t))
289{
290 char *parm, *delim;
291 size_t rc, len;
292
293 len = strlen(boot_command_line);
294
295 delim = boot_command_line + len; /* '\0' character position */
296 parm = boot_command_line + len + 1; /* append right after '\0' */
297
298 rc = ipl_data(parm, COMMAND_LINE_SIZE - len - 1);
299 if (rc) {
300 if (*parm == '=')
301 memmove(boot_command_line, parm + 1, rc);
302 else
303 *delim = ' '; /* replace '\0' with space */
304 }
305}
306
307static inline int has_ebcdic_char(const char *str)
308{
309 int i;
310
311 for (i = 0; str[i]; i++)
312 if (str[i] & 0x80)
313 return 1;
314 return 0;
315}
316
317static void __init setup_boot_command_line(void) 287static void __init setup_boot_command_line(void)
318{ 288{
319 COMMAND_LINE[ARCH_COMMAND_LINE_SIZE - 1] = 0;
320 /* convert arch command line to ascii if necessary */
321 if (has_ebcdic_char(COMMAND_LINE))
322 EBCASC(COMMAND_LINE, ARCH_COMMAND_LINE_SIZE);
323 /* copy arch command line */ 289 /* copy arch command line */
324 strlcpy(boot_command_line, strstrip(COMMAND_LINE), 290 strlcpy(boot_command_line, early_command_line, ARCH_COMMAND_LINE_SIZE);
325 ARCH_COMMAND_LINE_SIZE);
326
327 /* append IPL PARM data to the boot command line */
328 if (MACHINE_IS_VM)
329 append_to_cmdline(append_ipl_vmparm);
330
331 append_to_cmdline(append_ipl_scpdata);
332} 291}
333 292
334static void __init check_image_bootable(void) 293static void __init check_image_bootable(void)
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index 4296d7e61fb6..f1d69f78bb1d 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -29,6 +29,8 @@
29#include <asm/checksum.h> 29#include <asm/checksum.h>
30#include <asm/debug.h> 30#include <asm/debug.h>
31#include <asm/os_info.h> 31#include <asm/os_info.h>
32#include <asm/sections.h>
33#include <asm/boot_data.h>
32#include "entry.h" 34#include "entry.h"
33 35
34#define IPL_PARM_BLOCK_VERSION 0 36#define IPL_PARM_BLOCK_VERSION 0
@@ -117,6 +119,9 @@ static char *dump_type_str(enum dump_type type)
117 } 119 }
118} 120}
119 121
122struct ipl_parameter_block __bootdata(early_ipl_block);
123int __bootdata(early_ipl_block_valid);
124
120static int ipl_block_valid; 125static int ipl_block_valid;
121static struct ipl_parameter_block ipl_block; 126static struct ipl_parameter_block ipl_block;
122 127
@@ -262,115 +267,16 @@ static ssize_t ipl_type_show(struct kobject *kobj, struct kobj_attribute *attr,
262 267
263static struct kobj_attribute sys_ipl_type_attr = __ATTR_RO(ipl_type); 268static struct kobj_attribute sys_ipl_type_attr = __ATTR_RO(ipl_type);
264 269
265/* VM IPL PARM routines */
266static size_t reipl_get_ascii_vmparm(char *dest, size_t size,
267 const struct ipl_parameter_block *ipb)
268{
269 int i;
270 size_t len;
271 char has_lowercase = 0;
272
273 len = 0;
274 if ((ipb->ipl_info.ccw.vm_flags & DIAG308_VM_FLAGS_VP_VALID) &&
275 (ipb->ipl_info.ccw.vm_parm_len > 0)) {
276
277 len = min_t(size_t, size - 1, ipb->ipl_info.ccw.vm_parm_len);
278 memcpy(dest, ipb->ipl_info.ccw.vm_parm, len);
279 /* If at least one character is lowercase, we assume mixed
280 * case; otherwise we convert everything to lowercase.
281 */
282 for (i = 0; i < len; i++)
283 if ((dest[i] > 0x80 && dest[i] < 0x8a) || /* a-i */
284 (dest[i] > 0x90 && dest[i] < 0x9a) || /* j-r */
285 (dest[i] > 0xa1 && dest[i] < 0xaa)) { /* s-z */
286 has_lowercase = 1;
287 break;
288 }
289 if (!has_lowercase)
290 EBC_TOLOWER(dest, len);
291 EBCASC(dest, len);
292 }
293 dest[len] = 0;
294
295 return len;
296}
297
298size_t append_ipl_vmparm(char *dest, size_t size)
299{
300 size_t rc;
301
302 rc = 0;
303 if (ipl_block_valid && ipl_block.hdr.pbt == DIAG308_IPL_TYPE_CCW)
304 rc = reipl_get_ascii_vmparm(dest, size, &ipl_block);
305 else
306 dest[0] = 0;
307 return rc;
308}
309
310static ssize_t ipl_vm_parm_show(struct kobject *kobj, 270static ssize_t ipl_vm_parm_show(struct kobject *kobj,
311 struct kobj_attribute *attr, char *page) 271 struct kobj_attribute *attr, char *page)
312{ 272{
313 char parm[DIAG308_VMPARM_SIZE + 1] = {}; 273 char parm[DIAG308_VMPARM_SIZE + 1] = {};
314 274
315 append_ipl_vmparm(parm, sizeof(parm)); 275 if (ipl_block_valid && (ipl_block.hdr.pbt == DIAG308_IPL_TYPE_CCW))
276 ipl_block_get_ascii_vmparm(parm, sizeof(parm), &ipl_block);
316 return sprintf(page, "%s\n", parm); 277 return sprintf(page, "%s\n", parm);
317} 278}
318 279
319static size_t scpdata_length(const char* buf, size_t count)
320{
321 while (count) {
322 if (buf[count - 1] != '\0' && buf[count - 1] != ' ')
323 break;
324 count--;
325 }
326 return count;
327}
328
329static size_t reipl_append_ascii_scpdata(char *dest, size_t size,
330 const struct ipl_parameter_block *ipb)
331{
332 size_t count;
333 size_t i;
334 int has_lowercase;
335
336 count = min(size - 1, scpdata_length(ipb->ipl_info.fcp.scp_data,
337 ipb->ipl_info.fcp.scp_data_len));
338 if (!count)
339 goto out;
340
341 has_lowercase = 0;
342 for (i = 0; i < count; i++) {
343 if (!isascii(ipb->ipl_info.fcp.scp_data[i])) {
344 count = 0;
345 goto out;
346 }
347 if (!has_lowercase && islower(ipb->ipl_info.fcp.scp_data[i]))
348 has_lowercase = 1;
349 }
350
351 if (has_lowercase)
352 memcpy(dest, ipb->ipl_info.fcp.scp_data, count);
353 else
354 for (i = 0; i < count; i++)
355 dest[i] = tolower(ipb->ipl_info.fcp.scp_data[i]);
356out:
357 dest[count] = '\0';
358 return count;
359}
360
361size_t append_ipl_scpdata(char *dest, size_t len)
362{
363 size_t rc;
364
365 rc = 0;
366 if (ipl_block_valid && ipl_block.hdr.pbt == DIAG308_IPL_TYPE_FCP)
367 rc = reipl_append_ascii_scpdata(dest, len, &ipl_block);
368 else
369 dest[0] = 0;
370 return rc;
371}
372
373
374static struct kobj_attribute sys_ipl_vm_parm_attr = 280static struct kobj_attribute sys_ipl_vm_parm_attr =
375 __ATTR(parm, S_IRUGO, ipl_vm_parm_show, NULL); 281 __ATTR(parm, S_IRUGO, ipl_vm_parm_show, NULL);
376 282
@@ -564,7 +470,7 @@ static ssize_t reipl_generic_vmparm_show(struct ipl_parameter_block *ipb,
564{ 470{
565 char vmparm[DIAG308_VMPARM_SIZE + 1] = {}; 471 char vmparm[DIAG308_VMPARM_SIZE + 1] = {};
566 472
567 reipl_get_ascii_vmparm(vmparm, sizeof(vmparm), ipb); 473 ipl_block_get_ascii_vmparm(vmparm, sizeof(vmparm), ipb);
568 return sprintf(page, "%s\n", vmparm); 474 return sprintf(page, "%s\n", vmparm);
569} 475}
570 476
@@ -1769,11 +1675,10 @@ void __init setup_ipl(void)
1769 1675
1770void __init ipl_store_parameters(void) 1676void __init ipl_store_parameters(void)
1771{ 1677{
1772 int rc; 1678 if (early_ipl_block_valid) {
1773 1679 memcpy(&ipl_block, &early_ipl_block, sizeof(ipl_block));
1774 rc = diag308(DIAG308_STORE, &ipl_block);
1775 if (rc == DIAG308_RC_OK && ipl_block.hdr.version <= IPL_MAX_SUPPORTED_VERSION)
1776 ipl_block_valid = 1; 1680 ipl_block_valid = 1;
1681 }
1777} 1682}
1778 1683
1779void s390_reset_system(void) 1684void s390_reset_system(void)
diff --git a/arch/s390/kernel/ipl_vmparm.c b/arch/s390/kernel/ipl_vmparm.c
new file mode 100644
index 000000000000..411838c0a0af
--- /dev/null
+++ b/arch/s390/kernel/ipl_vmparm.c
@@ -0,0 +1,36 @@
1// SPDX-License-Identifier: GPL-2.0
2#include <asm/ebcdic.h>
3#include <asm/ipl.h>
4
5/* VM IPL PARM routines */
6size_t ipl_block_get_ascii_vmparm(char *dest, size_t size,
7 const struct ipl_parameter_block *ipb)
8{
9 int i;
10 size_t len;
11 char has_lowercase = 0;
12
13 len = 0;
14 if ((ipb->ipl_info.ccw.vm_flags & DIAG308_VM_FLAGS_VP_VALID) &&
15 (ipb->ipl_info.ccw.vm_parm_len > 0)) {
16
17 len = min_t(size_t, size - 1, ipb->ipl_info.ccw.vm_parm_len);
18 memcpy(dest, ipb->ipl_info.ccw.vm_parm, len);
19 /* If at least one character is lowercase, we assume mixed
20 * case; otherwise we convert everything to lowercase.
21 */
22 for (i = 0; i < len; i++)
23 if ((dest[i] > 0x80 && dest[i] < 0x8a) || /* a-i */
24 (dest[i] > 0x90 && dest[i] < 0x9a) || /* j-r */
25 (dest[i] > 0xa1 && dest[i] < 0xaa)) { /* s-z */
26 has_lowercase = 1;
27 break;
28 }
29 if (!has_lowercase)
30 EBC_TOLOWER(dest, len);
31 EBCASC(dest, len);
32 }
33 dest[len] = 0;
34
35 return len;
36}
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index 36fb37d7a36c..ae3810c04872 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -90,8 +90,8 @@ char elf_platform[ELF_PLATFORM_SIZE];
90 90
91unsigned long int_hwcap = 0; 91unsigned long int_hwcap = 0;
92 92
93int __initdata memory_end_set; 93int __bootdata(memory_end_set);
94unsigned long __initdata memory_end; 94unsigned long __bootdata(memory_end);
95unsigned long __bootdata(max_physmem_end); 95unsigned long __bootdata(max_physmem_end);
96struct mem_detect_info __bootdata(mem_detect); 96struct mem_detect_info __bootdata(mem_detect);
97 97
@@ -286,15 +286,6 @@ void machine_power_off(void)
286void (*pm_power_off)(void) = machine_power_off; 286void (*pm_power_off)(void) = machine_power_off;
287EXPORT_SYMBOL_GPL(pm_power_off); 287EXPORT_SYMBOL_GPL(pm_power_off);
288 288
289static int __init early_parse_mem(char *p)
290{
291 memory_end = memparse(p, &p);
292 memory_end &= PAGE_MASK;
293 memory_end_set = 1;
294 return 0;
295}
296early_param("mem", early_parse_mem);
297
298static int __init parse_vmalloc(char *arg) 289static int __init parse_vmalloc(char *arg)
299{ 290{
300 if (!arg) 291 if (!arg)
@@ -605,17 +596,8 @@ static struct notifier_block kdump_mem_nb = {
605 */ 596 */
606static void reserve_memory_end(void) 597static void reserve_memory_end(void)
607{ 598{
608#ifdef CONFIG_CRASH_DUMP 599 if (memory_end_set)
609 if (ipl_info.type == IPL_TYPE_FCP_DUMP && 600 memblock_reserve(memory_end, ULONG_MAX);
610 !OLDMEM_BASE && sclp.hsa_size) {
611 memory_end = sclp.hsa_size;
612 memory_end &= PAGE_MASK;
613 memory_end_set = 1;
614 }
615#endif
616 if (!memory_end_set)
617 return;
618 memblock_reserve(memory_end, ULONG_MAX);
619} 601}
620 602
621/* 603/*