aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kernel')
-rw-r--r--arch/s390/kernel/asm-offsets.c3
-rw-r--r--arch/s390/kernel/compat_ptrace.h3
-rw-r--r--arch/s390/kernel/debug.c1
-rw-r--r--arch/s390/kernel/dis.c145
-rw-r--r--arch/s390/kernel/early.c45
-rw-r--r--arch/s390/kernel/entry.S44
-rw-r--r--arch/s390/kernel/entry.h4
-rw-r--r--arch/s390/kernel/entry64.S45
-rw-r--r--arch/s390/kernel/head.S8
-rw-r--r--arch/s390/kernel/process.c10
-rw-r--r--arch/s390/kernel/processor.c2
-rw-r--r--arch/s390/kernel/s390_ext.c9
-rw-r--r--arch/s390/kernel/setup.c22
-rw-r--r--arch/s390/kernel/smp.c5
-rw-r--r--arch/s390/kernel/sysinfo.c41
-rw-r--r--arch/s390/kernel/time.c17
-rw-r--r--arch/s390/kernel/topology.c101
-rw-r--r--arch/s390/kernel/traps.c173
-rw-r--r--arch/s390/kernel/vdso.c6
-rw-r--r--arch/s390/kernel/vtime.c3
20 files changed, 388 insertions, 299 deletions
diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c
index 5232278d79ad..f3c1b823c9a8 100644
--- a/arch/s390/kernel/asm-offsets.c
+++ b/arch/s390/kernel/asm-offsets.c
@@ -84,6 +84,7 @@ int main(void)
84 DEFINE(__LC_SVC_INT_CODE, offsetof(struct _lowcore, svc_code)); 84 DEFINE(__LC_SVC_INT_CODE, offsetof(struct _lowcore, svc_code));
85 DEFINE(__LC_PGM_ILC, offsetof(struct _lowcore, pgm_ilc)); 85 DEFINE(__LC_PGM_ILC, offsetof(struct _lowcore, pgm_ilc));
86 DEFINE(__LC_PGM_INT_CODE, offsetof(struct _lowcore, pgm_code)); 86 DEFINE(__LC_PGM_INT_CODE, offsetof(struct _lowcore, pgm_code));
87 DEFINE(__LC_TRANS_EXC_CODE, offsetof(struct _lowcore, trans_exc_code));
87 DEFINE(__LC_PER_ATMID, offsetof(struct _lowcore, per_perc_atmid)); 88 DEFINE(__LC_PER_ATMID, offsetof(struct _lowcore, per_perc_atmid));
88 DEFINE(__LC_PER_ADDRESS, offsetof(struct _lowcore, per_address)); 89 DEFINE(__LC_PER_ADDRESS, offsetof(struct _lowcore, per_address));
89 DEFINE(__LC_PER_ACCESS_ID, offsetof(struct _lowcore, per_access_id)); 90 DEFINE(__LC_PER_ACCESS_ID, offsetof(struct _lowcore, per_access_id));
@@ -142,10 +143,8 @@ int main(void)
142 DEFINE(__LC_GPREGS_SAVE_AREA, offsetof(struct _lowcore, gpregs_save_area)); 143 DEFINE(__LC_GPREGS_SAVE_AREA, offsetof(struct _lowcore, gpregs_save_area));
143 DEFINE(__LC_CREGS_SAVE_AREA, offsetof(struct _lowcore, cregs_save_area)); 144 DEFINE(__LC_CREGS_SAVE_AREA, offsetof(struct _lowcore, cregs_save_area));
144#ifdef CONFIG_32BIT 145#ifdef CONFIG_32BIT
145 DEFINE(__LC_PFAULT_INTPARM, offsetof(struct _lowcore, ext_params));
146 DEFINE(SAVE_AREA_BASE, offsetof(struct _lowcore, extended_save_area_addr)); 146 DEFINE(SAVE_AREA_BASE, offsetof(struct _lowcore, extended_save_area_addr));
147#else /* CONFIG_32BIT */ 147#else /* CONFIG_32BIT */
148 DEFINE(__LC_PFAULT_INTPARM, offsetof(struct _lowcore, ext_params2));
149 DEFINE(__LC_EXT_PARAMS2, offsetof(struct _lowcore, ext_params2)); 148 DEFINE(__LC_EXT_PARAMS2, offsetof(struct _lowcore, ext_params2));
150 DEFINE(SAVE_AREA_BASE, offsetof(struct _lowcore, floating_pt_save_area)); 149 DEFINE(SAVE_AREA_BASE, offsetof(struct _lowcore, floating_pt_save_area));
151 DEFINE(__LC_PASTE, offsetof(struct _lowcore, paste)); 150 DEFINE(__LC_PASTE, offsetof(struct _lowcore, paste));
diff --git a/arch/s390/kernel/compat_ptrace.h b/arch/s390/kernel/compat_ptrace.h
index 123dd660d7fb..3141025724f4 100644
--- a/arch/s390/kernel/compat_ptrace.h
+++ b/arch/s390/kernel/compat_ptrace.h
@@ -51,8 +51,7 @@ struct user_regs_struct32
51 * watchpoints. This is the way intel does it. 51 * watchpoints. This is the way intel does it.
52 */ 52 */
53 per_struct32 per_info; 53 per_struct32 per_info;
54 u32 ieee_instruction_pointer; 54 u32 ieee_instruction_pointer; /* obsolete, always 0 */
55 /* Used to give failing instruction back to user for ieee exceptions */
56}; 55};
57 56
58struct user32 { 57struct user32 {
diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c
index 98192261491d..5ad6bc078bfd 100644
--- a/arch/s390/kernel/debug.c
+++ b/arch/s390/kernel/debug.c
@@ -174,6 +174,7 @@ static const struct file_operations debug_file_ops = {
174 .write = debug_input, 174 .write = debug_input,
175 .open = debug_open, 175 .open = debug_open,
176 .release = debug_close, 176 .release = debug_close,
177 .llseek = no_llseek,
177}; 178};
178 179
179static struct dentry *debug_debugfs_root_entry; 180static struct dentry *debug_debugfs_root_entry;
diff --git a/arch/s390/kernel/dis.c b/arch/s390/kernel/dis.c
index b39b27d68b45..c83726c9fe03 100644
--- a/arch/s390/kernel/dis.c
+++ b/arch/s390/kernel/dis.c
@@ -113,7 +113,7 @@ enum {
113 INSTR_INVALID, 113 INSTR_INVALID,
114 INSTR_E, 114 INSTR_E,
115 INSTR_RIE_R0IU, INSTR_RIE_R0UU, INSTR_RIE_RRP, INSTR_RIE_RRPU, 115 INSTR_RIE_R0IU, INSTR_RIE_R0UU, INSTR_RIE_RRP, INSTR_RIE_RRPU,
116 INSTR_RIE_RRUUU, INSTR_RIE_RUPI, INSTR_RIE_RUPU, 116 INSTR_RIE_RRUUU, INSTR_RIE_RUPI, INSTR_RIE_RUPU, INSTR_RIE_RRI0,
117 INSTR_RIL_RI, INSTR_RIL_RP, INSTR_RIL_RU, INSTR_RIL_UP, 117 INSTR_RIL_RI, INSTR_RIL_RP, INSTR_RIL_RU, INSTR_RIL_UP,
118 INSTR_RIS_R0RDU, INSTR_RIS_R0UU, INSTR_RIS_RURDI, INSTR_RIS_RURDU, 118 INSTR_RIS_R0RDU, INSTR_RIS_R0UU, INSTR_RIS_RURDI, INSTR_RIS_RURDU,
119 INSTR_RI_RI, INSTR_RI_RP, INSTR_RI_RU, INSTR_RI_UP, 119 INSTR_RI_RI, INSTR_RI_RP, INSTR_RI_RU, INSTR_RI_UP,
@@ -122,13 +122,14 @@ enum {
122 INSTR_RRE_RR, INSTR_RRE_RR_OPT, 122 INSTR_RRE_RR, INSTR_RRE_RR_OPT,
123 INSTR_RRF_0UFF, INSTR_RRF_F0FF, INSTR_RRF_F0FF2, INSTR_RRF_F0FR, 123 INSTR_RRF_0UFF, INSTR_RRF_F0FF, INSTR_RRF_F0FF2, INSTR_RRF_F0FR,
124 INSTR_RRF_FFRU, INSTR_RRF_FUFF, INSTR_RRF_M0RR, INSTR_RRF_R0RR, 124 INSTR_RRF_FFRU, INSTR_RRF_FUFF, INSTR_RRF_M0RR, INSTR_RRF_R0RR,
125 INSTR_RRF_RURR, INSTR_RRF_U0FF, INSTR_RRF_U0RF, INSTR_RRF_U0RR, 125 INSTR_RRF_R0RR2, INSTR_RRF_RURR, INSTR_RRF_U0FF, INSTR_RRF_U0RF,
126 INSTR_RRF_UUFF, INSTR_RRR_F0FF, INSTR_RRS_RRRDU, 126 INSTR_RRF_U0RR, INSTR_RRF_UUFF, INSTR_RRR_F0FF, INSTR_RRS_RRRDU,
127 INSTR_RR_FF, INSTR_RR_R0, INSTR_RR_RR, INSTR_RR_U0, INSTR_RR_UR, 127 INSTR_RR_FF, INSTR_RR_R0, INSTR_RR_RR, INSTR_RR_U0, INSTR_RR_UR,
128 INSTR_RSE_CCRD, INSTR_RSE_RRRD, INSTR_RSE_RURD, 128 INSTR_RSE_CCRD, INSTR_RSE_RRRD, INSTR_RSE_RURD,
129 INSTR_RSI_RRP, 129 INSTR_RSI_RRP,
130 INSTR_RSL_R0RD, 130 INSTR_RSL_R0RD,
131 INSTR_RSY_AARD, INSTR_RSY_CCRD, INSTR_RSY_RRRD, INSTR_RSY_RURD, 131 INSTR_RSY_AARD, INSTR_RSY_CCRD, INSTR_RSY_RRRD, INSTR_RSY_RURD,
132 INSTR_RSY_RDRM,
132 INSTR_RS_AARD, INSTR_RS_CCRD, INSTR_RS_R0RD, INSTR_RS_RRRD, 133 INSTR_RS_AARD, INSTR_RS_CCRD, INSTR_RS_R0RD, INSTR_RS_RRRD,
133 INSTR_RS_RURD, 134 INSTR_RS_RURD,
134 INSTR_RXE_FRRD, INSTR_RXE_RRRD, 135 INSTR_RXE_FRRD, INSTR_RXE_RRRD,
@@ -139,7 +140,7 @@ enum {
139 INSTR_SIY_IRD, INSTR_SIY_URD, 140 INSTR_SIY_IRD, INSTR_SIY_URD,
140 INSTR_SI_URD, 141 INSTR_SI_URD,
141 INSTR_SSE_RDRD, 142 INSTR_SSE_RDRD,
142 INSTR_SSF_RRDRD, 143 INSTR_SSF_RRDRD, INSTR_SSF_RRDRD2,
143 INSTR_SS_L0RDRD, INSTR_SS_LIRDRD, INSTR_SS_LLRDRD, INSTR_SS_RRRDRD, 144 INSTR_SS_L0RDRD, INSTR_SS_LIRDRD, INSTR_SS_LLRDRD, INSTR_SS_RRRDRD,
144 INSTR_SS_RRRDRD2, INSTR_SS_RRRDRD3, 145 INSTR_SS_RRRDRD2, INSTR_SS_RRRDRD3,
145 INSTR_S_00, INSTR_S_RD, 146 INSTR_S_00, INSTR_S_RD,
@@ -152,7 +153,7 @@ struct operand {
152}; 153};
153 154
154struct insn { 155struct insn {
155 const char name[6]; 156 const char name[5];
156 unsigned char opfrag; 157 unsigned char opfrag;
157 unsigned char format; 158 unsigned char format;
158}; 159};
@@ -217,6 +218,7 @@ static const unsigned char formats[][7] = {
217 [INSTR_RIE_RRP] = { 0xff, R_8,R_12,J16_16,0,0,0 }, 218 [INSTR_RIE_RRP] = { 0xff, R_8,R_12,J16_16,0,0,0 },
218 [INSTR_RIE_RRUUU] = { 0xff, R_8,R_12,U8_16,U8_24,U8_32,0 }, 219 [INSTR_RIE_RRUUU] = { 0xff, R_8,R_12,U8_16,U8_24,U8_32,0 },
219 [INSTR_RIE_RUPI] = { 0xff, R_8,I8_32,U4_12,J16_16,0,0 }, 220 [INSTR_RIE_RUPI] = { 0xff, R_8,I8_32,U4_12,J16_16,0,0 },
221 [INSTR_RIE_RRI0] = { 0xff, R_8,R_12,I16_16,0,0,0 },
220 [INSTR_RIL_RI] = { 0x0f, R_8,I32_16,0,0,0,0 }, 222 [INSTR_RIL_RI] = { 0x0f, R_8,I32_16,0,0,0,0 },
221 [INSTR_RIL_RP] = { 0x0f, R_8,J32_16,0,0,0,0 }, 223 [INSTR_RIL_RP] = { 0x0f, R_8,J32_16,0,0,0,0 },
222 [INSTR_RIL_RU] = { 0x0f, R_8,U32_16,0,0,0,0 }, 224 [INSTR_RIL_RU] = { 0x0f, R_8,U32_16,0,0,0,0 },
@@ -248,6 +250,7 @@ static const unsigned char formats[][7] = {
248 [INSTR_RRF_FUFF] = { 0xff, F_24,F_16,F_28,U4_20,0,0 }, 250 [INSTR_RRF_FUFF] = { 0xff, F_24,F_16,F_28,U4_20,0,0 },
249 [INSTR_RRF_M0RR] = { 0xff, R_24,R_28,M_16,0,0,0 }, 251 [INSTR_RRF_M0RR] = { 0xff, R_24,R_28,M_16,0,0,0 },
250 [INSTR_RRF_R0RR] = { 0xff, R_24,R_16,R_28,0,0,0 }, 252 [INSTR_RRF_R0RR] = { 0xff, R_24,R_16,R_28,0,0,0 },
253 [INSTR_RRF_R0RR2] = { 0xff, R_24,R_28,R_16,0,0,0 },
251 [INSTR_RRF_RURR] = { 0xff, R_24,R_28,R_16,U4_20,0,0 }, 254 [INSTR_RRF_RURR] = { 0xff, R_24,R_28,R_16,U4_20,0,0 },
252 [INSTR_RRF_U0FF] = { 0xff, F_24,U4_16,F_28,0,0,0 }, 255 [INSTR_RRF_U0FF] = { 0xff, F_24,U4_16,F_28,0,0,0 },
253 [INSTR_RRF_U0RF] = { 0xff, R_24,U4_16,F_28,0,0,0 }, 256 [INSTR_RRF_U0RF] = { 0xff, R_24,U4_16,F_28,0,0,0 },
@@ -269,6 +272,7 @@ static const unsigned char formats[][7] = {
269 [INSTR_RSY_CCRD] = { 0xff, C_8,C_12,D20_20,B_16,0,0 }, 272 [INSTR_RSY_CCRD] = { 0xff, C_8,C_12,D20_20,B_16,0,0 },
270 [INSTR_RSY_RRRD] = { 0xff, R_8,R_12,D20_20,B_16,0,0 }, 273 [INSTR_RSY_RRRD] = { 0xff, R_8,R_12,D20_20,B_16,0,0 },
271 [INSTR_RSY_RURD] = { 0xff, R_8,U4_12,D20_20,B_16,0,0 }, 274 [INSTR_RSY_RURD] = { 0xff, R_8,U4_12,D20_20,B_16,0,0 },
275 [INSTR_RSY_RDRM] = { 0xff, R_8,D20_20,B_16,U4_12,0,0 },
272 [INSTR_RS_AARD] = { 0xff, A_8,A_12,D_20,B_16,0,0 }, 276 [INSTR_RS_AARD] = { 0xff, A_8,A_12,D_20,B_16,0,0 },
273 [INSTR_RS_CCRD] = { 0xff, C_8,C_12,D_20,B_16,0,0 }, 277 [INSTR_RS_CCRD] = { 0xff, C_8,C_12,D_20,B_16,0,0 },
274 [INSTR_RS_R0RD] = { 0xff, R_8,D_20,B_16,0,0,0 }, 278 [INSTR_RS_R0RD] = { 0xff, R_8,D_20,B_16,0,0,0 },
@@ -290,6 +294,7 @@ static const unsigned char formats[][7] = {
290 [INSTR_SI_URD] = { 0xff, D_20,B_16,U8_8,0,0,0 }, 294 [INSTR_SI_URD] = { 0xff, D_20,B_16,U8_8,0,0,0 },
291 [INSTR_SSE_RDRD] = { 0xff, D_20,B_16,D_36,B_32,0,0 }, 295 [INSTR_SSE_RDRD] = { 0xff, D_20,B_16,D_36,B_32,0,0 },
292 [INSTR_SSF_RRDRD] = { 0x00, D_20,B_16,D_36,B_32,R_8,0 }, 296 [INSTR_SSF_RRDRD] = { 0x00, D_20,B_16,D_36,B_32,R_8,0 },
297 [INSTR_SSF_RRDRD2]= { 0x00, R_8,D_20,B_16,D_36,B_32,0 },
293 [INSTR_SS_L0RDRD] = { 0xff, D_20,L8_8,B_16,D_36,B_32,0 }, 298 [INSTR_SS_L0RDRD] = { 0xff, D_20,L8_8,B_16,D_36,B_32,0 },
294 [INSTR_SS_LIRDRD] = { 0xff, D_20,L4_8,B_16,D_36,B_32,U4_12 }, 299 [INSTR_SS_LIRDRD] = { 0xff, D_20,L4_8,B_16,D_36,B_32,U4_12 },
295 [INSTR_SS_LLRDRD] = { 0xff, D_20,L4_8,B_16,D_36,L4_12,B_32 }, 300 [INSTR_SS_LLRDRD] = { 0xff, D_20,L4_8,B_16,D_36,L4_12,B_32 },
@@ -300,6 +305,36 @@ static const unsigned char formats[][7] = {
300 [INSTR_S_RD] = { 0xff, D_20,B_16,0,0,0,0 }, 305 [INSTR_S_RD] = { 0xff, D_20,B_16,0,0,0,0 },
301}; 306};
302 307
308enum {
309 LONG_INSN_ALGHSIK,
310 LONG_INSN_ALHSIK,
311 LONG_INSN_CLFHSI,
312 LONG_INSN_CLGFRL,
313 LONG_INSN_CLGHRL,
314 LONG_INSN_CLGHSI,
315 LONG_INSN_CLHHSI,
316 LONG_INSN_LLGFRL,
317 LONG_INSN_LLGHRL,
318 LONG_INSN_POPCNT,
319 LONG_INSN_RISBHG,
320 LONG_INSN_RISBLG,
321};
322
323static char *long_insn_name[] = {
324 [LONG_INSN_ALGHSIK] = "alghsik",
325 [LONG_INSN_ALHSIK] = "alhsik",
326 [LONG_INSN_CLFHSI] = "clfhsi",
327 [LONG_INSN_CLGFRL] = "clgfrl",
328 [LONG_INSN_CLGHRL] = "clghrl",
329 [LONG_INSN_CLGHSI] = "clghsi",
330 [LONG_INSN_CLHHSI] = "clhhsi",
331 [LONG_INSN_LLGFRL] = "llgfrl",
332 [LONG_INSN_LLGHRL] = "llghrl",
333 [LONG_INSN_POPCNT] = "popcnt",
334 [LONG_INSN_RISBHG] = "risbhg",
335 [LONG_INSN_RISBLG] = "risblk",
336};
337
303static struct insn opcode[] = { 338static struct insn opcode[] = {
304#ifdef CONFIG_64BIT 339#ifdef CONFIG_64BIT
305 { "lmd", 0xef, INSTR_SS_RRRDRD3 }, 340 { "lmd", 0xef, INSTR_SS_RRRDRD3 },
@@ -881,6 +916,35 @@ static struct insn opcode_b9[] = {
881 { "pfmf", 0xaf, INSTR_RRE_RR }, 916 { "pfmf", 0xaf, INSTR_RRE_RR },
882 { "trte", 0xbf, INSTR_RRF_M0RR }, 917 { "trte", 0xbf, INSTR_RRF_M0RR },
883 { "trtre", 0xbd, INSTR_RRF_M0RR }, 918 { "trtre", 0xbd, INSTR_RRF_M0RR },
919 { "ahhhr", 0xc8, INSTR_RRF_R0RR2 },
920 { "shhhr", 0xc9, INSTR_RRF_R0RR2 },
921 { "alhhh", 0xca, INSTR_RRF_R0RR2 },
922 { "alhhl", 0xca, INSTR_RRF_R0RR2 },
923 { "slhhh", 0xcb, INSTR_RRF_R0RR2 },
924 { "chhr ", 0xcd, INSTR_RRE_RR },
925 { "clhhr", 0xcf, INSTR_RRE_RR },
926 { "ahhlr", 0xd8, INSTR_RRF_R0RR2 },
927 { "shhlr", 0xd9, INSTR_RRF_R0RR2 },
928 { "slhhl", 0xdb, INSTR_RRF_R0RR2 },
929 { "chlr", 0xdd, INSTR_RRE_RR },
930 { "clhlr", 0xdf, INSTR_RRE_RR },
931 { { 0, LONG_INSN_POPCNT }, 0xe1, INSTR_RRE_RR },
932 { "locgr", 0xe2, INSTR_RRF_M0RR },
933 { "ngrk", 0xe4, INSTR_RRF_R0RR2 },
934 { "ogrk", 0xe6, INSTR_RRF_R0RR2 },
935 { "xgrk", 0xe7, INSTR_RRF_R0RR2 },
936 { "agrk", 0xe8, INSTR_RRF_R0RR2 },
937 { "sgrk", 0xe9, INSTR_RRF_R0RR2 },
938 { "algrk", 0xea, INSTR_RRF_R0RR2 },
939 { "slgrk", 0xeb, INSTR_RRF_R0RR2 },
940 { "locr", 0xf2, INSTR_RRF_M0RR },
941 { "nrk", 0xf4, INSTR_RRF_R0RR2 },
942 { "ork", 0xf6, INSTR_RRF_R0RR2 },
943 { "xrk", 0xf7, INSTR_RRF_R0RR2 },
944 { "ark", 0xf8, INSTR_RRF_R0RR2 },
945 { "srk", 0xf9, INSTR_RRF_R0RR2 },
946 { "alrk", 0xfa, INSTR_RRF_R0RR2 },
947 { "slrk", 0xfb, INSTR_RRF_R0RR2 },
884#endif 948#endif
885 { "kmac", 0x1e, INSTR_RRE_RR }, 949 { "kmac", 0x1e, INSTR_RRE_RR },
886 { "lrvr", 0x1f, INSTR_RRE_RR }, 950 { "lrvr", 0x1f, INSTR_RRE_RR },
@@ -949,9 +1013,9 @@ static struct insn opcode_c4[] = {
949 { "lgfrl", 0x0c, INSTR_RIL_RP }, 1013 { "lgfrl", 0x0c, INSTR_RIL_RP },
950 { "lhrl", 0x05, INSTR_RIL_RP }, 1014 { "lhrl", 0x05, INSTR_RIL_RP },
951 { "lghrl", 0x04, INSTR_RIL_RP }, 1015 { "lghrl", 0x04, INSTR_RIL_RP },
952 { "llgfrl", 0x0e, INSTR_RIL_RP }, 1016 { { 0, LONG_INSN_LLGFRL }, 0x0e, INSTR_RIL_RP },
953 { "llhrl", 0x02, INSTR_RIL_RP }, 1017 { "llhrl", 0x02, INSTR_RIL_RP },
954 { "llghrl", 0x06, INSTR_RIL_RP }, 1018 { { 0, LONG_INSN_LLGHRL }, 0x06, INSTR_RIL_RP },
955 { "strl", 0x0f, INSTR_RIL_RP }, 1019 { "strl", 0x0f, INSTR_RIL_RP },
956 { "stgrl", 0x0b, INSTR_RIL_RP }, 1020 { "stgrl", 0x0b, INSTR_RIL_RP },
957 { "sthrl", 0x07, INSTR_RIL_RP }, 1021 { "sthrl", 0x07, INSTR_RIL_RP },
@@ -968,9 +1032,9 @@ static struct insn opcode_c6[] = {
968 { "cghrl", 0x04, INSTR_RIL_RP }, 1032 { "cghrl", 0x04, INSTR_RIL_RP },
969 { "clrl", 0x0f, INSTR_RIL_RP }, 1033 { "clrl", 0x0f, INSTR_RIL_RP },
970 { "clgrl", 0x0a, INSTR_RIL_RP }, 1034 { "clgrl", 0x0a, INSTR_RIL_RP },
971 { "clgfrl", 0x0e, INSTR_RIL_RP }, 1035 { { 0, LONG_INSN_CLGFRL }, 0x0e, INSTR_RIL_RP },
972 { "clhrl", 0x07, INSTR_RIL_RP }, 1036 { "clhrl", 0x07, INSTR_RIL_RP },
973 { "clghrl", 0x06, INSTR_RIL_RP }, 1037 { { 0, LONG_INSN_CLGHRL }, 0x06, INSTR_RIL_RP },
974 { "pfdrl", 0x02, INSTR_RIL_UP }, 1038 { "pfdrl", 0x02, INSTR_RIL_UP },
975 { "exrl", 0x00, INSTR_RIL_RP }, 1039 { "exrl", 0x00, INSTR_RIL_RP },
976#endif 1040#endif
@@ -982,6 +1046,20 @@ static struct insn opcode_c8[] = {
982 { "mvcos", 0x00, INSTR_SSF_RRDRD }, 1046 { "mvcos", 0x00, INSTR_SSF_RRDRD },
983 { "ectg", 0x01, INSTR_SSF_RRDRD }, 1047 { "ectg", 0x01, INSTR_SSF_RRDRD },
984 { "csst", 0x02, INSTR_SSF_RRDRD }, 1048 { "csst", 0x02, INSTR_SSF_RRDRD },
1049 { "lpd", 0x04, INSTR_SSF_RRDRD2 },
1050 { "lpdg ", 0x05, INSTR_SSF_RRDRD2 },
1051#endif
1052 { "", 0, INSTR_INVALID }
1053};
1054
1055static struct insn opcode_cc[] = {
1056#ifdef CONFIG_64BIT
1057 { "brcth", 0x06, INSTR_RIL_RP },
1058 { "aih", 0x08, INSTR_RIL_RI },
1059 { "alsih", 0x0a, INSTR_RIL_RI },
1060 { "alsih", 0x0b, INSTR_RIL_RI },
1061 { "cih", 0x0d, INSTR_RIL_RI },
1062 { "clih ", 0x0f, INSTR_RIL_RI },
985#endif 1063#endif
986 { "", 0, INSTR_INVALID } 1064 { "", 0, INSTR_INVALID }
987}; 1065};
@@ -1063,6 +1141,16 @@ static struct insn opcode_e3[] = {
1063 { "mfy", 0x5c, INSTR_RXY_RRRD }, 1141 { "mfy", 0x5c, INSTR_RXY_RRRD },
1064 { "mhy", 0x7c, INSTR_RXY_RRRD }, 1142 { "mhy", 0x7c, INSTR_RXY_RRRD },
1065 { "pfd", 0x36, INSTR_RXY_URRD }, 1143 { "pfd", 0x36, INSTR_RXY_URRD },
1144 { "lbh", 0xc0, INSTR_RXY_RRRD },
1145 { "llch", 0xc2, INSTR_RXY_RRRD },
1146 { "stch", 0xc3, INSTR_RXY_RRRD },
1147 { "lhh", 0xc4, INSTR_RXY_RRRD },
1148 { "llhh", 0xc6, INSTR_RXY_RRRD },
1149 { "sthh", 0xc7, INSTR_RXY_RRRD },
1150 { "lfh", 0xca, INSTR_RXY_RRRD },
1151 { "stfh", 0xcb, INSTR_RXY_RRRD },
1152 { "chf", 0xcd, INSTR_RXY_RRRD },
1153 { "clhf", 0xcf, INSTR_RXY_RRRD },
1066#endif 1154#endif
1067 { "lrv", 0x1e, INSTR_RXY_RRRD }, 1155 { "lrv", 0x1e, INSTR_RXY_RRRD },
1068 { "lrvh", 0x1f, INSTR_RXY_RRRD }, 1156 { "lrvh", 0x1f, INSTR_RXY_RRRD },
@@ -1080,9 +1168,9 @@ static struct insn opcode_e5[] = {
1080 { "chhsi", 0x54, INSTR_SIL_RDI }, 1168 { "chhsi", 0x54, INSTR_SIL_RDI },
1081 { "chsi", 0x5c, INSTR_SIL_RDI }, 1169 { "chsi", 0x5c, INSTR_SIL_RDI },
1082 { "cghsi", 0x58, INSTR_SIL_RDI }, 1170 { "cghsi", 0x58, INSTR_SIL_RDI },
1083 { "clhhsi", 0x55, INSTR_SIL_RDU }, 1171 { { 0, LONG_INSN_CLHHSI }, 0x55, INSTR_SIL_RDU },
1084 { "clfhsi", 0x5d, INSTR_SIL_RDU }, 1172 { { 0, LONG_INSN_CLFHSI }, 0x5d, INSTR_SIL_RDU },
1085 { "clghsi", 0x59, INSTR_SIL_RDU }, 1173 { { 0, LONG_INSN_CLGHSI }, 0x59, INSTR_SIL_RDU },
1086 { "mvhhi", 0x44, INSTR_SIL_RDI }, 1174 { "mvhhi", 0x44, INSTR_SIL_RDI },
1087 { "mvhi", 0x4c, INSTR_SIL_RDI }, 1175 { "mvhi", 0x4c, INSTR_SIL_RDI },
1088 { "mvghi", 0x48, INSTR_SIL_RDI }, 1176 { "mvghi", 0x48, INSTR_SIL_RDI },
@@ -1137,6 +1225,24 @@ static struct insn opcode_eb[] = {
1137 { "alsi", 0x6e, INSTR_SIY_IRD }, 1225 { "alsi", 0x6e, INSTR_SIY_IRD },
1138 { "algsi", 0x7e, INSTR_SIY_IRD }, 1226 { "algsi", 0x7e, INSTR_SIY_IRD },
1139 { "ecag", 0x4c, INSTR_RSY_RRRD }, 1227 { "ecag", 0x4c, INSTR_RSY_RRRD },
1228 { "srak", 0xdc, INSTR_RSY_RRRD },
1229 { "slak", 0xdd, INSTR_RSY_RRRD },
1230 { "srlk", 0xde, INSTR_RSY_RRRD },
1231 { "sllk", 0xdf, INSTR_RSY_RRRD },
1232 { "locg", 0xe2, INSTR_RSY_RDRM },
1233 { "stocg", 0xe3, INSTR_RSY_RDRM },
1234 { "lang", 0xe4, INSTR_RSY_RRRD },
1235 { "laog", 0xe6, INSTR_RSY_RRRD },
1236 { "laxg", 0xe7, INSTR_RSY_RRRD },
1237 { "laag", 0xe8, INSTR_RSY_RRRD },
1238 { "laalg", 0xea, INSTR_RSY_RRRD },
1239 { "loc", 0xf2, INSTR_RSY_RDRM },
1240 { "stoc", 0xf3, INSTR_RSY_RDRM },
1241 { "lan", 0xf4, INSTR_RSY_RRRD },
1242 { "lao", 0xf6, INSTR_RSY_RRRD },
1243 { "lax", 0xf7, INSTR_RSY_RRRD },
1244 { "laa", 0xf8, INSTR_RSY_RRRD },
1245 { "laal", 0xfa, INSTR_RSY_RRRD },
1140#endif 1246#endif
1141 { "rll", 0x1d, INSTR_RSY_RRRD }, 1247 { "rll", 0x1d, INSTR_RSY_RRRD },
1142 { "mvclu", 0x8e, INSTR_RSY_RRRD }, 1248 { "mvclu", 0x8e, INSTR_RSY_RRRD },
@@ -1172,6 +1278,12 @@ static struct insn opcode_ec[] = {
1172 { "rxsbg", 0x57, INSTR_RIE_RRUUU }, 1278 { "rxsbg", 0x57, INSTR_RIE_RRUUU },
1173 { "rosbg", 0x56, INSTR_RIE_RRUUU }, 1279 { "rosbg", 0x56, INSTR_RIE_RRUUU },
1174 { "risbg", 0x55, INSTR_RIE_RRUUU }, 1280 { "risbg", 0x55, INSTR_RIE_RRUUU },
1281 { { 0, LONG_INSN_RISBLG }, 0x51, INSTR_RIE_RRUUU },
1282 { { 0, LONG_INSN_RISBHG }, 0x5D, INSTR_RIE_RRUUU },
1283 { "ahik", 0xd8, INSTR_RIE_RRI0 },
1284 { "aghik", 0xd9, INSTR_RIE_RRI0 },
1285 { { 0, LONG_INSN_ALHSIK }, 0xda, INSTR_RIE_RRI0 },
1286 { { 0, LONG_INSN_ALGHSIK }, 0xdb, INSTR_RIE_RRI0 },
1175#endif 1287#endif
1176 { "", 0, INSTR_INVALID } 1288 { "", 0, INSTR_INVALID }
1177}; 1289};
@@ -1321,6 +1433,9 @@ static struct insn *find_insn(unsigned char *code)
1321 case 0xc8: 1433 case 0xc8:
1322 table = opcode_c8; 1434 table = opcode_c8;
1323 break; 1435 break;
1436 case 0xcc:
1437 table = opcode_cc;
1438 break;
1324 case 0xe3: 1439 case 0xe3:
1325 table = opcode_e3; 1440 table = opcode_e3;
1326 opfrag = code[5]; 1441 opfrag = code[5];
@@ -1367,7 +1482,11 @@ static int print_insn(char *buffer, unsigned char *code, unsigned long addr)
1367 ptr = buffer; 1482 ptr = buffer;
1368 insn = find_insn(code); 1483 insn = find_insn(code);
1369 if (insn) { 1484 if (insn) {
1370 ptr += sprintf(ptr, "%.5s\t", insn->name); 1485 if (insn->name[0] == '\0')
1486 ptr += sprintf(ptr, "%s\t",
1487 long_insn_name[(int) insn->name[1]]);
1488 else
1489 ptr += sprintf(ptr, "%.5s\t", insn->name);
1371 /* Extract the operands. */ 1490 /* Extract the operands. */
1372 separator = 0; 1491 separator = 0;
1373 for (ops = formats[insn->format] + 1, i = 0; 1492 for (ops = formats[insn->format] + 1, i = 0;
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index c00856ad4e5a..d149609e46e6 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -208,7 +208,8 @@ static noinline __init void init_kernel_storage_key(void)
208 end_pfn = PFN_UP(__pa(&_end)); 208 end_pfn = PFN_UP(__pa(&_end));
209 209
210 for (init_pfn = 0 ; init_pfn < end_pfn; init_pfn++) 210 for (init_pfn = 0 ; init_pfn < end_pfn; init_pfn++)
211 page_set_storage_key(init_pfn << PAGE_SHIFT, PAGE_DEFAULT_KEY); 211 page_set_storage_key(init_pfn << PAGE_SHIFT,
212 PAGE_DEFAULT_KEY, 0);
212} 213}
213 214
214static __initdata struct sysinfo_3_2_2 vmms __aligned(PAGE_SIZE); 215static __initdata struct sysinfo_3_2_2 vmms __aligned(PAGE_SIZE);
@@ -255,13 +256,35 @@ static noinline __init void setup_lowcore_early(void)
255 s390_base_pgm_handler_fn = early_pgm_check_handler; 256 s390_base_pgm_handler_fn = early_pgm_check_handler;
256} 257}
257 258
259static noinline __init void setup_facility_list(void)
260{
261 unsigned long nr;
262
263 S390_lowcore.stfl_fac_list = 0;
264 asm volatile(
265 " .insn s,0xb2b10000,0(0)\n" /* stfl */
266 "0:\n"
267 EX_TABLE(0b,0b) : "=m" (S390_lowcore.stfl_fac_list));
268 memcpy(&S390_lowcore.stfle_fac_list, &S390_lowcore.stfl_fac_list, 4);
269 nr = 4; /* # bytes stored by stfl */
270 if (test_facility(7)) {
271 /* More facility bits available with stfle */
272 register unsigned long reg0 asm("0") = MAX_FACILITY_BIT/64 - 1;
273 asm volatile(".insn s,0xb2b00000,%0" /* stfle */
274 : "=m" (S390_lowcore.stfle_fac_list), "+d" (reg0)
275 : : "cc");
276 nr = (reg0 + 1) * 8; /* # bytes stored by stfle */
277 }
278 memset((char *) S390_lowcore.stfle_fac_list + nr, 0,
279 MAX_FACILITY_BIT/8 - nr);
280}
281
258static noinline __init void setup_hpage(void) 282static noinline __init void setup_hpage(void)
259{ 283{
260#ifndef CONFIG_DEBUG_PAGEALLOC 284#ifndef CONFIG_DEBUG_PAGEALLOC
261 unsigned int facilities; 285 unsigned int facilities;
262 286
263 facilities = stfl(); 287 if (!test_facility(2) || !test_facility(8))
264 if (!(facilities & (1UL << 23)) || !(facilities & (1UL << 29)))
265 return; 288 return;
266 S390_lowcore.machine_flags |= MACHINE_FLAG_HPAGE; 289 S390_lowcore.machine_flags |= MACHINE_FLAG_HPAGE;
267 __ctl_set_bit(0, 23); 290 __ctl_set_bit(0, 23);
@@ -355,18 +378,15 @@ static __init void detect_diag44(void)
355static __init void detect_machine_facilities(void) 378static __init void detect_machine_facilities(void)
356{ 379{
357#ifdef CONFIG_64BIT 380#ifdef CONFIG_64BIT
358 unsigned int facilities; 381 if (test_facility(3))
359 unsigned long long facility_bits;
360
361 facilities = stfl();
362 if (facilities & (1 << 28))
363 S390_lowcore.machine_flags |= MACHINE_FLAG_IDTE; 382 S390_lowcore.machine_flags |= MACHINE_FLAG_IDTE;
364 if (facilities & (1 << 23)) 383 if (test_facility(8))
365 S390_lowcore.machine_flags |= MACHINE_FLAG_PFMF; 384 S390_lowcore.machine_flags |= MACHINE_FLAG_PFMF;
366 if (facilities & (1 << 4)) 385 if (test_facility(11))
386 S390_lowcore.machine_flags |= MACHINE_FLAG_TOPOLOGY;
387 if (test_facility(27))
367 S390_lowcore.machine_flags |= MACHINE_FLAG_MVCOS; 388 S390_lowcore.machine_flags |= MACHINE_FLAG_MVCOS;
368 if ((stfle(&facility_bits, 1) > 0) && 389 if (test_facility(40))
369 (facility_bits & (1ULL << (63 - 40))))
370 S390_lowcore.machine_flags |= MACHINE_FLAG_SPP; 390 S390_lowcore.machine_flags |= MACHINE_FLAG_SPP;
371#endif 391#endif
372} 392}
@@ -447,6 +467,7 @@ void __init startup_init(void)
447 lockdep_off(); 467 lockdep_off();
448 sort_main_extable(); 468 sort_main_extable();
449 setup_lowcore_early(); 469 setup_lowcore_early();
470 setup_facility_list();
450 detect_machine_type(); 471 detect_machine_type();
451 ipl_update_parameters(); 472 ipl_update_parameters();
452 setup_boot_command_line(); 473 setup_boot_command_line();
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index bea9ee37ac9d..5efce7202984 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -72,25 +72,9 @@ STACK_SIZE = 1 << STACK_SHIFT
72 l %r1,BASED(.Ltrace_irq_off_caller) 72 l %r1,BASED(.Ltrace_irq_off_caller)
73 basr %r14,%r1 73 basr %r14,%r1
74 .endm 74 .endm
75
76 .macro TRACE_IRQS_CHECK_ON
77 tm SP_PSW(%r15),0x03 # irqs enabled?
78 bz BASED(0f)
79 TRACE_IRQS_ON
800:
81 .endm
82
83 .macro TRACE_IRQS_CHECK_OFF
84 tm SP_PSW(%r15),0x03 # irqs enabled?
85 bz BASED(0f)
86 TRACE_IRQS_OFF
870:
88 .endm
89#else 75#else
90#define TRACE_IRQS_ON 76#define TRACE_IRQS_ON
91#define TRACE_IRQS_OFF 77#define TRACE_IRQS_OFF
92#define TRACE_IRQS_CHECK_ON
93#define TRACE_IRQS_CHECK_OFF
94#endif 78#endif
95 79
96#ifdef CONFIG_LOCKDEP 80#ifdef CONFIG_LOCKDEP
@@ -198,6 +182,12 @@ STACK_SIZE = 1 << STACK_SHIFT
198 lpsw \psworg # back to caller 182 lpsw \psworg # back to caller
199 .endm 183 .endm
200 184
185 .macro REENABLE_IRQS
186 mvc __SF_EMPTY(1,%r15),SP_PSW(%r15)
187 ni __SF_EMPTY(%r15),0xbf
188 ssm __SF_EMPTY(%r15)
189 .endm
190
201/* 191/*
202 * Scheduler resume function, called by switch_to 192 * Scheduler resume function, called by switch_to
203 * gpr2 = (task_struct *) prev 193 * gpr2 = (task_struct *) prev
@@ -264,12 +254,11 @@ sysc_do_svc:
264 bnl BASED(sysc_nr_ok) 254 bnl BASED(sysc_nr_ok)
265 lr %r7,%r1 # copy svc number to %r7 255 lr %r7,%r1 # copy svc number to %r7
266sysc_nr_ok: 256sysc_nr_ok:
267 mvc SP_ARGS(4,%r15),SP_R7(%r15)
268sysc_do_restart:
269 sth %r7,SP_SVCNR(%r15) 257 sth %r7,SP_SVCNR(%r15)
270 sll %r7,2 # svc number *4 258 sll %r7,2 # svc number *4
271 l %r8,BASED(.Lsysc_table) 259 l %r8,BASED(.Lsysc_table)
272 tm __TI_flags+2(%r9),_TIF_SYSCALL 260 tm __TI_flags+2(%r9),_TIF_SYSCALL
261 mvc SP_ARGS(4,%r15),SP_R7(%r15)
273 l %r8,0(%r7,%r8) # get system call addr. 262 l %r8,0(%r7,%r8) # get system call addr.
274 bnz BASED(sysc_tracesys) 263 bnz BASED(sysc_tracesys)
275 basr %r14,%r8 # call sys_xxxx 264 basr %r14,%r8 # call sys_xxxx
@@ -357,7 +346,7 @@ sysc_restart:
357 l %r7,SP_R2(%r15) # load new svc number 346 l %r7,SP_R2(%r15) # load new svc number
358 mvc SP_R2(4,%r15),SP_ORIG_R2(%r15) # restore first argument 347 mvc SP_R2(4,%r15),SP_ORIG_R2(%r15) # restore first argument
359 lm %r2,%r6,SP_R2(%r15) # load svc arguments 348 lm %r2,%r6,SP_R2(%r15) # load svc arguments
360 b BASED(sysc_do_restart) # restart svc 349 b BASED(sysc_nr_ok) # restart svc
361 350
362# 351#
363# _TIF_SINGLE_STEP is set, call do_single_step 352# _TIF_SINGLE_STEP is set, call do_single_step
@@ -390,6 +379,7 @@ sysc_tracesys:
390 l %r8,0(%r7,%r8) 379 l %r8,0(%r7,%r8)
391sysc_tracego: 380sysc_tracego:
392 lm %r3,%r6,SP_R3(%r15) 381 lm %r3,%r6,SP_R3(%r15)
382 mvc SP_ARGS(4,%r15),SP_R7(%r15)
393 l %r2,SP_ORIG_R2(%r15) 383 l %r2,SP_ORIG_R2(%r15)
394 basr %r14,%r8 # call sys_xxx 384 basr %r14,%r8 # call sys_xxx
395 st %r2,SP_R2(%r15) # store return value 385 st %r2,SP_R2(%r15) # store return value
@@ -440,13 +430,11 @@ kernel_execve:
440 br %r14 430 br %r14
441 # execve succeeded. 431 # execve succeeded.
4420: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts 4320: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts
443 TRACE_IRQS_OFF
444 l %r15,__LC_KERNEL_STACK # load ksp 433 l %r15,__LC_KERNEL_STACK # load ksp
445 s %r15,BASED(.Lc_spsize) # make room for registers & psw 434 s %r15,BASED(.Lc_spsize) # make room for registers & psw
446 l %r9,__LC_THREAD_INFO 435 l %r9,__LC_THREAD_INFO
447 mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs 436 mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs
448 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) 437 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
449 TRACE_IRQS_ON
450 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 438 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
451 l %r1,BASED(.Lexecve_tail) 439 l %r1,BASED(.Lexecve_tail)
452 basr %r14,%r1 440 basr %r14,%r1
@@ -483,9 +471,10 @@ pgm_check_handler:
483 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 471 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
484 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 472 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
485pgm_no_vtime: 473pgm_no_vtime:
486 TRACE_IRQS_CHECK_OFF
487 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct 474 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
488 l %r3,__LC_PGM_ILC # load program interruption code 475 l %r3,__LC_PGM_ILC # load program interruption code
476 l %r4,__LC_TRANS_EXC_CODE
477 REENABLE_IRQS
489 la %r8,0x7f 478 la %r8,0x7f
490 nr %r8,%r3 479 nr %r8,%r3
491pgm_do_call: 480pgm_do_call:
@@ -495,7 +484,6 @@ pgm_do_call:
495 la %r2,SP_PTREGS(%r15) # address of register-save area 484 la %r2,SP_PTREGS(%r15) # address of register-save area
496 basr %r14,%r7 # branch to interrupt-handler 485 basr %r14,%r7 # branch to interrupt-handler
497pgm_exit: 486pgm_exit:
498 TRACE_IRQS_CHECK_ON
499 b BASED(sysc_return) 487 b BASED(sysc_return)
500 488
501# 489#
@@ -523,7 +511,6 @@ pgm_per_std:
523 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 511 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
524 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 512 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
525pgm_no_vtime2: 513pgm_no_vtime2:
526 TRACE_IRQS_CHECK_OFF
527 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct 514 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
528 l %r1,__TI_task(%r9) 515 l %r1,__TI_task(%r9)
529 tm SP_PSW+1(%r15),0x01 # kernel per event ? 516 tm SP_PSW+1(%r15),0x01 # kernel per event ?
@@ -533,6 +520,8 @@ pgm_no_vtime2:
533 mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID 520 mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
534 oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP 521 oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
535 l %r3,__LC_PGM_ILC # load program interruption code 522 l %r3,__LC_PGM_ILC # load program interruption code
523 l %r4,__LC_TRANS_EXC_CODE
524 REENABLE_IRQS
536 la %r8,0x7f 525 la %r8,0x7f
537 nr %r8,%r3 # clear per-event-bit and ilc 526 nr %r8,%r3 # clear per-event-bit and ilc
538 be BASED(pgm_exit2) # only per or per+check ? 527 be BASED(pgm_exit2) # only per or per+check ?
@@ -542,8 +531,6 @@ pgm_no_vtime2:
542 la %r2,SP_PTREGS(%r15) # address of register-save area 531 la %r2,SP_PTREGS(%r15) # address of register-save area
543 basr %r14,%r7 # branch to interrupt-handler 532 basr %r14,%r7 # branch to interrupt-handler
544pgm_exit2: 533pgm_exit2:
545 TRACE_IRQS_ON
546 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
547 b BASED(sysc_return) 534 b BASED(sysc_return)
548 535
549# 536#
@@ -557,13 +544,11 @@ pgm_svcper:
557 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 544 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
558 lh %r7,0x8a # get svc number from lowcore 545 lh %r7,0x8a # get svc number from lowcore
559 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct 546 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
560 TRACE_IRQS_OFF
561 l %r8,__TI_task(%r9) 547 l %r8,__TI_task(%r9)
562 mvc __THREAD_per+__PER_atmid(2,%r8),__LC_PER_ATMID 548 mvc __THREAD_per+__PER_atmid(2,%r8),__LC_PER_ATMID
563 mvc __THREAD_per+__PER_address(4,%r8),__LC_PER_ADDRESS 549 mvc __THREAD_per+__PER_address(4,%r8),__LC_PER_ADDRESS
564 mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID 550 mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID
565 oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP 551 oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
566 TRACE_IRQS_ON
567 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 552 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
568 lm %r2,%r6,SP_R2(%r15) # load svc arguments 553 lm %r2,%r6,SP_R2(%r15) # load svc arguments
569 b BASED(sysc_do_svc) 554 b BASED(sysc_do_svc)
@@ -737,7 +722,8 @@ ext_no_vtime:
737 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct 722 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
738 TRACE_IRQS_OFF 723 TRACE_IRQS_OFF
739 la %r2,SP_PTREGS(%r15) # address of register-save area 724 la %r2,SP_PTREGS(%r15) # address of register-save area
740 lh %r3,__LC_EXT_INT_CODE # get interruption code 725 l %r3,__LC_CPU_ADDRESS # get cpu address + interruption code
726 l %r4,__LC_EXT_PARAMS # get external parameters
741 l %r1,BASED(.Ldo_extint) 727 l %r1,BASED(.Ldo_extint)
742 basr %r14,%r1 728 basr %r14,%r1
743 b BASED(io_return) 729 b BASED(io_return)
diff --git a/arch/s390/kernel/entry.h b/arch/s390/kernel/entry.h
index ff579b6bde06..95c1dfc4ef31 100644
--- a/arch/s390/kernel/entry.h
+++ b/arch/s390/kernel/entry.h
@@ -5,7 +5,7 @@
5#include <linux/signal.h> 5#include <linux/signal.h>
6#include <asm/ptrace.h> 6#include <asm/ptrace.h>
7 7
8typedef void pgm_check_handler_t(struct pt_regs *, long); 8typedef void pgm_check_handler_t(struct pt_regs *, long, unsigned long);
9extern pgm_check_handler_t *pgm_check_table[128]; 9extern pgm_check_handler_t *pgm_check_table[128];
10pgm_check_handler_t do_protection_exception; 10pgm_check_handler_t do_protection_exception;
11pgm_check_handler_t do_dat_exception; 11pgm_check_handler_t do_dat_exception;
@@ -19,7 +19,7 @@ void do_signal(struct pt_regs *regs);
19int handle_signal32(unsigned long sig, struct k_sigaction *ka, 19int handle_signal32(unsigned long sig, struct k_sigaction *ka,
20 siginfo_t *info, sigset_t *oldset, struct pt_regs *regs); 20 siginfo_t *info, sigset_t *oldset, struct pt_regs *regs);
21 21
22void do_extint(struct pt_regs *regs, unsigned short code); 22void do_extint(struct pt_regs *regs, unsigned int, unsigned int, unsigned long);
23int __cpuinit start_secondary(void *cpuvoid); 23int __cpuinit start_secondary(void *cpuvoid);
24void __init startup_init(void); 24void __init startup_init(void);
25void die(const char * str, struct pt_regs * regs, long err); 25void die(const char * str, struct pt_regs * regs, long err);
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 8bccec15ea90..a2be23922f43 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -79,25 +79,9 @@ _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \
79 basr %r2,%r0 79 basr %r2,%r0
80 brasl %r14,trace_hardirqs_off_caller 80 brasl %r14,trace_hardirqs_off_caller
81 .endm 81 .endm
82
83 .macro TRACE_IRQS_CHECK_ON
84 tm SP_PSW(%r15),0x03 # irqs enabled?
85 jz 0f
86 TRACE_IRQS_ON
870:
88 .endm
89
90 .macro TRACE_IRQS_CHECK_OFF
91 tm SP_PSW(%r15),0x03 # irqs enabled?
92 jz 0f
93 TRACE_IRQS_OFF
940:
95 .endm
96#else 82#else
97#define TRACE_IRQS_ON 83#define TRACE_IRQS_ON
98#define TRACE_IRQS_OFF 84#define TRACE_IRQS_OFF
99#define TRACE_IRQS_CHECK_ON
100#define TRACE_IRQS_CHECK_OFF
101#endif 85#endif
102 86
103#ifdef CONFIG_LOCKDEP 87#ifdef CONFIG_LOCKDEP
@@ -207,6 +191,12 @@ _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \
2070: 1910:
208 .endm 192 .endm
209 193
194 .macro REENABLE_IRQS
195 mvc __SF_EMPTY(1,%r15),SP_PSW(%r15)
196 ni __SF_EMPTY(%r15),0xbf
197 ssm __SF_EMPTY(%r15)
198 .endm
199
210/* 200/*
211 * Scheduler resume function, called by switch_to 201 * Scheduler resume function, called by switch_to
212 * gpr2 = (task_struct *) prev 202 * gpr2 = (task_struct *) prev
@@ -256,7 +246,6 @@ sysc_saveall:
256 CREATE_STACK_FRAME __LC_SAVE_AREA 246 CREATE_STACK_FRAME __LC_SAVE_AREA
257 mvc SP_PSW(16,%r15),__LC_SVC_OLD_PSW 247 mvc SP_PSW(16,%r15),__LC_SVC_OLD_PSW
258 mvc SP_ILC(4,%r15),__LC_SVC_ILC 248 mvc SP_ILC(4,%r15),__LC_SVC_ILC
259 stg %r7,SP_ARGS(%r15)
260 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct 249 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct
261sysc_vtime: 250sysc_vtime:
262 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 251 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
@@ -284,6 +273,7 @@ sysc_nr_ok:
284sysc_noemu: 273sysc_noemu:
285#endif 274#endif
286 tm __TI_flags+6(%r12),_TIF_SYSCALL 275 tm __TI_flags+6(%r12),_TIF_SYSCALL
276 mvc SP_ARGS(8,%r15),SP_R7(%r15)
287 lgf %r8,0(%r7,%r10) # load address of system call routine 277 lgf %r8,0(%r7,%r10) # load address of system call routine
288 jnz sysc_tracesys 278 jnz sysc_tracesys
289 basr %r14,%r8 # call sys_xxxx 279 basr %r14,%r8 # call sys_xxxx
@@ -397,6 +387,7 @@ sysc_tracesys:
397 lgf %r8,0(%r7,%r10) 387 lgf %r8,0(%r7,%r10)
398sysc_tracego: 388sysc_tracego:
399 lmg %r3,%r6,SP_R3(%r15) 389 lmg %r3,%r6,SP_R3(%r15)
390 mvc SP_ARGS(8,%r15),SP_R7(%r15)
400 lg %r2,SP_ORIG_R2(%r15) 391 lg %r2,SP_ORIG_R2(%r15)
401 basr %r14,%r8 # call sys_xxx 392 basr %r14,%r8 # call sys_xxx
402 stg %r2,SP_R2(%r15) # store return value 393 stg %r2,SP_R2(%r15) # store return value
@@ -443,14 +434,12 @@ kernel_execve:
443 br %r14 434 br %r14
444 # execve succeeded. 435 # execve succeeded.
4450: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts 4360: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts
446# TRACE_IRQS_OFF
447 lg %r15,__LC_KERNEL_STACK # load ksp 437 lg %r15,__LC_KERNEL_STACK # load ksp
448 aghi %r15,-SP_SIZE # make room for registers & psw 438 aghi %r15,-SP_SIZE # make room for registers & psw
449 lg %r13,__LC_SVC_NEW_PSW+8 439 lg %r13,__LC_SVC_NEW_PSW+8
450 mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs 440 mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs
451 lg %r12,__LC_THREAD_INFO 441 lg %r12,__LC_THREAD_INFO
452 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 442 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
453# TRACE_IRQS_ON
454 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 443 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
455 brasl %r14,execve_tail 444 brasl %r14,execve_tail
456 j sysc_return 445 j sysc_return
@@ -490,19 +479,18 @@ pgm_check_handler:
490 LAST_BREAK 479 LAST_BREAK
491pgm_no_vtime: 480pgm_no_vtime:
492 HANDLE_SIE_INTERCEPT 481 HANDLE_SIE_INTERCEPT
493 TRACE_IRQS_CHECK_OFF
494 stg %r11,SP_ARGS(%r15) 482 stg %r11,SP_ARGS(%r15)
495 lgf %r3,__LC_PGM_ILC # load program interruption code 483 lgf %r3,__LC_PGM_ILC # load program interruption code
484 lg %r4,__LC_TRANS_EXC_CODE
485 REENABLE_IRQS
496 lghi %r8,0x7f 486 lghi %r8,0x7f
497 ngr %r8,%r3 487 ngr %r8,%r3
498pgm_do_call:
499 sll %r8,3 488 sll %r8,3
500 larl %r1,pgm_check_table 489 larl %r1,pgm_check_table
501 lg %r1,0(%r8,%r1) # load address of handler routine 490 lg %r1,0(%r8,%r1) # load address of handler routine
502 la %r2,SP_PTREGS(%r15) # address of register-save area 491 la %r2,SP_PTREGS(%r15) # address of register-save area
503 basr %r14,%r1 # branch to interrupt-handler 492 basr %r14,%r1 # branch to interrupt-handler
504pgm_exit: 493pgm_exit:
505 TRACE_IRQS_CHECK_ON
506 j sysc_return 494 j sysc_return
507 495
508# 496#
@@ -533,7 +521,6 @@ pgm_per_std:
533 LAST_BREAK 521 LAST_BREAK
534pgm_no_vtime2: 522pgm_no_vtime2:
535 HANDLE_SIE_INTERCEPT 523 HANDLE_SIE_INTERCEPT
536 TRACE_IRQS_CHECK_OFF
537 lg %r1,__TI_task(%r12) 524 lg %r1,__TI_task(%r12)
538 tm SP_PSW+1(%r15),0x01 # kernel per event ? 525 tm SP_PSW+1(%r15),0x01 # kernel per event ?
539 jz kernel_per 526 jz kernel_per
@@ -542,6 +529,8 @@ pgm_no_vtime2:
542 mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID 529 mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
543 oi __TI_flags+7(%r12),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP 530 oi __TI_flags+7(%r12),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
544 lgf %r3,__LC_PGM_ILC # load program interruption code 531 lgf %r3,__LC_PGM_ILC # load program interruption code
532 lg %r4,__LC_TRANS_EXC_CODE
533 REENABLE_IRQS
545 lghi %r8,0x7f 534 lghi %r8,0x7f
546 ngr %r8,%r3 # clear per-event-bit and ilc 535 ngr %r8,%r3 # clear per-event-bit and ilc
547 je pgm_exit2 536 je pgm_exit2
@@ -551,8 +540,6 @@ pgm_no_vtime2:
551 la %r2,SP_PTREGS(%r15) # address of register-save area 540 la %r2,SP_PTREGS(%r15) # address of register-save area
552 basr %r14,%r1 # branch to interrupt-handler 541 basr %r14,%r1 # branch to interrupt-handler
553pgm_exit2: 542pgm_exit2:
554 TRACE_IRQS_ON
555 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
556 j sysc_return 543 j sysc_return
557 544
558# 545#
@@ -568,13 +555,11 @@ pgm_svcper:
568 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 555 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
569 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 556 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
570 LAST_BREAK 557 LAST_BREAK
571 TRACE_IRQS_OFF
572 lg %r8,__TI_task(%r12) 558 lg %r8,__TI_task(%r12)
573 mvc __THREAD_per+__PER_atmid(2,%r8),__LC_PER_ATMID 559 mvc __THREAD_per+__PER_atmid(2,%r8),__LC_PER_ATMID
574 mvc __THREAD_per+__PER_address(8,%r8),__LC_PER_ADDRESS 560 mvc __THREAD_per+__PER_address(8,%r8),__LC_PER_ADDRESS
575 mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID 561 mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID
576 oi __TI_flags+7(%r12),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP 562 oi __TI_flags+7(%r12),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
577 TRACE_IRQS_ON
578 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 563 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
579 lmg %r2,%r6,SP_R2(%r15) # load svc arguments 564 lmg %r2,%r6,SP_R2(%r15) # load svc arguments
580 j sysc_do_svc 565 j sysc_do_svc
@@ -743,8 +728,11 @@ ext_int_handler:
743ext_no_vtime: 728ext_no_vtime:
744 HANDLE_SIE_INTERCEPT 729 HANDLE_SIE_INTERCEPT
745 TRACE_IRQS_OFF 730 TRACE_IRQS_OFF
731 lghi %r1,4096
746 la %r2,SP_PTREGS(%r15) # address of register-save area 732 la %r2,SP_PTREGS(%r15) # address of register-save area
747 llgh %r3,__LC_EXT_INT_CODE # get interruption code 733 llgf %r3,__LC_CPU_ADDRESS # get cpu address + interruption code
734 llgf %r4,__LC_EXT_PARAMS # get external parameter
735 lg %r5,__LC_EXT_PARAMS2-4096(%r1) # get 64 bit external parameter
748 brasl %r14,do_extint 736 brasl %r14,do_extint
749 j io_return 737 j io_return
750 738
@@ -966,7 +954,6 @@ cleanup_system_call:
966 CREATE_STACK_FRAME __LC_SAVE_AREA 954 CREATE_STACK_FRAME __LC_SAVE_AREA
967 mvc SP_PSW(16,%r15),__LC_SVC_OLD_PSW 955 mvc SP_PSW(16,%r15),__LC_SVC_OLD_PSW
968 mvc SP_ILC(4,%r15),__LC_SVC_ILC 956 mvc SP_ILC(4,%r15),__LC_SVC_ILC
969 stg %r7,SP_ARGS(%r15)
970 mvc 8(8,%r12),__LC_THREAD_INFO 957 mvc 8(8,%r12),__LC_THREAD_INFO
971cleanup_vtime: 958cleanup_vtime:
972 clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+24) 959 clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+24)
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S
index db1696e210af..7061398341d5 100644
--- a/arch/s390/kernel/head.S
+++ b/arch/s390/kernel/head.S
@@ -488,7 +488,9 @@ startup:
488 .align 16 488 .align 16
4892: .long 0x000a0000,0x8badcccc 4892: .long 0x000a0000,0x8badcccc
490#if defined(CONFIG_64BIT) 490#if defined(CONFIG_64BIT)
491#if defined(CONFIG_MARCH_Z10) 491#if defined(CONFIG_MARCH_Z196)
492 .long 0xc100efe3, 0xf46c0000
493#elif defined(CONFIG_MARCH_Z10)
492 .long 0xc100efe3, 0xf0680000 494 .long 0xc100efe3, 0xf0680000
493#elif defined(CONFIG_MARCH_Z9_109) 495#elif defined(CONFIG_MARCH_Z9_109)
494 .long 0xc100efc3, 0x00000000 496 .long 0xc100efc3, 0x00000000
@@ -498,7 +500,9 @@ startup:
498 .long 0xc0000000, 0x00000000 500 .long 0xc0000000, 0x00000000
499#endif 501#endif
500#else 502#else
501#if defined(CONFIG_MARCH_Z10) 503#if defined(CONFIG_MARCH_Z196)
504 .long 0x8100c880, 0x00000000
505#elif defined(CONFIG_MARCH_Z10)
502 .long 0x8100c880, 0x00000000 506 .long 0x8100c880, 0x00000000
503#elif defined(CONFIG_MARCH_Z9_109) 507#elif defined(CONFIG_MARCH_Z9_109)
504 .long 0x8100c880, 0x00000000 508 .long 0x8100c880, 0x00000000
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index d3a2d1c6438e..ec2e03b22ead 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -76,17 +76,17 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
76static void default_idle(void) 76static void default_idle(void)
77{ 77{
78 /* CPU is going idle. */ 78 /* CPU is going idle. */
79 local_irq_disable();
80 if (need_resched()) {
81 local_irq_enable();
82 return;
83 }
84#ifdef CONFIG_HOTPLUG_CPU 79#ifdef CONFIG_HOTPLUG_CPU
85 if (cpu_is_offline(smp_processor_id())) { 80 if (cpu_is_offline(smp_processor_id())) {
86 preempt_enable_no_resched(); 81 preempt_enable_no_resched();
87 cpu_die(); 82 cpu_die();
88 } 83 }
89#endif 84#endif
85 local_irq_disable();
86 if (need_resched()) {
87 local_irq_enable();
88 return;
89 }
90 local_mcck_disable(); 90 local_mcck_disable();
91 if (test_thread_flag(TIF_MCCK_PENDING)) { 91 if (test_thread_flag(TIF_MCCK_PENDING)) {
92 local_mcck_enable(); 92 local_mcck_enable();
diff --git a/arch/s390/kernel/processor.c b/arch/s390/kernel/processor.c
index ecb2d02b02e4..644548e615c6 100644
--- a/arch/s390/kernel/processor.c
+++ b/arch/s390/kernel/processor.c
@@ -42,7 +42,7 @@ void __cpuinit print_cpu_info(void)
42 struct cpuid *id = &per_cpu(cpu_id, smp_processor_id()); 42 struct cpuid *id = &per_cpu(cpu_id, smp_processor_id());
43 43
44 pr_info("Processor %d started, address %d, identification %06X\n", 44 pr_info("Processor %d started, address %d, identification %06X\n",
45 S390_lowcore.cpu_nr, S390_lowcore.cpu_addr, id->ident); 45 S390_lowcore.cpu_nr, stap(), id->ident);
46} 46}
47 47
48/* 48/*
diff --git a/arch/s390/kernel/s390_ext.c b/arch/s390/kernel/s390_ext.c
index 9ce641b5291f..bd1db508e8af 100644
--- a/arch/s390/kernel/s390_ext.c
+++ b/arch/s390/kernel/s390_ext.c
@@ -113,12 +113,15 @@ int unregister_early_external_interrupt(__u16 code, ext_int_handler_t handler,
113 return 0; 113 return 0;
114} 114}
115 115
116void __irq_entry do_extint(struct pt_regs *regs, unsigned short code) 116void __irq_entry do_extint(struct pt_regs *regs, unsigned int ext_int_code,
117 unsigned int param32, unsigned long param64)
117{ 118{
119 struct pt_regs *old_regs;
120 unsigned short code;
118 ext_int_info_t *p; 121 ext_int_info_t *p;
119 int index; 122 int index;
120 struct pt_regs *old_regs;
121 123
124 code = (unsigned short) ext_int_code;
122 old_regs = set_irq_regs(regs); 125 old_regs = set_irq_regs(regs);
123 s390_idle_check(regs, S390_lowcore.int_clock, 126 s390_idle_check(regs, S390_lowcore.int_clock,
124 S390_lowcore.async_enter_timer); 127 S390_lowcore.async_enter_timer);
@@ -132,7 +135,7 @@ void __irq_entry do_extint(struct pt_regs *regs, unsigned short code)
132 index = ext_hash(code); 135 index = ext_hash(code);
133 for (p = ext_int_hash[index]; p; p = p->next) { 136 for (p = ext_int_hash[index]; p; p = p->next) {
134 if (likely(p->code == code)) 137 if (likely(p->code == code))
135 p->handler(code); 138 p->handler(ext_int_code, param32, param64);
136 } 139 }
137 irq_exit(); 140 irq_exit();
138 set_irq_regs(old_regs); 141 set_irq_regs(old_regs);
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index c8e8e1354e1d..e3ceb911dc75 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -409,6 +409,9 @@ setup_lowcore(void)
409 lc->current_task = (unsigned long) init_thread_union.thread_info.task; 409 lc->current_task = (unsigned long) init_thread_union.thread_info.task;
410 lc->thread_info = (unsigned long) &init_thread_union; 410 lc->thread_info = (unsigned long) &init_thread_union;
411 lc->machine_flags = S390_lowcore.machine_flags; 411 lc->machine_flags = S390_lowcore.machine_flags;
412 lc->stfl_fac_list = S390_lowcore.stfl_fac_list;
413 memcpy(lc->stfle_fac_list, S390_lowcore.stfle_fac_list,
414 MAX_FACILITY_BIT/8);
412#ifndef CONFIG_64BIT 415#ifndef CONFIG_64BIT
413 if (MACHINE_HAS_IEEE) { 416 if (MACHINE_HAS_IEEE) {
414 lc->extended_save_area_addr = (__u32) 417 lc->extended_save_area_addr = (__u32)
@@ -627,7 +630,8 @@ setup_memory(void)
627 add_active_range(0, start_chunk, end_chunk); 630 add_active_range(0, start_chunk, end_chunk);
628 pfn = max(start_chunk, start_pfn); 631 pfn = max(start_chunk, start_pfn);
629 for (; pfn < end_chunk; pfn++) 632 for (; pfn < end_chunk; pfn++)
630 page_set_storage_key(PFN_PHYS(pfn), PAGE_DEFAULT_KEY); 633 page_set_storage_key(PFN_PHYS(pfn),
634 PAGE_DEFAULT_KEY, 0);
631 } 635 }
632 636
633 psw_set_key(PAGE_DEFAULT_KEY); 637 psw_set_key(PAGE_DEFAULT_KEY);
@@ -674,12 +678,9 @@ setup_memory(void)
674static void __init setup_hwcaps(void) 678static void __init setup_hwcaps(void)
675{ 679{
676 static const int stfl_bits[6] = { 0, 2, 7, 17, 19, 21 }; 680 static const int stfl_bits[6] = { 0, 2, 7, 17, 19, 21 };
677 unsigned long long facility_list_extended;
678 unsigned int facility_list;
679 struct cpuid cpu_id; 681 struct cpuid cpu_id;
680 int i; 682 int i;
681 683
682 facility_list = stfl();
683 /* 684 /*
684 * The store facility list bits numbers as found in the principles 685 * The store facility list bits numbers as found in the principles
685 * of operation are numbered with bit 1UL<<31 as number 0 to 686 * of operation are numbered with bit 1UL<<31 as number 0 to
@@ -699,11 +700,10 @@ static void __init setup_hwcaps(void)
699 * HWCAP_S390_ETF3EH bit 8 (22 && 30). 700 * HWCAP_S390_ETF3EH bit 8 (22 && 30).
700 */ 701 */
701 for (i = 0; i < 6; i++) 702 for (i = 0; i < 6; i++)
702 if (facility_list & (1UL << (31 - stfl_bits[i]))) 703 if (test_facility(stfl_bits[i]))
703 elf_hwcap |= 1UL << i; 704 elf_hwcap |= 1UL << i;
704 705
705 if ((facility_list & (1UL << (31 - 22))) 706 if (test_facility(22) && test_facility(30))
706 && (facility_list & (1UL << (31 - 30))))
707 elf_hwcap |= HWCAP_S390_ETF3EH; 707 elf_hwcap |= HWCAP_S390_ETF3EH;
708 708
709 /* 709 /*
@@ -719,12 +719,8 @@ static void __init setup_hwcaps(void)
719 * translated to: 719 * translated to:
720 * HWCAP_S390_DFP bit 6 (42 && 44). 720 * HWCAP_S390_DFP bit 6 (42 && 44).
721 */ 721 */
722 if ((elf_hwcap & (1UL << 2)) && 722 if ((elf_hwcap & (1UL << 2)) && test_facility(42) && test_facility(44))
723 __stfle(&facility_list_extended, 1) > 0) { 723 elf_hwcap |= HWCAP_S390_DFP;
724 if ((facility_list_extended & (1ULL << (63 - 42)))
725 && (facility_list_extended & (1ULL << (63 - 44))))
726 elf_hwcap |= HWCAP_S390_DFP;
727 }
728 724
729 /* 725 /*
730 * Huge page support HWCAP_S390_HPAGE is bit 7. 726 * Huge page support HWCAP_S390_HPAGE is bit 7.
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 8127ebd59c4d..94cf510b8fe1 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -156,7 +156,8 @@ void smp_send_stop(void)
156 * cpus are handled. 156 * cpus are handled.
157 */ 157 */
158 158
159static void do_ext_call_interrupt(__u16 code) 159static void do_ext_call_interrupt(unsigned int ext_int_code,
160 unsigned int param32, unsigned long param64)
160{ 161{
161 unsigned long bits; 162 unsigned long bits;
162 163
@@ -593,6 +594,8 @@ int __cpuinit __cpu_up(unsigned int cpu)
593 cpu_lowcore->kernel_asce = S390_lowcore.kernel_asce; 594 cpu_lowcore->kernel_asce = S390_lowcore.kernel_asce;
594 cpu_lowcore->machine_flags = S390_lowcore.machine_flags; 595 cpu_lowcore->machine_flags = S390_lowcore.machine_flags;
595 cpu_lowcore->ftrace_func = S390_lowcore.ftrace_func; 596 cpu_lowcore->ftrace_func = S390_lowcore.ftrace_func;
597 memcpy(cpu_lowcore->stfle_fac_list, S390_lowcore.stfle_fac_list,
598 MAX_FACILITY_BIT/8);
596 eieio(); 599 eieio();
597 600
598 while (sigp(cpu, sigp_restart) == sigp_busy) 601 while (sigp(cpu, sigp_restart) == sigp_busy)
diff --git a/arch/s390/kernel/sysinfo.c b/arch/s390/kernel/sysinfo.c
index a0ffc7717ed6..f04d93aa48ec 100644
--- a/arch/s390/kernel/sysinfo.c
+++ b/arch/s390/kernel/sysinfo.c
@@ -15,6 +15,7 @@
15#include <asm/ebcdic.h> 15#include <asm/ebcdic.h>
16#include <asm/sysinfo.h> 16#include <asm/sysinfo.h>
17#include <asm/cpcmd.h> 17#include <asm/cpcmd.h>
18#include <asm/topology.h>
18 19
19/* Sigh, math-emu. Don't ask. */ 20/* Sigh, math-emu. Don't ask. */
20#include <asm/sfp-util.h> 21#include <asm/sfp-util.h>
@@ -74,6 +75,42 @@ static int stsi_1_1_1(struct sysinfo_1_1_1 *info, char *page, int len)
74 "Model Temp. Capacity: %-16.16s %08u\n", 75 "Model Temp. Capacity: %-16.16s %08u\n",
75 info->model_temp_cap, 76 info->model_temp_cap,
76 *(u32 *) info->model_temp_cap_rating); 77 *(u32 *) info->model_temp_cap_rating);
78 if (info->cai) {
79 len += sprintf(page + len,
80 "Capacity Adj. Ind.: %d\n",
81 info->cai);
82 len += sprintf(page + len, "Capacity Ch. Reason: %d\n",
83 info->ccr);
84 }
85 return len;
86}
87
88static int stsi_15_1_x(struct sysinfo_15_1_x *info, char *page, int len)
89{
90 static int max_mnest;
91 int i, rc;
92
93 len += sprintf(page + len, "\n");
94 if (!MACHINE_HAS_TOPOLOGY)
95 return len;
96 if (max_mnest) {
97 stsi(info, 15, 1, max_mnest);
98 } else {
99 for (max_mnest = 6; max_mnest > 1; max_mnest--) {
100 rc = stsi(info, 15, 1, max_mnest);
101 if (rc != -ENOSYS)
102 break;
103 }
104 }
105 len += sprintf(page + len, "CPU Topology HW: ");
106 for (i = 0; i < TOPOLOGY_NR_MAG; i++)
107 len += sprintf(page + len, " %d", info->mag[i]);
108 len += sprintf(page + len, "\n");
109 store_topology(info);
110 len += sprintf(page + len, "CPU Topology SW: ");
111 for (i = 0; i < TOPOLOGY_NR_MAG; i++)
112 len += sprintf(page + len, " %d", info->mag[i]);
113 len += sprintf(page + len, "\n");
77 return len; 114 return len;
78} 115}
79 116
@@ -87,7 +124,6 @@ static int stsi_1_2_2(struct sysinfo_1_2_2 *info, char *page, int len)
87 ext = (struct sysinfo_1_2_2_extension *) 124 ext = (struct sysinfo_1_2_2_extension *)
88 ((unsigned long) info + info->acc_offset); 125 ((unsigned long) info + info->acc_offset);
89 126
90 len += sprintf(page + len, "\n");
91 len += sprintf(page + len, "CPUs Total: %d\n", 127 len += sprintf(page + len, "CPUs Total: %d\n",
92 info->cpus_total); 128 info->cpus_total);
93 len += sprintf(page + len, "CPUs Configured: %d\n", 129 len += sprintf(page + len, "CPUs Configured: %d\n",
@@ -217,6 +253,9 @@ static int proc_read_sysinfo(char *page, char **start,
217 len = stsi_1_1_1((struct sysinfo_1_1_1 *) info, page, len); 253 len = stsi_1_1_1((struct sysinfo_1_1_1 *) info, page, len);
218 254
219 if (level >= 1) 255 if (level >= 1)
256 len = stsi_15_1_x((struct sysinfo_15_1_x *) info, page, len);
257
258 if (level >= 1)
220 len = stsi_1_2_2((struct sysinfo_1_2_2 *) info, page, len); 259 len = stsi_1_2_2((struct sysinfo_1_2_2 *) info, page, len);
221 260
222 if (level >= 2) 261 if (level >= 2)
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 2896cac9c14a..f754a6dc4f94 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -155,7 +155,9 @@ void init_cpu_timer(void)
155 __ctl_set_bit(0, 4); 155 __ctl_set_bit(0, 4);
156} 156}
157 157
158static void clock_comparator_interrupt(__u16 code) 158static void clock_comparator_interrupt(unsigned int ext_int_code,
159 unsigned int param32,
160 unsigned long param64)
159{ 161{
160 if (S390_lowcore.clock_comparator == -1ULL) 162 if (S390_lowcore.clock_comparator == -1ULL)
161 set_clock_comparator(S390_lowcore.clock_comparator); 163 set_clock_comparator(S390_lowcore.clock_comparator);
@@ -164,14 +166,13 @@ static void clock_comparator_interrupt(__u16 code)
164static void etr_timing_alert(struct etr_irq_parm *); 166static void etr_timing_alert(struct etr_irq_parm *);
165static void stp_timing_alert(struct stp_irq_parm *); 167static void stp_timing_alert(struct stp_irq_parm *);
166 168
167static void timing_alert_interrupt(__u16 code) 169static void timing_alert_interrupt(unsigned int ext_int_code,
170 unsigned int param32, unsigned long param64)
168{ 171{
169 if (S390_lowcore.ext_params & 0x00c40000) 172 if (param32 & 0x00c40000)
170 etr_timing_alert((struct etr_irq_parm *) 173 etr_timing_alert((struct etr_irq_parm *) &param32);
171 &S390_lowcore.ext_params); 174 if (param32 & 0x00038000)
172 if (S390_lowcore.ext_params & 0x00038000) 175 stp_timing_alert((struct stp_irq_parm *) &param32);
173 stp_timing_alert((struct stp_irq_parm *)
174 &S390_lowcore.ext_params);
175} 176}
176 177
177static void etr_reset(void); 178static void etr_reset(void);
diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c
index 13559c993847..a9dee9048ee5 100644
--- a/arch/s390/kernel/topology.c
+++ b/arch/s390/kernel/topology.c
@@ -18,55 +18,20 @@
18#include <linux/cpuset.h> 18#include <linux/cpuset.h>
19#include <asm/delay.h> 19#include <asm/delay.h>
20#include <asm/s390_ext.h> 20#include <asm/s390_ext.h>
21#include <asm/sysinfo.h>
22
23#define CPU_BITS 64
24#define NR_MAG 6
25 21
26#define PTF_HORIZONTAL (0UL) 22#define PTF_HORIZONTAL (0UL)
27#define PTF_VERTICAL (1UL) 23#define PTF_VERTICAL (1UL)
28#define PTF_CHECK (2UL) 24#define PTF_CHECK (2UL)
29 25
30struct tl_cpu {
31 unsigned char reserved0[4];
32 unsigned char :6;
33 unsigned char pp:2;
34 unsigned char reserved1;
35 unsigned short origin;
36 unsigned long mask[CPU_BITS / BITS_PER_LONG];
37};
38
39struct tl_container {
40 unsigned char reserved[7];
41 unsigned char id;
42};
43
44union tl_entry {
45 unsigned char nl;
46 struct tl_cpu cpu;
47 struct tl_container container;
48};
49
50struct tl_info {
51 unsigned char reserved0[2];
52 unsigned short length;
53 unsigned char mag[NR_MAG];
54 unsigned char reserved1;
55 unsigned char mnest;
56 unsigned char reserved2[4];
57 union tl_entry tle[0];
58};
59
60struct mask_info { 26struct mask_info {
61 struct mask_info *next; 27 struct mask_info *next;
62 unsigned char id; 28 unsigned char id;
63 cpumask_t mask; 29 cpumask_t mask;
64}; 30};
65 31
66static int topology_enabled; 32static int topology_enabled = 1;
67static void topology_work_fn(struct work_struct *work); 33static void topology_work_fn(struct work_struct *work);
68static struct tl_info *tl_info; 34static struct sysinfo_15_1_x *tl_info;
69static int machine_has_topology;
70static struct timer_list topology_timer; 35static struct timer_list topology_timer;
71static void set_topology_timer(void); 36static void set_topology_timer(void);
72static DECLARE_WORK(topology_work, topology_work_fn); 37static DECLARE_WORK(topology_work, topology_work_fn);
@@ -88,7 +53,7 @@ static cpumask_t cpu_group_map(struct mask_info *info, unsigned int cpu)
88 cpumask_t mask; 53 cpumask_t mask;
89 54
90 cpus_clear(mask); 55 cpus_clear(mask);
91 if (!topology_enabled || !machine_has_topology) 56 if (!topology_enabled || !MACHINE_HAS_TOPOLOGY)
92 return cpu_possible_map; 57 return cpu_possible_map;
93 while (info) { 58 while (info) {
94 if (cpu_isset(cpu, info->mask)) { 59 if (cpu_isset(cpu, info->mask)) {
@@ -102,18 +67,18 @@ static cpumask_t cpu_group_map(struct mask_info *info, unsigned int cpu)
102 return mask; 67 return mask;
103} 68}
104 69
105static void add_cpus_to_mask(struct tl_cpu *tl_cpu, struct mask_info *book, 70static void add_cpus_to_mask(struct topology_cpu *tl_cpu,
106 struct mask_info *core) 71 struct mask_info *book, struct mask_info *core)
107{ 72{
108 unsigned int cpu; 73 unsigned int cpu;
109 74
110 for (cpu = find_first_bit(&tl_cpu->mask[0], CPU_BITS); 75 for (cpu = find_first_bit(&tl_cpu->mask[0], TOPOLOGY_CPU_BITS);
111 cpu < CPU_BITS; 76 cpu < TOPOLOGY_CPU_BITS;
112 cpu = find_next_bit(&tl_cpu->mask[0], CPU_BITS, cpu + 1)) 77 cpu = find_next_bit(&tl_cpu->mask[0], TOPOLOGY_CPU_BITS, cpu + 1))
113 { 78 {
114 unsigned int rcpu, lcpu; 79 unsigned int rcpu, lcpu;
115 80
116 rcpu = CPU_BITS - 1 - cpu + tl_cpu->origin; 81 rcpu = TOPOLOGY_CPU_BITS - 1 - cpu + tl_cpu->origin;
117 for_each_present_cpu(lcpu) { 82 for_each_present_cpu(lcpu) {
118 if (cpu_logical_map(lcpu) != rcpu) 83 if (cpu_logical_map(lcpu) != rcpu)
119 continue; 84 continue;
@@ -146,15 +111,14 @@ static void clear_masks(void)
146#endif 111#endif
147} 112}
148 113
149static union tl_entry *next_tle(union tl_entry *tle) 114static union topology_entry *next_tle(union topology_entry *tle)
150{ 115{
151 if (tle->nl) 116 if (!tle->nl)
152 return (union tl_entry *)((struct tl_container *)tle + 1); 117 return (union topology_entry *)((struct topology_cpu *)tle + 1);
153 else 118 return (union topology_entry *)((struct topology_container *)tle + 1);
154 return (union tl_entry *)((struct tl_cpu *)tle + 1);
155} 119}
156 120
157static void tl_to_cores(struct tl_info *info) 121static void tl_to_cores(struct sysinfo_15_1_x *info)
158{ 122{
159#ifdef CONFIG_SCHED_BOOK 123#ifdef CONFIG_SCHED_BOOK
160 struct mask_info *book = &book_info; 124 struct mask_info *book = &book_info;
@@ -162,13 +126,13 @@ static void tl_to_cores(struct tl_info *info)
162 struct mask_info *book = NULL; 126 struct mask_info *book = NULL;
163#endif 127#endif
164 struct mask_info *core = &core_info; 128 struct mask_info *core = &core_info;
165 union tl_entry *tle, *end; 129 union topology_entry *tle, *end;
166 130
167 131
168 spin_lock_irq(&topology_lock); 132 spin_lock_irq(&topology_lock);
169 clear_masks(); 133 clear_masks();
170 tle = info->tle; 134 tle = info->tle;
171 end = (union tl_entry *)((unsigned long)info + info->length); 135 end = (union topology_entry *)((unsigned long)info + info->length);
172 while (tle < end) { 136 while (tle < end) {
173 switch (tle->nl) { 137 switch (tle->nl) {
174#ifdef CONFIG_SCHED_BOOK 138#ifdef CONFIG_SCHED_BOOK
@@ -186,7 +150,6 @@ static void tl_to_cores(struct tl_info *info)
186 break; 150 break;
187 default: 151 default:
188 clear_masks(); 152 clear_masks();
189 machine_has_topology = 0;
190 goto out; 153 goto out;
191 } 154 }
192 tle = next_tle(tle); 155 tle = next_tle(tle);
@@ -223,7 +186,7 @@ int topology_set_cpu_management(int fc)
223 int cpu; 186 int cpu;
224 int rc; 187 int rc;
225 188
226 if (!machine_has_topology) 189 if (!MACHINE_HAS_TOPOLOGY)
227 return -EOPNOTSUPP; 190 return -EOPNOTSUPP;
228 if (fc) 191 if (fc)
229 rc = ptf(PTF_VERTICAL); 192 rc = ptf(PTF_VERTICAL);
@@ -251,7 +214,7 @@ static void update_cpu_core_map(void)
251 spin_unlock_irqrestore(&topology_lock, flags); 214 spin_unlock_irqrestore(&topology_lock, flags);
252} 215}
253 216
254static void store_topology(struct tl_info *info) 217void store_topology(struct sysinfo_15_1_x *info)
255{ 218{
256#ifdef CONFIG_SCHED_BOOK 219#ifdef CONFIG_SCHED_BOOK
257 int rc; 220 int rc;
@@ -265,11 +228,11 @@ static void store_topology(struct tl_info *info)
265 228
266int arch_update_cpu_topology(void) 229int arch_update_cpu_topology(void)
267{ 230{
268 struct tl_info *info = tl_info; 231 struct sysinfo_15_1_x *info = tl_info;
269 struct sys_device *sysdev; 232 struct sys_device *sysdev;
270 int cpu; 233 int cpu;
271 234
272 if (!machine_has_topology) { 235 if (!MACHINE_HAS_TOPOLOGY) {
273 update_cpu_core_map(); 236 update_cpu_core_map();
274 topology_update_polarization_simple(); 237 topology_update_polarization_simple();
275 return 0; 238 return 0;
@@ -311,9 +274,9 @@ static void set_topology_timer(void)
311 274
312static int __init early_parse_topology(char *p) 275static int __init early_parse_topology(char *p)
313{ 276{
314 if (strncmp(p, "on", 2)) 277 if (strncmp(p, "off", 3))
315 return 0; 278 return 0;
316 topology_enabled = 1; 279 topology_enabled = 0;
317 return 0; 280 return 0;
318} 281}
319early_param("topology", early_parse_topology); 282early_param("topology", early_parse_topology);
@@ -323,7 +286,7 @@ static int __init init_topology_update(void)
323 int rc; 286 int rc;
324 287
325 rc = 0; 288 rc = 0;
326 if (!machine_has_topology) { 289 if (!MACHINE_HAS_TOPOLOGY) {
327 topology_update_polarization_simple(); 290 topology_update_polarization_simple();
328 goto out; 291 goto out;
329 } 292 }
@@ -335,13 +298,14 @@ out:
335} 298}
336__initcall(init_topology_update); 299__initcall(init_topology_update);
337 300
338static void alloc_masks(struct tl_info *info, struct mask_info *mask, int offset) 301static void alloc_masks(struct sysinfo_15_1_x *info, struct mask_info *mask,
302 int offset)
339{ 303{
340 int i, nr_masks; 304 int i, nr_masks;
341 305
342 nr_masks = info->mag[NR_MAG - offset]; 306 nr_masks = info->mag[TOPOLOGY_NR_MAG - offset];
343 for (i = 0; i < info->mnest - offset; i++) 307 for (i = 0; i < info->mnest - offset; i++)
344 nr_masks *= info->mag[NR_MAG - offset - 1 - i]; 308 nr_masks *= info->mag[TOPOLOGY_NR_MAG - offset - 1 - i];
345 nr_masks = max(nr_masks, 1); 309 nr_masks = max(nr_masks, 1);
346 for (i = 0; i < nr_masks; i++) { 310 for (i = 0; i < nr_masks; i++) {
347 mask->next = alloc_bootmem(sizeof(struct mask_info)); 311 mask->next = alloc_bootmem(sizeof(struct mask_info));
@@ -351,21 +315,16 @@ static void alloc_masks(struct tl_info *info, struct mask_info *mask, int offset
351 315
352void __init s390_init_cpu_topology(void) 316void __init s390_init_cpu_topology(void)
353{ 317{
354 unsigned long long facility_bits; 318 struct sysinfo_15_1_x *info;
355 struct tl_info *info;
356 int i; 319 int i;
357 320
358 if (stfle(&facility_bits, 1) <= 0) 321 if (!MACHINE_HAS_TOPOLOGY)
359 return;
360 if (!(facility_bits & (1ULL << 52)) || !(facility_bits & (1ULL << 61)))
361 return; 322 return;
362 machine_has_topology = 1;
363
364 tl_info = alloc_bootmem_pages(PAGE_SIZE); 323 tl_info = alloc_bootmem_pages(PAGE_SIZE);
365 info = tl_info; 324 info = tl_info;
366 store_topology(info); 325 store_topology(info);
367 pr_info("The CPU configuration topology of the machine is:"); 326 pr_info("The CPU configuration topology of the machine is:");
368 for (i = 0; i < NR_MAG; i++) 327 for (i = 0; i < TOPOLOGY_NR_MAG; i++)
369 printk(" %d", info->mag[i]); 328 printk(" %d", info->mag[i]);
370 printk(" / %d\n", info->mnest); 329 printk(" / %d\n", info->mnest);
371 alloc_masks(info, &core_info, 2); 330 alloc_masks(info, &core_info, 2);
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index 5d8f0f3d0250..70640822621a 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -329,27 +329,19 @@ int is_valid_bugaddr(unsigned long addr)
329 return 1; 329 return 1;
330} 330}
331 331
332static void __kprobes inline do_trap(long interruption_code, int signr, 332static inline void __kprobes do_trap(long pgm_int_code, int signr, char *str,
333 char *str, struct pt_regs *regs, 333 struct pt_regs *regs, siginfo_t *info)
334 siginfo_t *info)
335{ 334{
336 /* 335 if (notify_die(DIE_TRAP, str, regs, pgm_int_code,
337 * We got all needed information from the lowcore and can 336 pgm_int_code, signr) == NOTIFY_STOP)
338 * now safely switch on interrupts.
339 */
340 if (regs->psw.mask & PSW_MASK_PSTATE)
341 local_irq_enable();
342
343 if (notify_die(DIE_TRAP, str, regs, interruption_code,
344 interruption_code, signr) == NOTIFY_STOP)
345 return; 337 return;
346 338
347 if (regs->psw.mask & PSW_MASK_PSTATE) { 339 if (regs->psw.mask & PSW_MASK_PSTATE) {
348 struct task_struct *tsk = current; 340 struct task_struct *tsk = current;
349 341
350 tsk->thread.trap_no = interruption_code & 0xffff; 342 tsk->thread.trap_no = pgm_int_code & 0xffff;
351 force_sig_info(signr, info, tsk); 343 force_sig_info(signr, info, tsk);
352 report_user_fault(regs, interruption_code, signr); 344 report_user_fault(regs, pgm_int_code, signr);
353 } else { 345 } else {
354 const struct exception_table_entry *fixup; 346 const struct exception_table_entry *fixup;
355 fixup = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN); 347 fixup = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN);
@@ -361,14 +353,16 @@ static void __kprobes inline do_trap(long interruption_code, int signr,
361 btt = report_bug(regs->psw.addr & PSW_ADDR_INSN, regs); 353 btt = report_bug(regs->psw.addr & PSW_ADDR_INSN, regs);
362 if (btt == BUG_TRAP_TYPE_WARN) 354 if (btt == BUG_TRAP_TYPE_WARN)
363 return; 355 return;
364 die(str, regs, interruption_code); 356 die(str, regs, pgm_int_code);
365 } 357 }
366 } 358 }
367} 359}
368 360
369static inline void __user *get_check_address(struct pt_regs *regs) 361static inline void __user *get_psw_address(struct pt_regs *regs,
362 long pgm_int_code)
370{ 363{
371 return (void __user *)((regs->psw.addr-S390_lowcore.pgm_ilc) & PSW_ADDR_INSN); 364 return (void __user *)
365 ((regs->psw.addr - (pgm_int_code >> 16)) & PSW_ADDR_INSN);
372} 366}
373 367
374void __kprobes do_single_step(struct pt_regs *regs) 368void __kprobes do_single_step(struct pt_regs *regs)
@@ -381,57 +375,57 @@ void __kprobes do_single_step(struct pt_regs *regs)
381 force_sig(SIGTRAP, current); 375 force_sig(SIGTRAP, current);
382} 376}
383 377
384static void default_trap_handler(struct pt_regs * regs, long interruption_code) 378static void default_trap_handler(struct pt_regs *regs, long pgm_int_code,
379 unsigned long trans_exc_code)
385{ 380{
386 if (regs->psw.mask & PSW_MASK_PSTATE) { 381 if (regs->psw.mask & PSW_MASK_PSTATE) {
387 local_irq_enable(); 382 report_user_fault(regs, pgm_int_code, SIGSEGV);
388 report_user_fault(regs, interruption_code, SIGSEGV);
389 do_exit(SIGSEGV); 383 do_exit(SIGSEGV);
390 } else 384 } else
391 die("Unknown program exception", regs, interruption_code); 385 die("Unknown program exception", regs, pgm_int_code);
392} 386}
393 387
394#define DO_ERROR_INFO(signr, str, name, sicode, siaddr) \ 388#define DO_ERROR_INFO(name, signr, sicode, str) \
395static void name(struct pt_regs * regs, long interruption_code) \ 389static void name(struct pt_regs *regs, long pgm_int_code, \
390 unsigned long trans_exc_code) \
396{ \ 391{ \
397 siginfo_t info; \ 392 siginfo_t info; \
398 info.si_signo = signr; \ 393 info.si_signo = signr; \
399 info.si_errno = 0; \ 394 info.si_errno = 0; \
400 info.si_code = sicode; \ 395 info.si_code = sicode; \
401 info.si_addr = siaddr; \ 396 info.si_addr = get_psw_address(regs, pgm_int_code); \
402 do_trap(interruption_code, signr, str, regs, &info); \ 397 do_trap(pgm_int_code, signr, str, regs, &info); \
403} 398}
404 399
405DO_ERROR_INFO(SIGILL, "addressing exception", addressing_exception, 400DO_ERROR_INFO(addressing_exception, SIGILL, ILL_ILLADR,
406 ILL_ILLADR, get_check_address(regs)) 401 "addressing exception")
407DO_ERROR_INFO(SIGILL, "execute exception", execute_exception, 402DO_ERROR_INFO(execute_exception, SIGILL, ILL_ILLOPN,
408 ILL_ILLOPN, get_check_address(regs)) 403 "execute exception")
409DO_ERROR_INFO(SIGFPE, "fixpoint divide exception", divide_exception, 404DO_ERROR_INFO(divide_exception, SIGFPE, FPE_INTDIV,
410 FPE_INTDIV, get_check_address(regs)) 405 "fixpoint divide exception")
411DO_ERROR_INFO(SIGFPE, "fixpoint overflow exception", overflow_exception, 406DO_ERROR_INFO(overflow_exception, SIGFPE, FPE_INTOVF,
412 FPE_INTOVF, get_check_address(regs)) 407 "fixpoint overflow exception")
413DO_ERROR_INFO(SIGFPE, "HFP overflow exception", hfp_overflow_exception, 408DO_ERROR_INFO(hfp_overflow_exception, SIGFPE, FPE_FLTOVF,
414 FPE_FLTOVF, get_check_address(regs)) 409 "HFP overflow exception")
415DO_ERROR_INFO(SIGFPE, "HFP underflow exception", hfp_underflow_exception, 410DO_ERROR_INFO(hfp_underflow_exception, SIGFPE, FPE_FLTUND,
416 FPE_FLTUND, get_check_address(regs)) 411 "HFP underflow exception")
417DO_ERROR_INFO(SIGFPE, "HFP significance exception", hfp_significance_exception, 412DO_ERROR_INFO(hfp_significance_exception, SIGFPE, FPE_FLTRES,
418 FPE_FLTRES, get_check_address(regs)) 413 "HFP significance exception")
419DO_ERROR_INFO(SIGFPE, "HFP divide exception", hfp_divide_exception, 414DO_ERROR_INFO(hfp_divide_exception, SIGFPE, FPE_FLTDIV,
420 FPE_FLTDIV, get_check_address(regs)) 415 "HFP divide exception")
421DO_ERROR_INFO(SIGFPE, "HFP square root exception", hfp_sqrt_exception, 416DO_ERROR_INFO(hfp_sqrt_exception, SIGFPE, FPE_FLTINV,
422 FPE_FLTINV, get_check_address(regs)) 417 "HFP square root exception")
423DO_ERROR_INFO(SIGILL, "operand exception", operand_exception, 418DO_ERROR_INFO(operand_exception, SIGILL, ILL_ILLOPN,
424 ILL_ILLOPN, get_check_address(regs)) 419 "operand exception")
425DO_ERROR_INFO(SIGILL, "privileged operation", privileged_op, 420DO_ERROR_INFO(privileged_op, SIGILL, ILL_PRVOPC,
426 ILL_PRVOPC, get_check_address(regs)) 421 "privileged operation")
427DO_ERROR_INFO(SIGILL, "special operation exception", special_op_exception, 422DO_ERROR_INFO(special_op_exception, SIGILL, ILL_ILLOPN,
428 ILL_ILLOPN, get_check_address(regs)) 423 "special operation exception")
429DO_ERROR_INFO(SIGILL, "translation exception", translation_exception, 424DO_ERROR_INFO(translation_exception, SIGILL, ILL_ILLOPN,
430 ILL_ILLOPN, get_check_address(regs)) 425 "translation exception")
431 426
432static inline void 427static inline void do_fp_trap(struct pt_regs *regs, void __user *location,
433do_fp_trap(struct pt_regs *regs, void __user *location, 428 int fpc, long pgm_int_code)
434 int fpc, long interruption_code)
435{ 429{
436 siginfo_t si; 430 siginfo_t si;
437 431
@@ -453,26 +447,19 @@ do_fp_trap(struct pt_regs *regs, void __user *location,
453 else if (fpc & 0x0800) /* inexact */ 447 else if (fpc & 0x0800) /* inexact */
454 si.si_code = FPE_FLTRES; 448 si.si_code = FPE_FLTRES;
455 } 449 }
456 current->thread.ieee_instruction_pointer = (addr_t) location; 450 do_trap(pgm_int_code, SIGFPE,
457 do_trap(interruption_code, SIGFPE,
458 "floating point exception", regs, &si); 451 "floating point exception", regs, &si);
459} 452}
460 453
461static void illegal_op(struct pt_regs * regs, long interruption_code) 454static void illegal_op(struct pt_regs *regs, long pgm_int_code,
455 unsigned long trans_exc_code)
462{ 456{
463 siginfo_t info; 457 siginfo_t info;
464 __u8 opcode[6]; 458 __u8 opcode[6];
465 __u16 __user *location; 459 __u16 __user *location;
466 int signal = 0; 460 int signal = 0;
467 461
468 location = get_check_address(regs); 462 location = get_psw_address(regs, pgm_int_code);
469
470 /*
471 * We got all needed information from the lowcore and can
472 * now safely switch on interrupts.
473 */
474 if (regs->psw.mask & PSW_MASK_PSTATE)
475 local_irq_enable();
476 463
477 if (regs->psw.mask & PSW_MASK_PSTATE) { 464 if (regs->psw.mask & PSW_MASK_PSTATE) {
478 if (get_user(*((__u16 *) opcode), (__u16 __user *) location)) 465 if (get_user(*((__u16 *) opcode), (__u16 __user *) location))
@@ -512,7 +499,7 @@ static void illegal_op(struct pt_regs * regs, long interruption_code)
512 * If we get an illegal op in kernel mode, send it through the 499 * If we get an illegal op in kernel mode, send it through the
513 * kprobes notifier. If kprobes doesn't pick it up, SIGILL 500 * kprobes notifier. If kprobes doesn't pick it up, SIGILL
514 */ 501 */
515 if (notify_die(DIE_BPT, "bpt", regs, interruption_code, 502 if (notify_die(DIE_BPT, "bpt", regs, pgm_int_code,
516 3, SIGTRAP) != NOTIFY_STOP) 503 3, SIGTRAP) != NOTIFY_STOP)
517 signal = SIGILL; 504 signal = SIGILL;
518 } 505 }
@@ -520,13 +507,13 @@ static void illegal_op(struct pt_regs * regs, long interruption_code)
520#ifdef CONFIG_MATHEMU 507#ifdef CONFIG_MATHEMU
521 if (signal == SIGFPE) 508 if (signal == SIGFPE)
522 do_fp_trap(regs, location, 509 do_fp_trap(regs, location,
523 current->thread.fp_regs.fpc, interruption_code); 510 current->thread.fp_regs.fpc, pgm_int_code);
524 else if (signal == SIGSEGV) { 511 else if (signal == SIGSEGV) {
525 info.si_signo = signal; 512 info.si_signo = signal;
526 info.si_errno = 0; 513 info.si_errno = 0;
527 info.si_code = SEGV_MAPERR; 514 info.si_code = SEGV_MAPERR;
528 info.si_addr = (void __user *) location; 515 info.si_addr = (void __user *) location;
529 do_trap(interruption_code, signal, 516 do_trap(pgm_int_code, signal,
530 "user address fault", regs, &info); 517 "user address fault", regs, &info);
531 } else 518 } else
532#endif 519#endif
@@ -535,28 +522,22 @@ static void illegal_op(struct pt_regs * regs, long interruption_code)
535 info.si_errno = 0; 522 info.si_errno = 0;
536 info.si_code = ILL_ILLOPC; 523 info.si_code = ILL_ILLOPC;
537 info.si_addr = (void __user *) location; 524 info.si_addr = (void __user *) location;
538 do_trap(interruption_code, signal, 525 do_trap(pgm_int_code, signal,
539 "illegal operation", regs, &info); 526 "illegal operation", regs, &info);
540 } 527 }
541} 528}
542 529
543 530
544#ifdef CONFIG_MATHEMU 531#ifdef CONFIG_MATHEMU
545asmlinkage void 532asmlinkage void specification_exception(struct pt_regs *regs,
546specification_exception(struct pt_regs * regs, long interruption_code) 533 long pgm_int_code,
534 unsigned long trans_exc_code)
547{ 535{
548 __u8 opcode[6]; 536 __u8 opcode[6];
549 __u16 __user *location = NULL; 537 __u16 __user *location = NULL;
550 int signal = 0; 538 int signal = 0;
551 539
552 location = (__u16 __user *) get_check_address(regs); 540 location = (__u16 __user *) get_psw_address(regs, pgm_int_code);
553
554 /*
555 * We got all needed information from the lowcore and can
556 * now safely switch on interrupts.
557 */
558 if (regs->psw.mask & PSW_MASK_PSTATE)
559 local_irq_enable();
560 541
561 if (regs->psw.mask & PSW_MASK_PSTATE) { 542 if (regs->psw.mask & PSW_MASK_PSTATE) {
562 get_user(*((__u16 *) opcode), location); 543 get_user(*((__u16 *) opcode), location);
@@ -592,35 +573,29 @@ specification_exception(struct pt_regs * regs, long interruption_code)
592 573
593 if (signal == SIGFPE) 574 if (signal == SIGFPE)
594 do_fp_trap(regs, location, 575 do_fp_trap(regs, location,
595 current->thread.fp_regs.fpc, interruption_code); 576 current->thread.fp_regs.fpc, pgm_int_code);
596 else if (signal) { 577 else if (signal) {
597 siginfo_t info; 578 siginfo_t info;
598 info.si_signo = signal; 579 info.si_signo = signal;
599 info.si_errno = 0; 580 info.si_errno = 0;
600 info.si_code = ILL_ILLOPN; 581 info.si_code = ILL_ILLOPN;
601 info.si_addr = location; 582 info.si_addr = location;
602 do_trap(interruption_code, signal, 583 do_trap(pgm_int_code, signal,
603 "specification exception", regs, &info); 584 "specification exception", regs, &info);
604 } 585 }
605} 586}
606#else 587#else
607DO_ERROR_INFO(SIGILL, "specification exception", specification_exception, 588DO_ERROR_INFO(specification_exception, SIGILL, ILL_ILLOPN,
608 ILL_ILLOPN, get_check_address(regs)); 589 "specification exception");
609#endif 590#endif
610 591
611static void data_exception(struct pt_regs * regs, long interruption_code) 592static void data_exception(struct pt_regs *regs, long pgm_int_code,
593 unsigned long trans_exc_code)
612{ 594{
613 __u16 __user *location; 595 __u16 __user *location;
614 int signal = 0; 596 int signal = 0;
615 597
616 location = get_check_address(regs); 598 location = get_psw_address(regs, pgm_int_code);
617
618 /*
619 * We got all needed information from the lowcore and can
620 * now safely switch on interrupts.
621 */
622 if (regs->psw.mask & PSW_MASK_PSTATE)
623 local_irq_enable();
624 599
625 if (MACHINE_HAS_IEEE) 600 if (MACHINE_HAS_IEEE)
626 asm volatile("stfpc %0" : "=m" (current->thread.fp_regs.fpc)); 601 asm volatile("stfpc %0" : "=m" (current->thread.fp_regs.fpc));
@@ -686,19 +661,19 @@ static void data_exception(struct pt_regs * regs, long interruption_code)
686 signal = SIGILL; 661 signal = SIGILL;
687 if (signal == SIGFPE) 662 if (signal == SIGFPE)
688 do_fp_trap(regs, location, 663 do_fp_trap(regs, location,
689 current->thread.fp_regs.fpc, interruption_code); 664 current->thread.fp_regs.fpc, pgm_int_code);
690 else if (signal) { 665 else if (signal) {
691 siginfo_t info; 666 siginfo_t info;
692 info.si_signo = signal; 667 info.si_signo = signal;
693 info.si_errno = 0; 668 info.si_errno = 0;
694 info.si_code = ILL_ILLOPN; 669 info.si_code = ILL_ILLOPN;
695 info.si_addr = location; 670 info.si_addr = location;
696 do_trap(interruption_code, signal, 671 do_trap(pgm_int_code, signal, "data exception", regs, &info);
697 "data exception", regs, &info);
698 } 672 }
699} 673}
700 674
701static void space_switch_exception(struct pt_regs * regs, long int_code) 675static void space_switch_exception(struct pt_regs *regs, long pgm_int_code,
676 unsigned long trans_exc_code)
702{ 677{
703 siginfo_t info; 678 siginfo_t info;
704 679
@@ -709,8 +684,8 @@ static void space_switch_exception(struct pt_regs * regs, long int_code)
709 info.si_signo = SIGILL; 684 info.si_signo = SIGILL;
710 info.si_errno = 0; 685 info.si_errno = 0;
711 info.si_code = ILL_PRVOPC; 686 info.si_code = ILL_PRVOPC;
712 info.si_addr = get_check_address(regs); 687 info.si_addr = get_psw_address(regs, pgm_int_code);
713 do_trap(int_code, SIGILL, "space switch event", regs, &info); 688 do_trap(pgm_int_code, SIGILL, "space switch event", regs, &info);
714} 689}
715 690
716asmlinkage void kernel_stack_overflow(struct pt_regs * regs) 691asmlinkage void kernel_stack_overflow(struct pt_regs * regs)
diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c
index 6b83870507d5..e3150dd2fe74 100644
--- a/arch/s390/kernel/vdso.c
+++ b/arch/s390/kernel/vdso.c
@@ -84,11 +84,7 @@ struct vdso_data *vdso_data = &vdso_data_store.data;
84 */ 84 */
85static void vdso_init_data(struct vdso_data *vd) 85static void vdso_init_data(struct vdso_data *vd)
86{ 86{
87 unsigned int facility_list; 87 vd->ectg_available = user_mode != HOME_SPACE_MODE && test_facility(31);
88
89 facility_list = stfl();
90 vd->ectg_available =
91 user_mode != HOME_SPACE_MODE && (facility_list & 1);
92} 88}
93 89
94#ifdef CONFIG_64BIT 90#ifdef CONFIG_64BIT
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c
index 3479f1b0d4e0..56c8687b29b3 100644
--- a/arch/s390/kernel/vtime.c
+++ b/arch/s390/kernel/vtime.c
@@ -314,7 +314,8 @@ static void do_callbacks(struct list_head *cb_list)
314/* 314/*
315 * Handler for the virtual CPU timer. 315 * Handler for the virtual CPU timer.
316 */ 316 */
317static void do_cpu_timer_interrupt(__u16 error_code) 317static void do_cpu_timer_interrupt(unsigned int ext_int_code,
318 unsigned int param32, unsigned long param64)
318{ 319{
319 struct vtimer_queue *vq; 320 struct vtimer_queue *vq;
320 struct vtimer_list *event, *tmp; 321 struct vtimer_list *event, *tmp;