aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVasily Gorbik <gor@linux.ibm.com>2018-04-03 10:03:32 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2018-04-10 01:38:59 -0400
commitd485235b005407ae64246a8fe2171d1b369b3b30 (patch)
tree93a2a5b33b06b4d790c32a22eece0e3c1d6ea4a6
parentecc0df0f23cb5f83ee580a8d1d818524955cbc97 (diff)
s390: assume diag308 set always works
diag308 set has been available for many machine generations, and alternative reipl code paths has not been exercised and seems to be broken without noticing for a while now. So, cleaning up all obsolete reipl methods except currently used ones, assuming that diag308 set always works. Also removing not longer needed reset callbacks. Reviewed-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--arch/s390/include/asm/cio.h2
-rw-r--r--arch/s390/include/asm/ipl.h1
-rw-r--r--arch/s390/include/asm/reset.h20
-rw-r--r--arch/s390/kernel/ipl.c209
-rw-r--r--arch/s390/kernel/machine_kexec.c1
-rw-r--r--arch/s390/kernel/reipl.S87
-rw-r--r--arch/s390/kernel/relocate_kernel.S54
-rw-r--r--drivers/s390/cio/cio.c224
-rw-r--r--drivers/s390/cio/ioasm.c24
-rw-r--r--drivers/s390/cio/ioasm.h1
-rw-r--r--drivers/s390/crypto/ap_bus.c23
11 files changed, 16 insertions, 630 deletions
diff --git a/arch/s390/include/asm/cio.h b/arch/s390/include/asm/cio.h
index 80c1179bc666..225667652069 100644
--- a/arch/s390/include/asm/cio.h
+++ b/arch/s390/include/asm/cio.h
@@ -328,8 +328,6 @@ static inline u8 pathmask_to_pos(u8 mask)
328void channel_subsystem_reinit(void); 328void channel_subsystem_reinit(void);
329extern void css_schedule_reprobe(void); 329extern void css_schedule_reprobe(void);
330 330
331extern void reipl_ccw_dev(struct ccw_dev_id *id);
332
333/* Function from drivers/s390/cio/chsc.c */ 331/* Function from drivers/s390/cio/chsc.c */
334int chsc_sstpc(void *page, unsigned int op, u16 ctrl, u64 *clock_delta); 332int chsc_sstpc(void *page, unsigned int op, u16 ctrl, u64 *clock_delta);
335int chsc_sstpi(void *page, void *result, size_t size); 333int chsc_sstpi(void *page, void *result, size_t size);
diff --git a/arch/s390/include/asm/ipl.h b/arch/s390/include/asm/ipl.h
index eb10df9ef607..b218019ff8f3 100644
--- a/arch/s390/include/asm/ipl.h
+++ b/arch/s390/include/asm/ipl.h
@@ -87,6 +87,7 @@ struct save_area * __init save_area_boot_cpu(void);
87void __init save_area_add_regs(struct save_area *, void *regs); 87void __init save_area_add_regs(struct save_area *, void *regs);
88void __init save_area_add_vxrs(struct save_area *, __vector128 *vxrs); 88void __init save_area_add_vxrs(struct save_area *, __vector128 *vxrs);
89 89
90extern void s390_reset_system(void);
90extern void do_reipl(void); 91extern void do_reipl(void);
91extern void do_halt(void); 92extern void do_halt(void);
92extern void do_poff(void); 93extern void do_poff(void);
diff --git a/arch/s390/include/asm/reset.h b/arch/s390/include/asm/reset.h
deleted file mode 100644
index 6450b31ade03..000000000000
--- a/arch/s390/include/asm/reset.h
+++ /dev/null
@@ -1,20 +0,0 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright IBM Corp. 2006
4 * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
5 */
6
7#ifndef _ASM_S390_RESET_H
8#define _ASM_S390_RESET_H
9
10#include <linux/list.h>
11
12struct reset_call {
13 struct list_head list;
14 void (*fn)(void);
15};
16
17extern void register_reset_call(struct reset_call *reset);
18extern void unregister_reset_call(struct reset_call *reset);
19extern void s390_reset_system(void);
20#endif /* _ASM_S390_RESET_H */
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index 39572ee8e2a7..db86c67f48ec 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -25,7 +25,6 @@
25#include <asm/setup.h> 25#include <asm/setup.h>
26#include <asm/cpcmd.h> 26#include <asm/cpcmd.h>
27#include <asm/ebcdic.h> 27#include <asm/ebcdic.h>
28#include <asm/reset.h>
29#include <asm/sclp.h> 28#include <asm/sclp.h>
30#include <asm/checksum.h> 29#include <asm/checksum.h>
31#include <asm/debug.h> 30#include <asm/debug.h>
@@ -119,29 +118,20 @@ static char *dump_type_str(enum dump_type type)
119} 118}
120 119
121enum ipl_method { 120enum ipl_method {
122 REIPL_METHOD_CCW_CIO,
123 REIPL_METHOD_CCW_DIAG, 121 REIPL_METHOD_CCW_DIAG,
124 REIPL_METHOD_CCW_VM, 122 REIPL_METHOD_FCP_DIAG,
125 REIPL_METHOD_FCP_RO_DIAG,
126 REIPL_METHOD_FCP_RW_DIAG,
127 REIPL_METHOD_FCP_RO_VM,
128 REIPL_METHOD_FCP_DUMP, 123 REIPL_METHOD_FCP_DUMP,
129 REIPL_METHOD_NSS,
130 REIPL_METHOD_NSS_DIAG, 124 REIPL_METHOD_NSS_DIAG,
131 REIPL_METHOD_DEFAULT, 125 REIPL_METHOD_DEFAULT,
132}; 126};
133 127
134enum dump_method { 128enum dump_method {
135 DUMP_METHOD_NONE, 129 DUMP_METHOD_NONE,
136 DUMP_METHOD_CCW_CIO,
137 DUMP_METHOD_CCW_DIAG, 130 DUMP_METHOD_CCW_DIAG,
138 DUMP_METHOD_CCW_VM,
139 DUMP_METHOD_FCP_DIAG, 131 DUMP_METHOD_FCP_DIAG,
140}; 132};
141 133
142static int ipl_block_valid; 134static int ipl_block_valid;
143static int diag308_set_works;
144
145static struct ipl_parameter_block ipl_block; 135static struct ipl_parameter_block ipl_block;
146 136
147static int reipl_capabilities = IPL_TYPE_UNKNOWN; 137static int reipl_capabilities = IPL_TYPE_UNKNOWN;
@@ -256,14 +246,6 @@ static struct kobj_attribute sys_##_prefix##_##_name##_attr = \
256 sys_##_prefix##_##_name##_show, \ 246 sys_##_prefix##_##_name##_show, \
257 sys_##_prefix##_##_name##_store) 247 sys_##_prefix##_##_name##_store)
258 248
259static void make_attrs_ro(struct attribute **attrs)
260{
261 while (*attrs) {
262 (*attrs)->mode = S_IRUGO;
263 attrs++;
264 }
265}
266
267/* 249/*
268 * ipl section 250 * ipl section
269 */ 251 */
@@ -541,10 +523,6 @@ static void __ipl_run(void *unused)
541{ 523{
542 __bpon(); 524 __bpon();
543 diag308(DIAG308_LOAD_CLEAR, NULL); 525 diag308(DIAG308_LOAD_CLEAR, NULL);
544 if (MACHINE_IS_VM)
545 __cpcmd("IPL", NULL, 0, NULL);
546 else if (ipl_info.type == IPL_TYPE_CCW)
547 reipl_ccw_dev(&ipl_info.data.ccw.dev_id);
548} 526}
549 527
550static void ipl_run(struct shutdown_trigger *trigger) 528static void ipl_run(struct shutdown_trigger *trigger)
@@ -951,31 +929,18 @@ static int reipl_set_type(enum ipl_type type)
951 929
952 switch(type) { 930 switch(type) {
953 case IPL_TYPE_CCW: 931 case IPL_TYPE_CCW:
954 if (diag308_set_works) 932 reipl_method = REIPL_METHOD_CCW_DIAG;
955 reipl_method = REIPL_METHOD_CCW_DIAG;
956 else if (MACHINE_IS_VM)
957 reipl_method = REIPL_METHOD_CCW_VM;
958 else
959 reipl_method = REIPL_METHOD_CCW_CIO;
960 set_reipl_block_actual(reipl_block_ccw); 933 set_reipl_block_actual(reipl_block_ccw);
961 break; 934 break;
962 case IPL_TYPE_FCP: 935 case IPL_TYPE_FCP:
963 if (diag308_set_works) 936 reipl_method = REIPL_METHOD_FCP_DIAG;
964 reipl_method = REIPL_METHOD_FCP_RW_DIAG;
965 else if (MACHINE_IS_VM)
966 reipl_method = REIPL_METHOD_FCP_RO_VM;
967 else
968 reipl_method = REIPL_METHOD_FCP_RO_DIAG;
969 set_reipl_block_actual(reipl_block_fcp); 937 set_reipl_block_actual(reipl_block_fcp);
970 break; 938 break;
971 case IPL_TYPE_FCP_DUMP: 939 case IPL_TYPE_FCP_DUMP:
972 reipl_method = REIPL_METHOD_FCP_DUMP; 940 reipl_method = REIPL_METHOD_FCP_DUMP;
973 break; 941 break;
974 case IPL_TYPE_NSS: 942 case IPL_TYPE_NSS:
975 if (diag308_set_works) 943 reipl_method = REIPL_METHOD_NSS_DIAG;
976 reipl_method = REIPL_METHOD_NSS_DIAG;
977 else
978 reipl_method = REIPL_METHOD_NSS;
979 set_reipl_block_actual(reipl_block_nss); 944 set_reipl_block_actual(reipl_block_nss);
980 break; 945 break;
981 case IPL_TYPE_UNKNOWN: 946 case IPL_TYPE_UNKNOWN:
@@ -1015,74 +980,22 @@ static struct kobj_attribute reipl_type_attr =
1015static struct kset *reipl_kset; 980static struct kset *reipl_kset;
1016static struct kset *reipl_fcp_kset; 981static struct kset *reipl_fcp_kset;
1017 982
1018static void get_ipl_string(char *dst, struct ipl_parameter_block *ipb,
1019 const enum ipl_method m)
1020{
1021 char loadparm[LOADPARM_LEN + 1] = {};
1022 char vmparm[DIAG308_VMPARM_SIZE + 1] = {};
1023 char nss_name[NSS_NAME_SIZE + 1] = {};
1024 size_t pos = 0;
1025
1026 reipl_get_ascii_loadparm(loadparm, ipb);
1027 reipl_get_ascii_nss_name(nss_name, ipb);
1028 reipl_get_ascii_vmparm(vmparm, sizeof(vmparm), ipb);
1029
1030 switch (m) {
1031 case REIPL_METHOD_CCW_VM:
1032 pos = sprintf(dst, "IPL %X CLEAR", ipb->ipl_info.ccw.devno);
1033 break;
1034 case REIPL_METHOD_NSS:
1035 pos = sprintf(dst, "IPL %s", nss_name);
1036 break;
1037 default:
1038 break;
1039 }
1040 if (strlen(loadparm) > 0)
1041 pos += sprintf(dst + pos, " LOADPARM '%s'", loadparm);
1042 if (strlen(vmparm) > 0)
1043 sprintf(dst + pos, " PARM %s", vmparm);
1044}
1045
1046static void __reipl_run(void *unused) 983static void __reipl_run(void *unused)
1047{ 984{
1048 struct ccw_dev_id devid;
1049 static char buf[128];
1050
1051 switch (reipl_method) { 985 switch (reipl_method) {
1052 case REIPL_METHOD_CCW_CIO:
1053 devid.ssid = reipl_block_ccw->ipl_info.ccw.ssid;
1054 devid.devno = reipl_block_ccw->ipl_info.ccw.devno;
1055 reipl_ccw_dev(&devid);
1056 break;
1057 case REIPL_METHOD_CCW_VM:
1058 get_ipl_string(buf, reipl_block_ccw, REIPL_METHOD_CCW_VM);
1059 __cpcmd(buf, NULL, 0, NULL);
1060 break;
1061 case REIPL_METHOD_CCW_DIAG: 986 case REIPL_METHOD_CCW_DIAG:
1062 diag308(DIAG308_SET, reipl_block_ccw); 987 diag308(DIAG308_SET, reipl_block_ccw);
1063 diag308(DIAG308_LOAD_CLEAR, NULL); 988 diag308(DIAG308_LOAD_CLEAR, NULL);
1064 break; 989 break;
1065 case REIPL_METHOD_FCP_RW_DIAG: 990 case REIPL_METHOD_FCP_DIAG:
1066 diag308(DIAG308_SET, reipl_block_fcp); 991 diag308(DIAG308_SET, reipl_block_fcp);
1067 diag308(DIAG308_LOAD_CLEAR, NULL); 992 diag308(DIAG308_LOAD_CLEAR, NULL);
1068 break; 993 break;
1069 case REIPL_METHOD_FCP_RO_DIAG:
1070 diag308(DIAG308_LOAD_CLEAR, NULL);
1071 break;
1072 case REIPL_METHOD_FCP_RO_VM:
1073 __cpcmd("IPL", NULL, 0, NULL);
1074 break;
1075 case REIPL_METHOD_NSS_DIAG: 994 case REIPL_METHOD_NSS_DIAG:
1076 diag308(DIAG308_SET, reipl_block_nss); 995 diag308(DIAG308_SET, reipl_block_nss);
1077 diag308(DIAG308_LOAD_CLEAR, NULL); 996 diag308(DIAG308_LOAD_CLEAR, NULL);
1078 break; 997 break;
1079 case REIPL_METHOD_NSS:
1080 get_ipl_string(buf, reipl_block_nss, REIPL_METHOD_NSS);
1081 __cpcmd(buf, NULL, 0, NULL);
1082 break;
1083 case REIPL_METHOD_DEFAULT: 998 case REIPL_METHOD_DEFAULT:
1084 if (MACHINE_IS_VM)
1085 __cpcmd("IPL", NULL, 0, NULL);
1086 diag308(DIAG308_LOAD_CLEAR, NULL); 999 diag308(DIAG308_LOAD_CLEAR, NULL);
1087 break; 1000 break;
1088 case REIPL_METHOD_FCP_DUMP: 1001 case REIPL_METHOD_FCP_DUMP:
@@ -1138,9 +1051,6 @@ static int __init reipl_nss_init(void)
1138 if (!reipl_block_nss) 1051 if (!reipl_block_nss)
1139 return -ENOMEM; 1052 return -ENOMEM;
1140 1053
1141 if (!diag308_set_works)
1142 sys_reipl_nss_vmparm_attr.attr.mode = S_IRUGO;
1143
1144 rc = sysfs_create_group(&reipl_kset->kobj, &reipl_nss_attr_group); 1054 rc = sysfs_create_group(&reipl_kset->kobj, &reipl_nss_attr_group);
1145 if (rc) 1055 if (rc)
1146 return rc; 1056 return rc;
@@ -1158,17 +1068,9 @@ static int __init reipl_ccw_init(void)
1158 if (!reipl_block_ccw) 1068 if (!reipl_block_ccw)
1159 return -ENOMEM; 1069 return -ENOMEM;
1160 1070
1161 if (MACHINE_IS_VM) { 1071 rc = sysfs_create_group(&reipl_kset->kobj,
1162 if (!diag308_set_works) 1072 MACHINE_IS_VM ? &reipl_ccw_attr_group_vm
1163 sys_reipl_ccw_vmparm_attr.attr.mode = S_IRUGO; 1073 : &reipl_ccw_attr_group_lpar);
1164 rc = sysfs_create_group(&reipl_kset->kobj,
1165 &reipl_ccw_attr_group_vm);
1166 } else {
1167 if(!diag308_set_works)
1168 sys_reipl_ccw_loadparm_attr.attr.mode = S_IRUGO;
1169 rc = sysfs_create_group(&reipl_kset->kobj,
1170 &reipl_ccw_attr_group_lpar);
1171 }
1172 if (rc) 1074 if (rc)
1173 return rc; 1075 return rc;
1174 1076
@@ -1187,14 +1089,6 @@ static int __init reipl_fcp_init(void)
1187{ 1089{
1188 int rc; 1090 int rc;
1189 1091
1190 if (!diag308_set_works) {
1191 if (ipl_info.type == IPL_TYPE_FCP) {
1192 make_attrs_ro(reipl_fcp_attrs);
1193 sys_reipl_fcp_scp_data_attr.attr.mode = S_IRUGO;
1194 } else
1195 return 0;
1196 }
1197
1198 reipl_block_fcp = (void *) get_zeroed_page(GFP_KERNEL); 1092 reipl_block_fcp = (void *) get_zeroed_page(GFP_KERNEL);
1199 if (!reipl_block_fcp) 1093 if (!reipl_block_fcp)
1200 return -ENOMEM; 1094 return -ENOMEM;
@@ -1339,12 +1233,7 @@ static int dump_set_type(enum dump_type type)
1339 return -EINVAL; 1233 return -EINVAL;
1340 switch (type) { 1234 switch (type) {
1341 case DUMP_TYPE_CCW: 1235 case DUMP_TYPE_CCW:
1342 if (diag308_set_works) 1236 dump_method = DUMP_METHOD_CCW_DIAG;
1343 dump_method = DUMP_METHOD_CCW_DIAG;
1344 else if (MACHINE_IS_VM)
1345 dump_method = DUMP_METHOD_CCW_VM;
1346 else
1347 dump_method = DUMP_METHOD_CCW_CIO;
1348 break; 1237 break;
1349 case DUMP_TYPE_FCP: 1238 case DUMP_TYPE_FCP:
1350 dump_method = DUMP_METHOD_FCP_DIAG; 1239 dump_method = DUMP_METHOD_FCP_DIAG;
@@ -1394,21 +1283,7 @@ static void diag308_dump(void *dump_block)
1394 1283
1395static void __dump_run(void *unused) 1284static void __dump_run(void *unused)
1396{ 1285{
1397 struct ccw_dev_id devid;
1398 static char buf[100];
1399
1400 switch (dump_method) { 1286 switch (dump_method) {
1401 case DUMP_METHOD_CCW_CIO:
1402 devid.ssid = dump_block_ccw->ipl_info.ccw.ssid;
1403 devid.devno = dump_block_ccw->ipl_info.ccw.devno;
1404 reipl_ccw_dev(&devid);
1405 break;
1406 case DUMP_METHOD_CCW_VM:
1407 sprintf(buf, "STORE STATUS");
1408 __cpcmd(buf, NULL, 0, NULL);
1409 sprintf(buf, "IPL %X", dump_block_ccw->ipl_info.ccw.devno);
1410 __cpcmd(buf, NULL, 0, NULL);
1411 break;
1412 case DUMP_METHOD_CCW_DIAG: 1287 case DUMP_METHOD_CCW_DIAG:
1413 diag308_dump(dump_block_ccw); 1288 diag308_dump(dump_block_ccw);
1414 break; 1289 break;
@@ -1454,8 +1329,6 @@ static int __init dump_fcp_init(void)
1454 1329
1455 if (!sclp_ipl_info.has_dump) 1330 if (!sclp_ipl_info.has_dump)
1456 return 0; /* LDIPL DUMP is not installed */ 1331 return 0; /* LDIPL DUMP is not installed */
1457 if (!diag308_set_works)
1458 return 0;
1459 dump_block_fcp = (void *) get_zeroed_page(GFP_KERNEL); 1332 dump_block_fcp = (void *) get_zeroed_page(GFP_KERNEL);
1460 if (!dump_block_fcp) 1333 if (!dump_block_fcp)
1461 return -ENOMEM; 1334 return -ENOMEM;
@@ -1513,18 +1386,9 @@ static void dump_reipl_run(struct shutdown_trigger *trigger)
1513 dump_run(trigger); 1386 dump_run(trigger);
1514} 1387}
1515 1388
1516static int __init dump_reipl_init(void)
1517{
1518 if (!diag308_set_works)
1519 return -EOPNOTSUPP;
1520 else
1521 return 0;
1522}
1523
1524static struct shutdown_action __refdata dump_reipl_action = { 1389static struct shutdown_action __refdata dump_reipl_action = {
1525 .name = SHUTDOWN_ACTION_DUMP_REIPL_STR, 1390 .name = SHUTDOWN_ACTION_DUMP_REIPL_STR,
1526 .fn = dump_reipl_run, 1391 .fn = dump_reipl_run,
1527 .init = dump_reipl_init,
1528}; 1392};
1529 1393
1530/* 1394/*
@@ -1944,67 +1808,16 @@ void __init ipl_store_parameters(void)
1944 int rc; 1808 int rc;
1945 1809
1946 rc = diag308(DIAG308_STORE, &ipl_block); 1810 rc = diag308(DIAG308_STORE, &ipl_block);
1947 if ((rc == DIAG308_RC_OK) || (rc == DIAG308_RC_NOCONFIG))
1948 diag308_set_works = 1;
1949 if (rc == DIAG308_RC_OK && ipl_block.hdr.version <= IPL_MAX_SUPPORTED_VERSION) 1811 if (rc == DIAG308_RC_OK && ipl_block.hdr.version <= IPL_MAX_SUPPORTED_VERSION)
1950 ipl_block_valid = 1; 1812 ipl_block_valid = 1;
1951} 1813}
1952 1814
1953static LIST_HEAD(rcall);
1954static DEFINE_MUTEX(rcall_mutex);
1955
1956void register_reset_call(struct reset_call *reset)
1957{
1958 mutex_lock(&rcall_mutex);
1959 list_add(&reset->list, &rcall);
1960 mutex_unlock(&rcall_mutex);
1961}
1962EXPORT_SYMBOL_GPL(register_reset_call);
1963
1964void unregister_reset_call(struct reset_call *reset)
1965{
1966 mutex_lock(&rcall_mutex);
1967 list_del(&reset->list);
1968 mutex_unlock(&rcall_mutex);
1969}
1970EXPORT_SYMBOL_GPL(unregister_reset_call);
1971
1972static void do_reset_calls(void)
1973{
1974 struct reset_call *reset;
1975
1976 if (diag308_set_works) {
1977 diag308_reset();
1978 return;
1979 }
1980 list_for_each_entry(reset, &rcall, list)
1981 reset->fn();
1982}
1983
1984void s390_reset_system(void) 1815void s390_reset_system(void)
1985{ 1816{
1986 struct lowcore *lc;
1987
1988 lc = (struct lowcore *)(unsigned long) store_prefix();
1989
1990 /* Stack for interrupt/machine check handler */
1991 lc->panic_stack = S390_lowcore.panic_stack;
1992
1993 /* Disable prefixing */ 1817 /* Disable prefixing */
1994 set_prefix(0); 1818 set_prefix(0);
1995 1819
1996 /* Disable lowcore protection */ 1820 /* Disable lowcore protection */
1997 __ctl_clear_bit(0,28); 1821 __ctl_clear_bit(0, 28);
1998 1822 diag308_reset();
1999 /* Set new machine check handler */
2000 S390_lowcore.mcck_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT;
2001 S390_lowcore.mcck_new_psw.addr =
2002 (unsigned long) s390_base_mcck_handler;
2003
2004 /* Set new program check handler */
2005 S390_lowcore.program_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT;
2006 S390_lowcore.program_new_psw.addr =
2007 (unsigned long) s390_base_pgm_handler;
2008
2009 do_reset_calls();
2010} 1823}
diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c
index a80050bbe2e4..9adae2a1e1a0 100644
--- a/arch/s390/kernel/machine_kexec.c
+++ b/arch/s390/kernel/machine_kexec.c
@@ -20,7 +20,6 @@
20#include <asm/pgtable.h> 20#include <asm/pgtable.h>
21#include <asm/pgalloc.h> 21#include <asm/pgalloc.h>
22#include <asm/smp.h> 22#include <asm/smp.h>
23#include <asm/reset.h>
24#include <asm/ipl.h> 23#include <asm/ipl.h>
25#include <asm/diag.h> 24#include <asm/diag.h>
26#include <asm/elf.h> 25#include <asm/elf.h>
diff --git a/arch/s390/kernel/reipl.S b/arch/s390/kernel/reipl.S
index a40ebd1d29d0..73cc3750f0d3 100644
--- a/arch/s390/kernel/reipl.S
+++ b/arch/s390/kernel/reipl.S
@@ -75,90 +75,3 @@ ENTRY(store_status)
75 .align 8 75 .align 8
76.Lclkcmp: .quad 0x0000000000000000 76.Lclkcmp: .quad 0x0000000000000000
77 .previous 77 .previous
78
79#
80# do_reipl_asm
81# Parameter: r2 = schid of reipl device
82#
83
84ENTRY(do_reipl_asm)
85 basr %r13,0
86.Lpg0: lpswe .Lnewpsw-.Lpg0(%r13)
87.Lpg1: lgr %r3,%r2
88 larl %r2,.Lstatus
89 brasl %r14,store_status
90
91.Lstatus: lctlg %c6,%c6,.Lall-.Lpg0(%r13)
92 lgr %r1,%r2
93 mvc __LC_PGM_NEW_PSW(16),.Lpcnew-.Lpg0(%r13)
94 stsch .Lschib-.Lpg0(%r13)
95 oi .Lschib+5-.Lpg0(%r13),0x84
96.Lecs: xi .Lschib+27-.Lpg0(%r13),0x01
97 msch .Lschib-.Lpg0(%r13)
98 lghi %r0,5
99.Lssch: ssch .Liplorb-.Lpg0(%r13)
100 jz .L001
101 brct %r0,.Lssch
102 bas %r14,.Ldisab-.Lpg0(%r13)
103.L001: mvc __LC_IO_NEW_PSW(16),.Lionew-.Lpg0(%r13)
104.Ltpi: lpswe .Lwaitpsw-.Lpg0(%r13)
105.Lcont: c %r1,__LC_SUBCHANNEL_ID
106 jnz .Ltpi
107 clc __LC_IO_INT_PARM(4),.Liplorb-.Lpg0(%r13)
108 jnz .Ltpi
109 tsch .Liplirb-.Lpg0(%r13)
110 tm .Liplirb+9-.Lpg0(%r13),0xbf
111 jz .L002
112 bas %r14,.Ldisab-.Lpg0(%r13)
113.L002: tm .Liplirb+8-.Lpg0(%r13),0xf3
114 jz .L003
115 bas %r14,.Ldisab-.Lpg0(%r13)
116.L003: st %r1,__LC_SUBCHANNEL_ID
117 lhi %r1,0 # mode 0 = esa
118 slr %r0,%r0 # set cpuid to zero
119 sigp %r1,%r0,SIGP_SET_ARCHITECTURE # switch to esa mode
120 lpsw 0
121.Ldisab: sll %r14,1
122 srl %r14,1 # need to kill hi bit to avoid specification exceptions.
123 st %r14,.Ldispsw+12-.Lpg0(%r13)
124 lpswe .Ldispsw-.Lpg0(%r13)
125 .align 8
126.Lall: .quad 0x00000000ff000000
127 .align 16
128/*
129 * These addresses have to be 31 bit otherwise
130 * the sigp will throw a specifcation exception
131 * when switching to ESA mode as bit 31 be set
132 * in the ESA psw.
133 * Bit 31 of the addresses has to be 0 for the
134 * 31bit lpswe instruction a fact they appear to have
135 * omitted from the pop.
136 */
137.Lnewpsw: .quad 0x0000000080000000
138 .quad .Lpg1
139.Lpcnew: .quad 0x0000000080000000
140 .quad .Lecs
141.Lionew: .quad 0x0000000080000000
142 .quad .Lcont
143.Lwaitpsw: .quad 0x0202000080000000
144 .quad .Ltpi
145.Ldispsw: .quad 0x0002000080000000
146 .quad 0x0000000000000000
147.Liplccws: .long 0x02000000,0x60000018
148 .long 0x08000008,0x20000001
149.Liplorb: .long 0x0049504c,0x0040ff80
150 .long 0x00000000+.Liplccws
151.Lschib: .long 0x00000000,0x00000000
152 .long 0x00000000,0x00000000
153 .long 0x00000000,0x00000000
154 .long 0x00000000,0x00000000
155 .long 0x00000000,0x00000000
156 .long 0x00000000,0x00000000
157.Liplirb: .long 0x00000000,0x00000000
158 .long 0x00000000,0x00000000
159 .long 0x00000000,0x00000000
160 .long 0x00000000,0x00000000
161 .long 0x00000000,0x00000000
162 .long 0x00000000,0x00000000
163 .long 0x00000000,0x00000000
164 .long 0x00000000,0x00000000
diff --git a/arch/s390/kernel/relocate_kernel.S b/arch/s390/kernel/relocate_kernel.S
index 9c2c96da23d0..c97c2d40fe15 100644
--- a/arch/s390/kernel/relocate_kernel.S
+++ b/arch/s390/kernel/relocate_kernel.S
@@ -29,33 +29,6 @@
29ENTRY(relocate_kernel) 29ENTRY(relocate_kernel)
30 basr %r13,0 # base address 30 basr %r13,0 # base address
31 .base: 31 .base:
32 stctg %c0,%c15,ctlregs-.base(%r13)
33 stmg %r0,%r15,gprregs-.base(%r13)
34 lghi %r0,3
35 sllg %r0,%r0,31
36 stg %r0,0x1d0(%r0)
37 la %r0,.back_pgm-.base(%r13)
38 stg %r0,0x1d8(%r0)
39 la %r1,load_psw-.base(%r13)
40 mvc 0(8,%r0),0(%r1)
41 la %r0,.back-.base(%r13)
42 st %r0,4(%r0)
43 oi 4(%r0),0x80
44 lghi %r0,0
45 diag %r0,%r0,0x308
46 .back:
47 lhi %r1,1 # mode 1 = esame
48 sigp %r1,%r0,SIGP_SET_ARCHITECTURE # switch to esame mode
49 sam64 # switch to 64 bit addressing mode
50 basr %r13,0
51 .back_base:
52 oi have_diag308-.back_base(%r13),0x01
53 lctlg %c0,%c15,ctlregs-.back_base(%r13)
54 lmg %r0,%r15,gprregs-.back_base(%r13)
55 j .top
56 .back_pgm:
57 lmg %r0,%r15,gprregs-.base(%r13)
58 .top:
59 lghi %r7,PAGE_SIZE # load PAGE_SIZE in r7 32 lghi %r7,PAGE_SIZE # load PAGE_SIZE in r7
60 lghi %r9,PAGE_SIZE # load PAGE_SIZE in r9 33 lghi %r9,PAGE_SIZE # load PAGE_SIZE in r9
61 lg %r5,0(%r2) # read another word for indirection page 34 lg %r5,0(%r2) # read another word for indirection page
@@ -64,55 +37,36 @@ ENTRY(relocate_kernel)
64 je .indir_check # NO, goto "indir_check" 37 je .indir_check # NO, goto "indir_check"
65 lgr %r6,%r5 # r6 = r5 38 lgr %r6,%r5 # r6 = r5
66 nill %r6,0xf000 # mask it out and... 39 nill %r6,0xf000 # mask it out and...
67 j .top # ...next iteration 40 j .base # ...next iteration
68 .indir_check: 41 .indir_check:
69 tml %r5,0x2 # is it a indirection page? 42 tml %r5,0x2 # is it a indirection page?
70 je .done_test # NO, goto "done_test" 43 je .done_test # NO, goto "done_test"
71 nill %r5,0xf000 # YES, mask out, 44 nill %r5,0xf000 # YES, mask out,
72 lgr %r2,%r5 # move it into the right register, 45 lgr %r2,%r5 # move it into the right register,
73 j .top # and read next... 46 j .base # and read next...
74 .done_test: 47 .done_test:
75 tml %r5,0x4 # is it the done indicator? 48 tml %r5,0x4 # is it the done indicator?
76 je .source_test # NO! Well, then it should be the source indicator... 49 je .source_test # NO! Well, then it should be the source indicator...
77 j .done # ok, lets finish it here... 50 j .done # ok, lets finish it here...
78 .source_test: 51 .source_test:
79 tml %r5,0x8 # it should be a source indicator... 52 tml %r5,0x8 # it should be a source indicator...
80 je .top # NO, ignore it... 53 je .base # NO, ignore it...
81 lgr %r8,%r5 # r8 = r5 54 lgr %r8,%r5 # r8 = r5
82 nill %r8,0xf000 # masking 55 nill %r8,0xf000 # masking
83 0: mvcle %r6,%r8,0x0 # copy PAGE_SIZE bytes from r8 to r6 - pad with 0 56 0: mvcle %r6,%r8,0x0 # copy PAGE_SIZE bytes from r8 to r6 - pad with 0
84 jo 0b 57 jo 0b
85 j .top 58 j .base
86 .done: 59 .done:
87 sgr %r0,%r0 # clear register r0 60 sgr %r0,%r0 # clear register r0
88 la %r4,load_psw-.base(%r13) # load psw-address into the register 61 la %r4,load_psw-.base(%r13) # load psw-address into the register
89 o %r3,4(%r4) # or load address into psw 62 o %r3,4(%r4) # or load address into psw
90 st %r3,4(%r4) 63 st %r3,4(%r4)
91 mvc 0(8,%r0),0(%r4) # copy psw to absolute address 0 64 mvc 0(8,%r0),0(%r4) # copy psw to absolute address 0
92 tm have_diag308-.base(%r13),0x01
93 jno .no_diag308
94 diag %r0,%r0,0x308 65 diag %r0,%r0,0x308
95 .no_diag308:
96 sam31 # 31 bit mode
97 sr %r1,%r1 # erase register r1
98 sr %r2,%r2 # erase register r2
99 sigp %r1,%r2,SIGP_SET_ARCHITECTURE # set cpuid to zero
100 lpsw 0 # hopefully start new kernel...
101 66
102 .align 8 67 .align 8
103 load_psw: 68 load_psw:
104 .long 0x00080000,0x80000000 69 .long 0x00080000,0x80000000
105 ctlregs:
106 .rept 16
107 .quad 0
108 .endr
109 gprregs:
110 .rept 16
111 .quad 0
112 .endr
113 have_diag308:
114 .byte 0
115 .align 8
116 relocate_kernel_end: 70 relocate_kernel_end:
117 .align 8 71 .align 8
118 .globl relocate_kernel_len 72 .globl relocate_kernel_len
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index 28d4ee865a1c..5130d7c67239 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -25,7 +25,6 @@
25#include <asm/irq.h> 25#include <asm/irq.h>
26#include <asm/irq_regs.h> 26#include <asm/irq_regs.h>
27#include <asm/setup.h> 27#include <asm/setup.h>
28#include <asm/reset.h>
29#include <asm/ipl.h> 28#include <asm/ipl.h>
30#include <asm/chpid.h> 29#include <asm/chpid.h>
31#include <asm/airq.h> 30#include <asm/airq.h>
@@ -767,229 +766,6 @@ void cio_register_early_subchannels(void)
767} 766}
768#endif /* CONFIG_CCW_CONSOLE */ 767#endif /* CONFIG_CCW_CONSOLE */
769 768
770static int
771__disable_subchannel_easy(struct subchannel_id schid, struct schib *schib)
772{
773 int retry, cc;
774
775 cc = 0;
776 for (retry=0;retry<3;retry++) {
777 schib->pmcw.ena = 0;
778 cc = msch(schid, schib);
779 if (cc)
780 return (cc==3?-ENODEV:-EBUSY);
781 if (stsch(schid, schib) || !css_sch_is_valid(schib))
782 return -ENODEV;
783 if (!schib->pmcw.ena)
784 return 0;
785 }
786 return -EBUSY; /* uhm... */
787}
788
789static int
790__clear_io_subchannel_easy(struct subchannel_id schid)
791{
792 int retry;
793
794 if (csch(schid))
795 return -ENODEV;
796 for (retry=0;retry<20;retry++) {
797 struct tpi_info ti;
798
799 if (tpi(&ti)) {
800 tsch(ti.schid, this_cpu_ptr(&cio_irb));
801 if (schid_equal(&ti.schid, &schid))
802 return 0;
803 }
804 udelay_simple(100);
805 }
806 return -EBUSY;
807}
808
809static void __clear_chsc_subchannel_easy(void)
810{
811 /* It seems we can only wait for a bit here :/ */
812 udelay_simple(100);
813}
814
815static int pgm_check_occured;
816
817static void cio_reset_pgm_check_handler(void)
818{
819 pgm_check_occured = 1;
820}
821
822static int stsch_reset(struct subchannel_id schid, struct schib *addr)
823{
824 int rc;
825
826 pgm_check_occured = 0;
827 s390_base_pgm_handler_fn = cio_reset_pgm_check_handler;
828 rc = stsch(schid, addr);
829 s390_base_pgm_handler_fn = NULL;
830
831 /* The program check handler could have changed pgm_check_occured. */
832 barrier();
833
834 if (pgm_check_occured)
835 return -EIO;
836 else
837 return rc;
838}
839
840static int __shutdown_subchannel_easy(struct subchannel_id schid, void *data)
841{
842 struct schib schib;
843
844 if (stsch_reset(schid, &schib))
845 return -ENXIO;
846 if (!schib.pmcw.ena)
847 return 0;
848 switch(__disable_subchannel_easy(schid, &schib)) {
849 case 0:
850 case -ENODEV:
851 break;
852 default: /* -EBUSY */
853 switch (schib.pmcw.st) {
854 case SUBCHANNEL_TYPE_IO:
855 if (__clear_io_subchannel_easy(schid))
856 goto out; /* give up... */
857 break;
858 case SUBCHANNEL_TYPE_CHSC:
859 __clear_chsc_subchannel_easy();
860 break;
861 default:
862 /* No default clear strategy */
863 break;
864 }
865 stsch(schid, &schib);
866 __disable_subchannel_easy(schid, &schib);
867 }
868out:
869 return 0;
870}
871
872static atomic_t chpid_reset_count;
873
874static void s390_reset_chpids_mcck_handler(void)
875{
876 struct crw crw;
877 union mci mci;
878
879 /* Check for pending channel report word. */
880 mci.val = S390_lowcore.mcck_interruption_code;
881 if (!mci.cp)
882 return;
883 /* Process channel report words. */
884 while (stcrw(&crw) == 0) {
885 /* Check for responses to RCHP. */
886 if (crw.slct && crw.rsc == CRW_RSC_CPATH)
887 atomic_dec(&chpid_reset_count);
888 }
889}
890
891#define RCHP_TIMEOUT (30 * USEC_PER_SEC)
892static void css_reset(void)
893{
894 int i, ret;
895 unsigned long long timeout;
896 struct chp_id chpid;
897
898 /* Reset subchannels. */
899 for_each_subchannel(__shutdown_subchannel_easy, NULL);
900 /* Reset channel paths. */
901 s390_base_mcck_handler_fn = s390_reset_chpids_mcck_handler;
902 /* Enable channel report machine checks. */
903 __ctl_set_bit(14, 28);
904 /* Temporarily reenable machine checks. */
905 local_mcck_enable();
906 chp_id_init(&chpid);
907 for (i = 0; i <= __MAX_CHPID; i++) {
908 chpid.id = i;
909 ret = rchp(chpid);
910 if ((ret == 0) || (ret == 2))
911 /*
912 * rchp either succeeded, or another rchp is already
913 * in progress. In either case, we'll get a crw.
914 */
915 atomic_inc(&chpid_reset_count);
916 }
917 /* Wait for machine check for all channel paths. */
918 timeout = get_tod_clock_fast() + (RCHP_TIMEOUT << 12);
919 while (atomic_read(&chpid_reset_count) != 0) {
920 if (get_tod_clock_fast() > timeout)
921 break;
922 cpu_relax();
923 }
924 /* Disable machine checks again. */
925 local_mcck_disable();
926 /* Disable channel report machine checks. */
927 __ctl_clear_bit(14, 28);
928 s390_base_mcck_handler_fn = NULL;
929}
930
931static struct reset_call css_reset_call = {
932 .fn = css_reset,
933};
934
935static int __init init_css_reset_call(void)
936{
937 atomic_set(&chpid_reset_count, 0);
938 register_reset_call(&css_reset_call);
939 return 0;
940}
941
942arch_initcall(init_css_reset_call);
943
944struct sch_match_id {
945 struct subchannel_id schid;
946 struct ccw_dev_id devid;
947 int rc;
948};
949
950static int __reipl_subchannel_match(struct subchannel_id schid, void *data)
951{
952 struct schib schib;
953 struct sch_match_id *match_id = data;
954
955 if (stsch_reset(schid, &schib))
956 return -ENXIO;
957 if ((schib.pmcw.st == SUBCHANNEL_TYPE_IO) && schib.pmcw.dnv &&
958 (schib.pmcw.dev == match_id->devid.devno) &&
959 (schid.ssid == match_id->devid.ssid)) {
960 match_id->schid = schid;
961 match_id->rc = 0;
962 return 1;
963 }
964 return 0;
965}
966
967static int reipl_find_schid(struct ccw_dev_id *devid,
968 struct subchannel_id *schid)
969{
970 struct sch_match_id match_id;
971
972 match_id.devid = *devid;
973 match_id.rc = -ENODEV;
974 for_each_subchannel(__reipl_subchannel_match, &match_id);
975 if (match_id.rc == 0)
976 *schid = match_id.schid;
977 return match_id.rc;
978}
979
980extern void do_reipl_asm(__u32 schid);
981
982/* Make sure all subchannels are quiet before we re-ipl an lpar. */
983void reipl_ccw_dev(struct ccw_dev_id *devid)
984{
985 struct subchannel_id uninitialized_var(schid);
986
987 s390_reset_system();
988 if (reipl_find_schid(devid, &schid) != 0)
989 panic("IPL Device not found\n");
990 do_reipl_asm(*((__u32*)&schid));
991}
992
993/** 769/**
994 * cio_tm_start_key - perform start function 770 * cio_tm_start_key - perform start function
995 * @sch: subchannel on which to perform the start function 771 * @sch: subchannel on which to perform the start function
diff --git a/drivers/s390/cio/ioasm.c b/drivers/s390/cio/ioasm.c
index 4fa9ee1d09fa..14d328338ce2 100644
--- a/drivers/s390/cio/ioasm.c
+++ b/drivers/s390/cio/ioasm.c
@@ -183,30 +183,6 @@ int chsc(void *chsc_area)
183} 183}
184EXPORT_SYMBOL(chsc); 184EXPORT_SYMBOL(chsc);
185 185
186static inline int __rchp(struct chp_id chpid)
187{
188 register struct chp_id reg1 asm ("1") = chpid;
189 int ccode;
190
191 asm volatile(
192 " lr 1,%1\n"
193 " rchp\n"
194 " ipm %0\n"
195 " srl %0,28"
196 : "=d" (ccode) : "d" (reg1) : "cc");
197 return ccode;
198}
199
200int rchp(struct chp_id chpid)
201{
202 int ccode;
203
204 ccode = __rchp(chpid);
205 trace_s390_cio_rchp(chpid, ccode);
206
207 return ccode;
208}
209
210static inline int __rsch(struct subchannel_id schid) 186static inline int __rsch(struct subchannel_id schid)
211{ 187{
212 register struct subchannel_id reg1 asm("1") = schid; 188 register struct subchannel_id reg1 asm("1") = schid;
diff --git a/drivers/s390/cio/ioasm.h b/drivers/s390/cio/ioasm.h
index 35ad4ddd61e0..4be539cb9adc 100644
--- a/drivers/s390/cio/ioasm.h
+++ b/drivers/s390/cio/ioasm.h
@@ -20,7 +20,6 @@ int ssch(struct subchannel_id schid, union orb *addr);
20int csch(struct subchannel_id schid); 20int csch(struct subchannel_id schid);
21int tpi(struct tpi_info *addr); 21int tpi(struct tpi_info *addr);
22int chsc(void *chsc_area); 22int chsc(void *chsc_area);
23int rchp(struct chp_id chpid);
24int rsch(struct subchannel_id schid); 23int rsch(struct subchannel_id schid);
25int hsch(struct subchannel_id schid); 24int hsch(struct subchannel_id schid);
26int xsch(struct subchannel_id schid); 25int xsch(struct subchannel_id schid);
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index 743594e61da4..dfed422954b4 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -25,7 +25,6 @@
25#include <linux/kthread.h> 25#include <linux/kthread.h>
26#include <linux/mutex.h> 26#include <linux/mutex.h>
27#include <linux/suspend.h> 27#include <linux/suspend.h>
28#include <asm/reset.h>
29#include <asm/airq.h> 28#include <asm/airq.h>
30#include <linux/atomic.h> 29#include <linux/atomic.h>
31#include <asm/isc.h> 30#include <asm/isc.h>
@@ -1197,25 +1196,6 @@ static void ap_config_timeout(struct timer_list *unused)
1197 queue_work(system_long_wq, &ap_scan_work); 1196 queue_work(system_long_wq, &ap_scan_work);
1198} 1197}
1199 1198
1200static void ap_reset_all(void)
1201{
1202 int i, j;
1203
1204 for (i = 0; i < AP_DOMAINS; i++) {
1205 if (!ap_test_config_domain(i))
1206 continue;
1207 for (j = 0; j < AP_DEVICES; j++) {
1208 if (!ap_test_config_card_id(j))
1209 continue;
1210 ap_rapq(AP_MKQID(j, i));
1211 }
1212 }
1213}
1214
1215static struct reset_call ap_reset_call = {
1216 .fn = ap_reset_all,
1217};
1218
1219int __init ap_debug_init(void) 1199int __init ap_debug_init(void)
1220{ 1200{
1221 ap_dbf_info = debug_register("ap", 1, 1, 1201 ap_dbf_info = debug_register("ap", 1, 1,
@@ -1269,8 +1249,6 @@ int __init ap_module_init(void)
1269 ap_airq_flag = (rc == 0); 1249 ap_airq_flag = (rc == 0);
1270 } 1250 }
1271 1251
1272 register_reset_call(&ap_reset_call);
1273
1274 /* Create /sys/bus/ap. */ 1252 /* Create /sys/bus/ap. */
1275 rc = bus_register(&ap_bus_type); 1253 rc = bus_register(&ap_bus_type);
1276 if (rc) 1254 if (rc)
@@ -1326,7 +1304,6 @@ out_bus:
1326 bus_remove_file(&ap_bus_type, ap_bus_attrs[i]); 1304 bus_remove_file(&ap_bus_type, ap_bus_attrs[i]);
1327 bus_unregister(&ap_bus_type); 1305 bus_unregister(&ap_bus_type);
1328out: 1306out:
1329 unregister_reset_call(&ap_reset_call);
1330 if (ap_using_interrupts()) 1307 if (ap_using_interrupts())
1331 unregister_adapter_interrupt(&ap_airq); 1308 unregister_adapter_interrupt(&ap_airq);
1332 kfree(ap_configuration); 1309 kfree(ap_configuration);