diff options
| -rw-r--r-- | arch/s390/include/asm/ipl.h | 2 | ||||
| -rw-r--r-- | arch/s390/kernel/early.c | 47 | ||||
| -rw-r--r-- | arch/s390/kernel/ipl.c | 7 |
3 files changed, 47 insertions, 9 deletions
diff --git a/arch/s390/include/asm/ipl.h b/arch/s390/include/asm/ipl.h index 4da22b2f0521..edb5161df7e2 100644 --- a/arch/s390/include/asm/ipl.h +++ b/arch/s390/include/asm/ipl.h | |||
| @@ -97,7 +97,7 @@ void __init save_area_add_vxrs(struct save_area *, __vector128 *vxrs); | |||
| 97 | extern void do_reipl(void); | 97 | extern void do_reipl(void); |
| 98 | extern void do_halt(void); | 98 | extern void do_halt(void); |
| 99 | extern void do_poff(void); | 99 | extern void do_poff(void); |
| 100 | extern void ipl_save_parameters(void); | 100 | extern void ipl_verify_parameters(void); |
| 101 | extern void ipl_update_parameters(void); | 101 | extern void ipl_update_parameters(void); |
| 102 | extern size_t append_ipl_vmparm(char *, size_t); | 102 | extern size_t append_ipl_vmparm(char *, size_t); |
| 103 | extern size_t append_ipl_scpdata(char *, size_t); | 103 | extern size_t append_ipl_scpdata(char *, size_t); |
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index 9cd85adaa7c1..d038c8cea6cb 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c | |||
| @@ -392,7 +392,49 @@ static int __init cad_init(void) | |||
| 392 | } | 392 | } |
| 393 | early_initcall(cad_init); | 393 | early_initcall(cad_init); |
| 394 | 394 | ||
| 395 | static __init void rescue_initrd(void) | 395 | static __init void memmove_early(void *dst, const void *src, size_t n) |
| 396 | { | ||
| 397 | unsigned long addr; | ||
| 398 | long incr; | ||
| 399 | psw_t old; | ||
| 400 | |||
| 401 | if (!n) | ||
| 402 | return; | ||
| 403 | incr = 1; | ||
| 404 | if (dst > src) { | ||
| 405 | incr = -incr; | ||
| 406 | dst += n - 1; | ||
| 407 | src += n - 1; | ||
| 408 | } | ||
| 409 | old = S390_lowcore.program_new_psw; | ||
| 410 | S390_lowcore.program_new_psw.mask = __extract_psw(); | ||
| 411 | asm volatile( | ||
| 412 | " larl %[addr],1f\n" | ||
| 413 | " stg %[addr],%[psw_pgm_addr]\n" | ||
| 414 | "0: mvc 0(1,%[dst]),0(%[src])\n" | ||
| 415 | " agr %[dst],%[incr]\n" | ||
| 416 | " agr %[src],%[incr]\n" | ||
| 417 | " brctg %[n],0b\n" | ||
| 418 | "1:\n" | ||
| 419 | : [addr] "=&d" (addr), | ||
| 420 | [psw_pgm_addr] "=&Q" (S390_lowcore.program_new_psw.addr), | ||
| 421 | [dst] "+&a" (dst), [src] "+&a" (src), [n] "+d" (n) | ||
| 422 | : [incr] "d" (incr) | ||
| 423 | : "cc", "memory"); | ||
| 424 | S390_lowcore.program_new_psw = old; | ||
| 425 | } | ||
| 426 | |||
| 427 | static __init noinline void ipl_save_parameters(void) | ||
| 428 | { | ||
| 429 | void *src, *dst; | ||
| 430 | |||
| 431 | src = (void *)(unsigned long) S390_lowcore.ipl_parmblock_ptr; | ||
| 432 | dst = (void *) IPL_PARMBLOCK_ORIGIN; | ||
| 433 | memmove_early(dst, src, PAGE_SIZE); | ||
| 434 | S390_lowcore.ipl_parmblock_ptr = IPL_PARMBLOCK_ORIGIN; | ||
| 435 | } | ||
| 436 | |||
| 437 | static __init noinline void rescue_initrd(void) | ||
| 396 | { | 438 | { |
| 397 | #ifdef CONFIG_BLK_DEV_INITRD | 439 | #ifdef CONFIG_BLK_DEV_INITRD |
| 398 | unsigned long min_initrd_addr = (unsigned long) _end + (4UL << 20); | 440 | unsigned long min_initrd_addr = (unsigned long) _end + (4UL << 20); |
| @@ -406,7 +448,7 @@ static __init void rescue_initrd(void) | |||
| 406 | return; | 448 | return; |
| 407 | if (INITRD_START >= min_initrd_addr) | 449 | if (INITRD_START >= min_initrd_addr) |
| 408 | return; | 450 | return; |
| 409 | memmove((void *) min_initrd_addr, (void *) INITRD_START, INITRD_SIZE); | 451 | memmove_early((void *) min_initrd_addr, (void *) INITRD_START, INITRD_SIZE); |
| 410 | INITRD_START = min_initrd_addr; | 452 | INITRD_START = min_initrd_addr; |
| 411 | #endif | 453 | #endif |
| 412 | } | 454 | } |
| @@ -468,6 +510,7 @@ void __init startup_init(void) | |||
| 468 | ipl_save_parameters(); | 510 | ipl_save_parameters(); |
| 469 | rescue_initrd(); | 511 | rescue_initrd(); |
| 470 | clear_bss_section(); | 512 | clear_bss_section(); |
| 513 | ipl_verify_parameters(); | ||
| 471 | time_early_init(); | 514 | time_early_init(); |
| 472 | init_kernel_storage_key(); | 515 | init_kernel_storage_key(); |
| 473 | lockdep_off(); | 516 | lockdep_off(); |
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index 295bfb7124bc..ff3364a067ff 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c | |||
| @@ -1991,10 +1991,9 @@ void __init ipl_update_parameters(void) | |||
| 1991 | diag308_set_works = 1; | 1991 | diag308_set_works = 1; |
| 1992 | } | 1992 | } |
| 1993 | 1993 | ||
| 1994 | void __init ipl_save_parameters(void) | 1994 | void __init ipl_verify_parameters(void) |
| 1995 | { | 1995 | { |
| 1996 | struct cio_iplinfo iplinfo; | 1996 | struct cio_iplinfo iplinfo; |
| 1997 | void *src, *dst; | ||
| 1998 | 1997 | ||
| 1999 | if (cio_get_iplinfo(&iplinfo)) | 1998 | if (cio_get_iplinfo(&iplinfo)) |
| 2000 | return; | 1999 | return; |
| @@ -2005,10 +2004,6 @@ void __init ipl_save_parameters(void) | |||
| 2005 | if (!iplinfo.is_qdio) | 2004 | if (!iplinfo.is_qdio) |
| 2006 | return; | 2005 | return; |
| 2007 | ipl_flags |= IPL_PARMBLOCK_VALID; | 2006 | ipl_flags |= IPL_PARMBLOCK_VALID; |
| 2008 | src = (void *)(unsigned long)S390_lowcore.ipl_parmblock_ptr; | ||
| 2009 | dst = (void *)IPL_PARMBLOCK_ORIGIN; | ||
| 2010 | memmove(dst, src, PAGE_SIZE); | ||
| 2011 | S390_lowcore.ipl_parmblock_ptr = IPL_PARMBLOCK_ORIGIN; | ||
| 2012 | } | 2007 | } |
| 2013 | 2008 | ||
| 2014 | static LIST_HEAD(rcall); | 2009 | static LIST_HEAD(rcall); |
