diff options
Diffstat (limited to 'arch/s390/kernel')
-rw-r--r-- | arch/s390/kernel/asm-offsets.c | 3 | ||||
-rw-r--r-- | arch/s390/kernel/compat_ptrace.h | 3 | ||||
-rw-r--r-- | arch/s390/kernel/debug.c | 1 | ||||
-rw-r--r-- | arch/s390/kernel/dis.c | 145 | ||||
-rw-r--r-- | arch/s390/kernel/early.c | 45 | ||||
-rw-r--r-- | arch/s390/kernel/entry.S | 44 | ||||
-rw-r--r-- | arch/s390/kernel/entry.h | 4 | ||||
-rw-r--r-- | arch/s390/kernel/entry64.S | 45 | ||||
-rw-r--r-- | arch/s390/kernel/head.S | 8 | ||||
-rw-r--r-- | arch/s390/kernel/process.c | 10 | ||||
-rw-r--r-- | arch/s390/kernel/processor.c | 2 | ||||
-rw-r--r-- | arch/s390/kernel/s390_ext.c | 9 | ||||
-rw-r--r-- | arch/s390/kernel/setup.c | 22 | ||||
-rw-r--r-- | arch/s390/kernel/smp.c | 5 | ||||
-rw-r--r-- | arch/s390/kernel/sysinfo.c | 41 | ||||
-rw-r--r-- | arch/s390/kernel/time.c | 17 | ||||
-rw-r--r-- | arch/s390/kernel/topology.c | 101 | ||||
-rw-r--r-- | arch/s390/kernel/traps.c | 173 | ||||
-rw-r--r-- | arch/s390/kernel/vdso.c | 6 | ||||
-rw-r--r-- | arch/s390/kernel/vtime.c | 3 |
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 | ||
58 | struct user32 { | 57 | struct 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 | ||
179 | static struct dentry *debug_debugfs_root_entry; | 180 | static 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 | ||
154 | struct insn { | 155 | struct 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 | ||
308 | enum { | ||
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 | |||
323 | static 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 | |||
303 | static struct insn opcode[] = { | 338 | static 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 | |||
1055 | static 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 | ||
214 | static __initdata struct sysinfo_3_2_2 vmms __aligned(PAGE_SIZE); | 215 | static __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 | ||
259 | static 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 | |||
258 | static noinline __init void setup_hpage(void) | 282 | static 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) | |||
355 | static __init void detect_machine_facilities(void) | 378 | static __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 | ||
80 | 0: | ||
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 | ||
87 | 0: | ||
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 |
266 | sysc_nr_ok: | 256 | sysc_nr_ok: |
267 | mvc SP_ARGS(4,%r15),SP_R7(%r15) | ||
268 | sysc_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) |
391 | sysc_tracego: | 380 | sysc_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. |
442 | 0: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts | 432 | 0: 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 |
485 | pgm_no_vtime: | 473 | pgm_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 |
491 | pgm_do_call: | 480 | pgm_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 |
497 | pgm_exit: | 486 | pgm_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 |
525 | pgm_no_vtime2: | 513 | pgm_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 |
544 | pgm_exit2: | 533 | pgm_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 | ||
8 | typedef void pgm_check_handler_t(struct pt_regs *, long); | 8 | typedef void pgm_check_handler_t(struct pt_regs *, long, unsigned long); |
9 | extern pgm_check_handler_t *pgm_check_table[128]; | 9 | extern pgm_check_handler_t *pgm_check_table[128]; |
10 | pgm_check_handler_t do_protection_exception; | 10 | pgm_check_handler_t do_protection_exception; |
11 | pgm_check_handler_t do_dat_exception; | 11 | pgm_check_handler_t do_dat_exception; |
@@ -19,7 +19,7 @@ void do_signal(struct pt_regs *regs); | |||
19 | int handle_signal32(unsigned long sig, struct k_sigaction *ka, | 19 | int 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 | ||
22 | void do_extint(struct pt_regs *regs, unsigned short code); | 22 | void do_extint(struct pt_regs *regs, unsigned int, unsigned int, unsigned long); |
23 | int __cpuinit start_secondary(void *cpuvoid); | 23 | int __cpuinit start_secondary(void *cpuvoid); |
24 | void __init startup_init(void); | 24 | void __init startup_init(void); |
25 | void die(const char * str, struct pt_regs * regs, long err); | 25 | void 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 | ||
87 | 0: | ||
88 | .endm | ||
89 | |||
90 | .macro TRACE_IRQS_CHECK_OFF | ||
91 | tm SP_PSW(%r15),0x03 # irqs enabled? | ||
92 | jz 0f | ||
93 | TRACE_IRQS_OFF | ||
94 | 0: | ||
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 | \ | |||
207 | 0: | 191 | 0: |
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 |
261 | sysc_vtime: | 250 | sysc_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: | |||
284 | sysc_noemu: | 273 | sysc_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) |
398 | sysc_tracego: | 388 | sysc_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. |
445 | 0: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts | 436 | 0: 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 |
491 | pgm_no_vtime: | 480 | pgm_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 |
498 | pgm_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 |
504 | pgm_exit: | 493 | pgm_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 |
534 | pgm_no_vtime2: | 522 | pgm_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 |
553 | pgm_exit2: | 542 | pgm_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: | |||
743 | ext_no_vtime: | 728 | ext_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 |
971 | cleanup_vtime: | 958 | cleanup_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 |
489 | 2: .long 0x000a0000,0x8badcccc | 489 | 2: .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) | |||
76 | static void default_idle(void) | 76 | static 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 | ||
116 | void __irq_entry do_extint(struct pt_regs *regs, unsigned short code) | 116 | void __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) | |||
674 | static void __init setup_hwcaps(void) | 678 | static 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 | ||
159 | static void do_ext_call_interrupt(__u16 code) | 159 | static 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 | |||
88 | static 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 | ||
158 | static void clock_comparator_interrupt(__u16 code) | 158 | static 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) | |||
164 | static void etr_timing_alert(struct etr_irq_parm *); | 166 | static void etr_timing_alert(struct etr_irq_parm *); |
165 | static void stp_timing_alert(struct stp_irq_parm *); | 167 | static void stp_timing_alert(struct stp_irq_parm *); |
166 | 168 | ||
167 | static void timing_alert_interrupt(__u16 code) | 169 | static 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 *) ¶m32); |
171 | &S390_lowcore.ext_params); | 174 | if (param32 & 0x00038000) |
172 | if (S390_lowcore.ext_params & 0x00038000) | 175 | stp_timing_alert((struct stp_irq_parm *) ¶m32); |
173 | stp_timing_alert((struct stp_irq_parm *) | ||
174 | &S390_lowcore.ext_params); | ||
175 | } | 176 | } |
176 | 177 | ||
177 | static void etr_reset(void); | 178 | static 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 | ||
30 | struct 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 | |||
39 | struct tl_container { | ||
40 | unsigned char reserved[7]; | ||
41 | unsigned char id; | ||
42 | }; | ||
43 | |||
44 | union tl_entry { | ||
45 | unsigned char nl; | ||
46 | struct tl_cpu cpu; | ||
47 | struct tl_container container; | ||
48 | }; | ||
49 | |||
50 | struct 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 | |||
60 | struct mask_info { | 26 | struct 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 | ||
66 | static int topology_enabled; | 32 | static int topology_enabled = 1; |
67 | static void topology_work_fn(struct work_struct *work); | 33 | static void topology_work_fn(struct work_struct *work); |
68 | static struct tl_info *tl_info; | 34 | static struct sysinfo_15_1_x *tl_info; |
69 | static int machine_has_topology; | ||
70 | static struct timer_list topology_timer; | 35 | static struct timer_list topology_timer; |
71 | static void set_topology_timer(void); | 36 | static void set_topology_timer(void); |
72 | static DECLARE_WORK(topology_work, topology_work_fn); | 37 | static 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 | ||
105 | static void add_cpus_to_mask(struct tl_cpu *tl_cpu, struct mask_info *book, | 70 | static 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 | ||
149 | static union tl_entry *next_tle(union tl_entry *tle) | 114 | static 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 | ||
157 | static void tl_to_cores(struct tl_info *info) | 121 | static 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 | ||
254 | static void store_topology(struct tl_info *info) | 217 | void 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 | ||
266 | int arch_update_cpu_topology(void) | 229 | int 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 | ||
312 | static int __init early_parse_topology(char *p) | 275 | static 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 | } |
319 | early_param("topology", early_parse_topology); | 282 | early_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 | ||
338 | static void alloc_masks(struct tl_info *info, struct mask_info *mask, int offset) | 301 | static 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 | ||
352 | void __init s390_init_cpu_topology(void) | 316 | void __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 | ||
332 | static void __kprobes inline do_trap(long interruption_code, int signr, | 332 | static 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 | ||
369 | static inline void __user *get_check_address(struct pt_regs *regs) | 361 | static 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 | ||
374 | void __kprobes do_single_step(struct pt_regs *regs) | 368 | void __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 | ||
384 | static void default_trap_handler(struct pt_regs * regs, long interruption_code) | 378 | static 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) \ |
395 | static void name(struct pt_regs * regs, long interruption_code) \ | 389 | static 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 | ||
405 | DO_ERROR_INFO(SIGILL, "addressing exception", addressing_exception, | 400 | DO_ERROR_INFO(addressing_exception, SIGILL, ILL_ILLADR, |
406 | ILL_ILLADR, get_check_address(regs)) | 401 | "addressing exception") |
407 | DO_ERROR_INFO(SIGILL, "execute exception", execute_exception, | 402 | DO_ERROR_INFO(execute_exception, SIGILL, ILL_ILLOPN, |
408 | ILL_ILLOPN, get_check_address(regs)) | 403 | "execute exception") |
409 | DO_ERROR_INFO(SIGFPE, "fixpoint divide exception", divide_exception, | 404 | DO_ERROR_INFO(divide_exception, SIGFPE, FPE_INTDIV, |
410 | FPE_INTDIV, get_check_address(regs)) | 405 | "fixpoint divide exception") |
411 | DO_ERROR_INFO(SIGFPE, "fixpoint overflow exception", overflow_exception, | 406 | DO_ERROR_INFO(overflow_exception, SIGFPE, FPE_INTOVF, |
412 | FPE_INTOVF, get_check_address(regs)) | 407 | "fixpoint overflow exception") |
413 | DO_ERROR_INFO(SIGFPE, "HFP overflow exception", hfp_overflow_exception, | 408 | DO_ERROR_INFO(hfp_overflow_exception, SIGFPE, FPE_FLTOVF, |
414 | FPE_FLTOVF, get_check_address(regs)) | 409 | "HFP overflow exception") |
415 | DO_ERROR_INFO(SIGFPE, "HFP underflow exception", hfp_underflow_exception, | 410 | DO_ERROR_INFO(hfp_underflow_exception, SIGFPE, FPE_FLTUND, |
416 | FPE_FLTUND, get_check_address(regs)) | 411 | "HFP underflow exception") |
417 | DO_ERROR_INFO(SIGFPE, "HFP significance exception", hfp_significance_exception, | 412 | DO_ERROR_INFO(hfp_significance_exception, SIGFPE, FPE_FLTRES, |
418 | FPE_FLTRES, get_check_address(regs)) | 413 | "HFP significance exception") |
419 | DO_ERROR_INFO(SIGFPE, "HFP divide exception", hfp_divide_exception, | 414 | DO_ERROR_INFO(hfp_divide_exception, SIGFPE, FPE_FLTDIV, |
420 | FPE_FLTDIV, get_check_address(regs)) | 415 | "HFP divide exception") |
421 | DO_ERROR_INFO(SIGFPE, "HFP square root exception", hfp_sqrt_exception, | 416 | DO_ERROR_INFO(hfp_sqrt_exception, SIGFPE, FPE_FLTINV, |
422 | FPE_FLTINV, get_check_address(regs)) | 417 | "HFP square root exception") |
423 | DO_ERROR_INFO(SIGILL, "operand exception", operand_exception, | 418 | DO_ERROR_INFO(operand_exception, SIGILL, ILL_ILLOPN, |
424 | ILL_ILLOPN, get_check_address(regs)) | 419 | "operand exception") |
425 | DO_ERROR_INFO(SIGILL, "privileged operation", privileged_op, | 420 | DO_ERROR_INFO(privileged_op, SIGILL, ILL_PRVOPC, |
426 | ILL_PRVOPC, get_check_address(regs)) | 421 | "privileged operation") |
427 | DO_ERROR_INFO(SIGILL, "special operation exception", special_op_exception, | 422 | DO_ERROR_INFO(special_op_exception, SIGILL, ILL_ILLOPN, |
428 | ILL_ILLOPN, get_check_address(regs)) | 423 | "special operation exception") |
429 | DO_ERROR_INFO(SIGILL, "translation exception", translation_exception, | 424 | DO_ERROR_INFO(translation_exception, SIGILL, ILL_ILLOPN, |
430 | ILL_ILLOPN, get_check_address(regs)) | 425 | "translation exception") |
431 | 426 | ||
432 | static inline void | 427 | static inline void do_fp_trap(struct pt_regs *regs, void __user *location, |
433 | do_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 | ||
461 | static void illegal_op(struct pt_regs * regs, long interruption_code) | 454 | static 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 |
545 | asmlinkage void | 532 | asmlinkage void specification_exception(struct pt_regs *regs, |
546 | specification_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 |
607 | DO_ERROR_INFO(SIGILL, "specification exception", specification_exception, | 588 | DO_ERROR_INFO(specification_exception, SIGILL, ILL_ILLOPN, |
608 | ILL_ILLOPN, get_check_address(regs)); | 589 | "specification exception"); |
609 | #endif | 590 | #endif |
610 | 591 | ||
611 | static void data_exception(struct pt_regs * regs, long interruption_code) | 592 | static 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 | ||
701 | static void space_switch_exception(struct pt_regs * regs, long int_code) | 675 | static 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 | ||
716 | asmlinkage void kernel_stack_overflow(struct pt_regs * regs) | 691 | asmlinkage 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 | */ |
85 | static void vdso_init_data(struct vdso_data *vd) | 85 | static 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 | */ |
317 | static void do_cpu_timer_interrupt(__u16 error_code) | 317 | static 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; |