aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/ipl.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kernel/ipl.c')
-rw-r--r--arch/s390/kernel/ipl.c56
1 files changed, 36 insertions, 20 deletions
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index 4d73296fed74..a689070be287 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -15,6 +15,7 @@
15#include <linux/reboot.h> 15#include <linux/reboot.h>
16#include <linux/ctype.h> 16#include <linux/ctype.h>
17#include <linux/fs.h> 17#include <linux/fs.h>
18#include <linux/gfp.h>
18#include <asm/ipl.h> 19#include <asm/ipl.h>
19#include <asm/smp.h> 20#include <asm/smp.h>
20#include <asm/setup.h> 21#include <asm/setup.h>
@@ -402,8 +403,9 @@ static ssize_t sys_ipl_device_show(struct kobject *kobj,
402static struct kobj_attribute sys_ipl_device_attr = 403static struct kobj_attribute sys_ipl_device_attr =
403 __ATTR(device, S_IRUGO, sys_ipl_device_show, NULL); 404 __ATTR(device, S_IRUGO, sys_ipl_device_show, NULL);
404 405
405static ssize_t ipl_parameter_read(struct kobject *kobj, struct bin_attribute *attr, 406static ssize_t ipl_parameter_read(struct file *filp, struct kobject *kobj,
406 char *buf, loff_t off, size_t count) 407 struct bin_attribute *attr, char *buf,
408 loff_t off, size_t count)
407{ 409{
408 return memory_read_from_buffer(buf, count, &off, IPL_PARMBLOCK_START, 410 return memory_read_from_buffer(buf, count, &off, IPL_PARMBLOCK_START,
409 IPL_PARMBLOCK_SIZE); 411 IPL_PARMBLOCK_SIZE);
@@ -418,8 +420,9 @@ static struct bin_attribute ipl_parameter_attr = {
418 .read = &ipl_parameter_read, 420 .read = &ipl_parameter_read,
419}; 421};
420 422
421static ssize_t ipl_scp_data_read(struct kobject *kobj, struct bin_attribute *attr, 423static ssize_t ipl_scp_data_read(struct file *filp, struct kobject *kobj,
422 char *buf, loff_t off, size_t count) 424 struct bin_attribute *attr, char *buf,
425 loff_t off, size_t count)
423{ 426{
424 unsigned int size = IPL_PARMBLOCK_START->ipl_info.fcp.scp_data_len; 427 unsigned int size = IPL_PARMBLOCK_START->ipl_info.fcp.scp_data_len;
425 void *scp_data = &IPL_PARMBLOCK_START->ipl_info.fcp.scp_data; 428 void *scp_data = &IPL_PARMBLOCK_START->ipl_info.fcp.scp_data;
@@ -553,7 +556,7 @@ out:
553 return rc; 556 return rc;
554} 557}
555 558
556static void ipl_run(struct shutdown_trigger *trigger) 559static void __ipl_run(void *unused)
557{ 560{
558 diag308(DIAG308_IPL, NULL); 561 diag308(DIAG308_IPL, NULL);
559 if (MACHINE_IS_VM) 562 if (MACHINE_IS_VM)
@@ -562,6 +565,11 @@ static void ipl_run(struct shutdown_trigger *trigger)
562 reipl_ccw_dev(&ipl_info.data.ccw.dev_id); 565 reipl_ccw_dev(&ipl_info.data.ccw.dev_id);
563} 566}
564 567
568static void ipl_run(struct shutdown_trigger *trigger)
569{
570 smp_switch_to_ipl_cpu(__ipl_run, NULL);
571}
572
565static int __init ipl_init(void) 573static int __init ipl_init(void)
566{ 574{
567 int rc; 575 int rc;
@@ -688,7 +696,7 @@ static struct kobj_attribute sys_reipl_ccw_vmparm_attr =
688 696
689/* FCP reipl device attributes */ 697/* FCP reipl device attributes */
690 698
691static ssize_t reipl_fcp_scpdata_read(struct kobject *kobj, 699static ssize_t reipl_fcp_scpdata_read(struct file *filp, struct kobject *kobj,
692 struct bin_attribute *attr, 700 struct bin_attribute *attr,
693 char *buf, loff_t off, size_t count) 701 char *buf, loff_t off, size_t count)
694{ 702{
@@ -698,7 +706,7 @@ static ssize_t reipl_fcp_scpdata_read(struct kobject *kobj,
698 return memory_read_from_buffer(buf, count, &off, scp_data, size); 706 return memory_read_from_buffer(buf, count, &off, scp_data, size);
699} 707}
700 708
701static ssize_t reipl_fcp_scpdata_write(struct kobject *kobj, 709static ssize_t reipl_fcp_scpdata_write(struct file *filp, struct kobject *kobj,
702 struct bin_attribute *attr, 710 struct bin_attribute *attr,
703 char *buf, loff_t off, size_t count) 711 char *buf, loff_t off, size_t count)
704{ 712{
@@ -1039,7 +1047,7 @@ static void get_ipl_string(char *dst, struct ipl_parameter_block *ipb,
1039 sprintf(dst + pos, " PARM %s", vmparm); 1047 sprintf(dst + pos, " PARM %s", vmparm);
1040} 1048}
1041 1049
1042static void reipl_run(struct shutdown_trigger *trigger) 1050static void __reipl_run(void *unused)
1043{ 1051{
1044 struct ccw_dev_id devid; 1052 struct ccw_dev_id devid;
1045 static char buf[128]; 1053 static char buf[128];
@@ -1087,6 +1095,11 @@ static void reipl_run(struct shutdown_trigger *trigger)
1087 disabled_wait((unsigned long) __builtin_return_address(0)); 1095 disabled_wait((unsigned long) __builtin_return_address(0));
1088} 1096}
1089 1097
1098static void reipl_run(struct shutdown_trigger *trigger)
1099{
1100 smp_switch_to_ipl_cpu(__reipl_run, NULL);
1101}
1102
1090static void reipl_block_ccw_init(struct ipl_parameter_block *ipb) 1103static void reipl_block_ccw_init(struct ipl_parameter_block *ipb)
1091{ 1104{
1092 ipb->hdr.len = IPL_PARM_BLK_CCW_LEN; 1105 ipb->hdr.len = IPL_PARM_BLK_CCW_LEN;
@@ -1369,20 +1382,18 @@ static struct kobj_attribute dump_type_attr =
1369 1382
1370static struct kset *dump_kset; 1383static struct kset *dump_kset;
1371 1384
1372static void dump_run(struct shutdown_trigger *trigger) 1385static void __dump_run(void *unused)
1373{ 1386{
1374 struct ccw_dev_id devid; 1387 struct ccw_dev_id devid;
1375 static char buf[100]; 1388 static char buf[100];
1376 1389
1377 switch (dump_method) { 1390 switch (dump_method) {
1378 case DUMP_METHOD_CCW_CIO: 1391 case DUMP_METHOD_CCW_CIO:
1379 smp_send_stop();
1380 devid.devno = dump_block_ccw->ipl_info.ccw.devno; 1392 devid.devno = dump_block_ccw->ipl_info.ccw.devno;
1381 devid.ssid = 0; 1393 devid.ssid = 0;
1382 reipl_ccw_dev(&devid); 1394 reipl_ccw_dev(&devid);
1383 break; 1395 break;
1384 case DUMP_METHOD_CCW_VM: 1396 case DUMP_METHOD_CCW_VM:
1385 smp_send_stop();
1386 sprintf(buf, "STORE STATUS"); 1397 sprintf(buf, "STORE STATUS");
1387 __cpcmd(buf, NULL, 0, NULL); 1398 __cpcmd(buf, NULL, 0, NULL);
1388 sprintf(buf, "IPL %X", dump_block_ccw->ipl_info.ccw.devno); 1399 sprintf(buf, "IPL %X", dump_block_ccw->ipl_info.ccw.devno);
@@ -1396,10 +1407,17 @@ static void dump_run(struct shutdown_trigger *trigger)
1396 diag308(DIAG308_SET, dump_block_fcp); 1407 diag308(DIAG308_SET, dump_block_fcp);
1397 diag308(DIAG308_DUMP, NULL); 1408 diag308(DIAG308_DUMP, NULL);
1398 break; 1409 break;
1399 case DUMP_METHOD_NONE: 1410 default:
1400 return; 1411 break;
1401 } 1412 }
1402 printk(KERN_EMERG "Dump failed!\n"); 1413}
1414
1415static void dump_run(struct shutdown_trigger *trigger)
1416{
1417 if (dump_method == DUMP_METHOD_NONE)
1418 return;
1419 smp_send_stop();
1420 smp_switch_to_ipl_cpu(__dump_run, NULL);
1403} 1421}
1404 1422
1405static int __init dump_ccw_init(void) 1423static int __init dump_ccw_init(void)
@@ -1577,7 +1595,7 @@ static void vmcmd_run(struct shutdown_trigger *trigger)
1577static int vmcmd_init(void) 1595static int vmcmd_init(void)
1578{ 1596{
1579 if (!MACHINE_IS_VM) 1597 if (!MACHINE_IS_VM)
1580 return -ENOTSUPP; 1598 return -EOPNOTSUPP;
1581 vmcmd_kset = kset_create_and_add("vmcmd", NULL, firmware_kobj); 1599 vmcmd_kset = kset_create_and_add("vmcmd", NULL, firmware_kobj);
1582 if (!vmcmd_kset) 1600 if (!vmcmd_kset)
1583 return -ENOMEM; 1601 return -ENOMEM;
@@ -1595,7 +1613,7 @@ static void stop_run(struct shutdown_trigger *trigger)
1595{ 1613{
1596 if (strcmp(trigger->name, ON_PANIC_STR) == 0) 1614 if (strcmp(trigger->name, ON_PANIC_STR) == 0)
1597 disabled_wait((unsigned long) __builtin_return_address(0)); 1615 disabled_wait((unsigned long) __builtin_return_address(0));
1598 while (signal_processor(smp_processor_id(), sigp_stop) == sigp_busy) 1616 while (sigp(smp_processor_id(), sigp_stop) == sigp_busy)
1599 cpu_relax(); 1617 cpu_relax();
1600 for (;;); 1618 for (;;);
1601} 1619}
@@ -1902,7 +1920,6 @@ void __init ipl_update_parameters(void)
1902void __init ipl_save_parameters(void) 1920void __init ipl_save_parameters(void)
1903{ 1921{
1904 struct cio_iplinfo iplinfo; 1922 struct cio_iplinfo iplinfo;
1905 unsigned int *ipl_ptr;
1906 void *src, *dst; 1923 void *src, *dst;
1907 1924
1908 if (cio_get_iplinfo(&iplinfo)) 1925 if (cio_get_iplinfo(&iplinfo))
@@ -1913,11 +1930,10 @@ void __init ipl_save_parameters(void)
1913 if (!iplinfo.is_qdio) 1930 if (!iplinfo.is_qdio)
1914 return; 1931 return;
1915 ipl_flags |= IPL_PARMBLOCK_VALID; 1932 ipl_flags |= IPL_PARMBLOCK_VALID;
1916 ipl_ptr = (unsigned int *)__LC_IPL_PARMBLOCK_PTR; 1933 src = (void *)(unsigned long)S390_lowcore.ipl_parmblock_ptr;
1917 src = (void *)(unsigned long)*ipl_ptr;
1918 dst = (void *)IPL_PARMBLOCK_ORIGIN; 1934 dst = (void *)IPL_PARMBLOCK_ORIGIN;
1919 memmove(dst, src, PAGE_SIZE); 1935 memmove(dst, src, PAGE_SIZE);
1920 *ipl_ptr = IPL_PARMBLOCK_ORIGIN; 1936 S390_lowcore.ipl_parmblock_ptr = IPL_PARMBLOCK_ORIGIN;
1921} 1937}
1922 1938
1923static LIST_HEAD(rcall); 1939static LIST_HEAD(rcall);