aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/s390/include/asm/ipl.h2
-rw-r--r--arch/s390/kernel/early.c47
-rw-r--r--arch/s390/kernel/ipl.c7
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);
97extern void do_reipl(void); 97extern void do_reipl(void);
98extern void do_halt(void); 98extern void do_halt(void);
99extern void do_poff(void); 99extern void do_poff(void);
100extern void ipl_save_parameters(void); 100extern void ipl_verify_parameters(void);
101extern void ipl_update_parameters(void); 101extern void ipl_update_parameters(void);
102extern size_t append_ipl_vmparm(char *, size_t); 102extern size_t append_ipl_vmparm(char *, size_t);
103extern size_t append_ipl_scpdata(char *, size_t); 103extern 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}
393early_initcall(cad_init); 393early_initcall(cad_init);
394 394
395static __init void rescue_initrd(void) 395static __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
427static __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
437static __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
1994void __init ipl_save_parameters(void) 1994void __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
2014static LIST_HEAD(rcall); 2009static LIST_HEAD(rcall);