diff options
Diffstat (limited to 'arch/s390/kernel/early.c')
-rw-r--r-- | arch/s390/kernel/early.c | 74 |
1 files changed, 46 insertions, 28 deletions
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index cae14c499511..bf8b4ae7ff2d 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c | |||
@@ -6,6 +6,9 @@ | |||
6 | * Heiko Carstens <heiko.carstens@de.ibm.com> | 6 | * Heiko Carstens <heiko.carstens@de.ibm.com> |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #define KMSG_COMPONENT "setup" | ||
10 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | ||
11 | |||
9 | #include <linux/compiler.h> | 12 | #include <linux/compiler.h> |
10 | #include <linux/init.h> | 13 | #include <linux/init.h> |
11 | #include <linux/errno.h> | 14 | #include <linux/errno.h> |
@@ -16,6 +19,7 @@ | |||
16 | #include <linux/module.h> | 19 | #include <linux/module.h> |
17 | #include <linux/pfn.h> | 20 | #include <linux/pfn.h> |
18 | #include <linux/uaccess.h> | 21 | #include <linux/uaccess.h> |
22 | #include <linux/kernel.h> | ||
19 | #include <asm/ebcdic.h> | 23 | #include <asm/ebcdic.h> |
20 | #include <asm/ipl.h> | 24 | #include <asm/ipl.h> |
21 | #include <asm/lowcore.h> | 25 | #include <asm/lowcore.h> |
@@ -35,8 +39,6 @@ | |||
35 | 39 | ||
36 | char kernel_nss_name[NSS_NAME_SIZE + 1]; | 40 | char kernel_nss_name[NSS_NAME_SIZE + 1]; |
37 | 41 | ||
38 | static unsigned long machine_flags; | ||
39 | |||
40 | static void __init setup_boot_command_line(void); | 42 | static void __init setup_boot_command_line(void); |
41 | 43 | ||
42 | /* | 44 | /* |
@@ -81,6 +83,8 @@ asm( | |||
81 | " br 14\n" | 83 | " br 14\n" |
82 | " .size savesys_ipl_nss, .-savesys_ipl_nss\n"); | 84 | " .size savesys_ipl_nss, .-savesys_ipl_nss\n"); |
83 | 85 | ||
86 | static __initdata char upper_command_line[COMMAND_LINE_SIZE]; | ||
87 | |||
84 | static noinline __init void create_kernel_nss(void) | 88 | static noinline __init void create_kernel_nss(void) |
85 | { | 89 | { |
86 | unsigned int i, stext_pfn, eshared_pfn, end_pfn, min_size; | 90 | unsigned int i, stext_pfn, eshared_pfn, end_pfn, min_size; |
@@ -90,7 +94,6 @@ static noinline __init void create_kernel_nss(void) | |||
90 | int response; | 94 | int response; |
91 | size_t len; | 95 | size_t len; |
92 | char *savesys_ptr; | 96 | char *savesys_ptr; |
93 | char upper_command_line[COMMAND_LINE_SIZE]; | ||
94 | char defsys_cmd[DEFSYS_CMD_SIZE]; | 97 | char defsys_cmd[DEFSYS_CMD_SIZE]; |
95 | char savesys_cmd[SAVESYS_CMD_SIZE]; | 98 | char savesys_cmd[SAVESYS_CMD_SIZE]; |
96 | 99 | ||
@@ -141,6 +144,8 @@ static noinline __init void create_kernel_nss(void) | |||
141 | __cpcmd(defsys_cmd, NULL, 0, &response); | 144 | __cpcmd(defsys_cmd, NULL, 0, &response); |
142 | 145 | ||
143 | if (response != 0) { | 146 | if (response != 0) { |
147 | pr_err("Defining the Linux kernel NSS failed with rc=%d\n", | ||
148 | response); | ||
144 | kernel_nss_name[0] = '\0'; | 149 | kernel_nss_name[0] = '\0'; |
145 | return; | 150 | return; |
146 | } | 151 | } |
@@ -153,8 +158,11 @@ static noinline __init void create_kernel_nss(void) | |||
153 | * max SAVESYS_CMD_SIZE | 158 | * max SAVESYS_CMD_SIZE |
154 | * On error: response contains the numeric portion of cp error message. | 159 | * On error: response contains the numeric portion of cp error message. |
155 | * for SAVESYS it will be >= 263 | 160 | * for SAVESYS it will be >= 263 |
161 | * for missing privilege class, it will be 1 | ||
156 | */ | 162 | */ |
157 | if (response > SAVESYS_CMD_SIZE) { | 163 | if (response > SAVESYS_CMD_SIZE || response == 1) { |
164 | pr_err("Saving the Linux kernel NSS failed with rc=%d\n", | ||
165 | response); | ||
158 | kernel_nss_name[0] = '\0'; | 166 | kernel_nss_name[0] = '\0'; |
159 | return; | 167 | return; |
160 | } | 168 | } |
@@ -205,12 +213,9 @@ static noinline __init void detect_machine_type(void) | |||
205 | 213 | ||
206 | /* Running under KVM? If not we assume z/VM */ | 214 | /* Running under KVM? If not we assume z/VM */ |
207 | if (!memcmp(vmms.vm[0].cpi, "\xd2\xe5\xd4", 3)) | 215 | if (!memcmp(vmms.vm[0].cpi, "\xd2\xe5\xd4", 3)) |
208 | machine_flags |= MACHINE_FLAG_KVM; | 216 | S390_lowcore.machine_flags |= MACHINE_FLAG_KVM; |
209 | else | 217 | else |
210 | machine_flags |= MACHINE_FLAG_VM; | 218 | S390_lowcore.machine_flags |= MACHINE_FLAG_VM; |
211 | |||
212 | /* Store machine flags for setting up lowcore early */ | ||
213 | S390_lowcore.machine_flags = machine_flags; | ||
214 | } | 219 | } |
215 | 220 | ||
216 | static __init void early_pgm_check_handler(void) | 221 | static __init void early_pgm_check_handler(void) |
@@ -245,7 +250,7 @@ static noinline __init void setup_hpage(void) | |||
245 | facilities = stfl(); | 250 | facilities = stfl(); |
246 | if (!(facilities & (1UL << 23)) || !(facilities & (1UL << 29))) | 251 | if (!(facilities & (1UL << 23)) || !(facilities & (1UL << 29))) |
247 | return; | 252 | return; |
248 | machine_flags |= MACHINE_FLAG_HPAGE; | 253 | S390_lowcore.machine_flags |= MACHINE_FLAG_HPAGE; |
249 | __ctl_set_bit(0, 23); | 254 | __ctl_set_bit(0, 23); |
250 | #endif | 255 | #endif |
251 | } | 256 | } |
@@ -263,7 +268,7 @@ static __init void detect_mvpg(void) | |||
263 | EX_TABLE(0b,1b) | 268 | EX_TABLE(0b,1b) |
264 | : "=d" (rc) : "0" (-EOPNOTSUPP), "a" (0) : "memory", "cc", "0"); | 269 | : "=d" (rc) : "0" (-EOPNOTSUPP), "a" (0) : "memory", "cc", "0"); |
265 | if (!rc) | 270 | if (!rc) |
266 | machine_flags |= MACHINE_FLAG_MVPG; | 271 | S390_lowcore.machine_flags |= MACHINE_FLAG_MVPG; |
267 | #endif | 272 | #endif |
268 | } | 273 | } |
269 | 274 | ||
@@ -279,7 +284,7 @@ static __init void detect_ieee(void) | |||
279 | EX_TABLE(0b,1b) | 284 | EX_TABLE(0b,1b) |
280 | : "=d" (rc), "=d" (tmp): "0" (-EOPNOTSUPP) : "cc"); | 285 | : "=d" (rc), "=d" (tmp): "0" (-EOPNOTSUPP) : "cc"); |
281 | if (!rc) | 286 | if (!rc) |
282 | machine_flags |= MACHINE_FLAG_IEEE; | 287 | S390_lowcore.machine_flags |= MACHINE_FLAG_IEEE; |
283 | #endif | 288 | #endif |
284 | } | 289 | } |
285 | 290 | ||
@@ -298,7 +303,7 @@ static __init void detect_csp(void) | |||
298 | EX_TABLE(0b,1b) | 303 | EX_TABLE(0b,1b) |
299 | : "=d" (rc) : "0" (-EOPNOTSUPP) : "cc", "0", "1", "2"); | 304 | : "=d" (rc) : "0" (-EOPNOTSUPP) : "cc", "0", "1", "2"); |
300 | if (!rc) | 305 | if (!rc) |
301 | machine_flags |= MACHINE_FLAG_CSP; | 306 | S390_lowcore.machine_flags |= MACHINE_FLAG_CSP; |
302 | #endif | 307 | #endif |
303 | } | 308 | } |
304 | 309 | ||
@@ -315,7 +320,7 @@ static __init void detect_diag9c(void) | |||
315 | EX_TABLE(0b,1b) | 320 | EX_TABLE(0b,1b) |
316 | : "=d" (rc) : "0" (-EOPNOTSUPP), "d" (cpu_address) : "cc"); | 321 | : "=d" (rc) : "0" (-EOPNOTSUPP), "d" (cpu_address) : "cc"); |
317 | if (!rc) | 322 | if (!rc) |
318 | machine_flags |= MACHINE_FLAG_DIAG9C; | 323 | S390_lowcore.machine_flags |= MACHINE_FLAG_DIAG9C; |
319 | } | 324 | } |
320 | 325 | ||
321 | static __init void detect_diag44(void) | 326 | static __init void detect_diag44(void) |
@@ -330,7 +335,7 @@ static __init void detect_diag44(void) | |||
330 | EX_TABLE(0b,1b) | 335 | EX_TABLE(0b,1b) |
331 | : "=d" (rc) : "0" (-EOPNOTSUPP) : "cc"); | 336 | : "=d" (rc) : "0" (-EOPNOTSUPP) : "cc"); |
332 | if (!rc) | 337 | if (!rc) |
333 | machine_flags |= MACHINE_FLAG_DIAG44; | 338 | S390_lowcore.machine_flags |= MACHINE_FLAG_DIAG44; |
334 | #endif | 339 | #endif |
335 | } | 340 | } |
336 | 341 | ||
@@ -341,11 +346,11 @@ static __init void detect_machine_facilities(void) | |||
341 | 346 | ||
342 | facilities = stfl(); | 347 | facilities = stfl(); |
343 | if (facilities & (1 << 28)) | 348 | if (facilities & (1 << 28)) |
344 | machine_flags |= MACHINE_FLAG_IDTE; | 349 | S390_lowcore.machine_flags |= MACHINE_FLAG_IDTE; |
345 | if (facilities & (1 << 23)) | 350 | if (facilities & (1 << 23)) |
346 | machine_flags |= MACHINE_FLAG_PFMF; | 351 | S390_lowcore.machine_flags |= MACHINE_FLAG_PFMF; |
347 | if (facilities & (1 << 4)) | 352 | if (facilities & (1 << 4)) |
348 | machine_flags |= MACHINE_FLAG_MVCOS; | 353 | S390_lowcore.machine_flags |= MACHINE_FLAG_MVCOS; |
349 | #endif | 354 | #endif |
350 | } | 355 | } |
351 | 356 | ||
@@ -367,21 +372,35 @@ static __init void rescue_initrd(void) | |||
367 | } | 372 | } |
368 | 373 | ||
369 | /* Set up boot command line */ | 374 | /* Set up boot command line */ |
370 | static void __init setup_boot_command_line(void) | 375 | static void __init append_to_cmdline(size_t (*ipl_data)(char *, size_t)) |
371 | { | 376 | { |
372 | char *parm = NULL; | 377 | char *parm, *delim; |
378 | size_t rc, len; | ||
379 | |||
380 | len = strlen(boot_command_line); | ||
381 | |||
382 | delim = boot_command_line + len; /* '\0' character position */ | ||
383 | parm = boot_command_line + len + 1; /* append right after '\0' */ | ||
373 | 384 | ||
385 | rc = ipl_data(parm, COMMAND_LINE_SIZE - len - 1); | ||
386 | if (rc) { | ||
387 | if (*parm == '=') | ||
388 | memmove(boot_command_line, parm + 1, rc); | ||
389 | else | ||
390 | *delim = ' '; /* replace '\0' with space */ | ||
391 | } | ||
392 | } | ||
393 | |||
394 | static void __init setup_boot_command_line(void) | ||
395 | { | ||
374 | /* copy arch command line */ | 396 | /* copy arch command line */ |
375 | strlcpy(boot_command_line, COMMAND_LINE, ARCH_COMMAND_LINE_SIZE); | 397 | strlcpy(boot_command_line, COMMAND_LINE, ARCH_COMMAND_LINE_SIZE); |
376 | 398 | ||
377 | /* append IPL PARM data to the boot command line */ | 399 | /* append IPL PARM data to the boot command line */ |
378 | if (MACHINE_IS_VM) { | 400 | if (MACHINE_IS_VM) |
379 | parm = boot_command_line + strlen(boot_command_line); | 401 | append_to_cmdline(append_ipl_vmparm); |
380 | *parm++ = ' '; | 402 | |
381 | get_ipl_vmparm(parm); | 403 | append_to_cmdline(append_ipl_scpdata); |
382 | if (parm[0] == '=') | ||
383 | memmove(boot_command_line, parm + 1, strlen(parm)); | ||
384 | } | ||
385 | } | 404 | } |
386 | 405 | ||
387 | 406 | ||
@@ -413,7 +432,6 @@ void __init startup_init(void) | |||
413 | setup_hpage(); | 432 | setup_hpage(); |
414 | sclp_facilities_detect(); | 433 | sclp_facilities_detect(); |
415 | detect_memory_layout(memory_chunk); | 434 | detect_memory_layout(memory_chunk); |
416 | S390_lowcore.machine_flags = machine_flags; | ||
417 | #ifdef CONFIG_DYNAMIC_FTRACE | 435 | #ifdef CONFIG_DYNAMIC_FTRACE |
418 | S390_lowcore.ftrace_func = (unsigned long)ftrace_caller; | 436 | S390_lowcore.ftrace_func = (unsigned long)ftrace_caller; |
419 | #endif | 437 | #endif |