aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2011-12-27 05:27:15 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2011-12-27 05:27:12 -0500
commitc5328901aa1db134325607d65527742d8be07f7d (patch)
tree9643cf253b758d16918cd8591bd9dde022c39673 /arch/s390
parent3b7f993394db7c446c251fb8eb32ec501a330acc (diff)
[S390] entry[64].S improvements
Another round of cleanup for entry[64].S, in particular the program check handler looks more reasonable now. The code size for the 31 bit kernel has been reduced by 616 byte and by 528 byte for the 64 bit version. Even better the code is a bit faster as well. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/include/asm/lowcore.h142
-rw-r--r--arch/s390/kernel/asm-offsets.c4
-rw-r--r--arch/s390/kernel/base.S16
-rw-r--r--arch/s390/kernel/entry.S1099
-rw-r--r--arch/s390/kernel/entry64.S968
-rw-r--r--arch/s390/kernel/head.S4
-rw-r--r--arch/s390/kernel/reipl64.S4
-rw-r--r--arch/s390/kernel/smp.c2
8 files changed, 1002 insertions, 1237 deletions
diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h
index 3b97964e0e96..707f2306725b 100644
--- a/arch/s390/include/asm/lowcore.h
+++ b/arch/s390/include/asm/lowcore.h
@@ -97,47 +97,52 @@ struct _lowcore {
97 __u32 gpregs_save_area[16]; /* 0x0180 */ 97 __u32 gpregs_save_area[16]; /* 0x0180 */
98 __u32 cregs_save_area[16]; /* 0x01c0 */ 98 __u32 cregs_save_area[16]; /* 0x01c0 */
99 99
100 /* Save areas. */
101 __u32 save_area_sync[8]; /* 0x0200 */
102 __u32 save_area_async[8]; /* 0x0220 */
103 __u32 save_area_restart[1]; /* 0x0240 */
104 __u8 pad_0x0244[0x0248-0x0244]; /* 0x0244 */
105
100 /* Return psws. */ 106 /* Return psws. */
101 __u32 save_area[16]; /* 0x0200 */ 107 psw_t return_psw; /* 0x0248 */
102 psw_t return_psw; /* 0x0240 */ 108 psw_t return_mcck_psw; /* 0x0250 */
103 psw_t return_mcck_psw; /* 0x0248 */
104 109
105 /* CPU time accounting values */ 110 /* CPU time accounting values */
106 __u64 sync_enter_timer; /* 0x0250 */ 111 __u64 sync_enter_timer; /* 0x0258 */
107 __u64 async_enter_timer; /* 0x0258 */ 112 __u64 async_enter_timer; /* 0x0260 */
108 __u64 mcck_enter_timer; /* 0x0260 */ 113 __u64 mcck_enter_timer; /* 0x0268 */
109 __u64 exit_timer; /* 0x0268 */ 114 __u64 exit_timer; /* 0x0270 */
110 __u64 user_timer; /* 0x0270 */ 115 __u64 user_timer; /* 0x0278 */
111 __u64 system_timer; /* 0x0278 */ 116 __u64 system_timer; /* 0x0280 */
112 __u64 steal_timer; /* 0x0280 */ 117 __u64 steal_timer; /* 0x0288 */
113 __u64 last_update_timer; /* 0x0288 */ 118 __u64 last_update_timer; /* 0x0290 */
114 __u64 last_update_clock; /* 0x0290 */ 119 __u64 last_update_clock; /* 0x0298 */
115 120
116 /* Current process. */ 121 /* Current process. */
117 __u32 current_task; /* 0x0298 */ 122 __u32 current_task; /* 0x02a0 */
118 __u32 thread_info; /* 0x029c */ 123 __u32 thread_info; /* 0x02a4 */
119 __u32 kernel_stack; /* 0x02a0 */ 124 __u32 kernel_stack; /* 0x02a8 */
120 125
121 /* Interrupt and panic stack. */ 126 /* Interrupt and panic stack. */
122 __u32 async_stack; /* 0x02a4 */ 127 __u32 async_stack; /* 0x02ac */
123 __u32 panic_stack; /* 0x02a8 */ 128 __u32 panic_stack; /* 0x02b0 */
124 129
125 /* Address space pointer. */ 130 /* Address space pointer. */
126 __u32 kernel_asce; /* 0x02ac */ 131 __u32 kernel_asce; /* 0x02b4 */
127 __u32 user_asce; /* 0x02b0 */ 132 __u32 user_asce; /* 0x02b8 */
128 __u32 current_pid; /* 0x02b4 */ 133 __u32 current_pid; /* 0x02bc */
129 134
130 /* SMP info area */ 135 /* SMP info area */
131 __u32 cpu_nr; /* 0x02b8 */ 136 __u32 cpu_nr; /* 0x02c0 */
132 __u32 softirq_pending; /* 0x02bc */ 137 __u32 softirq_pending; /* 0x02c4 */
133 __u32 percpu_offset; /* 0x02c0 */ 138 __u32 percpu_offset; /* 0x02c8 */
134 __u32 ext_call_fast; /* 0x02c4 */ 139 __u32 ext_call_fast; /* 0x02cc */
135 __u64 int_clock; /* 0x02c8 */ 140 __u64 int_clock; /* 0x02d0 */
136 __u64 mcck_clock; /* 0x02d0 */ 141 __u64 mcck_clock; /* 0x02d8 */
137 __u64 clock_comparator; /* 0x02d8 */ 142 __u64 clock_comparator; /* 0x02e0 */
138 __u32 machine_flags; /* 0x02e0 */ 143 __u32 machine_flags; /* 0x02e8 */
139 __u32 ftrace_func; /* 0x02e4 */ 144 __u32 ftrace_func; /* 0x02ec */
140 __u8 pad_0x02e8[0x0300-0x02e8]; /* 0x02e8 */ 145 __u8 pad_0x02f8[0x0300-0x02f0]; /* 0x02f0 */
141 146
142 /* Interrupt response block */ 147 /* Interrupt response block */
143 __u8 irb[64]; /* 0x0300 */ 148 __u8 irb[64]; /* 0x0300 */
@@ -229,57 +234,62 @@ struct _lowcore {
229 psw_t mcck_new_psw; /* 0x01e0 */ 234 psw_t mcck_new_psw; /* 0x01e0 */
230 psw_t io_new_psw; /* 0x01f0 */ 235 psw_t io_new_psw; /* 0x01f0 */
231 236
232 /* Entry/exit save area & return psws. */ 237 /* Save areas. */
233 __u64 save_area[16]; /* 0x0200 */ 238 __u64 save_area_sync[8]; /* 0x0200 */
234 psw_t return_psw; /* 0x0280 */ 239 __u64 save_area_async[8]; /* 0x0240 */
235 psw_t return_mcck_psw; /* 0x0290 */ 240 __u64 save_area_restart[1]; /* 0x0280 */
241 __u8 pad_0x0288[0x0290-0x0288]; /* 0x0288 */
242
243 /* Return psws. */
244 psw_t return_psw; /* 0x0290 */
245 psw_t return_mcck_psw; /* 0x02a0 */
236 246
237 /* CPU accounting and timing values. */ 247 /* CPU accounting and timing values. */
238 __u64 sync_enter_timer; /* 0x02a0 */ 248 __u64 sync_enter_timer; /* 0x02b0 */
239 __u64 async_enter_timer; /* 0x02a8 */ 249 __u64 async_enter_timer; /* 0x02b8 */
240 __u64 mcck_enter_timer; /* 0x02b0 */ 250 __u64 mcck_enter_timer; /* 0x02c0 */
241 __u64 exit_timer; /* 0x02b8 */ 251 __u64 exit_timer; /* 0x02c8 */
242 __u64 user_timer; /* 0x02c0 */ 252 __u64 user_timer; /* 0x02d0 */
243 __u64 system_timer; /* 0x02c8 */ 253 __u64 system_timer; /* 0x02d8 */
244 __u64 steal_timer; /* 0x02d0 */ 254 __u64 steal_timer; /* 0x02e0 */
245 __u64 last_update_timer; /* 0x02d8 */ 255 __u64 last_update_timer; /* 0x02e8 */
246 __u64 last_update_clock; /* 0x02e0 */ 256 __u64 last_update_clock; /* 0x02f0 */
247 257
248 /* Current process. */ 258 /* Current process. */
249 __u64 current_task; /* 0x02e8 */ 259 __u64 current_task; /* 0x02f8 */
250 __u64 thread_info; /* 0x02f0 */ 260 __u64 thread_info; /* 0x0300 */
251 __u64 kernel_stack; /* 0x02f8 */ 261 __u64 kernel_stack; /* 0x0308 */
252 262
253 /* Interrupt and panic stack. */ 263 /* Interrupt and panic stack. */
254 __u64 async_stack; /* 0x0300 */ 264 __u64 async_stack; /* 0x0310 */
255 __u64 panic_stack; /* 0x0308 */ 265 __u64 panic_stack; /* 0x0318 */
256 266
257 /* Address space pointer. */ 267 /* Address space pointer. */
258 __u64 kernel_asce; /* 0x0310 */ 268 __u64 kernel_asce; /* 0x0320 */
259 __u64 user_asce; /* 0x0318 */ 269 __u64 user_asce; /* 0x0328 */
260 __u64 current_pid; /* 0x0320 */ 270 __u64 current_pid; /* 0x0330 */
261 271
262 /* SMP info area */ 272 /* SMP info area */
263 __u32 cpu_nr; /* 0x0328 */ 273 __u32 cpu_nr; /* 0x0338 */
264 __u32 softirq_pending; /* 0x032c */ 274 __u32 softirq_pending; /* 0x033c */
265 __u64 percpu_offset; /* 0x0330 */ 275 __u64 percpu_offset; /* 0x0340 */
266 __u64 ext_call_fast; /* 0x0338 */ 276 __u64 ext_call_fast; /* 0x0348 */
267 __u64 int_clock; /* 0x0340 */ 277 __u64 int_clock; /* 0x0350 */
268 __u64 mcck_clock; /* 0x0348 */ 278 __u64 mcck_clock; /* 0x0358 */
269 __u64 clock_comparator; /* 0x0350 */ 279 __u64 clock_comparator; /* 0x0360 */
270 __u64 vdso_per_cpu_data; /* 0x0358 */ 280 __u64 vdso_per_cpu_data; /* 0x0368 */
271 __u64 machine_flags; /* 0x0360 */ 281 __u64 machine_flags; /* 0x0370 */
272 __u64 ftrace_func; /* 0x0368 */ 282 __u64 ftrace_func; /* 0x0378 */
273 __u64 gmap; /* 0x0370 */ 283 __u64 gmap; /* 0x0380 */
274 __u8 pad_0x0378[0x0380-0x0378]; /* 0x0378 */ 284 __u8 pad_0x0388[0x0400-0x0388]; /* 0x0388 */
275 285
276 /* Interrupt response block. */ 286 /* Interrupt response block. */
277 __u8 irb[64]; /* 0x0380 */ 287 __u8 irb[64]; /* 0x0400 */
278 288
279 /* Per cpu primary space access list */ 289 /* Per cpu primary space access list */
280 __u32 paste[16]; /* 0x03c0 */ 290 __u32 paste[16]; /* 0x0440 */
281 291
282 __u8 pad_0x0400[0x0e00-0x0400]; /* 0x0400 */ 292 __u8 pad_0x0480[0x0e00-0x0480]; /* 0x0480 */
283 293
284 /* 294 /*
285 * 0xe00 contains the address of the IPL Parameter Information 295 * 0xe00 contains the address of the IPL Parameter Information
diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c
index 0717363033eb..c1a56ba5f848 100644
--- a/arch/s390/kernel/asm-offsets.c
+++ b/arch/s390/kernel/asm-offsets.c
@@ -108,7 +108,9 @@ int main(void)
108 DEFINE(__LC_PGM_NEW_PSW, offsetof(struct _lowcore, program_new_psw)); 108 DEFINE(__LC_PGM_NEW_PSW, offsetof(struct _lowcore, program_new_psw));
109 DEFINE(__LC_MCK_NEW_PSW, offsetof(struct _lowcore, mcck_new_psw)); 109 DEFINE(__LC_MCK_NEW_PSW, offsetof(struct _lowcore, mcck_new_psw));
110 DEFINE(__LC_IO_NEW_PSW, offsetof(struct _lowcore, io_new_psw)); 110 DEFINE(__LC_IO_NEW_PSW, offsetof(struct _lowcore, io_new_psw));
111 DEFINE(__LC_SAVE_AREA, offsetof(struct _lowcore, save_area)); 111 DEFINE(__LC_SAVE_AREA_SYNC, offsetof(struct _lowcore, save_area_sync));
112 DEFINE(__LC_SAVE_AREA_ASYNC, offsetof(struct _lowcore, save_area_async));
113 DEFINE(__LC_SAVE_AREA_RESTART, offsetof(struct _lowcore, save_area_restart));
112 DEFINE(__LC_RETURN_PSW, offsetof(struct _lowcore, return_psw)); 114 DEFINE(__LC_RETURN_PSW, offsetof(struct _lowcore, return_psw));
113 DEFINE(__LC_RETURN_MCCK_PSW, offsetof(struct _lowcore, return_mcck_psw)); 115 DEFINE(__LC_RETURN_MCCK_PSW, offsetof(struct _lowcore, return_mcck_psw));
114 DEFINE(__LC_SYNC_ENTER_TIMER, offsetof(struct _lowcore, sync_enter_timer)); 116 DEFINE(__LC_SYNC_ENTER_TIMER, offsetof(struct _lowcore, sync_enter_timer));
diff --git a/arch/s390/kernel/base.S b/arch/s390/kernel/base.S
index f8828d38fa6e..3aa4d00aaf50 100644
--- a/arch/s390/kernel/base.S
+++ b/arch/s390/kernel/base.S
@@ -33,7 +33,7 @@ s390_base_mcck_handler_fn:
33 .previous 33 .previous
34 34
35ENTRY(s390_base_ext_handler) 35ENTRY(s390_base_ext_handler)
36 stmg %r0,%r15,__LC_SAVE_AREA 36 stmg %r0,%r15,__LC_SAVE_AREA_ASYNC
37 basr %r13,0 37 basr %r13,0
380: aghi %r15,-STACK_FRAME_OVERHEAD 380: aghi %r15,-STACK_FRAME_OVERHEAD
39 larl %r1,s390_base_ext_handler_fn 39 larl %r1,s390_base_ext_handler_fn
@@ -41,7 +41,7 @@ ENTRY(s390_base_ext_handler)
41 ltgr %r1,%r1 41 ltgr %r1,%r1
42 jz 1f 42 jz 1f
43 basr %r14,%r1 43 basr %r14,%r1
441: lmg %r0,%r15,__LC_SAVE_AREA 441: lmg %r0,%r15,__LC_SAVE_AREA_ASYNC
45 ni __LC_EXT_OLD_PSW+1,0xfd # clear wait state bit 45 ni __LC_EXT_OLD_PSW+1,0xfd # clear wait state bit
46 lpswe __LC_EXT_OLD_PSW 46 lpswe __LC_EXT_OLD_PSW
47 47
@@ -53,7 +53,7 @@ s390_base_ext_handler_fn:
53 .previous 53 .previous
54 54
55ENTRY(s390_base_pgm_handler) 55ENTRY(s390_base_pgm_handler)
56 stmg %r0,%r15,__LC_SAVE_AREA 56 stmg %r0,%r15,__LC_SAVE_AREA_SYNC
57 basr %r13,0 57 basr %r13,0
580: aghi %r15,-STACK_FRAME_OVERHEAD 580: aghi %r15,-STACK_FRAME_OVERHEAD
59 larl %r1,s390_base_pgm_handler_fn 59 larl %r1,s390_base_pgm_handler_fn
@@ -61,7 +61,7 @@ ENTRY(s390_base_pgm_handler)
61 ltgr %r1,%r1 61 ltgr %r1,%r1
62 jz 1f 62 jz 1f
63 basr %r14,%r1 63 basr %r14,%r1
64 lmg %r0,%r15,__LC_SAVE_AREA 64 lmg %r0,%r15,__LC_SAVE_AREA_SYNC
65 lpswe __LC_PGM_OLD_PSW 65 lpswe __LC_PGM_OLD_PSW
661: lpswe disabled_wait_psw-0b(%r13) 661: lpswe disabled_wait_psw-0b(%r13)
67 67
@@ -142,7 +142,7 @@ s390_base_mcck_handler_fn:
142 .previous 142 .previous
143 143
144ENTRY(s390_base_ext_handler) 144ENTRY(s390_base_ext_handler)
145 stm %r0,%r15,__LC_SAVE_AREA 145 stm %r0,%r15,__LC_SAVE_AREA_ASYNC
146 basr %r13,0 146 basr %r13,0
1470: ahi %r15,-STACK_FRAME_OVERHEAD 1470: ahi %r15,-STACK_FRAME_OVERHEAD
148 l %r1,2f-0b(%r13) 148 l %r1,2f-0b(%r13)
@@ -150,7 +150,7 @@ ENTRY(s390_base_ext_handler)
150 ltr %r1,%r1 150 ltr %r1,%r1
151 jz 1f 151 jz 1f
152 basr %r14,%r1 152 basr %r14,%r1
1531: lm %r0,%r15,__LC_SAVE_AREA 1531: lm %r0,%r15,__LC_SAVE_AREA_ASYNC
154 ni __LC_EXT_OLD_PSW+1,0xfd # clear wait state bit 154 ni __LC_EXT_OLD_PSW+1,0xfd # clear wait state bit
155 lpsw __LC_EXT_OLD_PSW 155 lpsw __LC_EXT_OLD_PSW
156 156
@@ -164,7 +164,7 @@ s390_base_ext_handler_fn:
164 .previous 164 .previous
165 165
166ENTRY(s390_base_pgm_handler) 166ENTRY(s390_base_pgm_handler)
167 stm %r0,%r15,__LC_SAVE_AREA 167 stm %r0,%r15,__LC_SAVE_AREA_SYNC
168 basr %r13,0 168 basr %r13,0
1690: ahi %r15,-STACK_FRAME_OVERHEAD 1690: ahi %r15,-STACK_FRAME_OVERHEAD
170 l %r1,2f-0b(%r13) 170 l %r1,2f-0b(%r13)
@@ -172,7 +172,7 @@ ENTRY(s390_base_pgm_handler)
172 ltr %r1,%r1 172 ltr %r1,%r1
173 jz 1f 173 jz 1f
174 basr %r14,%r1 174 basr %r14,%r1
175 lm %r0,%r15,__LC_SAVE_AREA 175 lm %r0,%r15,__LC_SAVE_AREA_SYNC
176 lpsw __LC_PGM_OLD_PSW 176 lpsw __LC_PGM_OLD_PSW
177 177
1781: lpsw disabled_wait_psw-0b(%r13) 1781: lpsw disabled_wait_psw-0b(%r13)
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index b13157057e02..c2773cff89c3 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -19,32 +19,22 @@
19#include <asm/unistd.h> 19#include <asm/unistd.h>
20#include <asm/page.h> 20#include <asm/page.h>
21 21
22/* 22__PT_R0 = __PT_GPRS
23 * Stack layout for the system_call stack entry. 23__PT_R1 = __PT_GPRS + 4
24 * The first few entries are identical to the user_regs_struct. 24__PT_R2 = __PT_GPRS + 8
25 */ 25__PT_R3 = __PT_GPRS + 12
26SP_PTREGS = STACK_FRAME_OVERHEAD 26__PT_R4 = __PT_GPRS + 16
27SP_ARGS = STACK_FRAME_OVERHEAD + __PT_ARGS 27__PT_R5 = __PT_GPRS + 20
28SP_PSW = STACK_FRAME_OVERHEAD + __PT_PSW 28__PT_R6 = __PT_GPRS + 24
29SP_R0 = STACK_FRAME_OVERHEAD + __PT_GPRS 29__PT_R7 = __PT_GPRS + 28
30SP_R1 = STACK_FRAME_OVERHEAD + __PT_GPRS + 4 30__PT_R8 = __PT_GPRS + 32
31SP_R2 = STACK_FRAME_OVERHEAD + __PT_GPRS + 8 31__PT_R9 = __PT_GPRS + 36
32SP_R3 = STACK_FRAME_OVERHEAD + __PT_GPRS + 12 32__PT_R10 = __PT_GPRS + 40
33SP_R4 = STACK_FRAME_OVERHEAD + __PT_GPRS + 16 33__PT_R11 = __PT_GPRS + 44
34SP_R5 = STACK_FRAME_OVERHEAD + __PT_GPRS + 20 34__PT_R12 = __PT_GPRS + 48
35SP_R6 = STACK_FRAME_OVERHEAD + __PT_GPRS + 24 35__PT_R13 = __PT_GPRS + 524
36SP_R7 = STACK_FRAME_OVERHEAD + __PT_GPRS + 28 36__PT_R14 = __PT_GPRS + 56
37SP_R8 = STACK_FRAME_OVERHEAD + __PT_GPRS + 32 37__PT_R15 = __PT_GPRS + 60
38SP_R9 = STACK_FRAME_OVERHEAD + __PT_GPRS + 36
39SP_R10 = STACK_FRAME_OVERHEAD + __PT_GPRS + 40
40SP_R11 = STACK_FRAME_OVERHEAD + __PT_GPRS + 44
41SP_R12 = STACK_FRAME_OVERHEAD + __PT_GPRS + 48
42SP_R13 = STACK_FRAME_OVERHEAD + __PT_GPRS + 52
43SP_R14 = STACK_FRAME_OVERHEAD + __PT_GPRS + 56
44SP_R15 = STACK_FRAME_OVERHEAD + __PT_GPRS + 60
45SP_ORIG_R2 = STACK_FRAME_OVERHEAD + __PT_ORIG_GPR2
46SP_SVC_CODE = STACK_FRAME_OVERHEAD + __PT_SVC_CODE
47SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE
48 38
49_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ 39_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
50 _TIF_MCCK_PENDING | _TIF_PER_TRAP ) 40 _TIF_MCCK_PENDING | _TIF_PER_TRAP )
@@ -58,133 +48,91 @@ STACK_SIZE = 1 << STACK_SHIFT
58 48
59#define BASED(name) name-system_call(%r13) 49#define BASED(name) name-system_call(%r13)
60 50
61#ifdef CONFIG_TRACE_IRQFLAGS
62 .macro TRACE_IRQS_ON 51 .macro TRACE_IRQS_ON
52#ifdef CONFIG_TRACE_IRQFLAGS
63 basr %r2,%r0 53 basr %r2,%r0
64 l %r1,BASED(.Ltrace_irq_on_caller) 54 l %r1,BASED(.Lhardirqs_on)
65 basr %r14,%r1 55 basr %r14,%r1 # call trace_hardirqs_on_caller
56#endif
66 .endm 57 .endm
67 58
68 .macro TRACE_IRQS_OFF 59 .macro TRACE_IRQS_OFF
60#ifdef CONFIG_TRACE_IRQFLAGS
69 basr %r2,%r0 61 basr %r2,%r0
70 l %r1,BASED(.Ltrace_irq_off_caller) 62 l %r1,BASED(.Lhardirqs_off)
71 basr %r14,%r1 63 basr %r14,%r1 # call trace_hardirqs_off_caller
72 .endm
73#else
74#define TRACE_IRQS_ON
75#define TRACE_IRQS_OFF
76#endif 64#endif
65 .endm
77 66
78#ifdef CONFIG_LOCKDEP
79 .macro LOCKDEP_SYS_EXIT 67 .macro LOCKDEP_SYS_EXIT
80 tm SP_PSW+1(%r15),0x01 # returning to user ? 68#ifdef CONFIG_LOCKDEP
81 jz 0f 69 tm __PT_PSW+1(%r11),0x01 # returning to user ?
70 jz .+10
82 l %r1,BASED(.Llockdep_sys_exit) 71 l %r1,BASED(.Llockdep_sys_exit)
83 basr %r14,%r1 72 basr %r14,%r1 # call lockdep_sys_exit
840:
85 .endm
86#else
87#define LOCKDEP_SYS_EXIT
88#endif 73#endif
89
90/*
91 * Register usage in interrupt handlers:
92 * R9 - pointer to current task structure
93 * R13 - pointer to literal pool
94 * R14 - return register for function calls
95 * R15 - kernel stack pointer
96 */
97
98 .macro UPDATE_VTIME lc_from,lc_to,lc_sum
99 lm %r10,%r11,\lc_from
100 sl %r10,\lc_to
101 sl %r11,\lc_to+4
102 bc 3,BASED(0f)
103 sl %r10,BASED(.Lc_1)
1040: al %r10,\lc_sum
105 al %r11,\lc_sum+4
106 bc 12,BASED(1f)
107 al %r10,BASED(.Lc_1)
1081: stm %r10,%r11,\lc_sum
109 .endm
110
111 .macro SAVE_ALL_SVC psworg,savearea
112 stm %r12,%r15,\savearea
113 l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13
114 l %r15,__LC_KERNEL_STACK # problem state -> load ksp
115 s %r15,BASED(.Lc_spsize) # make room for registers & psw
116 .endm
117
118 .macro SAVE_ALL_BASE savearea
119 stm %r12,%r15,\savearea
120 l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13
121 .endm 74 .endm
122 75
123 .macro SAVE_ALL_PGM psworg,savearea 76 .macro CHECK_STACK stacksize,savearea
124 tm \psworg+1,0x01 # test problem state bit
125#ifdef CONFIG_CHECK_STACK 77#ifdef CONFIG_CHECK_STACK
126 bnz BASED(1f) 78 tml %r15,\stacksize - CONFIG_STACK_GUARD
127 tml %r15,STACK_SIZE - CONFIG_STACK_GUARD 79 la %r14,\savearea
128 bnz BASED(2f) 80 jz stack_overflow
129 la %r12,\psworg
130 b BASED(stack_overflow)
131#else
132 bz BASED(2f)
133#endif 81#endif
1341: l %r15,__LC_KERNEL_STACK # problem state -> load ksp
1352: s %r15,BASED(.Lc_spsize) # make room for registers & psw
136 .endm 82 .endm
137 83
138 .macro SAVE_ALL_ASYNC psworg,savearea 84 .macro SWITCH_ASYNC savearea,stack,shift
139 stm %r12,%r15,\savearea 85 tmh %r8,0x0001 # interrupting from user ?
140 l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13 86 jnz 1f
141 la %r12,\psworg 87 lr %r14,%r9
142 tm \psworg+1,0x01 # test problem state bit 88 sl %r14,BASED(.Lcritical_start)
143 bnz BASED(1f) # from user -> load async stack 89 cl %r14,BASED(.Lcritical_length)
144 clc \psworg+4(4),BASED(.Lcritical_end) 90 jhe 0f
145 bhe BASED(0f) 91 la %r11,\savearea # inside critical section, do cleanup
146 clc \psworg+4(4),BASED(.Lcritical_start) 92 bras %r14,cleanup_critical
147 bl BASED(0f) 93 tmh %r8,0x0001 # retest problem state after cleanup
148 l %r14,BASED(.Lcleanup_critical) 94 jnz 1f
149 basr %r14,%r14 950: l %r14,\stack # are we already on the target stack?
150 tm 1(%r12),0x01 # retest problem state after cleanup
151 bnz BASED(1f)
1520: l %r14,__LC_ASYNC_STACK # are we already on the async stack ?
153 slr %r14,%r15 96 slr %r14,%r15
154 sra %r14,STACK_SHIFT 97 sra %r14,\shift
155#ifdef CONFIG_CHECK_STACK 98 jnz 1f
156 bnz BASED(1f) 99 CHECK_STACK 1<<\shift,\savearea
157 tml %r15,STACK_SIZE - CONFIG_STACK_GUARD 100 j 2f
158 bnz BASED(2f) 1011: l %r15,\stack # load target stack
159 b BASED(stack_overflow) 1022: ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
160#else 103 la %r11,STACK_FRAME_OVERHEAD(%r15)
161 bz BASED(2f)
162#endif
1631: l %r15,__LC_ASYNC_STACK
1642: s %r15,BASED(.Lc_spsize) # make room for registers & psw
165 .endm 104 .endm
166 105
167 .macro CREATE_STACK_FRAME savearea 106 .macro ADD64 high,low,timer
168 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) 107 al \high,\timer
169 st %r2,SP_ORIG_R2(%r15) # store original content of gpr 2 108 al \low,\timer+4
170 mvc SP_R12(16,%r15),\savearea # move %r12-%r15 to stack 109 brc 12,.+8
171 stm %r0,%r11,SP_R0(%r15) # store gprs %r0-%r11 to kernel stack 110 ahi \high,1
172 .endm 111 .endm
173 112
174 .macro RESTORE_ALL psworg,sync 113 .macro SUB64 high,low,timer
175 mvc \psworg(8),SP_PSW(%r15) # move user PSW to lowcore 114 sl \high,\timer
176 .if !\sync 115 sl \low,\timer+4
177 ni \psworg+1,0xfd # clear wait state bit 116 brc 3,.+8
178 .endif 117 ahi \high,-1
179 lm %r0,%r15,SP_R0(%r15) # load gprs 0-15 of user 118 .endm
180 stpt __LC_EXIT_TIMER 119
181 lpsw \psworg # back to caller 120 .macro UPDATE_VTIME high,low,enter_timer
121 lm \high,\low,__LC_EXIT_TIMER
122 SUB64 \high,\low,\enter_timer
123 ADD64 \high,\low,__LC_USER_TIMER
124 stm \high,\low,__LC_USER_TIMER
125 lm \high,\low,__LC_LAST_UPDATE_TIMER
126 SUB64 \high,\low,__LC_EXIT_TIMER
127 ADD64 \high,\low,__LC_SYSTEM_TIMER
128 stm \high,\low,__LC_SYSTEM_TIMER
129 mvc __LC_LAST_UPDATE_TIMER(8),\enter_timer
182 .endm 130 .endm
183 131
184 .macro REENABLE_IRQS 132 .macro REENABLE_IRQS
185 mvc __SF_EMPTY(1,%r15),SP_PSW(%r15) 133 st %r8,__LC_RETURN_PSW
186 ni __SF_EMPTY(%r15),0xbf 134 ni __LC_RETURN_PSW,0xbf
187 ssm __SF_EMPTY(%r15) 135 ssm __LC_RETURN_PSW
188 .endm 136 .endm
189 137
190 .section .kprobes.text, "ax" 138 .section .kprobes.text, "ax"
@@ -197,14 +145,13 @@ STACK_SIZE = 1 << STACK_SHIFT
197 * gpr2 = prev 145 * gpr2 = prev
198 */ 146 */
199ENTRY(__switch_to) 147ENTRY(__switch_to)
200 basr %r1,0 148 l %r4,__THREAD_info(%r2) # get thread_info of prev
2010: l %r4,__THREAD_info(%r2) # get thread_info of prev
202 l %r5,__THREAD_info(%r3) # get thread_info of next 149 l %r5,__THREAD_info(%r3) # get thread_info of next
203 tm __TI_flags+3(%r4),_TIF_MCCK_PENDING # machine check pending? 150 tm __TI_flags+3(%r4),_TIF_MCCK_PENDING # machine check pending?
204 bz 1f-0b(%r1) 151 jz 0f
205 ni __TI_flags+3(%r4),255-_TIF_MCCK_PENDING # clear flag in prev 152 ni __TI_flags+3(%r4),255-_TIF_MCCK_PENDING # clear flag in prev
206 oi __TI_flags+3(%r5),_TIF_MCCK_PENDING # set it in next 153 oi __TI_flags+3(%r5),_TIF_MCCK_PENDING # set it in next
2071: stm %r6,%r15,__SF_GPRS(%r15) # store gprs of prev task 1540: stm %r6,%r15,__SF_GPRS(%r15) # store gprs of prev task
208 st %r15,__THREAD_ksp(%r2) # store kernel stack of prev 155 st %r15,__THREAD_ksp(%r2) # store kernel stack of prev
209 l %r15,__THREAD_ksp(%r3) # load kernel stack of next 156 l %r15,__THREAD_ksp(%r3) # load kernel stack of next
210 lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4 157 lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4
@@ -224,48 +171,55 @@ __critical_start:
224 171
225ENTRY(system_call) 172ENTRY(system_call)
226 stpt __LC_SYNC_ENTER_TIMER 173 stpt __LC_SYNC_ENTER_TIMER
227sysc_saveall: 174sysc_stm:
228 SAVE_ALL_SVC __LC_SVC_OLD_PSW,__LC_SAVE_AREA 175 stm %r8,%r15,__LC_SAVE_AREA_SYNC
229 CREATE_STACK_FRAME __LC_SAVE_AREA 176 l %r12,__LC_THREAD_INFO
230 l %r12,__LC_THREAD_INFO # load pointer to thread_info struct 177 l %r13,__LC_SVC_NEW_PSW+4
231 mvc SP_PSW(8,%r15),__LC_SVC_OLD_PSW 178sysc_per:
232 mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC 179 l %r15,__LC_KERNEL_STACK
233 oi __TI_flags+3(%r12),_TIF_SYSCALL 180 ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
181 la %r11,STACK_FRAME_OVERHEAD(%r15) # pointer to pt_regs
234sysc_vtime: 182sysc_vtime:
235 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 183 UPDATE_VTIME %r8,%r9,__LC_SYNC_ENTER_TIMER
236sysc_stime: 184 stm %r0,%r7,__PT_R0(%r11)
237 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 185 mvc __PT_R8(32,%r11),__LC_SAVE_AREA_SYNC
238sysc_update: 186 mvc __PT_PSW(8,%r11),__LC_SVC_OLD_PSW
239 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 187 mvc __PT_SVC_CODE(4,%r11),__LC_SVC_ILC
240sysc_do_svc: 188sysc_do_svc:
241 xr %r7,%r7 189 oi __TI_flags+3(%r12),_TIF_SYSCALL
242 icm %r7,3,SP_SVC_CODE+2(%r15)# load svc number and test for svc 0 190 lh %r8,__PT_SVC_CODE+2(%r11)
243 bnz BASED(sysc_nr_ok) # svc number > 0 191 sla %r8,2 # shift and test for svc0
192 jnz sysc_nr_ok
244 # svc 0: system call number in %r1 193 # svc 0: system call number in %r1
245 cl %r1,BASED(.Lnr_syscalls) 194 cl %r1,BASED(.Lnr_syscalls)
246 bnl BASED(sysc_nr_ok) 195 jnl sysc_nr_ok
247 sth %r1,SP_SVC_CODE+2(%r15) 196 sth %r1,__PT_SVC_CODE+2(%r11)
248 lr %r7,%r1 # copy svc number to %r7 197 lr %r8,%r1
198 sla %r8,2
249sysc_nr_ok: 199sysc_nr_ok:
250 sll %r7,2 # svc number *4 200 l %r10,BASED(.Lsys_call_table) # 31 bit system call table
251 l %r10,BASED(.Lsysc_table) 201 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
202 st %r2,__PT_ORIG_GPR2(%r11)
203 st %r7,STACK_FRAME_OVERHEAD(%r15)
204 l %r9,0(%r8,%r10) # get system call addr.
252 tm __TI_flags+2(%r12),_TIF_TRACE >> 8 205 tm __TI_flags+2(%r12),_TIF_TRACE >> 8
253 mvc SP_ARGS(4,%r15),SP_R7(%r15) 206 jnz sysc_tracesys
254 l %r8,0(%r7,%r10) # get system call addr. 207 basr %r14,%r9 # call sys_xxxx
255 bnz BASED(sysc_tracesys) 208 st %r2,__PT_R2(%r11) # store return value
256 basr %r14,%r8 # call sys_xxxx
257 st %r2,SP_R2(%r15) # store return value (change R2 on stack)
258 209
259sysc_return: 210sysc_return:
260 LOCKDEP_SYS_EXIT 211 LOCKDEP_SYS_EXIT
261sysc_tif: 212sysc_tif:
262 tm SP_PSW+1(%r15),0x01 # returning to user ? 213 tm __PT_PSW+1(%r11),0x01 # returning to user ?
263 bno BASED(sysc_restore) 214 jno sysc_restore
264 tm __TI_flags+3(%r12),_TIF_WORK_SVC 215 tm __TI_flags+3(%r12),_TIF_WORK_SVC
265 bnz BASED(sysc_work) # there is work to do (signals etc.) 216 jnz sysc_work # check for work
266 ni __TI_flags+3(%r12),255-_TIF_SYSCALL 217 ni __TI_flags+3(%r12),255-_TIF_SYSCALL
267sysc_restore: 218sysc_restore:
268 RESTORE_ALL __LC_RETURN_PSW,1 219 mvc __LC_RETURN_PSW(8),__PT_PSW(%r11)
220 stpt __LC_EXIT_TIMER
221 lm %r0,%r15,__PT_R0(%r11)
222 lpsw __LC_RETURN_PSW
269sysc_done: 223sysc_done:
270 224
271# 225#
@@ -273,16 +227,16 @@ sysc_done:
273# 227#
274sysc_work: 228sysc_work:
275 tm __TI_flags+3(%r12),_TIF_MCCK_PENDING 229 tm __TI_flags+3(%r12),_TIF_MCCK_PENDING
276 bo BASED(sysc_mcck_pending) 230 jo sysc_mcck_pending
277 tm __TI_flags+3(%r12),_TIF_NEED_RESCHED 231 tm __TI_flags+3(%r12),_TIF_NEED_RESCHED
278 bo BASED(sysc_reschedule) 232 jo sysc_reschedule
279 tm __TI_flags+3(%r12),_TIF_SIGPENDING 233 tm __TI_flags+3(%r12),_TIF_SIGPENDING
280 bo BASED(sysc_sigpending) 234 jo sysc_sigpending
281 tm __TI_flags+3(%r12),_TIF_NOTIFY_RESUME 235 tm __TI_flags+3(%r12),_TIF_NOTIFY_RESUME
282 bo BASED(sysc_notify_resume) 236 jo sysc_notify_resume
283 tm __TI_flags+3(%r12),_TIF_PER_TRAP 237 tm __TI_flags+3(%r12),_TIF_PER_TRAP
284 bo BASED(sysc_singlestep) 238 jo sysc_singlestep
285 b BASED(sysc_return) # beware of critical section cleanup 239 j sysc_return # beware of critical section cleanup
286 240
287# 241#
288# _TIF_NEED_RESCHED is set, call schedule 242# _TIF_NEED_RESCHED is set, call schedule
@@ -290,13 +244,13 @@ sysc_work:
290sysc_reschedule: 244sysc_reschedule:
291 l %r1,BASED(.Lschedule) 245 l %r1,BASED(.Lschedule)
292 la %r14,BASED(sysc_return) 246 la %r14,BASED(sysc_return)
293 br %r1 # call scheduler 247 br %r1 # call schedule
294 248
295# 249#
296# _TIF_MCCK_PENDING is set, call handler 250# _TIF_MCCK_PENDING is set, call handler
297# 251#
298sysc_mcck_pending: 252sysc_mcck_pending:
299 l %r1,BASED(.Ls390_handle_mcck) 253 l %r1,BASED(.Lhandle_mcck)
300 la %r14,BASED(sysc_return) 254 la %r14,BASED(sysc_return)
301 br %r1 # TIF bit will be cleared by handler 255 br %r1 # TIF bit will be cleared by handler
302 256
@@ -305,23 +259,24 @@ sysc_mcck_pending:
305# 259#
306sysc_sigpending: 260sysc_sigpending:
307 ni __TI_flags+3(%r12),255-_TIF_PER_TRAP # clear TIF_PER_TRAP 261 ni __TI_flags+3(%r12),255-_TIF_PER_TRAP # clear TIF_PER_TRAP
308 la %r2,SP_PTREGS(%r15) # load pt_regs 262 lr %r2,%r11 # pass pointer to pt_regs
309 l %r1,BASED(.Ldo_signal) 263 l %r1,BASED(.Ldo_signal)
310 basr %r14,%r1 # call do_signal 264 basr %r14,%r1 # call do_signal
311 tm __TI_flags+3(%r12),_TIF_SYSCALL 265 tm __TI_flags+3(%r12),_TIF_SYSCALL
312 bno BASED(sysc_return) 266 jno sysc_return
313 lm %r2,%r6,SP_R2(%r15) # load svc arguments 267 lm %r2,%r7,__PT_R2(%r11) # load svc arguments
314 xr %r7,%r7 # svc 0 returns -ENOSYS 268 xr %r8,%r8 # svc 0 returns -ENOSYS
315 clc SP_SVC_CODE+2(2,%r15),BASED(.Lnr_syscalls+2) 269 clc __PT_SVC_CODE+2(2,%r11),BASED(.Lnr_syscalls+2)
316 bnl BASED(sysc_nr_ok) # invalid svc number -> do svc 0 270 jnl sysc_nr_ok # invalid svc number -> do svc 0
317 icm %r7,3,SP_SVC_CODE+2(%r15)# load new svc number 271 lh %r8,__PT_SVC_CODE+2(%r11) # load new svc number
318 b BASED(sysc_nr_ok) # restart svc 272 sla %r8,2
273 j sysc_nr_ok # restart svc
319 274
320# 275#
321# _TIF_NOTIFY_RESUME is set, call do_notify_resume 276# _TIF_NOTIFY_RESUME is set, call do_notify_resume
322# 277#
323sysc_notify_resume: 278sysc_notify_resume:
324 la %r2,SP_PTREGS(%r15) # load pt_regs 279 lr %r2,%r11 # pass pointer to pt_regs
325 l %r1,BASED(.Ldo_notify_resume) 280 l %r1,BASED(.Ldo_notify_resume)
326 la %r14,BASED(sysc_return) 281 la %r14,BASED(sysc_return)
327 br %r1 # call do_notify_resume 282 br %r1 # call do_notify_resume
@@ -331,56 +286,57 @@ sysc_notify_resume:
331# 286#
332sysc_singlestep: 287sysc_singlestep:
333 ni __TI_flags+3(%r12),255-(_TIF_SYSCALL | _TIF_PER_TRAP) 288 ni __TI_flags+3(%r12),255-(_TIF_SYSCALL | _TIF_PER_TRAP)
334 la %r2,SP_PTREGS(%r15) # address of register-save area 289 lr %r2,%r11 # pass pointer to pt_regs
335 l %r1,BASED(.Lhandle_per) # load adr. of per handler 290 l %r1,BASED(.Ldo_per_trap)
336 la %r14,BASED(sysc_return) # load adr. of system return 291 la %r14,BASED(sysc_return)
337 br %r1 # branch to do_per_trap 292 br %r1 # call do_per_trap
338 293
339# 294#
340# call tracehook_report_syscall_entry/tracehook_report_syscall_exit before 295# call tracehook_report_syscall_entry/tracehook_report_syscall_exit before
341# and after the system call 296# and after the system call
342# 297#
343sysc_tracesys: 298sysc_tracesys:
344 l %r1,BASED(.Ltrace_entry) 299 l %r1,BASED(.Ltrace_enter)
345 la %r2,SP_PTREGS(%r15) # load pt_regs 300 lr %r2,%r11 # pass pointer to pt_regs
346 la %r3,0 301 la %r3,0
347 xr %r0,%r0 302 xr %r0,%r0
348 icm %r0,3,SP_SVC_CODE(%r15) 303 icm %r0,3,__PT_SVC_CODE+2(%r11)
349 st %r0,SP_R2(%r15) 304 st %r0,__PT_R2(%r11)
350 basr %r14,%r1 305 basr %r14,%r1 # call do_syscall_trace_enter
351 cl %r2,BASED(.Lnr_syscalls) 306 cl %r2,BASED(.Lnr_syscalls)
352 bnl BASED(sysc_tracenogo) 307 jnl sysc_tracenogo
353 lr %r7,%r2 308 lr %r8,%r2
354 sll %r7,2 # svc number *4 309 sll %r8,2
355 l %r8,0(%r7,%r10) 310 l %r9,0(%r8,%r10)
356sysc_tracego: 311sysc_tracego:
357 lm %r3,%r6,SP_R3(%r15) 312 lm %r3,%r7,__PT_R3(%r11)
358 mvc SP_ARGS(4,%r15),SP_R7(%r15) 313 st %r7,STACK_FRAME_OVERHEAD(%r15)
359 l %r2,SP_ORIG_R2(%r15) 314 l %r2,__PT_ORIG_GPR2(%r11)
360 basr %r14,%r8 # call sys_xxx 315 basr %r14,%r9 # call sys_xxx
361 st %r2,SP_R2(%r15) # store return value 316 st %r2,__PT_R2(%r11) # store return value
362sysc_tracenogo: 317sysc_tracenogo:
363 tm __TI_flags+2(%r12),_TIF_TRACE >> 8 318 tm __TI_flags+2(%r12),_TIF_TRACE >> 8
364 bz BASED(sysc_return) 319 jz sysc_return
365 l %r1,BASED(.Ltrace_exit) 320 l %r1,BASED(.Ltrace_exit)
366 la %r2,SP_PTREGS(%r15) # load pt_regs 321 lr %r2,%r11 # pass pointer to pt_regs
367 la %r14,BASED(sysc_return) 322 la %r14,BASED(sysc_return)
368 br %r1 323 br %r1 # call do_syscall_trace_exit
369 324
370# 325#
371# a new process exits the kernel with ret_from_fork 326# a new process exits the kernel with ret_from_fork
372# 327#
373ENTRY(ret_from_fork) 328ENTRY(ret_from_fork)
329 la %r11,STACK_FRAME_OVERHEAD(%r15)
330 l %r12,__LC_THREAD_INFO
374 l %r13,__LC_SVC_NEW_PSW+4 331 l %r13,__LC_SVC_NEW_PSW+4
375 l %r12,__LC_THREAD_INFO # load pointer to thread_info struct 332 tm __PT_PSW+1(%r11),0x01 # forking a kernel thread ?
376 tm SP_PSW+1(%r15),0x01 # forking a kernel thread ? 333 jo 0f
377 bo BASED(0f) 334 st %r15,__PT_R15(%r11) # store stack pointer for new kthread
378 st %r15,SP_R15(%r15) # store stack pointer for new kthread 3350: l %r1,BASED(.Lschedule_tail)
3790: l %r1,BASED(.Lschedtail) 336 basr %r14,%r1 # call schedule_tail
380 basr %r14,%r1
381 TRACE_IRQS_ON 337 TRACE_IRQS_ON
382 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 338 ssm __LC_SVC_NEW_PSW # reenable interrupts
383 b BASED(sysc_tracenogo) 339 j sysc_tracenogo
384 340
385# 341#
386# kernel_execve function needs to deal with pt_regs that is not 342# kernel_execve function needs to deal with pt_regs that is not
@@ -390,153 +346,98 @@ ENTRY(kernel_execve)
390 stm %r12,%r15,48(%r15) 346 stm %r12,%r15,48(%r15)
391 lr %r14,%r15 347 lr %r14,%r15
392 l %r13,__LC_SVC_NEW_PSW+4 348 l %r13,__LC_SVC_NEW_PSW+4
393 s %r15,BASED(.Lc_spsize) 349 ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
394 st %r14,__SF_BACKCHAIN(%r15) 350 st %r14,__SF_BACKCHAIN(%r15)
395 la %r12,SP_PTREGS(%r15) 351 la %r12,STACK_FRAME_OVERHEAD(%r15)
396 xc 0(__PT_SIZE,%r12),0(%r12) 352 xc 0(__PT_SIZE,%r12),0(%r12)
397 l %r1,BASED(.Ldo_execve) 353 l %r1,BASED(.Ldo_execve)
398 lr %r5,%r12 354 lr %r5,%r12
399 basr %r14,%r1 355 basr %r14,%r1 # call do_execve
400 ltr %r2,%r2 356 ltr %r2,%r2
401 be BASED(0f) 357 je 0f
402 a %r15,BASED(.Lc_spsize) 358 ahi %r15,(STACK_FRAME_OVERHEAD + __PT_SIZE)
403 lm %r12,%r15,48(%r15) 359 lm %r12,%r15,48(%r15)
404 br %r14 360 br %r14
405 # execve succeeded. 361 # execve succeeded.
4060: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts 3620: ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
407 l %r15,__LC_KERNEL_STACK # load ksp 363 l %r15,__LC_KERNEL_STACK # load ksp
408 s %r15,BASED(.Lc_spsize) # make room for registers & psw 364 ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
409 mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs 365 la %r11,STACK_FRAME_OVERHEAD(%r15)
366 mvc 0(__PT_SIZE,%r11),0(%r12) # copy pt_regs
410 l %r12,__LC_THREAD_INFO 367 l %r12,__LC_THREAD_INFO
411 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) 368 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
412 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 369 ssm __LC_SVC_NEW_PSW # reenable interrupts
413 l %r1,BASED(.Lexecve_tail) 370 l %r1,BASED(.Lexecve_tail)
414 basr %r14,%r1 371 basr %r14,%r1 # call execve_tail
415 b BASED(sysc_return) 372 j sysc_return
416 373
417/* 374/*
418 * Program check handler routine 375 * Program check handler routine
419 */ 376 */
420 377
421ENTRY(pgm_check_handler) 378ENTRY(pgm_check_handler)
422/*
423 * First we need to check for a special case:
424 * Single stepping an instruction that disables the PER event mask will
425 * cause a PER event AFTER the mask has been set. Example: SVC or LPSW.
426 * For a single stepped SVC the program check handler gets control after
427 * the SVC new PSW has been loaded. But we want to execute the SVC first and
428 * then handle the PER event. Therefore we update the SVC old PSW to point
429 * to the pgm_check_handler and branch to the SVC handler after we checked
430 * if we have to load the kernel stack register.
431 * For every other possible cause for PER event without the PER mask set
432 * we just ignore the PER event (FIXME: is there anything we have to do
433 * for LPSW?).
434 */
435 stpt __LC_SYNC_ENTER_TIMER 379 stpt __LC_SYNC_ENTER_TIMER
436 SAVE_ALL_BASE __LC_SAVE_AREA 380 stm %r8,%r15,__LC_SAVE_AREA_SYNC
437 tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception 381 l %r12,__LC_THREAD_INFO
438 bnz BASED(pgm_per) # got per exception -> special case 382 l %r13,__LC_SVC_NEW_PSW+4
439 SAVE_ALL_PGM __LC_PGM_OLD_PSW,__LC_SAVE_AREA 383 lm %r8,%r9,__LC_PGM_OLD_PSW
440 CREATE_STACK_FRAME __LC_SAVE_AREA 384 tmh %r8,0x0001 # test problem state bit
441 mvc SP_PSW(8,%r15),__LC_PGM_OLD_PSW 385 jnz 1f # -> fault in user space
442 l %r12,__LC_THREAD_INFO # load pointer to thread_info struct 386 tmh %r8,0x4000 # PER bit set in old PSW ?
443 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 387 jnz 0f # -> enabled, can't be a double fault
444 bz BASED(pgm_no_vtime) 388 tm __LC_PGM_ILC+3,0x80 # check for per exception
445 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 389 jnz pgm_svcper # -> single stepped svc
446 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 3900: CHECK_STACK STACK_SIZE,__LC_SAVE_AREA_SYNC
447 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 391 j 2f
448pgm_no_vtime: 3921: UPDATE_VTIME %r14,%r15,__LC_SYNC_ENTER_TIMER
449 l %r3,__LC_PGM_ILC # load program interruption code 393 l %r15,__LC_KERNEL_STACK
450 l %r4,__LC_TRANS_EXC_CODE 3942: ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
451 REENABLE_IRQS 395 la %r11,STACK_FRAME_OVERHEAD(%r15)
452 la %r8,0x7f 396 stm %r0,%r7,__PT_R0(%r11)
453 nr %r8,%r3 397 mvc __PT_R8(32,%r11),__LC_SAVE_AREA_SYNC
454 sll %r8,2 398 stm %r8,%r9,__PT_PSW(%r11)
455 l %r1,BASED(.Ljump_table) 399 tm __LC_PGM_ILC+3,0x80 # check for per exception
456 l %r1,0(%r8,%r1) # load address of handler routine 400 jz 0f
457 la %r2,SP_PTREGS(%r15) # address of register-save area
458 basr %r14,%r1 # branch to interrupt-handler
459pgm_exit:
460 b BASED(sysc_return)
461
462#
463# handle per exception
464#
465pgm_per:
466 tm __LC_PGM_OLD_PSW,0x40 # test if per event recording is on
467 bnz BASED(pgm_per_std) # ok, normal per event from user space
468# ok its one of the special cases, now we need to find out which one
469 clc __LC_PGM_OLD_PSW(8),__LC_SVC_NEW_PSW
470 be BASED(pgm_svcper)
471# no interesting special case, ignore PER event
472 lm %r12,%r15,__LC_SAVE_AREA
473 lpsw 0x28
474
475#
476# Normal per exception
477#
478pgm_per_std:
479 SAVE_ALL_PGM __LC_PGM_OLD_PSW,__LC_SAVE_AREA
480 CREATE_STACK_FRAME __LC_SAVE_AREA
481 mvc SP_PSW(8,%r15),__LC_PGM_OLD_PSW
482 l %r12,__LC_THREAD_INFO # load pointer to thread_info struct
483 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
484 bz BASED(pgm_no_vtime2)
485 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
486 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
487 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
488pgm_no_vtime2:
489 l %r1,__TI_task(%r12) 401 l %r1,__TI_task(%r12)
490 tm SP_PSW+1(%r15),0x01 # kernel per event ? 402 tmh %r8,0x0001 # kernel per event ?
491 bz BASED(kernel_per) 403 jz pgm_kprobe
492 mvc __THREAD_per_cause(2,%r1),__LC_PER_CAUSE 404 oi __TI_flags+3(%r12),_TIF_PER_TRAP
493 mvc __THREAD_per_address(4,%r1),__LC_PER_ADDRESS 405 mvc __THREAD_per_address(4,%r1),__LC_PER_ADDRESS
406 mvc __THREAD_per_cause(2,%r1),__LC_PER_CAUSE
494 mvc __THREAD_per_paid(1,%r1),__LC_PER_PAID 407 mvc __THREAD_per_paid(1,%r1),__LC_PER_PAID
495 oi __TI_flags+3(%r12),_TIF_PER_TRAP # set TIF_PER_TRAP 4080: l %r3,__LC_PGM_ILC # load program interruption code
496 l %r3,__LC_PGM_ILC # load program interruption code
497 l %r4,__LC_TRANS_EXC_CODE 409 l %r4,__LC_TRANS_EXC_CODE
498 REENABLE_IRQS 410 REENABLE_IRQS
499 la %r8,0x7f 411 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
500 nr %r8,%r3 # clear per-event-bit and ilc
501 be BASED(pgm_exit2) # only per or per+check ?
502 sll %r8,2
503 l %r1,BASED(.Ljump_table) 412 l %r1,BASED(.Ljump_table)
504 l %r1,0(%r8,%r1) # load address of handler routine 413 la %r10,0x7f
505 la %r2,SP_PTREGS(%r15) # address of register-save area 414 nr %r10,%r3
415 je sysc_return
416 sll %r10,2
417 l %r1,0(%r10,%r1) # load address of handler routine
418 lr %r2,%r11 # pass pointer to pt_regs
506 basr %r14,%r1 # branch to interrupt-handler 419 basr %r14,%r1 # branch to interrupt-handler
507pgm_exit2: 420 j sysc_return
508 b BASED(sysc_return)
509 421
510# 422#
511# it was a single stepped SVC that is causing all the trouble 423# PER event in supervisor state, must be kprobes
512# 424#
513pgm_svcper: 425pgm_kprobe:
514 SAVE_ALL_PGM __LC_SVC_OLD_PSW,__LC_SAVE_AREA 426 REENABLE_IRQS
515 CREATE_STACK_FRAME __LC_SAVE_AREA 427 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
516 l %r12,__LC_THREAD_INFO # load pointer to thread_info struct 428 l %r1,BASED(.Ldo_per_trap)
517 mvc SP_PSW(8,%r15),__LC_SVC_OLD_PSW 429 lr %r2,%r11 # pass pointer to pt_regs
518 mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC 430 basr %r14,%r1 # call do_per_trap
519 oi __TI_flags+3(%r12),(_TIF_SYSCALL | _TIF_PER_TRAP) 431 j sysc_return
520 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
521 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
522 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
523 l %r8,__TI_task(%r12)
524 mvc __THREAD_per_cause(2,%r8),__LC_PER_CAUSE
525 mvc __THREAD_per_address(4,%r8),__LC_PER_ADDRESS
526 mvc __THREAD_per_paid(1,%r8),__LC_PER_PAID
527 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
528 lm %r2,%r6,SP_R2(%r15) # load svc arguments
529 b BASED(sysc_do_svc)
530 432
531# 433#
532# per was called from kernel, must be kprobes 434# single stepped system call
533# 435#
534kernel_per: 436pgm_svcper:
535 REENABLE_IRQS 437 oi __TI_flags+3(%r12),_TIF_PER_TRAP
536 la %r2,SP_PTREGS(%r15) # address of register-save area 438 mvc __LC_RETURN_PSW(4),__LC_SVC_NEW_PSW
537 l %r1,BASED(.Lhandle_per) # load adr. of per handler 439 mvc __LC_RETURN_PSW+4(4),BASED(.Lsysc_per)
538 basr %r14,%r1 # branch to do_single_step 440 lpsw __LC_RETURN_PSW # branch to sysc_per and enable irqs
539 b BASED(pgm_exit)
540 441
541/* 442/*
542 * IO interrupt handler routine 443 * IO interrupt handler routine
@@ -545,28 +446,35 @@ kernel_per:
545ENTRY(io_int_handler) 446ENTRY(io_int_handler)
546 stck __LC_INT_CLOCK 447 stck __LC_INT_CLOCK
547 stpt __LC_ASYNC_ENTER_TIMER 448 stpt __LC_ASYNC_ENTER_TIMER
548 SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+16 449 stm %r8,%r15,__LC_SAVE_AREA_ASYNC
549 CREATE_STACK_FRAME __LC_SAVE_AREA+16 450 l %r12,__LC_THREAD_INFO
550 mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack 451 l %r13,__LC_SVC_NEW_PSW+4
551 l %r12,__LC_THREAD_INFO # load pointer to thread_info struct 452 lm %r8,%r9,__LC_IO_OLD_PSW
552 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 453 tmh %r8,0x0001 # interrupting from user ?
553 bz BASED(io_no_vtime) 454 jz io_skip
554 UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER 455 UPDATE_VTIME %r14,%r15,__LC_ASYNC_ENTER_TIMER
555 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 456io_skip:
556 mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER 457 SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT
557io_no_vtime: 458 stm %r0,%r7,__PT_R0(%r11)
459 mvc __PT_R8(32,%r11),__LC_SAVE_AREA_ASYNC
460 stm %r8,%r9,__PT_PSW(%r11)
558 TRACE_IRQS_OFF 461 TRACE_IRQS_OFF
559 l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ 462 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
560 la %r2,SP_PTREGS(%r15) # address of register-save area 463 l %r1,BASED(.Ldo_IRQ)
561 basr %r14,%r1 # branch to standard irq handler 464 lr %r2,%r11 # pass pointer to pt_regs
465 basr %r14,%r1 # call do_IRQ
562io_return: 466io_return:
563 LOCKDEP_SYS_EXIT 467 LOCKDEP_SYS_EXIT
564 TRACE_IRQS_ON 468 TRACE_IRQS_ON
565io_tif: 469io_tif:
566 tm __TI_flags+3(%r12),_TIF_WORK_INT 470 tm __TI_flags+3(%r12),_TIF_WORK_INT
567 bnz BASED(io_work) # there is work to do (signals etc.) 471 jnz io_work # there is work to do (signals etc.)
568io_restore: 472io_restore:
569 RESTORE_ALL __LC_RETURN_PSW,0 473 mvc __LC_RETURN_PSW(8),__PT_PSW(%r11)
474 ni __LC_RETURN_PSW+1,0xfd # clean wait state bit
475 stpt __LC_EXIT_TIMER
476 lm %r0,%r15,__PT_R0(%r11)
477 lpsw __LC_RETURN_PSW
570io_done: 478io_done:
571 479
572# 480#
@@ -577,28 +485,29 @@ io_done:
577# Before any work can be done, a switch to the kernel stack is required. 485# Before any work can be done, a switch to the kernel stack is required.
578# 486#
579io_work: 487io_work:
580 tm SP_PSW+1(%r15),0x01 # returning to user ? 488 tm __PT_PSW+1(%r11),0x01 # returning to user ?
581 bo BASED(io_work_user) # yes -> do resched & signal 489 jo io_work_user # yes -> do resched & signal
582#ifdef CONFIG_PREEMPT 490#ifdef CONFIG_PREEMPT
583 # check for preemptive scheduling 491 # check for preemptive scheduling
584 icm %r0,15,__TI_precount(%r12) 492 icm %r0,15,__TI_precount(%r12)
585 bnz BASED(io_restore) # preemption disabled 493 jnz io_restore # preemption disabled
586 tm __TI_flags+3(%r12),_TIF_NEED_RESCHED 494 tm __TI_flags+3(%r12),_TIF_NEED_RESCHED
587 bno BASED(io_restore) 495 jno io_restore
588 # switch to kernel stack 496 # switch to kernel stack
589 l %r1,SP_R15(%r15) 497 l %r1,__PT_R15(%r11)
590 s %r1,BASED(.Lc_spsize) 498 ahi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
591 mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) 499 mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
592 xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain 500 xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1)
501 la %r11,STACK_FRAME_OVERHEAD(%r1)
593 lr %r15,%r1 502 lr %r15,%r1
594 # TRACE_IRQS_ON already done at io_return, call 503 # TRACE_IRQS_ON already done at io_return, call
595 # TRACE_IRQS_OFF to keep things symmetrical 504 # TRACE_IRQS_OFF to keep things symmetrical
596 TRACE_IRQS_OFF 505 TRACE_IRQS_OFF
597 l %r1,BASED(.Lpreempt_schedule_irq) 506 l %r1,BASED(.Lpreempt_irq)
598 basr %r14,%r1 # call preempt_schedule_irq 507 basr %r14,%r1 # call preempt_schedule_irq
599 b BASED(io_return) 508 j io_return
600#else 509#else
601 b BASED(io_restore) 510 j io_restore
602#endif 511#endif
603 512
604# 513#
@@ -606,9 +515,10 @@ io_work:
606# 515#
607io_work_user: 516io_work_user:
608 l %r1,__LC_KERNEL_STACK 517 l %r1,__LC_KERNEL_STACK
609 s %r1,BASED(.Lc_spsize) 518 ahi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
610 mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) 519 mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
611 xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain 520 xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1)
521 la %r11,STACK_FRAME_OVERHEAD(%r1)
612 lr %r15,%r1 522 lr %r15,%r1
613 523
614# 524#
@@ -618,24 +528,24 @@ io_work_user:
618# 528#
619io_work_tif: 529io_work_tif:
620 tm __TI_flags+3(%r12),_TIF_MCCK_PENDING 530 tm __TI_flags+3(%r12),_TIF_MCCK_PENDING
621 bo BASED(io_mcck_pending) 531 jo io_mcck_pending
622 tm __TI_flags+3(%r12),_TIF_NEED_RESCHED 532 tm __TI_flags+3(%r12),_TIF_NEED_RESCHED
623 bo BASED(io_reschedule) 533 jo io_reschedule
624 tm __TI_flags+3(%r12),_TIF_SIGPENDING 534 tm __TI_flags+3(%r12),_TIF_SIGPENDING
625 bo BASED(io_sigpending) 535 jo io_sigpending
626 tm __TI_flags+3(%r12),_TIF_NOTIFY_RESUME 536 tm __TI_flags+3(%r12),_TIF_NOTIFY_RESUME
627 bo BASED(io_notify_resume) 537 jo io_notify_resume
628 b BASED(io_return) # beware of critical section cleanup 538 j io_return # beware of critical section cleanup
629 539
630# 540#
631# _TIF_MCCK_PENDING is set, call handler 541# _TIF_MCCK_PENDING is set, call handler
632# 542#
633io_mcck_pending: 543io_mcck_pending:
634 # TRACE_IRQS_ON already done at io_return 544 # TRACE_IRQS_ON already done at io_return
635 l %r1,BASED(.Ls390_handle_mcck) 545 l %r1,BASED(.Lhandle_mcck)
636 basr %r14,%r1 # TIF bit will be cleared by handler 546 basr %r14,%r1 # TIF bit will be cleared by handler
637 TRACE_IRQS_OFF 547 TRACE_IRQS_OFF
638 b BASED(io_return) 548 j io_return
639 549
640# 550#
641# _TIF_NEED_RESCHED is set, call schedule 551# _TIF_NEED_RESCHED is set, call schedule
@@ -643,37 +553,37 @@ io_mcck_pending:
643io_reschedule: 553io_reschedule:
644 # TRACE_IRQS_ON already done at io_return 554 # TRACE_IRQS_ON already done at io_return
645 l %r1,BASED(.Lschedule) 555 l %r1,BASED(.Lschedule)
646 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 556 ssm __LC_SVC_NEW_PSW # reenable interrupts
647 basr %r14,%r1 # call scheduler 557 basr %r14,%r1 # call scheduler
648 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 558 ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
649 TRACE_IRQS_OFF 559 TRACE_IRQS_OFF
650 b BASED(io_return) 560 j io_return
651 561
652# 562#
653# _TIF_SIGPENDING is set, call do_signal 563# _TIF_SIGPENDING is set, call do_signal
654# 564#
655io_sigpending: 565io_sigpending:
656 # TRACE_IRQS_ON already done at io_return 566 # TRACE_IRQS_ON already done at io_return
657 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
658 la %r2,SP_PTREGS(%r15) # load pt_regs
659 l %r1,BASED(.Ldo_signal) 567 l %r1,BASED(.Ldo_signal)
568 ssm __LC_SVC_NEW_PSW # reenable interrupts
569 lr %r2,%r11 # pass pointer to pt_regs
660 basr %r14,%r1 # call do_signal 570 basr %r14,%r1 # call do_signal
661 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 571 ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
662 TRACE_IRQS_OFF 572 TRACE_IRQS_OFF
663 b BASED(io_return) 573 j io_return
664 574
665# 575#
666# _TIF_SIGPENDING is set, call do_signal 576# _TIF_SIGPENDING is set, call do_signal
667# 577#
668io_notify_resume: 578io_notify_resume:
669 # TRACE_IRQS_ON already done at io_return 579 # TRACE_IRQS_ON already done at io_return
670 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
671 la %r2,SP_PTREGS(%r15) # load pt_regs
672 l %r1,BASED(.Ldo_notify_resume) 580 l %r1,BASED(.Ldo_notify_resume)
673 basr %r14,%r1 # call do_signal 581 ssm __LC_SVC_NEW_PSW # reenable interrupts
674 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 582 lr %r2,%r11 # pass pointer to pt_regs
583 basr %r14,%r1 # call do_notify_resume
584 ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
675 TRACE_IRQS_OFF 585 TRACE_IRQS_OFF
676 b BASED(io_return) 586 j io_return
677 587
678/* 588/*
679 * External interrupt handler routine 589 * External interrupt handler routine
@@ -682,23 +592,25 @@ io_notify_resume:
682ENTRY(ext_int_handler) 592ENTRY(ext_int_handler)
683 stck __LC_INT_CLOCK 593 stck __LC_INT_CLOCK
684 stpt __LC_ASYNC_ENTER_TIMER 594 stpt __LC_ASYNC_ENTER_TIMER
685 SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16 595 stm %r8,%r15,__LC_SAVE_AREA_ASYNC
686 CREATE_STACK_FRAME __LC_SAVE_AREA+16 596 l %r12,__LC_THREAD_INFO
687 mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack 597 l %r13,__LC_SVC_NEW_PSW+4
688 l %r12,__LC_THREAD_INFO # load pointer to thread_info struct 598 lm %r8,%r9,__LC_EXT_OLD_PSW
689 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 599 tmh %r8,0x0001 # interrupting from user ?
690 bz BASED(ext_no_vtime) 600 jz ext_skip
691 UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER 601 UPDATE_VTIME %r14,%r15,__LC_ASYNC_ENTER_TIMER
692 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 602ext_skip:
693 mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER 603 SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT
694ext_no_vtime: 604 stm %r0,%r7,__PT_R0(%r11)
605 mvc __PT_R8(32,%r11),__LC_SAVE_AREA_ASYNC
606 stm %r8,%r9,__PT_PSW(%r11)
695 TRACE_IRQS_OFF 607 TRACE_IRQS_OFF
696 la %r2,SP_PTREGS(%r15) # address of register-save area 608 lr %r2,%r11 # pass pointer to pt_regs
697 l %r3,__LC_CPU_ADDRESS # get cpu address + interruption code 609 l %r3,__LC_CPU_ADDRESS # get cpu address + interruption code
698 l %r4,__LC_EXT_PARAMS # get external parameters 610 l %r4,__LC_EXT_PARAMS # get external parameters
699 l %r1,BASED(.Ldo_extint) 611 l %r1,BASED(.Ldo_extint)
700 basr %r14,%r1 612 basr %r14,%r1 # call do_extint
701 b BASED(io_return) 613 j io_return
702 614
703__critical_end: 615__critical_end:
704 616
@@ -710,82 +622,74 @@ ENTRY(mcck_int_handler)
710 stck __LC_MCCK_CLOCK 622 stck __LC_MCCK_CLOCK
711 spt __LC_CPU_TIMER_SAVE_AREA # revalidate cpu timer 623 spt __LC_CPU_TIMER_SAVE_AREA # revalidate cpu timer
712 lm %r0,%r15,__LC_GPREGS_SAVE_AREA # revalidate gprs 624 lm %r0,%r15,__LC_GPREGS_SAVE_AREA # revalidate gprs
713 SAVE_ALL_BASE __LC_SAVE_AREA+32 625 l %r12,__LC_THREAD_INFO
714 la %r12,__LC_MCK_OLD_PSW 626 l %r13,__LC_SVC_NEW_PSW+4
627 lm %r8,%r9,__LC_MCK_OLD_PSW
715 tm __LC_MCCK_CODE,0x80 # system damage? 628 tm __LC_MCCK_CODE,0x80 # system damage?
716 bo BASED(mcck_int_main) # yes -> rest of mcck code invalid 629 jo mcck_panic # yes -> rest of mcck code invalid
717 mvc __LC_MCCK_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA 630 la %r14,__LC_CPU_TIMER_SAVE_AREA
631 mvc __LC_MCCK_ENTER_TIMER(8),0(%r14)
718 tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid? 632 tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid?
719 bo BASED(1f) 633 jo 3f
720 la %r14,__LC_SYNC_ENTER_TIMER 634 la %r14,__LC_SYNC_ENTER_TIMER
721 clc 0(8,%r14),__LC_ASYNC_ENTER_TIMER 635 clc 0(8,%r14),__LC_ASYNC_ENTER_TIMER
722 bl BASED(0f) 636 jl 0f
723 la %r14,__LC_ASYNC_ENTER_TIMER 637 la %r14,__LC_ASYNC_ENTER_TIMER
7240: clc 0(8,%r14),__LC_EXIT_TIMER 6380: clc 0(8,%r14),__LC_EXIT_TIMER
725 bl BASED(0f) 639 jl 1f
726 la %r14,__LC_EXIT_TIMER 640 la %r14,__LC_EXIT_TIMER
7270: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER 6411: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER
728 bl BASED(0f) 642 jl 2f
729 la %r14,__LC_LAST_UPDATE_TIMER 643 la %r14,__LC_LAST_UPDATE_TIMER
7300: spt 0(%r14) 6442: spt 0(%r14)
731 mvc __LC_MCCK_ENTER_TIMER(8),0(%r14) 645 mvc __LC_MCCK_ENTER_TIMER(8),0(%r14)
7321: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? 6463: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid?
733 bno BASED(mcck_int_main) # no -> skip cleanup critical 647 jno mcck_panic # no -> skip cleanup critical
734 tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit 648 tm %r8,0x0001 # interrupting from user ?
735 bnz BASED(mcck_int_main) # from user -> load async stack 649 jz mcck_skip
736 clc __LC_MCK_OLD_PSW+4(4),BASED(.Lcritical_end) 650 UPDATE_VTIME %r14,%r15,__LC_MCCK_ENTER_TIMER
737 bhe BASED(mcck_int_main) 651mcck_skip:
738 clc __LC_MCK_OLD_PSW+4(4),BASED(.Lcritical_start) 652 SWITCH_ASYNC __LC_GPREGS_SAVE_AREA+32,__LC_PANIC_STACK,PAGE_SHIFT
739 bl BASED(mcck_int_main) 653 mvc __PT_R0(64,%r11),__LC_GPREGS_SAVE_AREA
740 l %r14,BASED(.Lcleanup_critical) 654 stm %r8,%r9,__PT_PSW(%r11)
741 basr %r14,%r14 655 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
742mcck_int_main: 656 l %r1,BASED(.Ldo_machine_check)
743 l %r14,__LC_PANIC_STACK # are we already on the panic stack? 657 lr %r2,%r11 # pass pointer to pt_regs
744 slr %r14,%r15 658 basr %r14,%r1 # call s390_do_machine_check
745 sra %r14,PAGE_SHIFT 659 tm __PT_PSW+1(%r11),0x01 # returning to user ?
746 be BASED(0f) 660 jno mcck_return
747 l %r15,__LC_PANIC_STACK # load panic stack
7480: s %r15,BASED(.Lc_spsize) # make room for registers & psw
749 CREATE_STACK_FRAME __LC_SAVE_AREA+32
750 mvc SP_PSW(8,%r15),0(%r12)
751 l %r12,__LC_THREAD_INFO # load pointer to thread_info struct
752 tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid?
753 bno BASED(mcck_no_vtime) # no -> skip cleanup critical
754 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
755 bz BASED(mcck_no_vtime)
756 UPDATE_VTIME __LC_EXIT_TIMER,__LC_MCCK_ENTER_TIMER,__LC_USER_TIMER
757 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
758 mvc __LC_LAST_UPDATE_TIMER(8),__LC_MCCK_ENTER_TIMER
759mcck_no_vtime:
760 la %r2,SP_PTREGS(%r15) # load pt_regs
761 l %r1,BASED(.Ls390_mcck)
762 basr %r14,%r1 # call machine check handler
763 tm SP_PSW+1(%r15),0x01 # returning to user ?
764 bno BASED(mcck_return)
765 l %r1,__LC_KERNEL_STACK # switch to kernel stack 661 l %r1,__LC_KERNEL_STACK # switch to kernel stack
766 s %r1,BASED(.Lc_spsize) 662 ahi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
767 mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) 663 mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
768 xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain 664 xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1)
665 la %r11,STACK_FRAME_OVERHEAD(%r15)
769 lr %r15,%r1 666 lr %r15,%r1
770 stosm __SF_EMPTY(%r15),0x04 # turn dat on 667 ssm __LC_PGM_NEW_PSW # turn dat on, keep irqs off
771 tm __TI_flags+3(%r12),_TIF_MCCK_PENDING 668 tm __TI_flags+3(%r12),_TIF_MCCK_PENDING
772 bno BASED(mcck_return) 669 jno mcck_return
773 TRACE_IRQS_OFF 670 TRACE_IRQS_OFF
774 l %r1,BASED(.Ls390_handle_mcck) 671 l %r1,BASED(.Lhandle_mcck)
775 basr %r14,%r1 # call machine check handler 672 basr %r14,%r1 # call s390_handle_mcck
776 TRACE_IRQS_ON 673 TRACE_IRQS_ON
777mcck_return: 674mcck_return:
778 mvc __LC_RETURN_MCCK_PSW(8),SP_PSW(%r15) # move return PSW 675 mvc __LC_RETURN_MCCK_PSW(8),__PT_PSW(%r11) # move return PSW
779 ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit 676 ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit
780 tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ? 677 tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ?
781 bno BASED(0f) 678 jno 0f
782 lm %r0,%r15,SP_R0(%r15) # load gprs 0-15 679 lm %r0,%r15,__PT_R0(%r11)
783 stpt __LC_EXIT_TIMER 680 stpt __LC_EXIT_TIMER
784 lpsw __LC_RETURN_MCCK_PSW # back to caller 681 lpsw __LC_RETURN_MCCK_PSW
7850: lm %r0,%r15,SP_R0(%r15) # load gprs 0-15 6820: lm %r0,%r15,__PT_R0(%r11)
786 lpsw __LC_RETURN_MCCK_PSW # back to caller 683 lpsw __LC_RETURN_MCCK_PSW
787 684
788 RESTORE_ALL __LC_RETURN_MCCK_PSW,0 685mcck_panic:
686 l %r14,__LC_PANIC_STACK
687 slr %r14,%r15
688 sra %r14,PAGE_SHIFT
689 jz 0f
690 l %r15,__LC_PANIC_STACK
6910: ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
692 j mcck_skip
789 693
790/* 694/*
791 * Restart interruption handler, kick starter for additional CPUs 695 * Restart interruption handler, kick starter for additional CPUs
@@ -799,18 +703,18 @@ restart_base:
799 stck __LC_LAST_UPDATE_CLOCK 703 stck __LC_LAST_UPDATE_CLOCK
800 mvc __LC_LAST_UPDATE_TIMER(8),restart_vtime-restart_base(%r1) 704 mvc __LC_LAST_UPDATE_TIMER(8),restart_vtime-restart_base(%r1)
801 mvc __LC_EXIT_TIMER(8),restart_vtime-restart_base(%r1) 705 mvc __LC_EXIT_TIMER(8),restart_vtime-restart_base(%r1)
802 l %r15,__LC_SAVE_AREA+60 # load ksp 706 l %r15,__LC_GPREGS_SAVE_AREA+60 # load ksp
803 lctl %c0,%c15,__LC_CREGS_SAVE_AREA # get new ctl regs 707 lctl %c0,%c15,__LC_CREGS_SAVE_AREA # get new ctl regs
804 lam %a0,%a15,__LC_AREGS_SAVE_AREA 708 lam %a0,%a15,__LC_AREGS_SAVE_AREA
805 lm %r6,%r15,__SF_GPRS(%r15) # load registers from clone 709 lm %r6,%r15,__SF_GPRS(%r15)# load registers from clone
806 l %r1,__LC_THREAD_INFO 710 l %r1,__LC_THREAD_INFO
807 mvc __LC_USER_TIMER(8),__TI_user_timer(%r1) 711 mvc __LC_USER_TIMER(8),__TI_user_timer(%r1)
808 mvc __LC_SYSTEM_TIMER(8),__TI_system_timer(%r1) 712 mvc __LC_SYSTEM_TIMER(8),__TI_system_timer(%r1)
809 xc __LC_STEAL_TIMER(8),__LC_STEAL_TIMER 713 xc __LC_STEAL_TIMER(8),__LC_STEAL_TIMER
810 stosm __SF_EMPTY(%r15),0x04 # now we can turn dat on 714 ssm __LC_PGM_NEW_PSW # turn dat on, keep irqs off
811 basr %r14,0 715 basr %r14,0
812 l %r14,restart_addr-.(%r14) 716 l %r14,restart_addr-.(%r14)
813 basr %r14,%r14 # branch to start_secondary 717 basr %r14,%r14 # call start_secondary
814restart_addr: 718restart_addr:
815 .long start_secondary 719 .long start_secondary
816 .align 8 720 .align 8
@@ -835,19 +739,19 @@ restart_go:
835# PSW restart interrupt handler 739# PSW restart interrupt handler
836# 740#
837ENTRY(psw_restart_int_handler) 741ENTRY(psw_restart_int_handler)
838 st %r15,__LC_SAVE_AREA+48(%r0) # save r15 742 st %r15,__LC_SAVE_AREA_RESTART
839 basr %r15,0 743 basr %r15,0
8400: l %r15,.Lrestart_stack-0b(%r15) # load restart stack 7440: l %r15,.Lrestart_stack-0b(%r15) # load restart stack
841 l %r15,0(%r15) 745 l %r15,0(%r15)
842 ahi %r15,-SP_SIZE # make room for pt_regs 746 ahi %r15,-__PT_SIZE # create pt_regs on stack
843 stm %r0,%r14,SP_R0(%r15) # store gprs %r0-%r14 to stack 747 stm %r0,%r14,__PT_R0(%r15)
844 mvc SP_R15(4,%r15),__LC_SAVE_AREA+48(%r0)# store saved %r15 to stack 748 mvc __PT_R15(4,%r15),__LC_SAVE_AREA_RESTART
845 mvc SP_PSW(8,%r15),__LC_RST_OLD_PSW(%r0) # store restart old psw 749 mvc __PT_PSW(8,%r15),__LC_RST_OLD_PSW # store restart old psw
846 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # set backchain to 0 750 ahi %r15,-STACK_FRAME_OVERHEAD
751 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
847 basr %r14,0 752 basr %r14,0
8481: l %r14,.Ldo_restart-1b(%r14) 7531: l %r14,.Ldo_restart-1b(%r14)
849 basr %r14,%r14 754 basr %r14,%r14
850
851 basr %r14,0 # load disabled wait PSW if 755 basr %r14,0 # load disabled wait PSW if
8522: lpsw restart_psw_crash-2b(%r14) # do_restart returns 7562: lpsw restart_psw_crash-2b(%r14) # do_restart returns
853 .align 4 757 .align 4
@@ -869,215 +773,174 @@ restart_psw_crash:
869 */ 773 */
870stack_overflow: 774stack_overflow:
871 l %r15,__LC_PANIC_STACK # change to panic stack 775 l %r15,__LC_PANIC_STACK # change to panic stack
872 sl %r15,BASED(.Lc_spsize) 776 ahi %r15,-__PT_SIZE # create pt_regs
873 mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack 777 stm %r0,%r7,__PT_R0(%r15)
874 stm %r0,%r11,SP_R0(%r15) # store gprs %r0-%r11 to kernel stack 778 stm %r8,%r9,__PT_PSW(%r15)
875 la %r1,__LC_SAVE_AREA 779 mvc __PT_R8(32,%r11),0(%r14)
876 ch %r12,BASED(.L0x020) # old psw addr == __LC_SVC_OLD_PSW ? 780 lr %r15,%r11
877 be BASED(0f) 781 ahi %r15,-STACK_FRAME_OVERHEAD
878 ch %r12,BASED(.L0x028) # old psw addr == __LC_PGM_OLD_PSW ? 782 l %r1,BASED(1f)
879 be BASED(0f) 783 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
880 la %r1,__LC_SAVE_AREA+16 784 lr %r2,%r11 # pass pointer to pt_regs
8810: mvc SP_R12(16,%r15),0(%r1) # move %r12-%r15 to stack 785 br %r1 # branch to kernel_stack_overflow
882 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear back chain
883 l %r1,BASED(1f) # branch to kernel_stack_overflow
884 la %r2,SP_PTREGS(%r15) # load pt_regs
885 br %r1
8861: .long kernel_stack_overflow 7861: .long kernel_stack_overflow
887#endif 787#endif
888 788
889cleanup_table_system_call: 789cleanup_table:
890 .long system_call + 0x80000000, sysc_do_svc + 0x80000000 790 .long system_call + 0x80000000
891cleanup_table_sysc_tif: 791 .long sysc_do_svc + 0x80000000
892 .long sysc_tif + 0x80000000, sysc_restore + 0x80000000 792 .long sysc_tif + 0x80000000
893cleanup_table_sysc_restore: 793 .long sysc_restore + 0x80000000
894 .long sysc_restore + 0x80000000, sysc_done + 0x80000000 794 .long sysc_done + 0x80000000
895cleanup_table_io_tif: 795 .long io_tif + 0x80000000
896 .long io_tif + 0x80000000, io_restore + 0x80000000 796 .long io_restore + 0x80000000
897cleanup_table_io_restore: 797 .long io_done + 0x80000000
898 .long io_restore + 0x80000000, io_done + 0x80000000
899 798
900cleanup_critical: 799cleanup_critical:
901 clc 4(4,%r12),BASED(cleanup_table_system_call) 800 cl %r9,BASED(cleanup_table) # system_call
902 bl BASED(0f) 801 jl 0f
903 clc 4(4,%r12),BASED(cleanup_table_system_call+4) 802 cl %r9,BASED(cleanup_table+4) # sysc_do_svc
904 bl BASED(cleanup_system_call) 803 jl cleanup_system_call
9050: 804 cl %r9,BASED(cleanup_table+8) # sysc_tif
906 clc 4(4,%r12),BASED(cleanup_table_sysc_tif) 805 jl 0f
907 bl BASED(0f) 806 cl %r9,BASED(cleanup_table+12) # sysc_restore
908 clc 4(4,%r12),BASED(cleanup_table_sysc_tif+4) 807 jl cleanup_sysc_tif
909 bl BASED(cleanup_sysc_tif) 808 cl %r9,BASED(cleanup_table+16) # sysc_done
9100: 809 jl cleanup_sysc_restore
911 clc 4(4,%r12),BASED(cleanup_table_sysc_restore) 810 cl %r9,BASED(cleanup_table+20) # io_tif
912 bl BASED(0f) 811 jl 0f
913 clc 4(4,%r12),BASED(cleanup_table_sysc_restore+4) 812 cl %r9,BASED(cleanup_table+24) # io_restore
914 bl BASED(cleanup_sysc_restore) 813 jl cleanup_io_tif
9150: 814 cl %r9,BASED(cleanup_table+28) # io_done
916 clc 4(4,%r12),BASED(cleanup_table_io_tif) 815 jl cleanup_io_restore
917 bl BASED(0f) 8160: br %r14
918 clc 4(4,%r12),BASED(cleanup_table_io_tif+4)
919 bl BASED(cleanup_io_tif)
9200:
921 clc 4(4,%r12),BASED(cleanup_table_io_restore)
922 bl BASED(0f)
923 clc 4(4,%r12),BASED(cleanup_table_io_restore+4)
924 bl BASED(cleanup_io_restore)
9250:
926 br %r14
927 817
928cleanup_system_call: 818cleanup_system_call:
929 mvc __LC_RETURN_PSW(8),0(%r12) 819 # check if stpt has been executed
930 clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+4) 820 cl %r9,BASED(cleanup_system_call_insn)
931 bh BASED(0f) 821 jh 0f
932 mvc __LC_SYNC_ENTER_TIMER(8),__LC_MCCK_ENTER_TIMER
933 c %r12,BASED(.Lmck_old_psw)
934 be BASED(0f)
935 mvc __LC_SYNC_ENTER_TIMER(8),__LC_ASYNC_ENTER_TIMER 822 mvc __LC_SYNC_ENTER_TIMER(8),__LC_ASYNC_ENTER_TIMER
9360: c %r12,BASED(.Lmck_old_psw) 823 chi %r11,__LC_SAVE_AREA_ASYNC
937 la %r12,__LC_SAVE_AREA+32 824 je 0f
938 be BASED(0f) 825 mvc __LC_SYNC_ENTER_TIMER(8),__LC_MCCK_ENTER_TIMER
939 la %r12,__LC_SAVE_AREA+16 8260: # check if stm has been executed
9400: clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+8) 827 cl %r9,BASED(cleanup_system_call_insn+4)
941 bhe BASED(cleanup_vtime) 828 jh 0f
942 clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn) 829 mvc __LC_SAVE_AREA_SYNC(32),0(%r11)
943 bh BASED(0f) 8300: # set up saved registers r12, and r13
944 mvc __LC_SAVE_AREA(16),0(%r12) 831 st %r12,16(%r11) # r12 thread-info pointer
9450: st %r13,4(%r12) 832 st %r13,20(%r11) # r13 literal-pool pointer
946 l %r15,__LC_KERNEL_STACK # problem state -> load ksp 833 # check if the user time calculation has been done
947 s %r15,BASED(.Lc_spsize) # make room for registers & psw 834 cl %r9,BASED(cleanup_system_call_insn+8)
948 st %r15,12(%r12) 835 jh 0f
949 CREATE_STACK_FRAME __LC_SAVE_AREA 836 l %r10,__LC_EXIT_TIMER
950 mvc 0(4,%r12),__LC_THREAD_INFO 837 l %r15,__LC_EXIT_TIMER+4
951 l %r12,__LC_THREAD_INFO 838 SUB64 %r10,%r15,__LC_SYNC_ENTER_TIMER
952 mvc SP_PSW(8,%r15),__LC_SVC_OLD_PSW 839 ADD64 %r10,%r15,__LC_USER_TIMER
953 mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC 840 st %r10,__LC_USER_TIMER
954 oi __TI_flags+3(%r12),_TIF_SYSCALL 841 st %r15,__LC_USER_TIMER+4
955cleanup_vtime: 8420: # check if the system time calculation has been done
956 clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+12) 843 cl %r9,BASED(cleanup_system_call_insn+12)
957 bhe BASED(cleanup_stime) 844 jh 0f
958 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 845 l %r10,__LC_LAST_UPDATE_TIMER
959cleanup_stime: 846 l %r15,__LC_LAST_UPDATE_TIMER+4
960 clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+16) 847 SUB64 %r10,%r15,__LC_EXIT_TIMER
961 bh BASED(cleanup_update) 848 ADD64 %r10,%r15,__LC_SYSTEM_TIMER
962 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 849 st %r10,__LC_SYSTEM_TIMER
963cleanup_update: 850 st %r15,__LC_SYSTEM_TIMER+4
8510: # update accounting time stamp
964 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 852 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
965 mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_system_call+4) 853 # set up saved register 11
966 la %r12,__LC_RETURN_PSW 854 l %r15,__LC_KERNEL_STACK
855 ahi %r15,-__PT_SIZE
856 st %r15,12(%r11) # r11 pt_regs pointer
857 # fill pt_regs
858 mvc __PT_R8(32,%r15),__LC_SAVE_AREA_SYNC
859 stm %r0,%r7,__PT_R0(%r15)
860 mvc __PT_PSW(8,%r15),__LC_SVC_OLD_PSW
861 mvc __PT_SVC_CODE(4,%r15),__LC_SVC_ILC
862 # setup saved register 15
863 ahi %r15,-STACK_FRAME_OVERHEAD
864 st %r15,28(%r11) # r15 stack pointer
865 # set new psw address and exit
866 l %r9,BASED(cleanup_table+4) # sysc_do_svc + 0x80000000
967 br %r14 867 br %r14
968cleanup_system_call_insn: 868cleanup_system_call_insn:
969 .long sysc_saveall + 0x80000000
970 .long system_call + 0x80000000 869 .long system_call + 0x80000000
971 .long sysc_vtime + 0x80000000 870 .long sysc_stm + 0x80000000
972 .long sysc_stime + 0x80000000 871 .long sysc_vtime + 0x80000000 + 36
973 .long sysc_update + 0x80000000 872 .long sysc_vtime + 0x80000000 + 76
974 873
975cleanup_sysc_tif: 874cleanup_sysc_tif:
976 mvc __LC_RETURN_PSW(4),0(%r12) 875 l %r9,BASED(cleanup_table+8) # sysc_tif + 0x80000000
977 mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_sysc_tif)
978 la %r12,__LC_RETURN_PSW
979 br %r14 876 br %r14
980 877
981cleanup_sysc_restore: 878cleanup_sysc_restore:
982 clc 4(4,%r12),BASED(cleanup_sysc_restore_insn) 879 cl %r9,BASED(cleanup_sysc_restore_insn)
983 be BASED(2f) 880 jhe 0f
984 mvc __LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER 881 l %r9,12(%r11) # get saved pointer to pt_regs
985 c %r12,BASED(.Lmck_old_psw) 882 mvc __LC_RETURN_PSW(8),__PT_PSW(%r9)
986 be BASED(0f) 883 mvc 0(32,%r11),__PT_R8(%r9)
987 mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER 884 lm %r0,%r7,__PT_R0(%r9)
9880: clc 4(4,%r12),BASED(cleanup_sysc_restore_insn+4) 8850: lm %r8,%r9,__LC_RETURN_PSW
989 be BASED(2f)
990 mvc __LC_RETURN_PSW(8),SP_PSW(%r15)
991 c %r12,BASED(.Lmck_old_psw)
992 la %r12,__LC_SAVE_AREA+32
993 be BASED(1f)
994 la %r12,__LC_SAVE_AREA+16
9951: mvc 0(16,%r12),SP_R12(%r15)
996 lm %r0,%r11,SP_R0(%r15)
997 l %r15,SP_R15(%r15)
9982: la %r12,__LC_RETURN_PSW
999 br %r14 886 br %r14
1000cleanup_sysc_restore_insn: 887cleanup_sysc_restore_insn:
1001 .long sysc_done - 4 + 0x80000000 888 .long sysc_done - 4 + 0x80000000
1002 .long sysc_done - 8 + 0x80000000
1003 889
1004cleanup_io_tif: 890cleanup_io_tif:
1005 mvc __LC_RETURN_PSW(4),0(%r12) 891 l %r9,BASED(cleanup_table+20) # io_tif + 0x80000000
1006 mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_io_tif)
1007 la %r12,__LC_RETURN_PSW
1008 br %r14 892 br %r14
1009 893
1010cleanup_io_restore: 894cleanup_io_restore:
1011 clc 4(4,%r12),BASED(cleanup_io_restore_insn) 895 cl %r9,BASED(cleanup_io_restore_insn)
1012 be BASED(1f) 896 jhe 0f
1013 mvc __LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER 897 l %r9,12(%r11) # get saved r11 pointer to pt_regs
1014 clc 4(4,%r12),BASED(cleanup_io_restore_insn+4) 898 mvc __LC_RETURN_PSW(8),__PT_PSW(%r9)
1015 be BASED(1f) 899 ni __LC_RETURN_PSW+1,0xfd # clear wait state bit
1016 mvc __LC_RETURN_PSW(8),SP_PSW(%r15) 900 mvc 0(32,%r11),__PT_R8(%r9)
1017 mvc __LC_SAVE_AREA+32(16),SP_R12(%r15) 901 lm %r0,%r7,__PT_R0(%r9)
1018 lm %r0,%r11,SP_R0(%r15) 9020: lm %r8,%r9,__LC_RETURN_PSW
1019 l %r15,SP_R15(%r15)
10201: la %r12,__LC_RETURN_PSW
1021 br %r14 903 br %r14
1022cleanup_io_restore_insn: 904cleanup_io_restore_insn:
1023 .long io_done - 4 + 0x80000000 905 .long io_done - 4 + 0x80000000
1024 .long io_done - 8 + 0x80000000
1025 906
1026/* 907/*
1027 * Integer constants 908 * Integer constants
1028 */ 909 */
1029 .align 4 910 .align 4
1030.Lc_spsize: .long SP_SIZE 911.Lnr_syscalls: .long NR_syscalls
1031.Lc_overhead: .long STACK_FRAME_OVERHEAD
1032.Lnr_syscalls: .long NR_syscalls
1033.L0x018: .short 0x018
1034.L0x020: .short 0x020
1035.L0x028: .short 0x028
1036.L0x030: .short 0x030
1037.L0x038: .short 0x038
1038.Lc_1: .long 1
1039 912
1040/* 913/*
1041 * Symbol constants 914 * Symbol constants
1042 */ 915 */
1043.Ls390_mcck: .long s390_do_machine_check 916.Ldo_machine_check: .long s390_do_machine_check
1044.Ls390_handle_mcck: 917.Lhandle_mcck: .long s390_handle_mcck
1045 .long s390_handle_mcck 918.Ldo_IRQ: .long do_IRQ
1046.Lmck_old_psw: .long __LC_MCK_OLD_PSW 919.Ldo_extint: .long do_extint
1047.Ldo_IRQ: .long do_IRQ 920.Ldo_signal: .long do_signal
1048.Ldo_extint: .long do_extint 921.Ldo_notify_resume: .long do_notify_resume
1049.Ldo_signal: .long do_signal 922.Ldo_per_trap: .long do_per_trap
1050.Ldo_notify_resume: 923.Ldo_execve: .long do_execve
1051 .long do_notify_resume 924.Lexecve_tail: .long execve_tail
1052.Lhandle_per: .long do_per_trap 925.Ljump_table: .long pgm_check_table
1053.Ldo_execve: .long do_execve 926.Lschedule: .long schedule
1054.Lexecve_tail: .long execve_tail
1055.Ljump_table: .long pgm_check_table
1056.Lschedule: .long schedule
1057#ifdef CONFIG_PREEMPT 927#ifdef CONFIG_PREEMPT
1058.Lpreempt_schedule_irq: 928.Lpreempt_irq: .long preempt_schedule_irq
1059 .long preempt_schedule_irq
1060#endif 929#endif
1061.Ltrace_entry: .long do_syscall_trace_enter 930.Ltrace_enter: .long do_syscall_trace_enter
1062.Ltrace_exit: .long do_syscall_trace_exit 931.Ltrace_exit: .long do_syscall_trace_exit
1063.Lschedtail: .long schedule_tail 932.Lschedule_tail: .long schedule_tail
1064.Lsysc_table: .long sys_call_table 933.Lsys_call_table: .long sys_call_table
934.Lsysc_per: .long sysc_per + 0x80000000
1065#ifdef CONFIG_TRACE_IRQFLAGS 935#ifdef CONFIG_TRACE_IRQFLAGS
1066.Ltrace_irq_on_caller: 936.Lhardirqs_on: .long trace_hardirqs_on_caller
1067 .long trace_hardirqs_on_caller 937.Lhardirqs_off: .long trace_hardirqs_off_caller
1068.Ltrace_irq_off_caller:
1069 .long trace_hardirqs_off_caller
1070#endif 938#endif
1071#ifdef CONFIG_LOCKDEP 939#ifdef CONFIG_LOCKDEP
1072.Llockdep_sys_exit: 940.Llockdep_sys_exit: .long lockdep_sys_exit
1073 .long lockdep_sys_exit
1074#endif 941#endif
1075.Lcritical_start: 942.Lcritical_start: .long __critical_start + 0x80000000
1076 .long __critical_start + 0x80000000 943.Lcritical_length: .long __critical_end - __critical_start
1077.Lcritical_end:
1078 .long __critical_end + 0x80000000
1079.Lcleanup_critical:
1080 .long cleanup_critical
1081 944
1082 .section .rodata, "a" 945 .section .rodata, "a"
1083#define SYSCALL(esa,esame,emu) .long esa 946#define SYSCALL(esa,esame,emu) .long esa
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 130fb02305c1..73845a9e587c 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -1,3 +1,4 @@
1
1/* 2/*
2 * arch/s390/kernel/entry64.S 3 * arch/s390/kernel/entry64.S
3 * S390 low-level entry points. 4 * S390 low-level entry points.
@@ -19,32 +20,22 @@
19#include <asm/unistd.h> 20#include <asm/unistd.h>
20#include <asm/page.h> 21#include <asm/page.h>
21 22
22/* 23__PT_R0 = __PT_GPRS
23 * Stack layout for the system_call stack entry. 24__PT_R1 = __PT_GPRS + 8
24 * The first few entries are identical to the user_regs_struct. 25__PT_R2 = __PT_GPRS + 16
25 */ 26__PT_R3 = __PT_GPRS + 24
26SP_PTREGS = STACK_FRAME_OVERHEAD 27__PT_R4 = __PT_GPRS + 32
27SP_ARGS = STACK_FRAME_OVERHEAD + __PT_ARGS 28__PT_R5 = __PT_GPRS + 40
28SP_PSW = STACK_FRAME_OVERHEAD + __PT_PSW 29__PT_R6 = __PT_GPRS + 48
29SP_R0 = STACK_FRAME_OVERHEAD + __PT_GPRS 30__PT_R7 = __PT_GPRS + 56
30SP_R1 = STACK_FRAME_OVERHEAD + __PT_GPRS + 8 31__PT_R8 = __PT_GPRS + 64
31SP_R2 = STACK_FRAME_OVERHEAD + __PT_GPRS + 16 32__PT_R9 = __PT_GPRS + 72
32SP_R3 = STACK_FRAME_OVERHEAD + __PT_GPRS + 24 33__PT_R10 = __PT_GPRS + 80
33SP_R4 = STACK_FRAME_OVERHEAD + __PT_GPRS + 32 34__PT_R11 = __PT_GPRS + 88
34SP_R5 = STACK_FRAME_OVERHEAD + __PT_GPRS + 40 35__PT_R12 = __PT_GPRS + 96
35SP_R6 = STACK_FRAME_OVERHEAD + __PT_GPRS + 48 36__PT_R13 = __PT_GPRS + 104
36SP_R7 = STACK_FRAME_OVERHEAD + __PT_GPRS + 56 37__PT_R14 = __PT_GPRS + 112
37SP_R8 = STACK_FRAME_OVERHEAD + __PT_GPRS + 64 38__PT_R15 = __PT_GPRS + 120
38SP_R9 = STACK_FRAME_OVERHEAD + __PT_GPRS + 72
39SP_R10 = STACK_FRAME_OVERHEAD + __PT_GPRS + 80
40SP_R11 = STACK_FRAME_OVERHEAD + __PT_GPRS + 88
41SP_R12 = STACK_FRAME_OVERHEAD + __PT_GPRS + 96
42SP_R13 = STACK_FRAME_OVERHEAD + __PT_GPRS + 104
43SP_R14 = STACK_FRAME_OVERHEAD + __PT_GPRS + 112
44SP_R15 = STACK_FRAME_OVERHEAD + __PT_GPRS + 120
45SP_ORIG_R2 = STACK_FRAME_OVERHEAD + __PT_ORIG_GPR2
46SP_SVC_CODE = STACK_FRAME_OVERHEAD + __PT_SVC_CODE
47SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE
48 39
49STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER 40STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER
50STACK_SIZE = 1 << STACK_SHIFT 41STACK_SIZE = 1 << STACK_SHIFT
@@ -59,154 +50,103 @@ _TIF_EXIT_SIE = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING)
59 50
60#define BASED(name) name-system_call(%r13) 51#define BASED(name) name-system_call(%r13)
61 52
62 .macro SPP newpp
63#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
64 tm __LC_MACHINE_FLAGS+6,0x20 # MACHINE_FLAG_SPP
65 jz .+8
66 .insn s,0xb2800000,\newpp
67#endif
68 .endm
69
70 .macro HANDLE_SIE_INTERCEPT
71#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
72 tm __TI_flags+6(%r12),_TIF_SIE>>8
73 jz 0f
74 SPP BASED(.Lhost_id) # set host id
75 clc SP_PSW+8(8,%r15),BASED(.Lsie_loop)
76 jl 0f
77 clc SP_PSW+8(8,%r15),BASED(.Lsie_done)
78 jhe 0f
79 mvc SP_PSW+8(8,%r15),BASED(.Lsie_loop)
800:
81#endif
82 .endm
83
84#ifdef CONFIG_TRACE_IRQFLAGS
85 .macro TRACE_IRQS_ON 53 .macro TRACE_IRQS_ON
54#ifdef CONFIG_TRACE_IRQFLAGS
86 basr %r2,%r0 55 basr %r2,%r0
87 brasl %r14,trace_hardirqs_on_caller 56 brasl %r14,trace_hardirqs_on_caller
57#endif
88 .endm 58 .endm
89 59
90 .macro TRACE_IRQS_OFF 60 .macro TRACE_IRQS_OFF
61#ifdef CONFIG_TRACE_IRQFLAGS
91 basr %r2,%r0 62 basr %r2,%r0
92 brasl %r14,trace_hardirqs_off_caller 63 brasl %r14,trace_hardirqs_off_caller
93 .endm
94#else
95#define TRACE_IRQS_ON
96#define TRACE_IRQS_OFF
97#endif 64#endif
65 .endm
98 66
99#ifdef CONFIG_LOCKDEP
100 .macro LOCKDEP_SYS_EXIT 67 .macro LOCKDEP_SYS_EXIT
101 tm SP_PSW+1(%r15),0x01 # returning to user ? 68#ifdef CONFIG_LOCKDEP
102 jz 0f 69 tm __PT_PSW+1(%r11),0x01 # returning to user ?
70 jz .+10
103 brasl %r14,lockdep_sys_exit 71 brasl %r14,lockdep_sys_exit
1040:
105 .endm
106#else
107#define LOCKDEP_SYS_EXIT
108#endif 72#endif
109
110 .macro UPDATE_VTIME lc_from,lc_to,lc_sum
111 lg %r10,\lc_from
112 slg %r10,\lc_to
113 alg %r10,\lc_sum
114 stg %r10,\lc_sum
115 .endm 73 .endm
116 74
117/* 75 .macro SPP newpp
118 * Register usage in interrupt handlers: 76#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
119 * R9 - pointer to current task structure 77 tm __LC_MACHINE_FLAGS+6,0x20 # MACHINE_FLAG_SPP
120 * R13 - pointer to literal pool 78 jz .+8
121 * R14 - return register for function calls 79 .insn s,0xb2800000,\newpp
122 * R15 - kernel stack pointer 80#endif
123 */ 81 .endm
124 82
125 .macro SAVE_ALL_SVC psworg,savearea 83 .macro HANDLE_SIE_INTERCEPT scratch
126 stmg %r11,%r15,\savearea 84#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
127 lg %r15,__LC_KERNEL_STACK # problem state -> load ksp 85 tm __TI_flags+6(%r12),_TIF_SIE>>8
128 aghi %r15,-SP_SIZE # make room for registers & psw 86 jz .+42
129 lg %r11,__LC_LAST_BREAK 87 tm __LC_MACHINE_FLAGS+6,0x20 # MACHINE_FLAG_SPP
88 jz .+8
89 .insn s,0xb2800000,BASED(.Lhost_id) # set host id
90 lgr \scratch,%r9
91 slg \scratch,BASED(.Lsie_loop)
92 clg \scratch,BASED(.Lsie_length)
93 jhe .+10
94 lg %r9,BASED(.Lsie_loop)
95#endif
130 .endm 96 .endm
131 97
132 .macro SAVE_ALL_PGM psworg,savearea 98 .macro CHECK_STACK stacksize,savearea
133 stmg %r11,%r15,\savearea
134 tm \psworg+1,0x01 # test problem state bit
135#ifdef CONFIG_CHECK_STACK 99#ifdef CONFIG_CHECK_STACK
136 jnz 1f 100 tml %r15,\stacksize - CONFIG_STACK_GUARD
137 tml %r15,STACK_SIZE - CONFIG_STACK_GUARD 101 lghi %r14,\savearea
138 jnz 2f 102 jz stack_overflow
139 la %r12,\psworg
140 j stack_overflow
141#else
142 jz 2f
143#endif 103#endif
1441: lg %r15,__LC_KERNEL_STACK # problem state -> load ksp
1452: aghi %r15,-SP_SIZE # make room for registers & psw
146 larl %r13,system_call
147 lg %r11,__LC_LAST_BREAK
148 .endm 104 .endm
149 105
150 .macro SAVE_ALL_ASYNC psworg,savearea 106 .macro SWITCH_ASYNC savearea,stack,shift
151 stmg %r11,%r15,\savearea 107 tmhh %r8,0x0001 # interrupting from user ?
152 larl %r13,system_call 108 jnz 1f
153 lg %r11,__LC_LAST_BREAK 109 lgr %r14,%r9
154 la %r12,\psworg 110 slg %r14,BASED(.Lcritical_start)
155 tm \psworg+1,0x01 # test problem state bit 111 clg %r14,BASED(.Lcritical_length)
156 jnz 1f # from user -> load kernel stack
157 clc \psworg+8(8),BASED(.Lcritical_end)
158 jhe 0f 112 jhe 0f
159 clc \psworg+8(8),BASED(.Lcritical_start) 113 lghi %r11,\savearea # inside critical section, do cleanup
160 jl 0f
161 brasl %r14,cleanup_critical 114 brasl %r14,cleanup_critical
162 tm 1(%r12),0x01 # retest problem state after cleanup 115 tmhh %r8,0x0001 # retest problem state after cleanup
163 jnz 1f 116 jnz 1f
1640: lg %r14,__LC_ASYNC_STACK # are we already on the async. stack ? 1170: lg %r14,\stack # are we already on the target stack?
165 slgr %r14,%r15 118 slgr %r14,%r15
166 srag %r14,%r14,STACK_SHIFT 119 srag %r14,%r14,\shift
167#ifdef CONFIG_CHECK_STACK
168 jnz 1f 120 jnz 1f
169 tml %r15,STACK_SIZE - CONFIG_STACK_GUARD 121 CHECK_STACK 1<<\shift,\savearea
170 jnz 2f 122 j 2f
171 j stack_overflow 1231: lg %r15,\stack # load target stack
172#else 1242: aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
173 jz 2f 125 la %r11,STACK_FRAME_OVERHEAD(%r15)
174#endif
1751: lg %r15,__LC_ASYNC_STACK # load async stack
1762: aghi %r15,-SP_SIZE # make room for registers & psw
177 .endm
178
179 .macro CREATE_STACK_FRAME savearea
180 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
181 stg %r2,SP_ORIG_R2(%r15) # store original content of gpr 2
182 mvc SP_R11(40,%r15),\savearea # move %r11-%r15 to stack
183 stmg %r0,%r10,SP_R0(%r15) # store gprs %r0-%r10 to kernel stack
184 .endm 126 .endm
185 127
186 .macro RESTORE_ALL psworg,sync 128 .macro UPDATE_VTIME scratch,enter_timer
187 mvc \psworg(16),SP_PSW(%r15) # move user PSW to lowcore 129 lg \scratch,__LC_EXIT_TIMER
188 .if !\sync 130 slg \scratch,\enter_timer
189 ni \psworg+1,0xfd # clear wait state bit 131 alg \scratch,__LC_USER_TIMER
190 .endif 132 stg \scratch,__LC_USER_TIMER
191 lg %r14,__LC_VDSO_PER_CPU 133 lg \scratch,__LC_LAST_UPDATE_TIMER
192 lmg %r0,%r13,SP_R0(%r15) # load gprs 0-13 of user 134 slg \scratch,__LC_EXIT_TIMER
193 stpt __LC_EXIT_TIMER 135 alg \scratch,__LC_SYSTEM_TIMER
194 mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER 136 stg \scratch,__LC_SYSTEM_TIMER
195 lmg %r14,%r15,SP_R14(%r15) # load grps 14-15 of user 137 mvc __LC_LAST_UPDATE_TIMER(8),\enter_timer
196 lpswe \psworg # back to caller
197 .endm 138 .endm
198 139
199 .macro LAST_BREAK 140 .macro LAST_BREAK scratch
200 srag %r10,%r11,23 141 srag \scratch,%r10,23
201 jz 0f 142 jz .+10
202 stg %r11,__TI_last_break(%r12) 143 stg %r10,__TI_last_break(%r12)
2030:
204 .endm 144 .endm
205 145
206 .macro REENABLE_IRQS 146 .macro REENABLE_IRQS
207 mvc __SF_EMPTY(1,%r15),SP_PSW(%r15) 147 stg %r8,__LC_RETURN_PSW
208 ni __SF_EMPTY(%r15),0xbf 148 ni __LC_RETURN_PSW,0xbf
209 ssm __SF_EMPTY(%r15) 149 ssm __LC_RETURN_PSW
210 .endm 150 .endm
211 151
212 .section .kprobes.text, "ax" 152 .section .kprobes.text, "ax"
@@ -245,55 +185,66 @@ __critical_start:
245 185
246ENTRY(system_call) 186ENTRY(system_call)
247 stpt __LC_SYNC_ENTER_TIMER 187 stpt __LC_SYNC_ENTER_TIMER
248sysc_saveall: 188sysc_stmg:
249 SAVE_ALL_SVC __LC_SVC_OLD_PSW,__LC_SAVE_AREA 189 stmg %r8,%r15,__LC_SAVE_AREA_SYNC
250 CREATE_STACK_FRAME __LC_SAVE_AREA 190 lg %r10,__LC_LAST_BREAK
251 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct 191 lg %r12,__LC_THREAD_INFO
252 mvc SP_PSW(16,%r15),__LC_SVC_OLD_PSW 192 larl %r13,system_call
253 mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC 193sysc_per:
254 oi __TI_flags+7(%r12),_TIF_SYSCALL 194 lg %r15,__LC_KERNEL_STACK
195 aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
196 la %r11,STACK_FRAME_OVERHEAD(%r15) # pointer to pt_regs
255sysc_vtime: 197sysc_vtime:
256 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 198 UPDATE_VTIME %r13,__LC_SYNC_ENTER_TIMER
257sysc_stime: 199 LAST_BREAK %r13
258 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 200 stmg %r0,%r7,__PT_R0(%r11)
259sysc_update: 201 mvc __PT_R8(64,%r11),__LC_SAVE_AREA_SYNC
260 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 202 mvc __PT_PSW(16,%r11),__LC_SVC_OLD_PSW
261 LAST_BREAK 203 mvc __PT_SVC_CODE(4,%r11),__LC_SVC_ILC
262sysc_do_svc: 204sysc_do_svc:
263 llgh %r7,SP_SVC_CODE+2(%r15) 205 oi __TI_flags+7(%r12),_TIF_SYSCALL
264 slag %r7,%r7,2 # shift and test for svc 0 206 llgh %r8,__PT_SVC_CODE+2(%r11)
207 slag %r8,%r8,2 # shift and test for svc 0
265 jnz sysc_nr_ok 208 jnz sysc_nr_ok
266 # svc 0: system call number in %r1 209 # svc 0: system call number in %r1
267 llgfr %r1,%r1 # clear high word in r1 210 llgfr %r1,%r1 # clear high word in r1
268 cghi %r1,NR_syscalls 211 cghi %r1,NR_syscalls
269 jnl sysc_nr_ok 212 jnl sysc_nr_ok
270 sth %r1,SP_SVC_CODE+2(%r15) 213 sth %r1,__PT_SVC_CODE+2(%r11)
271 slag %r7,%r1,2 # shift and test for svc 0 214 slag %r8,%r1,2
272sysc_nr_ok: 215sysc_nr_ok:
273 larl %r10,sys_call_table 216 larl %r10,sys_call_table # 64 bit system call table
274#ifdef CONFIG_COMPAT 217#ifdef CONFIG_COMPAT
275 tm __TI_flags+5(%r12),(_TIF_31BIT>>16) # running in 31 bit mode ? 218 tm __TI_flags+5(%r12),(_TIF_31BIT>>16)
276 jno sysc_noemu 219 jno sysc_noemu
277 larl %r10,sys_call_table_emu # use 31 bit emulation system calls 220 larl %r10,sys_call_table_emu # 31 bit system call table
278sysc_noemu: 221sysc_noemu:
279#endif 222#endif
223 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
224 stg %r2,__PT_ORIG_GPR2(%r11)
225 stg %r7,STACK_FRAME_OVERHEAD(%r15)
226 lgf %r9,0(%r8,%r10) # get system call add.
280 tm __TI_flags+6(%r12),_TIF_TRACE >> 8 227 tm __TI_flags+6(%r12),_TIF_TRACE >> 8
281 mvc SP_ARGS(8,%r15),SP_R7(%r15)
282 lgf %r8,0(%r7,%r10) # load address of system call routine
283 jnz sysc_tracesys 228 jnz sysc_tracesys
284 basr %r14,%r8 # call sys_xxxx 229 basr %r14,%r9 # call sys_xxxx
285 stg %r2,SP_R2(%r15) # store return value (change R2 on stack) 230 stg %r2,__PT_R2(%r11) # store return value
286 231
287sysc_return: 232sysc_return:
288 LOCKDEP_SYS_EXIT 233 LOCKDEP_SYS_EXIT
289sysc_tif: 234sysc_tif:
290 tm SP_PSW+1(%r15),0x01 # returning to user ? 235 tm __PT_PSW+1(%r11),0x01 # returning to user ?
291 jno sysc_restore 236 jno sysc_restore
292 tm __TI_flags+7(%r12),_TIF_WORK_SVC 237 tm __TI_flags+7(%r12),_TIF_WORK_SVC
293 jnz sysc_work # there is work to do (signals etc.) 238 jnz sysc_work # check for work
294 ni __TI_flags+7(%r12),255-_TIF_SYSCALL 239 ni __TI_flags+7(%r12),255-_TIF_SYSCALL
295sysc_restore: 240sysc_restore:
296 RESTORE_ALL __LC_RETURN_PSW,1 241 lg %r14,__LC_VDSO_PER_CPU
242 lmg %r0,%r10,__PT_R0(%r11)
243 mvc __LC_RETURN_PSW(16),__PT_PSW(%r11)
244 stpt __LC_EXIT_TIMER
245 mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
246 lmg %r11,%r15,__PT_R11(%r11)
247 lpswe __LC_RETURN_PSW
297sysc_done: 248sysc_done:
298 249
299# 250#
@@ -317,7 +268,7 @@ sysc_work:
317# 268#
318sysc_reschedule: 269sysc_reschedule:
319 larl %r14,sysc_return 270 larl %r14,sysc_return
320 jg schedule # return point is sysc_return 271 jg schedule
321 272
322# 273#
323# _TIF_MCCK_PENDING is set, call handler 274# _TIF_MCCK_PENDING is set, call handler
@@ -331,33 +282,33 @@ sysc_mcck_pending:
331# 282#
332sysc_sigpending: 283sysc_sigpending:
333 ni __TI_flags+7(%r12),255-_TIF_PER_TRAP # clear TIF_PER_TRAP 284 ni __TI_flags+7(%r12),255-_TIF_PER_TRAP # clear TIF_PER_TRAP
334 la %r2,SP_PTREGS(%r15) # load pt_regs 285 lgr %r2,%r11 # pass pointer to pt_regs
335 brasl %r14,do_signal # call do_signal 286 brasl %r14,do_signal
336 tm __TI_flags+7(%r12),_TIF_SYSCALL 287 tm __TI_flags+7(%r12),_TIF_SYSCALL
337 jno sysc_return 288 jno sysc_return
338 lmg %r2,%r6,SP_R2(%r15) # load svc arguments 289 lmg %r2,%r7,__PT_R2(%r11) # load svc arguments
339 lghi %r7,0 # svc 0 returns -ENOSYS 290 lghi %r8,0 # svc 0 returns -ENOSYS
340 lh %r1,SP_SVC_CODE+2(%r15) # load new svc number 291 lh %r1,__PT_SVC_CODE+2(%r11) # load new svc number
341 cghi %r1,NR_syscalls 292 cghi %r1,NR_syscalls
342 jnl sysc_nr_ok # invalid svc number -> do svc 0 293 jnl sysc_nr_ok # invalid svc number -> do svc 0
343 slag %r7,%r1,2 294 slag %r8,%r1,2
344 j sysc_nr_ok # restart svc 295 j sysc_nr_ok # restart svc
345 296
346# 297#
347# _TIF_NOTIFY_RESUME is set, call do_notify_resume 298# _TIF_NOTIFY_RESUME is set, call do_notify_resume
348# 299#
349sysc_notify_resume: 300sysc_notify_resume:
350 la %r2,SP_PTREGS(%r15) # load pt_regs 301 lgr %r2,%r11 # pass pointer to pt_regs
351 larl %r14,sysc_return 302 larl %r14,sysc_return
352 jg do_notify_resume # call do_notify_resume 303 jg do_notify_resume
353 304
354# 305#
355# _TIF_PER_TRAP is set, call do_per_trap 306# _TIF_PER_TRAP is set, call do_per_trap
356# 307#
357sysc_singlestep: 308sysc_singlestep:
358 ni __TI_flags+7(%r12),255-(_TIF_SYSCALL | _TIF_PER_TRAP) 309 ni __TI_flags+7(%r12),255-(_TIF_SYSCALL | _TIF_PER_TRAP)
359 la %r2,SP_PTREGS(%r15) # address of register-save area 310 lgr %r2,%r11 # pass pointer to pt_regs
360 larl %r14,sysc_return # load adr. of system return 311 larl %r14,sysc_return
361 jg do_per_trap 312 jg do_per_trap
362 313
363# 314#
@@ -365,41 +316,41 @@ sysc_singlestep:
365# and after the system call 316# and after the system call
366# 317#
367sysc_tracesys: 318sysc_tracesys:
368 la %r2,SP_PTREGS(%r15) # load pt_regs 319 lgr %r2,%r11 # pass pointer to pt_regs
369 la %r3,0 320 la %r3,0
370 llgh %r0,SP_SVC_CODE+2(%r15) 321 llgh %r0,__PT_SVC_CODE+2(%r11)
371 stg %r0,SP_R2(%r15) 322 stg %r0,__PT_R2(%r11)
372 brasl %r14,do_syscall_trace_enter 323 brasl %r14,do_syscall_trace_enter
373 lghi %r0,NR_syscalls 324 lghi %r0,NR_syscalls
374 clgr %r0,%r2 325 clgr %r0,%r2
375 jnh sysc_tracenogo 326 jnh sysc_tracenogo
376 sllg %r7,%r2,2 # svc number *4 327 sllg %r8,%r2,2
377 lgf %r8,0(%r7,%r10) 328 lgf %r9,0(%r8,%r10)
378sysc_tracego: 329sysc_tracego:
379 lmg %r3,%r6,SP_R3(%r15) 330 lmg %r3,%r7,__PT_R3(%r11)
380 mvc SP_ARGS(8,%r15),SP_R7(%r15) 331 stg %r7,STACK_FRAME_OVERHEAD(%r15)
381 lg %r2,SP_ORIG_R2(%r15) 332 lg %r2,__PT_ORIG_GPR2(%r11)
382 basr %r14,%r8 # call sys_xxx 333 basr %r14,%r9 # call sys_xxx
383 stg %r2,SP_R2(%r15) # store return value 334 stg %r2,__PT_R2(%r11) # store return value
384sysc_tracenogo: 335sysc_tracenogo:
385 tm __TI_flags+6(%r12),_TIF_TRACE >> 8 336 tm __TI_flags+6(%r12),_TIF_TRACE >> 8
386 jz sysc_return 337 jz sysc_return
387 la %r2,SP_PTREGS(%r15) # load pt_regs 338 lgr %r2,%r11 # pass pointer to pt_regs
388 larl %r14,sysc_return # return point is sysc_return 339 larl %r14,sysc_return
389 jg do_syscall_trace_exit 340 jg do_syscall_trace_exit
390 341
391# 342#
392# a new process exits the kernel with ret_from_fork 343# a new process exits the kernel with ret_from_fork
393# 344#
394ENTRY(ret_from_fork) 345ENTRY(ret_from_fork)
395 lg %r13,__LC_SVC_NEW_PSW+8 346 la %r11,STACK_FRAME_OVERHEAD(%r15)
396 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct 347 lg %r12,__LC_THREAD_INFO
397 tm SP_PSW+1(%r15),0x01 # forking a kernel thread ? 348 tm __PT_PSW+1(%r11),0x01 # forking a kernel thread ?
398 jo 0f 349 jo 0f
399 stg %r15,SP_R15(%r15) # store stack pointer for new kthread 350 stg %r15,__PT_R15(%r11) # store stack pointer for new kthread
4000: brasl %r14,schedule_tail 3510: brasl %r14,schedule_tail
401 TRACE_IRQS_ON 352 TRACE_IRQS_ON
402 stosm 24(%r15),0x03 # reenable interrupts 353 ssm __LC_SVC_NEW_PSW # reenable interrupts
403 j sysc_tracenogo 354 j sysc_tracenogo
404 355
405# 356#
@@ -409,26 +360,26 @@ ENTRY(ret_from_fork)
409ENTRY(kernel_execve) 360ENTRY(kernel_execve)
410 stmg %r12,%r15,96(%r15) 361 stmg %r12,%r15,96(%r15)
411 lgr %r14,%r15 362 lgr %r14,%r15
412 aghi %r15,-SP_SIZE 363 aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
413 stg %r14,__SF_BACKCHAIN(%r15) 364 stg %r14,__SF_BACKCHAIN(%r15)
414 la %r12,SP_PTREGS(%r15) 365 la %r12,STACK_FRAME_OVERHEAD(%r15)
415 xc 0(__PT_SIZE,%r12),0(%r12) 366 xc 0(__PT_SIZE,%r12),0(%r12)
416 lgr %r5,%r12 367 lgr %r5,%r12
417 brasl %r14,do_execve 368 brasl %r14,do_execve
418 ltgfr %r2,%r2 369 ltgfr %r2,%r2
419 je 0f 370 je 0f
420 aghi %r15,SP_SIZE 371 aghi %r15,(STACK_FRAME_OVERHEAD + __PT_SIZE)
421 lmg %r12,%r15,96(%r15) 372 lmg %r12,%r15,96(%r15)
422 br %r14 373 br %r14
423 # execve succeeded. 374 # execve succeeded.
4240: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts 3750: ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
425 lg %r15,__LC_KERNEL_STACK # load ksp 376 lg %r15,__LC_KERNEL_STACK # load ksp
426 aghi %r15,-SP_SIZE # make room for registers & psw 377 aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
427 lg %r13,__LC_SVC_NEW_PSW+8 378 la %r11,STACK_FRAME_OVERHEAD(%r15)
428 mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs 379 mvc 0(__PT_SIZE,%r11),0(%r12) # copy pt_regs
429 lg %r12,__LC_THREAD_INFO 380 lg %r12,__LC_THREAD_INFO
430 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 381 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
431 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 382 ssm __LC_SVC_NEW_PSW # reenable interrupts
432 brasl %r14,execve_tail 383 brasl %r14,execve_tail
433 j sysc_return 384 j sysc_return
434 385
@@ -437,127 +388,72 @@ ENTRY(kernel_execve)
437 */ 388 */
438 389
439ENTRY(pgm_check_handler) 390ENTRY(pgm_check_handler)
440/*
441 * First we need to check for a special case:
442 * Single stepping an instruction that disables the PER event mask will
443 * cause a PER event AFTER the mask has been set. Example: SVC or LPSW.
444 * For a single stepped SVC the program check handler gets control after
445 * the SVC new PSW has been loaded. But we want to execute the SVC first and
446 * then handle the PER event. Therefore we update the SVC old PSW to point
447 * to the pgm_check_handler and branch to the SVC handler after we checked
448 * if we have to load the kernel stack register.
449 * For every other possible cause for PER event without the PER mask set
450 * we just ignore the PER event (FIXME: is there anything we have to do
451 * for LPSW?).
452 */
453 stpt __LC_SYNC_ENTER_TIMER 391 stpt __LC_SYNC_ENTER_TIMER
454 tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception 392 stmg %r8,%r15,__LC_SAVE_AREA_SYNC
455 jnz pgm_per # got per exception -> special case 393 lg %r10,__LC_LAST_BREAK
456 SAVE_ALL_PGM __LC_PGM_OLD_PSW,__LC_SAVE_AREA 394 lg %r12,__LC_THREAD_INFO
457 CREATE_STACK_FRAME __LC_SAVE_AREA 395 larl %r13,system_call
458 mvc SP_PSW(16,%r15),__LC_PGM_OLD_PSW 396 lmg %r8,%r9,__LC_PGM_OLD_PSW
459 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct 397 HANDLE_SIE_INTERCEPT %r14
460 HANDLE_SIE_INTERCEPT 398 tmhh %r8,0x0001 # test problem state bit
461 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 399 jnz 1f # -> fault in user space
462 jz pgm_no_vtime 400 tmhh %r8,0x4000 # PER bit set in old PSW ?
463 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 401 jnz 0f # -> enabled, can't be a double fault
464 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 402 tm __LC_PGM_ILC+3,0x80 # check for per exception
465 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 403 jnz pgm_svcper # -> single stepped svc
466 LAST_BREAK 4040: CHECK_STACK STACK_SIZE,__LC_SAVE_AREA_SYNC
467pgm_no_vtime: 405 j 2f
468 stg %r11,SP_ARGS(%r15) 4061: UPDATE_VTIME %r14,__LC_SYNC_ENTER_TIMER
469 lgf %r3,__LC_PGM_ILC # load program interruption code 407 LAST_BREAK %r14
470 lg %r4,__LC_TRANS_EXC_CODE 408 lg %r15,__LC_KERNEL_STACK
471 REENABLE_IRQS 4092: aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
472 lghi %r8,0x7f 410 la %r11,STACK_FRAME_OVERHEAD(%r15)
473 ngr %r8,%r3 411 stmg %r0,%r7,__PT_R0(%r11)
474 sll %r8,3 412 mvc __PT_R8(64,%r11),__LC_SAVE_AREA_SYNC
475 larl %r1,pgm_check_table 413 stmg %r8,%r9,__PT_PSW(%r11)
476 lg %r1,0(%r8,%r1) # load address of handler routine 414 stg %r10,__PT_ARGS(%r11)
477 la %r2,SP_PTREGS(%r15) # address of register-save area 415 tm __LC_PGM_ILC+3,0x80 # check for per exception
478 basr %r14,%r1 # branch to interrupt-handler 416 jz 0f
479pgm_exit:
480 j sysc_return
481
482#
483# handle per exception
484#
485pgm_per:
486 tm __LC_PGM_OLD_PSW,0x40 # test if per event recording is on
487 jnz pgm_per_std # ok, normal per event from user space
488# ok its one of the special cases, now we need to find out which one
489 clc __LC_PGM_OLD_PSW(16),__LC_SVC_NEW_PSW
490 je pgm_svcper
491# no interesting special case, ignore PER event
492 lpswe __LC_PGM_OLD_PSW
493
494#
495# Normal per exception
496#
497pgm_per_std:
498 SAVE_ALL_PGM __LC_PGM_OLD_PSW,__LC_SAVE_AREA
499 CREATE_STACK_FRAME __LC_SAVE_AREA
500 mvc SP_PSW(16,%r15),__LC_PGM_OLD_PSW
501 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct
502 HANDLE_SIE_INTERCEPT
503 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
504 jz pgm_no_vtime2
505 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
506 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
507 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
508 LAST_BREAK
509pgm_no_vtime2:
510 lg %r1,__TI_task(%r12) 417 lg %r1,__TI_task(%r12)
511 tm SP_PSW+1(%r15),0x01 # kernel per event ? 418 tmhh %r8,0x0001 # kernel per event ?
512 jz kernel_per 419 jz pgm_kprobe
513 mvc __THREAD_per_cause(2,%r1),__LC_PER_CAUSE 420 oi __TI_flags+7(%r12),_TIF_PER_TRAP
514 mvc __THREAD_per_address(8,%r1),__LC_PER_ADDRESS 421 mvc __THREAD_per_address(8,%r1),__LC_PER_ADDRESS
422 mvc __THREAD_per_cause(2,%r1),__LC_PER_CAUSE
515 mvc __THREAD_per_paid(1,%r1),__LC_PER_PAID 423 mvc __THREAD_per_paid(1,%r1),__LC_PER_PAID
516 oi __TI_flags+7(%r12),_TIF_PER_TRAP # set TIF_PER_TRAP 4240: lgf %r3,__LC_PGM_ILC # load program interruption code
517 lgf %r3,__LC_PGM_ILC # load program interruption code
518 lg %r4,__LC_TRANS_EXC_CODE 425 lg %r4,__LC_TRANS_EXC_CODE
519 REENABLE_IRQS 426 REENABLE_IRQS
520 lghi %r8,0x7f 427 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
521 ngr %r8,%r3 # clear per-event-bit and ilc 428 lghi %r10,0x7f
522 je pgm_exit2 429 ngr %r10,%r3
523 sll %r8,3 430 je sysc_return
431 sll %r10,3
524 larl %r1,pgm_check_table 432 larl %r1,pgm_check_table
525 lg %r1,0(%r8,%r1) # load address of handler routine 433 lg %r1,0(%r10,%r1) # load address of handler routine
526 la %r2,SP_PTREGS(%r15) # address of register-save area 434 lgr %r2,%r11 # pass pointer to pt_regs
527 basr %r14,%r1 # branch to interrupt-handler 435 basr %r14,%r1 # branch to interrupt-handler
528pgm_exit2:
529 j sysc_return 436 j sysc_return
530 437
531# 438#
532# it was a single stepped SVC that is causing all the trouble 439# PER event in supervisor state, must be kprobes
533# 440#
534pgm_svcper: 441pgm_kprobe:
535 SAVE_ALL_PGM __LC_SVC_OLD_PSW,__LC_SAVE_AREA 442 REENABLE_IRQS
536 CREATE_STACK_FRAME __LC_SAVE_AREA 443 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
537 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct 444 lgr %r2,%r11 # pass pointer to pt_regs
538 mvc SP_PSW(16,%r15),__LC_SVC_OLD_PSW 445 brasl %r14,do_per_trap
539 mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC 446 j sysc_return
540 oi __TI_flags+7(%r12),(_TIF_SYSCALL | _TIF_PER_TRAP)
541 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
542 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
543 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
544 LAST_BREAK
545 lg %r8,__TI_task(%r12)
546 mvc __THREAD_per_cause(2,%r8),__LC_PER_CAUSE
547 mvc __THREAD_per_address(8,%r8),__LC_PER_ADDRESS
548 mvc __THREAD_per_paid(1,%r8),__LC_PER_PAID
549 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
550 lmg %r2,%r6,SP_R2(%r15) # load svc arguments
551 j sysc_do_svc
552 447
553# 448#
554# per was called from kernel, must be kprobes 449# single stepped system call
555# 450#
556kernel_per: 451pgm_svcper:
557 REENABLE_IRQS 452 oi __TI_flags+7(%r12),_TIF_PER_TRAP
558 la %r2,SP_PTREGS(%r15) # address of register-save area 453 mvc __LC_RETURN_PSW(8),__LC_SVC_NEW_PSW
559 brasl %r14,do_per_trap 454 larl %r14,sysc_per
560 j pgm_exit 455 stg %r14,__LC_RETURN_PSW+8
456 lpswe __LC_RETURN_PSW # branch to sysc_per and enable irqs
561 457
562/* 458/*
563 * IO interrupt handler routine 459 * IO interrupt handler routine
@@ -565,21 +461,25 @@ kernel_per:
565ENTRY(io_int_handler) 461ENTRY(io_int_handler)
566 stck __LC_INT_CLOCK 462 stck __LC_INT_CLOCK
567 stpt __LC_ASYNC_ENTER_TIMER 463 stpt __LC_ASYNC_ENTER_TIMER
568 SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+40 464 stmg %r8,%r15,__LC_SAVE_AREA_ASYNC
569 CREATE_STACK_FRAME __LC_SAVE_AREA+40 465 lg %r10,__LC_LAST_BREAK
570 mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack 466 lg %r12,__LC_THREAD_INFO
571 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct 467 larl %r13,system_call
572 HANDLE_SIE_INTERCEPT 468 lmg %r8,%r9,__LC_IO_OLD_PSW
573 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 469 HANDLE_SIE_INTERCEPT %r14
574 jz io_no_vtime 470 SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT
575 UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER 471 tmhh %r8,0x0001 # interrupting from user?
576 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 472 jz io_skip
577 mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER 473 UPDATE_VTIME %r14,__LC_ASYNC_ENTER_TIMER
578 LAST_BREAK 474 LAST_BREAK %r14
579io_no_vtime: 475io_skip:
476 stmg %r0,%r7,__PT_R0(%r11)
477 mvc __PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC
478 stmg %r8,%r9,__PT_PSW(%r11)
580 TRACE_IRQS_OFF 479 TRACE_IRQS_OFF
581 la %r2,SP_PTREGS(%r15) # address of register-save area 480 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
582 brasl %r14,do_IRQ # call standard irq handler 481 lgr %r2,%r11 # pass pointer to pt_regs
482 brasl %r14,do_IRQ
583io_return: 483io_return:
584 LOCKDEP_SYS_EXIT 484 LOCKDEP_SYS_EXIT
585 TRACE_IRQS_ON 485 TRACE_IRQS_ON
@@ -587,7 +487,14 @@ io_tif:
587 tm __TI_flags+7(%r12),_TIF_WORK_INT 487 tm __TI_flags+7(%r12),_TIF_WORK_INT
588 jnz io_work # there is work to do (signals etc.) 488 jnz io_work # there is work to do (signals etc.)
589io_restore: 489io_restore:
590 RESTORE_ALL __LC_RETURN_PSW,0 490 lg %r14,__LC_VDSO_PER_CPU
491 lmg %r0,%r10,__PT_R0(%r11)
492 mvc __LC_RETURN_PSW(16),__PT_PSW(%r11)
493 ni __LC_RETURN_PSW+1,0xfd # clear wait state bit
494 stpt __LC_EXIT_TIMER
495 mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
496 lmg %r11,%r15,__PT_R11(%r11)
497 lpswe __LC_RETURN_PSW
591io_done: 498io_done:
592 499
593# 500#
@@ -600,7 +507,7 @@ io_done:
600# Before any work can be done, a switch to the kernel stack is required. 507# Before any work can be done, a switch to the kernel stack is required.
601# 508#
602io_work: 509io_work:
603 tm SP_PSW+1(%r15),0x01 # returning to user ? 510 tm __PT_PSW+1(%r11),0x01 # returning to user ?
604 jo io_work_user # yes -> do resched & signal 511 jo io_work_user # yes -> do resched & signal
605#ifdef CONFIG_PREEMPT 512#ifdef CONFIG_PREEMPT
606 # check for preemptive scheduling 513 # check for preemptive scheduling
@@ -609,10 +516,11 @@ io_work:
609 tm __TI_flags+7(%r12),_TIF_NEED_RESCHED 516 tm __TI_flags+7(%r12),_TIF_NEED_RESCHED
610 jno io_restore 517 jno io_restore
611 # switch to kernel stack 518 # switch to kernel stack
612 lg %r1,SP_R15(%r15) 519 lg %r1,__PT_R15(%r11)
613 aghi %r1,-SP_SIZE 520 aghi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
614 mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) 521 mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
615 xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain 522 xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
523 la %r11,STACK_FRAME_OVERHEAD(%r1)
616 lgr %r15,%r1 524 lgr %r15,%r1
617 # TRACE_IRQS_ON already done at io_return, call 525 # TRACE_IRQS_ON already done at io_return, call
618 # TRACE_IRQS_OFF to keep things symmetrical 526 # TRACE_IRQS_OFF to keep things symmetrical
@@ -628,9 +536,10 @@ io_work:
628# 536#
629io_work_user: 537io_work_user:
630 lg %r1,__LC_KERNEL_STACK 538 lg %r1,__LC_KERNEL_STACK
631 aghi %r1,-SP_SIZE 539 aghi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
632 mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) 540 mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
633 xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain 541 xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
542 la %r11,STACK_FRAME_OVERHEAD(%r1)
634 lgr %r15,%r1 543 lgr %r15,%r1
635 544
636# 545#
@@ -663,9 +572,9 @@ io_mcck_pending:
663# 572#
664io_reschedule: 573io_reschedule:
665 # TRACE_IRQS_ON already done at io_return 574 # TRACE_IRQS_ON already done at io_return
666 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 575 ssm __LC_SVC_NEW_PSW # reenable interrupts
667 brasl %r14,schedule # call scheduler 576 brasl %r14,schedule # call scheduler
668 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 577 ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
669 TRACE_IRQS_OFF 578 TRACE_IRQS_OFF
670 j io_return 579 j io_return
671 580
@@ -674,10 +583,10 @@ io_reschedule:
674# 583#
675io_sigpending: 584io_sigpending:
676 # TRACE_IRQS_ON already done at io_return 585 # TRACE_IRQS_ON already done at io_return
677 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 586 ssm __LC_SVC_NEW_PSW # reenable interrupts
678 la %r2,SP_PTREGS(%r15) # load pt_regs 587 lgr %r2,%r11 # pass pointer to pt_regs
679 brasl %r14,do_signal # call do_signal 588 brasl %r14,do_signal
680 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 589 ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
681 TRACE_IRQS_OFF 590 TRACE_IRQS_OFF
682 j io_return 591 j io_return
683 592
@@ -686,10 +595,10 @@ io_sigpending:
686# 595#
687io_notify_resume: 596io_notify_resume:
688 # TRACE_IRQS_ON already done at io_return 597 # TRACE_IRQS_ON already done at io_return
689 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 598 ssm __LC_SVC_NEW_PSW # reenable interrupts
690 la %r2,SP_PTREGS(%r15) # load pt_regs 599 lgr %r2,%r11 # pass pointer to pt_regs
691 brasl %r14,do_notify_resume # call do_notify_resume 600 brasl %r14,do_notify_resume
692 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 601 ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
693 TRACE_IRQS_OFF 602 TRACE_IRQS_OFF
694 j io_return 603 j io_return
695 604
@@ -699,21 +608,24 @@ io_notify_resume:
699ENTRY(ext_int_handler) 608ENTRY(ext_int_handler)
700 stck __LC_INT_CLOCK 609 stck __LC_INT_CLOCK
701 stpt __LC_ASYNC_ENTER_TIMER 610 stpt __LC_ASYNC_ENTER_TIMER
702 SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+40 611 stmg %r8,%r15,__LC_SAVE_AREA_ASYNC
703 CREATE_STACK_FRAME __LC_SAVE_AREA+40 612 lg %r10,__LC_LAST_BREAK
704 mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack 613 lg %r12,__LC_THREAD_INFO
705 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct 614 larl %r13,system_call
706 HANDLE_SIE_INTERCEPT 615 lmg %r8,%r9,__LC_EXT_OLD_PSW
707 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 616 HANDLE_SIE_INTERCEPT %r14
708 jz ext_no_vtime 617 SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT
709 UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER 618 tmhh %r8,0x0001 # interrupting from user ?
710 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 619 jz ext_skip
711 mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER 620 UPDATE_VTIME %r14,__LC_ASYNC_ENTER_TIMER
712 LAST_BREAK 621 LAST_BREAK %r14
713ext_no_vtime: 622ext_skip:
623 stmg %r0,%r7,__PT_R0(%r11)
624 mvc __PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC
625 stmg %r8,%r9,__PT_PSW(%r11)
714 TRACE_IRQS_OFF 626 TRACE_IRQS_OFF
715 lghi %r1,4096 627 lghi %r1,4096
716 la %r2,SP_PTREGS(%r15) # address of register-save area 628 lgr %r2,%r11 # pass pointer to pt_regs
717 llgf %r3,__LC_CPU_ADDRESS # get cpu address + interruption code 629 llgf %r3,__LC_CPU_ADDRESS # get cpu address + interruption code
718 llgf %r4,__LC_EXT_PARAMS # get external parameter 630 llgf %r4,__LC_EXT_PARAMS # get external parameter
719 lg %r5,__LC_EXT_PARAMS2-4096(%r1) # get 64 bit external parameter 631 lg %r5,__LC_EXT_PARAMS2-4096(%r1) # get 64 bit external parameter
@@ -730,81 +642,77 @@ ENTRY(mcck_int_handler)
730 la %r1,4095 # revalidate r1 642 la %r1,4095 # revalidate r1
731 spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer 643 spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer
732 lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs 644 lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs
733 stmg %r11,%r15,__LC_SAVE_AREA+80 645 lg %r10,__LC_LAST_BREAK
646 lg %r12,__LC_THREAD_INFO
734 larl %r13,system_call 647 larl %r13,system_call
735 lg %r11,__LC_LAST_BREAK 648 lmg %r8,%r9,__LC_MCK_OLD_PSW
736 la %r12,__LC_MCK_OLD_PSW 649 HANDLE_SIE_INTERCEPT %r14
737 tm __LC_MCCK_CODE,0x80 # system damage? 650 tm __LC_MCCK_CODE,0x80 # system damage?
738 jo mcck_int_main # yes -> rest of mcck code invalid 651 jo mcck_panic # yes -> rest of mcck code invalid
739 la %r14,4095 652 lghi %r14,__LC_CPU_TIMER_SAVE_AREA
740 mvc __LC_MCCK_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA-4095(%r14) 653 mvc __LC_MCCK_ENTER_TIMER(8),0(%r14)
741 tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid? 654 tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid?
742 jo 1f 655 jo 3f
743 la %r14,__LC_SYNC_ENTER_TIMER 656 la %r14,__LC_SYNC_ENTER_TIMER
744 clc 0(8,%r14),__LC_ASYNC_ENTER_TIMER 657 clc 0(8,%r14),__LC_ASYNC_ENTER_TIMER
745 jl 0f 658 jl 0f
746 la %r14,__LC_ASYNC_ENTER_TIMER 659 la %r14,__LC_ASYNC_ENTER_TIMER
7470: clc 0(8,%r14),__LC_EXIT_TIMER 6600: clc 0(8,%r14),__LC_EXIT_TIMER
748 jl 0f 661 jl 1f
749 la %r14,__LC_EXIT_TIMER 662 la %r14,__LC_EXIT_TIMER
7500: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER 6631: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER
751 jl 0f 664 jl 2f
752 la %r14,__LC_LAST_UPDATE_TIMER 665 la %r14,__LC_LAST_UPDATE_TIMER
7530: spt 0(%r14) 6662: spt 0(%r14)
754 mvc __LC_MCCK_ENTER_TIMER(8),0(%r14) 667 mvc __LC_MCCK_ENTER_TIMER(8),0(%r14)
7551: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? 6683: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid?
756 jno mcck_int_main # no -> skip cleanup critical 669 jno mcck_panic # no -> skip cleanup critical
757 tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit 670 SWITCH_ASYNC __LC_GPREGS_SAVE_AREA+64,__LC_PANIC_STACK,PAGE_SHIFT
758 jnz mcck_int_main # from user -> load kernel stack 671 tm %r8,0x0001 # interrupting from user ?
759 clc __LC_MCK_OLD_PSW+8(8),BASED(.Lcritical_end) 672 jz mcck_skip
760 jhe mcck_int_main 673 UPDATE_VTIME %r14,__LC_MCCK_ENTER_TIMER
761 clc __LC_MCK_OLD_PSW+8(8),BASED(.Lcritical_start) 674 LAST_BREAK %r14
762 jl mcck_int_main 675mcck_skip:
763 brasl %r14,cleanup_critical 676 lghi %r14,__LC_GPREGS_SAVE_AREA
764mcck_int_main: 677 mvc __PT_R0(128,%r11),0(%r14)
765 lg %r14,__LC_PANIC_STACK # are we already on the panic stack? 678 stmg %r8,%r9,__PT_PSW(%r11)
766 slgr %r14,%r15 679 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
767 srag %r14,%r14,PAGE_SHIFT 680 lgr %r2,%r11 # pass pointer to pt_regs
768 jz 0f
769 lg %r15,__LC_PANIC_STACK # load panic stack
7700: aghi %r15,-SP_SIZE # make room for registers & psw
771 CREATE_STACK_FRAME __LC_SAVE_AREA+80
772 mvc SP_PSW(16,%r15),0(%r12)
773 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct
774 tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid?
775 jno mcck_no_vtime # no -> no timer update
776 HANDLE_SIE_INTERCEPT
777 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
778 jz mcck_no_vtime
779 UPDATE_VTIME __LC_EXIT_TIMER,__LC_MCCK_ENTER_TIMER,__LC_USER_TIMER
780 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
781 mvc __LC_LAST_UPDATE_TIMER(8),__LC_MCCK_ENTER_TIMER
782 LAST_BREAK
783mcck_no_vtime:
784 la %r2,SP_PTREGS(%r15) # load pt_regs
785 brasl %r14,s390_do_machine_check 681 brasl %r14,s390_do_machine_check
786 tm SP_PSW+1(%r15),0x01 # returning to user ? 682 tm __PT_PSW+1(%r11),0x01 # returning to user ?
787 jno mcck_return 683 jno mcck_return
788 lg %r1,__LC_KERNEL_STACK # switch to kernel stack 684 lg %r1,__LC_KERNEL_STACK # switch to kernel stack
789 aghi %r1,-SP_SIZE 685 aghi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
790 mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) 686 mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
791 xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain 687 xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
688 la %r11,STACK_FRAME_OVERHEAD(%r1)
792 lgr %r15,%r1 689 lgr %r15,%r1
793 stosm __SF_EMPTY(%r15),0x04 # turn dat on 690 ssm __LC_PGM_NEW_PSW # turn dat on, keep irqs off
794 tm __TI_flags+7(%r12),_TIF_MCCK_PENDING 691 tm __TI_flags+7(%r12),_TIF_MCCK_PENDING
795 jno mcck_return 692 jno mcck_return
796 TRACE_IRQS_OFF 693 TRACE_IRQS_OFF
797 brasl %r14,s390_handle_mcck 694 brasl %r14,s390_handle_mcck
798 TRACE_IRQS_ON 695 TRACE_IRQS_ON
799mcck_return: 696mcck_return:
800 mvc __LC_RETURN_MCCK_PSW(16),SP_PSW(%r15) # move return PSW 697 lg %r14,__LC_VDSO_PER_CPU
698 lmg %r0,%r10,__PT_R0(%r11)
699 mvc __LC_RETURN_MCCK_PSW(16),__PT_PSW(%r11) # move return PSW
801 ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit 700 ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit
802 lmg %r0,%r15,SP_R0(%r15) # load gprs 0-15
803 tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ? 701 tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ?
804 jno 0f 702 jno 0f
805 stpt __LC_EXIT_TIMER 703 stpt __LC_EXIT_TIMER
8060: lpswe __LC_RETURN_MCCK_PSW # back to caller 704 mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
807mcck_done: 7050: lmg %r11,%r15,__PT_R11(%r11)
706 lpswe __LC_RETURN_MCCK_PSW
707
708mcck_panic:
709 lg %r14,__LC_PANIC_STACK
710 slgr %r14,%r15
711 srag %r14,%r14,PAGE_SHIFT
712 jz 0f
713 lg %r15,__LC_PANIC_STACK
7140: aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
715 j mcck_skip
808 716
809/* 717/*
810 * Restart interruption handler, kick starter for additional CPUs 718 * Restart interruption handler, kick starter for additional CPUs
@@ -818,17 +726,18 @@ restart_base:
818 stck __LC_LAST_UPDATE_CLOCK 726 stck __LC_LAST_UPDATE_CLOCK
819 mvc __LC_LAST_UPDATE_TIMER(8),restart_vtime-restart_base(%r1) 727 mvc __LC_LAST_UPDATE_TIMER(8),restart_vtime-restart_base(%r1)
820 mvc __LC_EXIT_TIMER(8),restart_vtime-restart_base(%r1) 728 mvc __LC_EXIT_TIMER(8),restart_vtime-restart_base(%r1)
821 lg %r15,__LC_SAVE_AREA+120 # load ksp 729 lghi %r10,__LC_GPREGS_SAVE_AREA
730 lg %r15,120(%r10) # load ksp
822 lghi %r10,__LC_CREGS_SAVE_AREA 731 lghi %r10,__LC_CREGS_SAVE_AREA
823 lctlg %c0,%c15,0(%r10) # get new ctl regs 732 lctlg %c0,%c15,0(%r10) # get new ctl regs
824 lghi %r10,__LC_AREGS_SAVE_AREA 733 lghi %r10,__LC_AREGS_SAVE_AREA
825 lam %a0,%a15,0(%r10) 734 lam %a0,%a15,0(%r10)
826 lmg %r6,%r15,__SF_GPRS(%r15) # load registers from clone 735 lmg %r6,%r15,__SF_GPRS(%r15)# load registers from clone
827 lg %r1,__LC_THREAD_INFO 736 lg %r1,__LC_THREAD_INFO
828 mvc __LC_USER_TIMER(8),__TI_user_timer(%r1) 737 mvc __LC_USER_TIMER(8),__TI_user_timer(%r1)
829 mvc __LC_SYSTEM_TIMER(8),__TI_system_timer(%r1) 738 mvc __LC_SYSTEM_TIMER(8),__TI_system_timer(%r1)
830 xc __LC_STEAL_TIMER(8),__LC_STEAL_TIMER 739 xc __LC_STEAL_TIMER(8),__LC_STEAL_TIMER
831 stosm __SF_EMPTY(%r15),0x04 # now we can turn dat on 740 ssm __LC_PGM_NEW_PSW # turn dat on, keep irqs off
832 brasl %r14,start_secondary 741 brasl %r14,start_secondary
833 .align 8 742 .align 8
834restart_vtime: 743restart_vtime:
@@ -852,16 +761,16 @@ restart_go:
852# PSW restart interrupt handler 761# PSW restart interrupt handler
853# 762#
854ENTRY(psw_restart_int_handler) 763ENTRY(psw_restart_int_handler)
855 stg %r15,__LC_SAVE_AREA+120(%r0) # save r15 764 stg %r15,__LC_SAVE_AREA_RESTART
856 larl %r15,restart_stack # load restart stack 765 larl %r15,restart_stack # load restart stack
857 lg %r15,0(%r15) 766 lg %r15,0(%r15)
858 aghi %r15,-SP_SIZE # make room for pt_regs 767 aghi %r15,-__PT_SIZE # create pt_regs on stack
859 stmg %r0,%r14,SP_R0(%r15) # store gprs %r0-%r14 to stack 768 stmg %r0,%r14,__PT_R0(%r15)
860 mvc SP_R15(8,%r15),__LC_SAVE_AREA+120(%r0)# store saved %r15 to stack 769 mvc __PT_R15(8,%r15),__LC_SAVE_AREA_RESTART
861 mvc SP_PSW(16,%r15),__LC_RST_OLD_PSW(%r0)# store restart old psw 770 mvc __PT_PSW(16,%r15),__LC_RST_OLD_PSW # store restart old psw
862 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) # set backchain to 0 771 aghi %r15,-STACK_FRAME_OVERHEAD
772 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
863 brasl %r14,do_restart 773 brasl %r14,do_restart
864
865 larl %r14,restart_psw_crash # load disabled wait PSW if 774 larl %r14,restart_psw_crash # load disabled wait PSW if
866 lpswe 0(%r14) # do_restart returns 775 lpswe 0(%r14) # do_restart returns
867 .align 8 776 .align 8
@@ -877,172 +786,153 @@ restart_psw_crash:
877 * Setup a pt_regs so that show_trace can provide a good call trace. 786 * Setup a pt_regs so that show_trace can provide a good call trace.
878 */ 787 */
879stack_overflow: 788stack_overflow:
880 lg %r15,__LC_PANIC_STACK # change to panic stack 789 lg %r11,__LC_PANIC_STACK # change to panic stack
881 aghi %r15,-SP_SIZE 790 aghi %r11,-__PT_SIZE # create pt_regs
882 mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack 791 stmg %r0,%r7,__PT_R0(%r11)
883 stmg %r0,%r10,SP_R0(%r15) # store gprs %r0-%r10 to kernel stack 792 stmg %r8,%r9,__PT_PSW(%r11)
884 la %r1,__LC_SAVE_AREA 793 mvc __PT_R8(64,%r11),0(%r14)
885 chi %r12,__LC_SVC_OLD_PSW 794 stg %r10,__PT_ORIG_GPR2(%r11) # store last break to orig_gpr2
886 je 0f 795 lgr %r15,%r11
887 chi %r12,__LC_PGM_OLD_PSW 796 aghi %r15,-STACK_FRAME_OVERHEAD
888 je 0f 797 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
889 la %r1,__LC_SAVE_AREA+40 798 lgr %r2,%r11 # pass pointer to pt_regs
8900: mvc SP_R11(40,%r15),0(%r1) # move %r11-%r15 to stack
891 mvc SP_ARGS(8,%r15),__LC_LAST_BREAK
892 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) # clear back chain
893 la %r2,SP_PTREGS(%r15) # load pt_regs
894 jg kernel_stack_overflow 799 jg kernel_stack_overflow
895#endif 800#endif
896 801
897cleanup_table_system_call: 802 .align 8
898 .quad system_call, sysc_do_svc 803cleanup_table:
899cleanup_table_sysc_tif: 804 .quad system_call
900 .quad sysc_tif, sysc_restore 805 .quad sysc_do_svc
901cleanup_table_sysc_restore: 806 .quad sysc_tif
902 .quad sysc_restore, sysc_done 807 .quad sysc_restore
903cleanup_table_io_tif: 808 .quad sysc_done
904 .quad io_tif, io_restore 809 .quad io_tif
905cleanup_table_io_restore: 810 .quad io_restore
906 .quad io_restore, io_done 811 .quad io_done
907 812
908cleanup_critical: 813cleanup_critical:
909 clc 8(8,%r12),BASED(cleanup_table_system_call) 814 clg %r9,BASED(cleanup_table) # system_call
910 jl 0f 815 jl 0f
911 clc 8(8,%r12),BASED(cleanup_table_system_call+8) 816 clg %r9,BASED(cleanup_table+8) # sysc_do_svc
912 jl cleanup_system_call 817 jl cleanup_system_call
9130: 818 clg %r9,BASED(cleanup_table+16) # sysc_tif
914 clc 8(8,%r12),BASED(cleanup_table_sysc_tif)
915 jl 0f 819 jl 0f
916 clc 8(8,%r12),BASED(cleanup_table_sysc_tif+8) 820 clg %r9,BASED(cleanup_table+24) # sysc_restore
917 jl cleanup_sysc_tif 821 jl cleanup_sysc_tif
9180: 822 clg %r9,BASED(cleanup_table+32) # sysc_done
919 clc 8(8,%r12),BASED(cleanup_table_sysc_restore)
920 jl 0f
921 clc 8(8,%r12),BASED(cleanup_table_sysc_restore+8)
922 jl cleanup_sysc_restore 823 jl cleanup_sysc_restore
9230: 824 clg %r9,BASED(cleanup_table+40) # io_tif
924 clc 8(8,%r12),BASED(cleanup_table_io_tif)
925 jl 0f 825 jl 0f
926 clc 8(8,%r12),BASED(cleanup_table_io_tif+8) 826 clg %r9,BASED(cleanup_table+48) # io_restore
927 jl cleanup_io_tif 827 jl cleanup_io_tif
9280: 828 clg %r9,BASED(cleanup_table+56) # io_done
929 clc 8(8,%r12),BASED(cleanup_table_io_restore)
930 jl 0f
931 clc 8(8,%r12),BASED(cleanup_table_io_restore+8)
932 jl cleanup_io_restore 829 jl cleanup_io_restore
9330: 8300: br %r14
934 br %r14 831
935 832
936cleanup_system_call: 833cleanup_system_call:
937 mvc __LC_RETURN_PSW(16),0(%r12) 834 # check if stpt has been executed
938 clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+8) 835 clg %r9,BASED(cleanup_system_call_insn)
939 jh 0f 836 jh 0f
940 mvc __LC_SYNC_ENTER_TIMER(8),__LC_MCCK_ENTER_TIMER
941 cghi %r12,__LC_MCK_OLD_PSW
942 je 0f
943 mvc __LC_SYNC_ENTER_TIMER(8),__LC_ASYNC_ENTER_TIMER 837 mvc __LC_SYNC_ENTER_TIMER(8),__LC_ASYNC_ENTER_TIMER
9440: cghi %r12,__LC_MCK_OLD_PSW 838 cghi %r11,__LC_SAVE_AREA_ASYNC
945 la %r12,__LC_SAVE_AREA+80
946 je 0f 839 je 0f
947 la %r12,__LC_SAVE_AREA+40 840 mvc __LC_SYNC_ENTER_TIMER(8),__LC_MCCK_ENTER_TIMER
9480: clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+16) 8410: # check if stmg has been executed
949 jhe cleanup_vtime 842 clg %r9,BASED(cleanup_system_call_insn+8)
950 clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn)
951 jh 0f 843 jh 0f
952 mvc __LC_SAVE_AREA(40),0(%r12) 844 mvc __LC_SAVE_AREA_SYNC(64),0(%r11)
9530: lg %r15,__LC_KERNEL_STACK # problem state -> load ksp 8450: # check if base register setup + TIF bit load has been done
954 aghi %r15,-SP_SIZE # make room for registers & psw 846 clg %r9,BASED(cleanup_system_call_insn+16)
955 stg %r15,32(%r12) 847 jhe 0f
956 stg %r11,0(%r12) 848 # set up saved registers r10 and r12
957 CREATE_STACK_FRAME __LC_SAVE_AREA 849 stg %r10,16(%r11) # r10 last break
958 mvc 8(8,%r12),__LC_THREAD_INFO 850 stg %r12,32(%r11) # r12 thread-info pointer
959 lg %r12,__LC_THREAD_INFO 8510: # check if the user time update has been done
960 mvc SP_PSW(16,%r15),__LC_SVC_OLD_PSW 852 clg %r9,BASED(cleanup_system_call_insn+24)
961 mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC 853 jh 0f
962 oi __TI_flags+7(%r12),_TIF_SYSCALL 854 lg %r15,__LC_EXIT_TIMER
963cleanup_vtime: 855 slg %r15,__LC_SYNC_ENTER_TIMER
964 clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+24) 856 alg %r15,__LC_USER_TIMER
965 jhe cleanup_stime 857 stg %r15,__LC_USER_TIMER
966 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 8580: # check if the system time update has been done
967cleanup_stime: 859 clg %r9,BASED(cleanup_system_call_insn+32)
968 clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+32) 860 jh 0f
969 jh cleanup_update 861 lg %r15,__LC_LAST_UPDATE_TIMER
970 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 862 slg %r15,__LC_EXIT_TIMER
971cleanup_update: 863 alg %r15,__LC_SYSTEM_TIMER
864 stg %r15,__LC_SYSTEM_TIMER
8650: # update accounting time stamp
972 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 866 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
973 srag %r12,%r11,23 867 # do LAST_BREAK
974 lg %r12,__LC_THREAD_INFO 868 lg %r9,16(%r11)
869 srag %r9,%r9,23
975 jz 0f 870 jz 0f
976 stg %r11,__TI_last_break(%r12) 871 mvc __TI_last_break(8,%r12),16(%r11)
9770: mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_system_call+8) 8720: # set up saved register r11
978 la %r12,__LC_RETURN_PSW 873 lg %r15,__LC_KERNEL_STACK
874 aghi %r15,-__PT_SIZE
875 stg %r15,24(%r11) # r11 pt_regs pointer
876 # fill pt_regs
877 mvc __PT_R8(64,%r15),__LC_SAVE_AREA_SYNC
878 stmg %r0,%r7,__PT_R0(%r15)
879 mvc __PT_PSW(16,%r15),__LC_SVC_OLD_PSW
880 mvc __PT_SVC_CODE(4,%r15),__LC_SVC_ILC
881 # setup saved register r15
882 aghi %r15,-STACK_FRAME_OVERHEAD
883 stg %r15,56(%r11) # r15 stack pointer
884 # set new psw address and exit
885 larl %r9,sysc_do_svc
979 br %r14 886 br %r14
980cleanup_system_call_insn: 887cleanup_system_call_insn:
981 .quad sysc_saveall
982 .quad system_call 888 .quad system_call
983 .quad sysc_vtime 889 .quad sysc_stmg
984 .quad sysc_stime 890 .quad sysc_per
985 .quad sysc_update 891 .quad sysc_vtime+18
892 .quad sysc_vtime+42
986 893
987cleanup_sysc_tif: 894cleanup_sysc_tif:
988 mvc __LC_RETURN_PSW(8),0(%r12) 895 larl %r9,sysc_tif
989 mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_sysc_tif)
990 la %r12,__LC_RETURN_PSW
991 br %r14 896 br %r14
992 897
993cleanup_sysc_restore: 898cleanup_sysc_restore:
994 clc 8(8,%r12),BASED(cleanup_sysc_restore_insn) 899 clg %r9,BASED(cleanup_sysc_restore_insn)
995 je 2f
996 clc 8(8,%r12),BASED(cleanup_sysc_restore_insn+8)
997 jhe 0f
998 mvc __LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER
999 cghi %r12,__LC_MCK_OLD_PSW
1000 je 0f 900 je 0f
1001 mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER 901 lg %r9,24(%r11) # get saved pointer to pt_regs
10020: mvc __LC_RETURN_PSW(16),SP_PSW(%r15) 902 mvc __LC_RETURN_PSW(16),__PT_PSW(%r9)
1003 cghi %r12,__LC_MCK_OLD_PSW 903 mvc 0(64,%r11),__PT_R8(%r9)
1004 la %r12,__LC_SAVE_AREA+80 904 lmg %r0,%r7,__PT_R0(%r9)
1005 je 1f 9050: lmg %r8,%r9,__LC_RETURN_PSW
1006 la %r12,__LC_SAVE_AREA+40
10071: mvc 0(40,%r12),SP_R11(%r15)
1008 lmg %r0,%r10,SP_R0(%r15)
1009 lg %r15,SP_R15(%r15)
10102: la %r12,__LC_RETURN_PSW
1011 br %r14 906 br %r14
1012cleanup_sysc_restore_insn: 907cleanup_sysc_restore_insn:
1013 .quad sysc_done - 4 908 .quad sysc_done - 4
1014 .quad sysc_done - 16
1015 909
1016cleanup_io_tif: 910cleanup_io_tif:
1017 mvc __LC_RETURN_PSW(8),0(%r12) 911 larl %r9,io_tif
1018 mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_io_tif)
1019 la %r12,__LC_RETURN_PSW
1020 br %r14 912 br %r14
1021 913
1022cleanup_io_restore: 914cleanup_io_restore:
1023 clc 8(8,%r12),BASED(cleanup_io_restore_insn) 915 clg %r9,BASED(cleanup_io_restore_insn)
1024 je 1f 916 je 0f
1025 clc 8(8,%r12),BASED(cleanup_io_restore_insn+8) 917 lg %r9,24(%r11) # get saved r11 pointer to pt_regs
1026 jhe 0f 918 mvc __LC_RETURN_PSW(16),__PT_PSW(%r9)
1027 mvc __LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER 919 ni __LC_RETURN_PSW+1,0xfd # clear wait state bit
10280: mvc __LC_RETURN_PSW(16),SP_PSW(%r15) 920 mvc 0(64,%r11),__PT_R8(%r9)
1029 mvc __LC_SAVE_AREA+80(40),SP_R11(%r15) 921 lmg %r0,%r7,__PT_R0(%r9)
1030 lmg %r0,%r10,SP_R0(%r15) 9220: lmg %r8,%r9,__LC_RETURN_PSW
1031 lg %r15,SP_R15(%r15)
10321: la %r12,__LC_RETURN_PSW
1033 br %r14 923 br %r14
1034cleanup_io_restore_insn: 924cleanup_io_restore_insn:
1035 .quad io_done - 4 925 .quad io_done - 4
1036 .quad io_done - 16
1037 926
1038/* 927/*
1039 * Integer constants 928 * Integer constants
1040 */ 929 */
1041 .align 4 930 .align 8
1042.Lcritical_start: 931.Lcritical_start:
1043 .quad __critical_start 932 .quad __critical_start
1044.Lcritical_end: 933.Lcritical_length:
1045 .quad __critical_end 934 .quad __critical_end - __critical_start
935
1046 936
1047#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) 937#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
1048/* 938/*
@@ -1094,8 +984,8 @@ sie_fault:
1094 .align 8 984 .align 8
1095.Lsie_loop: 985.Lsie_loop:
1096 .quad sie_loop 986 .quad sie_loop
1097.Lsie_done: 987.Lsie_length:
1098 .quad sie_done 988 .quad sie_done - sie_loop
1099.Lhost_id: 989.Lhost_id:
1100 .quad 0 990 .quad 0
1101 991
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S
index 900068d2bf92..c27a0727f930 100644
--- a/arch/s390/kernel/head.S
+++ b/arch/s390/kernel/head.S
@@ -329,8 +329,8 @@ iplstart:
329# 329#
330# reset files in VM reader 330# reset files in VM reader
331# 331#
332 stidp __LC_SAVE_AREA # store cpuid 332 stidp __LC_SAVE_AREA_SYNC # store cpuid
333 tm __LC_SAVE_AREA,0xff # running VM ? 333 tm __LC_SAVE_AREA_SYNC,0xff# running VM ?
334 bno .Lnoreset 334 bno .Lnoreset
335 la %r2,.Lreset 335 la %r2,.Lreset
336 lhi %r3,26 336 lhi %r3,26
diff --git a/arch/s390/kernel/reipl64.S b/arch/s390/kernel/reipl64.S
index 732a793ec53a..36b32658fb24 100644
--- a/arch/s390/kernel/reipl64.S
+++ b/arch/s390/kernel/reipl64.S
@@ -17,11 +17,11 @@
17# 17#
18ENTRY(store_status) 18ENTRY(store_status)
19 /* Save register one and load save area base */ 19 /* Save register one and load save area base */
20 stg %r1,__LC_SAVE_AREA+120(%r0) 20 stg %r1,__LC_SAVE_AREA_RESTART
21 lghi %r1,SAVE_AREA_BASE 21 lghi %r1,SAVE_AREA_BASE
22 /* General purpose registers */ 22 /* General purpose registers */
23 stmg %r0,%r15,__LC_GPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) 23 stmg %r0,%r15,__LC_GPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
24 lg %r2,__LC_SAVE_AREA+120(%r0) 24 lg %r2,__LC_SAVE_AREA_RESTART
25 stg %r2,__LC_GPREGS_SAVE_AREA-SAVE_AREA_BASE+8(%r1) 25 stg %r2,__LC_GPREGS_SAVE_AREA-SAVE_AREA_BASE+8(%r1)
26 /* Control registers */ 26 /* Control registers */
27 stctg %c0,%c15,__LC_CREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) 27 stctg %c0,%c15,__LC_CREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 9cf01e455e50..109e7422bb20 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -654,7 +654,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
654 - sizeof(struct stack_frame)); 654 - sizeof(struct stack_frame));
655 memset(sf, 0, sizeof(struct stack_frame)); 655 memset(sf, 0, sizeof(struct stack_frame));
656 sf->gprs[9] = (unsigned long) sf; 656 sf->gprs[9] = (unsigned long) sf;
657 cpu_lowcore->save_area[15] = (unsigned long) sf; 657 cpu_lowcore->gpregs_save_area[15] = (unsigned long) sf;
658 __ctl_store(cpu_lowcore->cregs_save_area, 0, 15); 658 __ctl_store(cpu_lowcore->cregs_save_area, 0, 15);
659 atomic_inc(&init_mm.context.attach_count); 659 atomic_inc(&init_mm.context.attach_count);
660 asm volatile( 660 asm volatile(