aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/entry64.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kernel/entry64.S')
-rw-r--r--arch/s390/kernel/entry64.S976
1 files changed, 434 insertions, 542 deletions
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 83a93747e2fd..412a7b8783d7 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.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 + 8
24 * The first few entries are identical to the user_regs_struct. 24__PT_R2 = __PT_GPRS + 16
25 */ 25__PT_R3 = __PT_GPRS + 24
26SP_PTREGS = STACK_FRAME_OVERHEAD 26__PT_R4 = __PT_GPRS + 32
27SP_ARGS = STACK_FRAME_OVERHEAD + __PT_ARGS 27__PT_R5 = __PT_GPRS + 40
28SP_PSW = STACK_FRAME_OVERHEAD + __PT_PSW 28__PT_R6 = __PT_GPRS + 48
29SP_R0 = STACK_FRAME_OVERHEAD + __PT_GPRS 29__PT_R7 = __PT_GPRS + 56
30SP_R1 = STACK_FRAME_OVERHEAD + __PT_GPRS + 8 30__PT_R8 = __PT_GPRS + 64
31SP_R2 = STACK_FRAME_OVERHEAD + __PT_GPRS + 16 31__PT_R9 = __PT_GPRS + 72
32SP_R3 = STACK_FRAME_OVERHEAD + __PT_GPRS + 24 32__PT_R10 = __PT_GPRS + 80
33SP_R4 = STACK_FRAME_OVERHEAD + __PT_GPRS + 32 33__PT_R11 = __PT_GPRS + 88
34SP_R5 = STACK_FRAME_OVERHEAD + __PT_GPRS + 40 34__PT_R12 = __PT_GPRS + 96
35SP_R6 = STACK_FRAME_OVERHEAD + __PT_GPRS + 48 35__PT_R13 = __PT_GPRS + 104
36SP_R7 = STACK_FRAME_OVERHEAD + __PT_GPRS + 56 36__PT_R14 = __PT_GPRS + 112
37SP_R8 = STACK_FRAME_OVERHEAD + __PT_GPRS + 64 37__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 38
49STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER 39STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER
50STACK_SIZE = 1 << STACK_SHIFT 40STACK_SIZE = 1 << STACK_SHIFT
@@ -59,154 +49,103 @@ _TIF_EXIT_SIE = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING)
59 49
60#define BASED(name) name-system_call(%r13) 50#define BASED(name) name-system_call(%r13)
61 51
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 __LC_CMF_HPP # 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 52 .macro TRACE_IRQS_ON
53#ifdef CONFIG_TRACE_IRQFLAGS
86 basr %r2,%r0 54 basr %r2,%r0
87 brasl %r14,trace_hardirqs_on_caller 55 brasl %r14,trace_hardirqs_on_caller
56#endif
88 .endm 57 .endm
89 58
90 .macro TRACE_IRQS_OFF 59 .macro TRACE_IRQS_OFF
60#ifdef CONFIG_TRACE_IRQFLAGS
91 basr %r2,%r0 61 basr %r2,%r0
92 brasl %r14,trace_hardirqs_off_caller 62 brasl %r14,trace_hardirqs_off_caller
93 .endm
94#else
95#define TRACE_IRQS_ON
96#define TRACE_IRQS_OFF
97#endif 63#endif
64 .endm
98 65
99#ifdef CONFIG_LOCKDEP
100 .macro LOCKDEP_SYS_EXIT 66 .macro LOCKDEP_SYS_EXIT
101 tm SP_PSW+1(%r15),0x01 # returning to user ? 67#ifdef CONFIG_LOCKDEP
102 jz 0f 68 tm __PT_PSW+1(%r11),0x01 # returning to user ?
69 jz .+10
103 brasl %r14,lockdep_sys_exit 70 brasl %r14,lockdep_sys_exit
1040:
105 .endm
106#else
107#define LOCKDEP_SYS_EXIT
108#endif 71#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 72 .endm
116 73
117/* 74 .macro SPP newpp
118 * Register usage in interrupt handlers: 75#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
119 * R9 - pointer to current task structure 76 tm __LC_MACHINE_FLAGS+6,0x20 # MACHINE_FLAG_SPP
120 * R13 - pointer to literal pool 77 jz .+8
121 * R14 - return register for function calls 78 .insn s,0xb2800000,\newpp
122 * R15 - kernel stack pointer 79#endif
123 */ 80 .endm
124 81
125 .macro SAVE_ALL_SVC psworg,savearea 82 .macro HANDLE_SIE_INTERCEPT scratch
126 stmg %r11,%r15,\savearea 83#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
127 lg %r15,__LC_KERNEL_STACK # problem state -> load ksp 84 tm __TI_flags+6(%r12),_TIF_SIE>>8
128 aghi %r15,-SP_SIZE # make room for registers & psw 85 jz .+42
129 lg %r11,__LC_LAST_BREAK 86 tm __LC_MACHINE_FLAGS+6,0x20 # MACHINE_FLAG_SPP
87 jz .+8
88 .insn s,0xb2800000,BASED(.Lhost_id) # set host id
89 lgr \scratch,%r9
90 slg \scratch,BASED(.Lsie_loop)
91 clg \scratch,BASED(.Lsie_length)
92 jhe .+10
93 lg %r9,BASED(.Lsie_loop)
94#endif
130 .endm 95 .endm
131 96
132 .macro SAVE_ALL_PGM psworg,savearea 97 .macro CHECK_STACK stacksize,savearea
133 stmg %r11,%r15,\savearea
134 tm \psworg+1,0x01 # test problem state bit
135#ifdef CONFIG_CHECK_STACK 98#ifdef CONFIG_CHECK_STACK
136 jnz 1f 99 tml %r15,\stacksize - CONFIG_STACK_GUARD
137 tml %r15,STACK_SIZE - CONFIG_STACK_GUARD 100 lghi %r14,\savearea
138 jnz 2f 101 jz stack_overflow
139 la %r12,\psworg
140 j stack_overflow
141#else
142 jz 2f
143#endif 102#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 103 .endm
149 104
150 .macro SAVE_ALL_ASYNC psworg,savearea 105 .macro SWITCH_ASYNC savearea,stack,shift
151 stmg %r11,%r15,\savearea 106 tmhh %r8,0x0001 # interrupting from user ?
152 larl %r13,system_call 107 jnz 1f
153 lg %r11,__LC_LAST_BREAK 108 lgr %r14,%r9
154 la %r12,\psworg 109 slg %r14,BASED(.Lcritical_start)
155 tm \psworg+1,0x01 # test problem state bit 110 clg %r14,BASED(.Lcritical_length)
156 jnz 1f # from user -> load kernel stack
157 clc \psworg+8(8),BASED(.Lcritical_end)
158 jhe 0f 111 jhe 0f
159 clc \psworg+8(8),BASED(.Lcritical_start) 112 lghi %r11,\savearea # inside critical section, do cleanup
160 jl 0f
161 brasl %r14,cleanup_critical 113 brasl %r14,cleanup_critical
162 tm 1(%r12),0x01 # retest problem state after cleanup 114 tmhh %r8,0x0001 # retest problem state after cleanup
163 jnz 1f 115 jnz 1f
1640: lg %r14,__LC_ASYNC_STACK # are we already on the async. stack ? 1160: lg %r14,\stack # are we already on the target stack?
165 slgr %r14,%r15 117 slgr %r14,%r15
166 srag %r14,%r14,STACK_SHIFT 118 srag %r14,%r14,\shift
167#ifdef CONFIG_CHECK_STACK
168 jnz 1f 119 jnz 1f
169 tml %r15,STACK_SIZE - CONFIG_STACK_GUARD 120 CHECK_STACK 1<<\shift,\savearea
170 jnz 2f 121 j 2f
171 j stack_overflow 1221: lg %r15,\stack # load target stack
172#else 1232: aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
173 jz 2f 124 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 125 .endm
185 126
186 .macro RESTORE_ALL psworg,sync 127 .macro UPDATE_VTIME scratch,enter_timer
187 mvc \psworg(16),SP_PSW(%r15) # move user PSW to lowcore 128 lg \scratch,__LC_EXIT_TIMER
188 .if !\sync 129 slg \scratch,\enter_timer
189 ni \psworg+1,0xfd # clear wait state bit 130 alg \scratch,__LC_USER_TIMER
190 .endif 131 stg \scratch,__LC_USER_TIMER
191 lg %r14,__LC_VDSO_PER_CPU 132 lg \scratch,__LC_LAST_UPDATE_TIMER
192 lmg %r0,%r13,SP_R0(%r15) # load gprs 0-13 of user 133 slg \scratch,__LC_EXIT_TIMER
193 stpt __LC_EXIT_TIMER 134 alg \scratch,__LC_SYSTEM_TIMER
194 mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER 135 stg \scratch,__LC_SYSTEM_TIMER
195 lmg %r14,%r15,SP_R14(%r15) # load grps 14-15 of user 136 mvc __LC_LAST_UPDATE_TIMER(8),\enter_timer
196 lpswe \psworg # back to caller
197 .endm 137 .endm
198 138
199 .macro LAST_BREAK 139 .macro LAST_BREAK scratch
200 srag %r10,%r11,23 140 srag \scratch,%r10,23
201 jz 0f 141 jz .+10
202 stg %r11,__TI_last_break(%r12) 142 stg %r10,__TI_last_break(%r12)
2030:
204 .endm 143 .endm
205 144
206 .macro REENABLE_IRQS 145 .macro REENABLE_IRQS
207 mvc __SF_EMPTY(1,%r15),SP_PSW(%r15) 146 stg %r8,__LC_RETURN_PSW
208 ni __SF_EMPTY(%r15),0xbf 147 ni __LC_RETURN_PSW,0xbf
209 ssm __SF_EMPTY(%r15) 148 ssm __LC_RETURN_PSW
210 .endm 149 .endm
211 150
212 .section .kprobes.text, "ax" 151 .section .kprobes.text, "ax"
@@ -245,55 +184,66 @@ __critical_start:
245 184
246ENTRY(system_call) 185ENTRY(system_call)
247 stpt __LC_SYNC_ENTER_TIMER 186 stpt __LC_SYNC_ENTER_TIMER
248sysc_saveall: 187sysc_stmg:
249 SAVE_ALL_SVC __LC_SVC_OLD_PSW,__LC_SAVE_AREA 188 stmg %r8,%r15,__LC_SAVE_AREA_SYNC
250 CREATE_STACK_FRAME __LC_SAVE_AREA 189 lg %r10,__LC_LAST_BREAK
251 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct 190 lg %r12,__LC_THREAD_INFO
252 mvc SP_PSW(16,%r15),__LC_SVC_OLD_PSW 191 larl %r13,system_call
253 mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC 192sysc_per:
254 oi __TI_flags+7(%r12),_TIF_SYSCALL 193 lg %r15,__LC_KERNEL_STACK
194 aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
195 la %r11,STACK_FRAME_OVERHEAD(%r15) # pointer to pt_regs
255sysc_vtime: 196sysc_vtime:
256 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 197 UPDATE_VTIME %r13,__LC_SYNC_ENTER_TIMER
257sysc_stime: 198 LAST_BREAK %r13
258 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 199 stmg %r0,%r7,__PT_R0(%r11)
259sysc_update: 200 mvc __PT_R8(64,%r11),__LC_SAVE_AREA_SYNC
260 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 201 mvc __PT_PSW(16,%r11),__LC_SVC_OLD_PSW
261 LAST_BREAK 202 mvc __PT_INT_CODE(4,%r11),__LC_SVC_ILC
262sysc_do_svc: 203sysc_do_svc:
263 llgh %r7,SP_SVC_CODE+2(%r15) 204 oi __TI_flags+7(%r12),_TIF_SYSCALL
264 slag %r7,%r7,2 # shift and test for svc 0 205 llgh %r8,__PT_INT_CODE+2(%r11)
206 slag %r8,%r8,2 # shift and test for svc 0
265 jnz sysc_nr_ok 207 jnz sysc_nr_ok
266 # svc 0: system call number in %r1 208 # svc 0: system call number in %r1
267 llgfr %r1,%r1 # clear high word in r1 209 llgfr %r1,%r1 # clear high word in r1
268 cghi %r1,NR_syscalls 210 cghi %r1,NR_syscalls
269 jnl sysc_nr_ok 211 jnl sysc_nr_ok
270 sth %r1,SP_SVC_CODE+2(%r15) 212 sth %r1,__PT_INT_CODE+2(%r11)
271 slag %r7,%r1,2 # shift and test for svc 0 213 slag %r8,%r1,2
272sysc_nr_ok: 214sysc_nr_ok:
273 larl %r10,sys_call_table 215 larl %r10,sys_call_table # 64 bit system call table
274#ifdef CONFIG_COMPAT 216#ifdef CONFIG_COMPAT
275 tm __TI_flags+5(%r12),(_TIF_31BIT>>16) # running in 31 bit mode ? 217 tm __TI_flags+5(%r12),(_TIF_31BIT>>16)
276 jno sysc_noemu 218 jno sysc_noemu
277 larl %r10,sys_call_table_emu # use 31 bit emulation system calls 219 larl %r10,sys_call_table_emu # 31 bit system call table
278sysc_noemu: 220sysc_noemu:
279#endif 221#endif
222 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
223 stg %r2,__PT_ORIG_GPR2(%r11)
224 stg %r7,STACK_FRAME_OVERHEAD(%r15)
225 lgf %r9,0(%r8,%r10) # get system call add.
280 tm __TI_flags+6(%r12),_TIF_TRACE >> 8 226 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 227 jnz sysc_tracesys
284 basr %r14,%r8 # call sys_xxxx 228 basr %r14,%r9 # call sys_xxxx
285 stg %r2,SP_R2(%r15) # store return value (change R2 on stack) 229 stg %r2,__PT_R2(%r11) # store return value
286 230
287sysc_return: 231sysc_return:
288 LOCKDEP_SYS_EXIT 232 LOCKDEP_SYS_EXIT
289sysc_tif: 233sysc_tif:
290 tm SP_PSW+1(%r15),0x01 # returning to user ? 234 tm __PT_PSW+1(%r11),0x01 # returning to user ?
291 jno sysc_restore 235 jno sysc_restore
292 tm __TI_flags+7(%r12),_TIF_WORK_SVC 236 tm __TI_flags+7(%r12),_TIF_WORK_SVC
293 jnz sysc_work # there is work to do (signals etc.) 237 jnz sysc_work # check for work
294 ni __TI_flags+7(%r12),255-_TIF_SYSCALL 238 ni __TI_flags+7(%r12),255-_TIF_SYSCALL
295sysc_restore: 239sysc_restore:
296 RESTORE_ALL __LC_RETURN_PSW,1 240 lg %r14,__LC_VDSO_PER_CPU
241 lmg %r0,%r10,__PT_R0(%r11)
242 mvc __LC_RETURN_PSW(16),__PT_PSW(%r11)
243 stpt __LC_EXIT_TIMER
244 mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
245 lmg %r11,%r15,__PT_R11(%r11)
246 lpswe __LC_RETURN_PSW
297sysc_done: 247sysc_done:
298 248
299# 249#
@@ -317,7 +267,7 @@ sysc_work:
317# 267#
318sysc_reschedule: 268sysc_reschedule:
319 larl %r14,sysc_return 269 larl %r14,sysc_return
320 jg schedule # return point is sysc_return 270 jg schedule
321 271
322# 272#
323# _TIF_MCCK_PENDING is set, call handler 273# _TIF_MCCK_PENDING is set, call handler
@@ -331,33 +281,33 @@ sysc_mcck_pending:
331# 281#
332sysc_sigpending: 282sysc_sigpending:
333 ni __TI_flags+7(%r12),255-_TIF_PER_TRAP # clear TIF_PER_TRAP 283 ni __TI_flags+7(%r12),255-_TIF_PER_TRAP # clear TIF_PER_TRAP
334 la %r2,SP_PTREGS(%r15) # load pt_regs 284 lgr %r2,%r11 # pass pointer to pt_regs
335 brasl %r14,do_signal # call do_signal 285 brasl %r14,do_signal
336 tm __TI_flags+7(%r12),_TIF_SYSCALL 286 tm __TI_flags+7(%r12),_TIF_SYSCALL
337 jno sysc_return 287 jno sysc_return
338 lmg %r2,%r6,SP_R2(%r15) # load svc arguments 288 lmg %r2,%r7,__PT_R2(%r11) # load svc arguments
339 lghi %r7,0 # svc 0 returns -ENOSYS 289 lghi %r8,0 # svc 0 returns -ENOSYS
340 lh %r1,SP_SVC_CODE+2(%r15) # load new svc number 290 lh %r1,__PT_INT_CODE+2(%r11) # load new svc number
341 cghi %r1,NR_syscalls 291 cghi %r1,NR_syscalls
342 jnl sysc_nr_ok # invalid svc number -> do svc 0 292 jnl sysc_nr_ok # invalid svc number -> do svc 0
343 slag %r7,%r1,2 293 slag %r8,%r1,2
344 j sysc_nr_ok # restart svc 294 j sysc_nr_ok # restart svc
345 295
346# 296#
347# _TIF_NOTIFY_RESUME is set, call do_notify_resume 297# _TIF_NOTIFY_RESUME is set, call do_notify_resume
348# 298#
349sysc_notify_resume: 299sysc_notify_resume:
350 la %r2,SP_PTREGS(%r15) # load pt_regs 300 lgr %r2,%r11 # pass pointer to pt_regs
351 larl %r14,sysc_return 301 larl %r14,sysc_return
352 jg do_notify_resume # call do_notify_resume 302 jg do_notify_resume
353 303
354# 304#
355# _TIF_PER_TRAP is set, call do_per_trap 305# _TIF_PER_TRAP is set, call do_per_trap
356# 306#
357sysc_singlestep: 307sysc_singlestep:
358 ni __TI_flags+7(%r12),255-(_TIF_SYSCALL | _TIF_PER_TRAP) 308 ni __TI_flags+7(%r12),255-(_TIF_SYSCALL | _TIF_PER_TRAP)
359 la %r2,SP_PTREGS(%r15) # address of register-save area 309 lgr %r2,%r11 # pass pointer to pt_regs
360 larl %r14,sysc_return # load adr. of system return 310 larl %r14,sysc_return
361 jg do_per_trap 311 jg do_per_trap
362 312
363# 313#
@@ -365,41 +315,41 @@ sysc_singlestep:
365# and after the system call 315# and after the system call
366# 316#
367sysc_tracesys: 317sysc_tracesys:
368 la %r2,SP_PTREGS(%r15) # load pt_regs 318 lgr %r2,%r11 # pass pointer to pt_regs
369 la %r3,0 319 la %r3,0
370 llgh %r0,SP_SVC_CODE+2(%r15) 320 llgh %r0,__PT_INT_CODE+2(%r11)
371 stg %r0,SP_R2(%r15) 321 stg %r0,__PT_R2(%r11)
372 brasl %r14,do_syscall_trace_enter 322 brasl %r14,do_syscall_trace_enter
373 lghi %r0,NR_syscalls 323 lghi %r0,NR_syscalls
374 clgr %r0,%r2 324 clgr %r0,%r2
375 jnh sysc_tracenogo 325 jnh sysc_tracenogo
376 sllg %r7,%r2,2 # svc number *4 326 sllg %r8,%r2,2
377 lgf %r8,0(%r7,%r10) 327 lgf %r9,0(%r8,%r10)
378sysc_tracego: 328sysc_tracego:
379 lmg %r3,%r6,SP_R3(%r15) 329 lmg %r3,%r7,__PT_R3(%r11)
380 mvc SP_ARGS(8,%r15),SP_R7(%r15) 330 stg %r7,STACK_FRAME_OVERHEAD(%r15)
381 lg %r2,SP_ORIG_R2(%r15) 331 lg %r2,__PT_ORIG_GPR2(%r11)
382 basr %r14,%r8 # call sys_xxx 332 basr %r14,%r9 # call sys_xxx
383 stg %r2,SP_R2(%r15) # store return value 333 stg %r2,__PT_R2(%r11) # store return value
384sysc_tracenogo: 334sysc_tracenogo:
385 tm __TI_flags+6(%r12),_TIF_TRACE >> 8 335 tm __TI_flags+6(%r12),_TIF_TRACE >> 8
386 jz sysc_return 336 jz sysc_return
387 la %r2,SP_PTREGS(%r15) # load pt_regs 337 lgr %r2,%r11 # pass pointer to pt_regs
388 larl %r14,sysc_return # return point is sysc_return 338 larl %r14,sysc_return
389 jg do_syscall_trace_exit 339 jg do_syscall_trace_exit
390 340
391# 341#
392# a new process exits the kernel with ret_from_fork 342# a new process exits the kernel with ret_from_fork
393# 343#
394ENTRY(ret_from_fork) 344ENTRY(ret_from_fork)
395 lg %r13,__LC_SVC_NEW_PSW+8 345 la %r11,STACK_FRAME_OVERHEAD(%r15)
396 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct 346 lg %r12,__LC_THREAD_INFO
397 tm SP_PSW+1(%r15),0x01 # forking a kernel thread ? 347 tm __PT_PSW+1(%r11),0x01 # forking a kernel thread ?
398 jo 0f 348 jo 0f
399 stg %r15,SP_R15(%r15) # store stack pointer for new kthread 349 stg %r15,__PT_R15(%r11) # store stack pointer for new kthread
4000: brasl %r14,schedule_tail 3500: brasl %r14,schedule_tail
401 TRACE_IRQS_ON 351 TRACE_IRQS_ON
402 stosm 24(%r15),0x03 # reenable interrupts 352 ssm __LC_SVC_NEW_PSW # reenable interrupts
403 j sysc_tracenogo 353 j sysc_tracenogo
404 354
405# 355#
@@ -409,26 +359,26 @@ ENTRY(ret_from_fork)
409ENTRY(kernel_execve) 359ENTRY(kernel_execve)
410 stmg %r12,%r15,96(%r15) 360 stmg %r12,%r15,96(%r15)
411 lgr %r14,%r15 361 lgr %r14,%r15
412 aghi %r15,-SP_SIZE 362 aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
413 stg %r14,__SF_BACKCHAIN(%r15) 363 stg %r14,__SF_BACKCHAIN(%r15)
414 la %r12,SP_PTREGS(%r15) 364 la %r12,STACK_FRAME_OVERHEAD(%r15)
415 xc 0(__PT_SIZE,%r12),0(%r12) 365 xc 0(__PT_SIZE,%r12),0(%r12)
416 lgr %r5,%r12 366 lgr %r5,%r12
417 brasl %r14,do_execve 367 brasl %r14,do_execve
418 ltgfr %r2,%r2 368 ltgfr %r2,%r2
419 je 0f 369 je 0f
420 aghi %r15,SP_SIZE 370 aghi %r15,(STACK_FRAME_OVERHEAD + __PT_SIZE)
421 lmg %r12,%r15,96(%r15) 371 lmg %r12,%r15,96(%r15)
422 br %r14 372 br %r14
423 # execve succeeded. 373 # execve succeeded.
4240: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts 3740: ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
425 lg %r15,__LC_KERNEL_STACK # load ksp 375 lg %r15,__LC_KERNEL_STACK # load ksp
426 aghi %r15,-SP_SIZE # make room for registers & psw 376 aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
427 lg %r13,__LC_SVC_NEW_PSW+8 377 la %r11,STACK_FRAME_OVERHEAD(%r15)
428 mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs 378 mvc 0(__PT_SIZE,%r11),0(%r12) # copy pt_regs
429 lg %r12,__LC_THREAD_INFO 379 lg %r12,__LC_THREAD_INFO
430 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 380 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
431 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 381 ssm __LC_SVC_NEW_PSW # reenable interrupts
432 brasl %r14,execve_tail 382 brasl %r14,execve_tail
433 j sysc_return 383 j sysc_return
434 384
@@ -437,127 +387,72 @@ ENTRY(kernel_execve)
437 */ 387 */
438 388
439ENTRY(pgm_check_handler) 389ENTRY(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 390 stpt __LC_SYNC_ENTER_TIMER
454 tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception 391 stmg %r8,%r15,__LC_SAVE_AREA_SYNC
455 jnz pgm_per # got per exception -> special case 392 lg %r10,__LC_LAST_BREAK
456 SAVE_ALL_PGM __LC_PGM_OLD_PSW,__LC_SAVE_AREA 393 lg %r12,__LC_THREAD_INFO
457 CREATE_STACK_FRAME __LC_SAVE_AREA 394 larl %r13,system_call
458 mvc SP_PSW(16,%r15),__LC_PGM_OLD_PSW 395 lmg %r8,%r9,__LC_PGM_OLD_PSW
459 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct 396 HANDLE_SIE_INTERCEPT %r14
460 HANDLE_SIE_INTERCEPT 397 tmhh %r8,0x0001 # test problem state bit
461 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 398 jnz 1f # -> fault in user space
462 jz pgm_no_vtime 399 tmhh %r8,0x4000 # PER bit set in old PSW ?
463 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 400 jnz 0f # -> enabled, can't be a double fault
464 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 401 tm __LC_PGM_ILC+3,0x80 # check for per exception
465 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 402 jnz pgm_svcper # -> single stepped svc
466 LAST_BREAK 4030: CHECK_STACK STACK_SIZE,__LC_SAVE_AREA_SYNC
467pgm_no_vtime: 404 j 2f
468 stg %r11,SP_ARGS(%r15) 4051: UPDATE_VTIME %r14,__LC_SYNC_ENTER_TIMER
469 lgf %r3,__LC_PGM_ILC # load program interruption code 406 LAST_BREAK %r14
470 lg %r4,__LC_TRANS_EXC_CODE 407 lg %r15,__LC_KERNEL_STACK
471 REENABLE_IRQS 4082: aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
472 lghi %r8,0x7f 409 la %r11,STACK_FRAME_OVERHEAD(%r15)
473 ngr %r8,%r3 410 stmg %r0,%r7,__PT_R0(%r11)
474 sll %r8,3 411 mvc __PT_R8(64,%r11),__LC_SAVE_AREA_SYNC
475 larl %r1,pgm_check_table 412 stmg %r8,%r9,__PT_PSW(%r11)
476 lg %r1,0(%r8,%r1) # load address of handler routine 413 mvc __PT_INT_CODE(4,%r11),__LC_PGM_ILC
477 la %r2,SP_PTREGS(%r15) # address of register-save area 414 mvc __PT_INT_PARM_LONG(8,%r11),__LC_TRANS_EXC_CODE
478 basr %r14,%r1 # branch to interrupt-handler 415 stg %r10,__PT_ARGS(%r11)
479pgm_exit: 416 tm __LC_PGM_ILC+3,0x80 # check for per exception
480 j sysc_return 417 jz 0f
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) 418 lg %r1,__TI_task(%r12)
511 tm SP_PSW+1(%r15),0x01 # kernel per event ? 419 tmhh %r8,0x0001 # kernel per event ?
512 jz kernel_per 420 jz pgm_kprobe
513 mvc __THREAD_per_cause(2,%r1),__LC_PER_CAUSE 421 oi __TI_flags+7(%r12),_TIF_PER_TRAP
514 mvc __THREAD_per_address(8,%r1),__LC_PER_ADDRESS 422 mvc __THREAD_per_address(8,%r1),__LC_PER_ADDRESS
423 mvc __THREAD_per_cause(2,%r1),__LC_PER_CAUSE
515 mvc __THREAD_per_paid(1,%r1),__LC_PER_PAID 424 mvc __THREAD_per_paid(1,%r1),__LC_PER_PAID
516 oi __TI_flags+7(%r12),_TIF_PER_TRAP # set TIF_PER_TRAP 4250: REENABLE_IRQS
517 lgf %r3,__LC_PGM_ILC # load program interruption code 426 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
518 lg %r4,__LC_TRANS_EXC_CODE
519 REENABLE_IRQS
520 lghi %r8,0x7f
521 ngr %r8,%r3 # clear per-event-bit and ilc
522 je pgm_exit2
523 sll %r8,3
524 larl %r1,pgm_check_table 427 larl %r1,pgm_check_table
525 lg %r1,0(%r8,%r1) # load address of handler routine 428 llgh %r10,__PT_INT_CODE+2(%r11)
526 la %r2,SP_PTREGS(%r15) # address of register-save area 429 nill %r10,0x007f
430 sll %r10,3
431 je sysc_return
432 lg %r1,0(%r10,%r1) # load address of handler routine
433 lgr %r2,%r11 # pass pointer to pt_regs
527 basr %r14,%r1 # branch to interrupt-handler 434 basr %r14,%r1 # branch to interrupt-handler
528pgm_exit2:
529 j sysc_return 435 j sysc_return
530 436
531# 437#
532# it was a single stepped SVC that is causing all the trouble 438# PER event in supervisor state, must be kprobes
533# 439#
534pgm_svcper: 440pgm_kprobe:
535 SAVE_ALL_PGM __LC_SVC_OLD_PSW,__LC_SAVE_AREA 441 REENABLE_IRQS
536 CREATE_STACK_FRAME __LC_SAVE_AREA 442 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
537 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct 443 lgr %r2,%r11 # pass pointer to pt_regs
538 mvc SP_PSW(16,%r15),__LC_SVC_OLD_PSW 444 brasl %r14,do_per_trap
539 mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC 445 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 446
553# 447#
554# per was called from kernel, must be kprobes 448# single stepped system call
555# 449#
556kernel_per: 450pgm_svcper:
557 REENABLE_IRQS 451 oi __TI_flags+7(%r12),_TIF_PER_TRAP
558 la %r2,SP_PTREGS(%r15) # address of register-save area 452 mvc __LC_RETURN_PSW(8),__LC_SVC_NEW_PSW
559 brasl %r14,do_per_trap 453 larl %r14,sysc_per
560 j pgm_exit 454 stg %r14,__LC_RETURN_PSW+8
455 lpswe __LC_RETURN_PSW # branch to sysc_per and enable irqs
561 456
562/* 457/*
563 * IO interrupt handler routine 458 * IO interrupt handler routine
@@ -565,21 +460,25 @@ kernel_per:
565ENTRY(io_int_handler) 460ENTRY(io_int_handler)
566 stck __LC_INT_CLOCK 461 stck __LC_INT_CLOCK
567 stpt __LC_ASYNC_ENTER_TIMER 462 stpt __LC_ASYNC_ENTER_TIMER
568 SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+40 463 stmg %r8,%r15,__LC_SAVE_AREA_ASYNC
569 CREATE_STACK_FRAME __LC_SAVE_AREA+40 464 lg %r10,__LC_LAST_BREAK
570 mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack 465 lg %r12,__LC_THREAD_INFO
571 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct 466 larl %r13,system_call
572 HANDLE_SIE_INTERCEPT 467 lmg %r8,%r9,__LC_IO_OLD_PSW
573 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 468 HANDLE_SIE_INTERCEPT %r14
574 jz io_no_vtime 469 SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT
575 UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER 470 tmhh %r8,0x0001 # interrupting from user?
576 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 471 jz io_skip
577 mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER 472 UPDATE_VTIME %r14,__LC_ASYNC_ENTER_TIMER
578 LAST_BREAK 473 LAST_BREAK %r14
579io_no_vtime: 474io_skip:
475 stmg %r0,%r7,__PT_R0(%r11)
476 mvc __PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC
477 stmg %r8,%r9,__PT_PSW(%r11)
580 TRACE_IRQS_OFF 478 TRACE_IRQS_OFF
581 la %r2,SP_PTREGS(%r15) # address of register-save area 479 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
582 brasl %r14,do_IRQ # call standard irq handler 480 lgr %r2,%r11 # pass pointer to pt_regs
481 brasl %r14,do_IRQ
583io_return: 482io_return:
584 LOCKDEP_SYS_EXIT 483 LOCKDEP_SYS_EXIT
585 TRACE_IRQS_ON 484 TRACE_IRQS_ON
@@ -587,7 +486,14 @@ io_tif:
587 tm __TI_flags+7(%r12),_TIF_WORK_INT 486 tm __TI_flags+7(%r12),_TIF_WORK_INT
588 jnz io_work # there is work to do (signals etc.) 487 jnz io_work # there is work to do (signals etc.)
589io_restore: 488io_restore:
590 RESTORE_ALL __LC_RETURN_PSW,0 489 lg %r14,__LC_VDSO_PER_CPU
490 lmg %r0,%r10,__PT_R0(%r11)
491 mvc __LC_RETURN_PSW(16),__PT_PSW(%r11)
492 ni __LC_RETURN_PSW+1,0xfd # clear wait state bit
493 stpt __LC_EXIT_TIMER
494 mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
495 lmg %r11,%r15,__PT_R11(%r11)
496 lpswe __LC_RETURN_PSW
591io_done: 497io_done:
592 498
593# 499#
@@ -600,7 +506,7 @@ io_done:
600# Before any work can be done, a switch to the kernel stack is required. 506# Before any work can be done, a switch to the kernel stack is required.
601# 507#
602io_work: 508io_work:
603 tm SP_PSW+1(%r15),0x01 # returning to user ? 509 tm __PT_PSW+1(%r11),0x01 # returning to user ?
604 jo io_work_user # yes -> do resched & signal 510 jo io_work_user # yes -> do resched & signal
605#ifdef CONFIG_PREEMPT 511#ifdef CONFIG_PREEMPT
606 # check for preemptive scheduling 512 # check for preemptive scheduling
@@ -609,10 +515,11 @@ io_work:
609 tm __TI_flags+7(%r12),_TIF_NEED_RESCHED 515 tm __TI_flags+7(%r12),_TIF_NEED_RESCHED
610 jno io_restore 516 jno io_restore
611 # switch to kernel stack 517 # switch to kernel stack
612 lg %r1,SP_R15(%r15) 518 lg %r1,__PT_R15(%r11)
613 aghi %r1,-SP_SIZE 519 aghi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
614 mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) 520 mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
615 xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain 521 xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
522 la %r11,STACK_FRAME_OVERHEAD(%r1)
616 lgr %r15,%r1 523 lgr %r15,%r1
617 # TRACE_IRQS_ON already done at io_return, call 524 # TRACE_IRQS_ON already done at io_return, call
618 # TRACE_IRQS_OFF to keep things symmetrical 525 # TRACE_IRQS_OFF to keep things symmetrical
@@ -628,9 +535,10 @@ io_work:
628# 535#
629io_work_user: 536io_work_user:
630 lg %r1,__LC_KERNEL_STACK 537 lg %r1,__LC_KERNEL_STACK
631 aghi %r1,-SP_SIZE 538 aghi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
632 mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) 539 mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
633 xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain 540 xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
541 la %r11,STACK_FRAME_OVERHEAD(%r1)
634 lgr %r15,%r1 542 lgr %r15,%r1
635 543
636# 544#
@@ -663,9 +571,9 @@ io_mcck_pending:
663# 571#
664io_reschedule: 572io_reschedule:
665 # TRACE_IRQS_ON already done at io_return 573 # TRACE_IRQS_ON already done at io_return
666 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 574 ssm __LC_SVC_NEW_PSW # reenable interrupts
667 brasl %r14,schedule # call scheduler 575 brasl %r14,schedule # call scheduler
668 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 576 ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
669 TRACE_IRQS_OFF 577 TRACE_IRQS_OFF
670 j io_return 578 j io_return
671 579
@@ -674,10 +582,10 @@ io_reschedule:
674# 582#
675io_sigpending: 583io_sigpending:
676 # TRACE_IRQS_ON already done at io_return 584 # TRACE_IRQS_ON already done at io_return
677 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 585 ssm __LC_SVC_NEW_PSW # reenable interrupts
678 la %r2,SP_PTREGS(%r15) # load pt_regs 586 lgr %r2,%r11 # pass pointer to pt_regs
679 brasl %r14,do_signal # call do_signal 587 brasl %r14,do_signal
680 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 588 ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
681 TRACE_IRQS_OFF 589 TRACE_IRQS_OFF
682 j io_return 590 j io_return
683 591
@@ -686,10 +594,10 @@ io_sigpending:
686# 594#
687io_notify_resume: 595io_notify_resume:
688 # TRACE_IRQS_ON already done at io_return 596 # TRACE_IRQS_ON already done at io_return
689 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 597 ssm __LC_SVC_NEW_PSW # reenable interrupts
690 la %r2,SP_PTREGS(%r15) # load pt_regs 598 lgr %r2,%r11 # pass pointer to pt_regs
691 brasl %r14,do_notify_resume # call do_notify_resume 599 brasl %r14,do_notify_resume
692 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 600 ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
693 TRACE_IRQS_OFF 601 TRACE_IRQS_OFF
694 j io_return 602 j io_return
695 603
@@ -699,21 +607,24 @@ io_notify_resume:
699ENTRY(ext_int_handler) 607ENTRY(ext_int_handler)
700 stck __LC_INT_CLOCK 608 stck __LC_INT_CLOCK
701 stpt __LC_ASYNC_ENTER_TIMER 609 stpt __LC_ASYNC_ENTER_TIMER
702 SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+40 610 stmg %r8,%r15,__LC_SAVE_AREA_ASYNC
703 CREATE_STACK_FRAME __LC_SAVE_AREA+40 611 lg %r10,__LC_LAST_BREAK
704 mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack 612 lg %r12,__LC_THREAD_INFO
705 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct 613 larl %r13,system_call
706 HANDLE_SIE_INTERCEPT 614 lmg %r8,%r9,__LC_EXT_OLD_PSW
707 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 615 HANDLE_SIE_INTERCEPT %r14
708 jz ext_no_vtime 616 SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT
709 UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER 617 tmhh %r8,0x0001 # interrupting from user ?
710 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 618 jz ext_skip
711 mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER 619 UPDATE_VTIME %r14,__LC_ASYNC_ENTER_TIMER
712 LAST_BREAK 620 LAST_BREAK %r14
713ext_no_vtime: 621ext_skip:
622 stmg %r0,%r7,__PT_R0(%r11)
623 mvc __PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC
624 stmg %r8,%r9,__PT_PSW(%r11)
714 TRACE_IRQS_OFF 625 TRACE_IRQS_OFF
715 lghi %r1,4096 626 lghi %r1,4096
716 la %r2,SP_PTREGS(%r15) # address of register-save area 627 lgr %r2,%r11 # pass pointer to pt_regs
717 llgf %r3,__LC_CPU_ADDRESS # get cpu address + interruption code 628 llgf %r3,__LC_CPU_ADDRESS # get cpu address + interruption code
718 llgf %r4,__LC_EXT_PARAMS # get external parameter 629 llgf %r4,__LC_EXT_PARAMS # get external parameter
719 lg %r5,__LC_EXT_PARAMS2-4096(%r1) # get 64 bit external parameter 630 lg %r5,__LC_EXT_PARAMS2-4096(%r1) # get 64 bit external parameter
@@ -730,81 +641,77 @@ ENTRY(mcck_int_handler)
730 la %r1,4095 # revalidate r1 641 la %r1,4095 # revalidate r1
731 spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer 642 spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer
732 lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs 643 lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs
733 stmg %r11,%r15,__LC_SAVE_AREA+80 644 lg %r10,__LC_LAST_BREAK
645 lg %r12,__LC_THREAD_INFO
734 larl %r13,system_call 646 larl %r13,system_call
735 lg %r11,__LC_LAST_BREAK 647 lmg %r8,%r9,__LC_MCK_OLD_PSW
736 la %r12,__LC_MCK_OLD_PSW 648 HANDLE_SIE_INTERCEPT %r14
737 tm __LC_MCCK_CODE,0x80 # system damage? 649 tm __LC_MCCK_CODE,0x80 # system damage?
738 jo mcck_int_main # yes -> rest of mcck code invalid 650 jo mcck_panic # yes -> rest of mcck code invalid
739 la %r14,4095 651 lghi %r14,__LC_CPU_TIMER_SAVE_AREA
740 mvc __LC_MCCK_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA-4095(%r14) 652 mvc __LC_MCCK_ENTER_TIMER(8),0(%r14)
741 tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid? 653 tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid?
742 jo 1f 654 jo 3f
743 la %r14,__LC_SYNC_ENTER_TIMER 655 la %r14,__LC_SYNC_ENTER_TIMER
744 clc 0(8,%r14),__LC_ASYNC_ENTER_TIMER 656 clc 0(8,%r14),__LC_ASYNC_ENTER_TIMER
745 jl 0f 657 jl 0f
746 la %r14,__LC_ASYNC_ENTER_TIMER 658 la %r14,__LC_ASYNC_ENTER_TIMER
7470: clc 0(8,%r14),__LC_EXIT_TIMER 6590: clc 0(8,%r14),__LC_EXIT_TIMER
748 jl 0f 660 jl 1f
749 la %r14,__LC_EXIT_TIMER 661 la %r14,__LC_EXIT_TIMER
7500: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER 6621: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER
751 jl 0f 663 jl 2f
752 la %r14,__LC_LAST_UPDATE_TIMER 664 la %r14,__LC_LAST_UPDATE_TIMER
7530: spt 0(%r14) 6652: spt 0(%r14)
754 mvc __LC_MCCK_ENTER_TIMER(8),0(%r14) 666 mvc __LC_MCCK_ENTER_TIMER(8),0(%r14)
7551: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? 6673: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid?
756 jno mcck_int_main # no -> skip cleanup critical 668 jno mcck_panic # no -> skip cleanup critical
757 tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit 669 SWITCH_ASYNC __LC_GPREGS_SAVE_AREA+64,__LC_PANIC_STACK,PAGE_SHIFT
758 jnz mcck_int_main # from user -> load kernel stack 670 tm %r8,0x0001 # interrupting from user ?
759 clc __LC_MCK_OLD_PSW+8(8),BASED(.Lcritical_end) 671 jz mcck_skip
760 jhe mcck_int_main 672 UPDATE_VTIME %r14,__LC_MCCK_ENTER_TIMER
761 clc __LC_MCK_OLD_PSW+8(8),BASED(.Lcritical_start) 673 LAST_BREAK %r14
762 jl mcck_int_main 674mcck_skip:
763 brasl %r14,cleanup_critical 675 lghi %r14,__LC_GPREGS_SAVE_AREA
764mcck_int_main: 676 mvc __PT_R0(128,%r11),0(%r14)
765 lg %r14,__LC_PANIC_STACK # are we already on the panic stack? 677 stmg %r8,%r9,__PT_PSW(%r11)
766 slgr %r14,%r15 678 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
767 srag %r14,%r14,PAGE_SHIFT 679 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 680 brasl %r14,s390_do_machine_check
786 tm SP_PSW+1(%r15),0x01 # returning to user ? 681 tm __PT_PSW+1(%r11),0x01 # returning to user ?
787 jno mcck_return 682 jno mcck_return
788 lg %r1,__LC_KERNEL_STACK # switch to kernel stack 683 lg %r1,__LC_KERNEL_STACK # switch to kernel stack
789 aghi %r1,-SP_SIZE 684 aghi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
790 mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) 685 mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
791 xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain 686 xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
687 la %r11,STACK_FRAME_OVERHEAD(%r1)
792 lgr %r15,%r1 688 lgr %r15,%r1
793 stosm __SF_EMPTY(%r15),0x04 # turn dat on 689 ssm __LC_PGM_NEW_PSW # turn dat on, keep irqs off
794 tm __TI_flags+7(%r12),_TIF_MCCK_PENDING 690 tm __TI_flags+7(%r12),_TIF_MCCK_PENDING
795 jno mcck_return 691 jno mcck_return
796 TRACE_IRQS_OFF 692 TRACE_IRQS_OFF
797 brasl %r14,s390_handle_mcck 693 brasl %r14,s390_handle_mcck
798 TRACE_IRQS_ON 694 TRACE_IRQS_ON
799mcck_return: 695mcck_return:
800 mvc __LC_RETURN_MCCK_PSW(16),SP_PSW(%r15) # move return PSW 696 lg %r14,__LC_VDSO_PER_CPU
697 lmg %r0,%r10,__PT_R0(%r11)
698 mvc __LC_RETURN_MCCK_PSW(16),__PT_PSW(%r11) # move return PSW
801 ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit 699 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 ? 700 tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ?
804 jno 0f 701 jno 0f
805 stpt __LC_EXIT_TIMER 702 stpt __LC_EXIT_TIMER
8060: lpswe __LC_RETURN_MCCK_PSW # back to caller 703 mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
807mcck_done: 7040: lmg %r11,%r15,__PT_R11(%r11)
705 lpswe __LC_RETURN_MCCK_PSW
706
707mcck_panic:
708 lg %r14,__LC_PANIC_STACK
709 slgr %r14,%r15
710 srag %r14,%r14,PAGE_SHIFT
711 jz 0f
712 lg %r15,__LC_PANIC_STACK
7130: aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
714 j mcck_skip
808 715
809/* 716/*
810 * Restart interruption handler, kick starter for additional CPUs 717 * Restart interruption handler, kick starter for additional CPUs
@@ -818,17 +725,18 @@ restart_base:
818 stck __LC_LAST_UPDATE_CLOCK 725 stck __LC_LAST_UPDATE_CLOCK
819 mvc __LC_LAST_UPDATE_TIMER(8),restart_vtime-restart_base(%r1) 726 mvc __LC_LAST_UPDATE_TIMER(8),restart_vtime-restart_base(%r1)
820 mvc __LC_EXIT_TIMER(8),restart_vtime-restart_base(%r1) 727 mvc __LC_EXIT_TIMER(8),restart_vtime-restart_base(%r1)
821 lg %r15,__LC_SAVE_AREA+120 # load ksp 728 lghi %r10,__LC_GPREGS_SAVE_AREA
729 lg %r15,120(%r10) # load ksp
822 lghi %r10,__LC_CREGS_SAVE_AREA 730 lghi %r10,__LC_CREGS_SAVE_AREA
823 lctlg %c0,%c15,0(%r10) # get new ctl regs 731 lctlg %c0,%c15,0(%r10) # get new ctl regs
824 lghi %r10,__LC_AREGS_SAVE_AREA 732 lghi %r10,__LC_AREGS_SAVE_AREA
825 lam %a0,%a15,0(%r10) 733 lam %a0,%a15,0(%r10)
826 lmg %r6,%r15,__SF_GPRS(%r15) # load registers from clone 734 lmg %r6,%r15,__SF_GPRS(%r15)# load registers from clone
827 lg %r1,__LC_THREAD_INFO 735 lg %r1,__LC_THREAD_INFO
828 mvc __LC_USER_TIMER(8),__TI_user_timer(%r1) 736 mvc __LC_USER_TIMER(8),__TI_user_timer(%r1)
829 mvc __LC_SYSTEM_TIMER(8),__TI_system_timer(%r1) 737 mvc __LC_SYSTEM_TIMER(8),__TI_system_timer(%r1)
830 xc __LC_STEAL_TIMER(8),__LC_STEAL_TIMER 738 xc __LC_STEAL_TIMER(8),__LC_STEAL_TIMER
831 stosm __SF_EMPTY(%r15),0x04 # now we can turn dat on 739 ssm __LC_PGM_NEW_PSW # turn dat on, keep irqs off
832 brasl %r14,start_secondary 740 brasl %r14,start_secondary
833 .align 8 741 .align 8
834restart_vtime: 742restart_vtime:
@@ -852,16 +760,16 @@ restart_go:
852# PSW restart interrupt handler 760# PSW restart interrupt handler
853# 761#
854ENTRY(psw_restart_int_handler) 762ENTRY(psw_restart_int_handler)
855 stg %r15,__LC_SAVE_AREA+120(%r0) # save r15 763 stg %r15,__LC_SAVE_AREA_RESTART
856 larl %r15,restart_stack # load restart stack 764 larl %r15,restart_stack # load restart stack
857 lg %r15,0(%r15) 765 lg %r15,0(%r15)
858 aghi %r15,-SP_SIZE # make room for pt_regs 766 aghi %r15,-__PT_SIZE # create pt_regs on stack
859 stmg %r0,%r14,SP_R0(%r15) # store gprs %r0-%r14 to stack 767 stmg %r0,%r14,__PT_R0(%r15)
860 mvc SP_R15(8,%r15),__LC_SAVE_AREA+120(%r0)# store saved %r15 to stack 768 mvc __PT_R15(8,%r15),__LC_SAVE_AREA_RESTART
861 mvc SP_PSW(16,%r15),__LC_RST_OLD_PSW(%r0)# store restart old psw 769 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 770 aghi %r15,-STACK_FRAME_OVERHEAD
771 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
863 brasl %r14,do_restart 772 brasl %r14,do_restart
864
865 larl %r14,restart_psw_crash # load disabled wait PSW if 773 larl %r14,restart_psw_crash # load disabled wait PSW if
866 lpswe 0(%r14) # do_restart returns 774 lpswe 0(%r14) # do_restart returns
867 .align 8 775 .align 8
@@ -877,172 +785,153 @@ restart_psw_crash:
877 * Setup a pt_regs so that show_trace can provide a good call trace. 785 * Setup a pt_regs so that show_trace can provide a good call trace.
878 */ 786 */
879stack_overflow: 787stack_overflow:
880 lg %r15,__LC_PANIC_STACK # change to panic stack 788 lg %r11,__LC_PANIC_STACK # change to panic stack
881 aghi %r15,-SP_SIZE 789 aghi %r11,-__PT_SIZE # create pt_regs
882 mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack 790 stmg %r0,%r7,__PT_R0(%r11)
883 stmg %r0,%r10,SP_R0(%r15) # store gprs %r0-%r10 to kernel stack 791 stmg %r8,%r9,__PT_PSW(%r11)
884 la %r1,__LC_SAVE_AREA 792 mvc __PT_R8(64,%r11),0(%r14)
885 chi %r12,__LC_SVC_OLD_PSW 793 stg %r10,__PT_ORIG_GPR2(%r11) # store last break to orig_gpr2
886 je 0f 794 lgr %r15,%r11
887 chi %r12,__LC_PGM_OLD_PSW 795 aghi %r15,-STACK_FRAME_OVERHEAD
888 je 0f 796 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
889 la %r1,__LC_SAVE_AREA+40 797 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 798 jg kernel_stack_overflow
895#endif 799#endif
896 800
897cleanup_table_system_call: 801 .align 8
898 .quad system_call, sysc_do_svc 802cleanup_table:
899cleanup_table_sysc_tif: 803 .quad system_call
900 .quad sysc_tif, sysc_restore 804 .quad sysc_do_svc
901cleanup_table_sysc_restore: 805 .quad sysc_tif
902 .quad sysc_restore, sysc_done 806 .quad sysc_restore
903cleanup_table_io_tif: 807 .quad sysc_done
904 .quad io_tif, io_restore 808 .quad io_tif
905cleanup_table_io_restore: 809 .quad io_restore
906 .quad io_restore, io_done 810 .quad io_done
907 811
908cleanup_critical: 812cleanup_critical:
909 clc 8(8,%r12),BASED(cleanup_table_system_call) 813 clg %r9,BASED(cleanup_table) # system_call
910 jl 0f 814 jl 0f
911 clc 8(8,%r12),BASED(cleanup_table_system_call+8) 815 clg %r9,BASED(cleanup_table+8) # sysc_do_svc
912 jl cleanup_system_call 816 jl cleanup_system_call
9130: 817 clg %r9,BASED(cleanup_table+16) # sysc_tif
914 clc 8(8,%r12),BASED(cleanup_table_sysc_tif)
915 jl 0f 818 jl 0f
916 clc 8(8,%r12),BASED(cleanup_table_sysc_tif+8) 819 clg %r9,BASED(cleanup_table+24) # sysc_restore
917 jl cleanup_sysc_tif 820 jl cleanup_sysc_tif
9180: 821 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 822 jl cleanup_sysc_restore
9230: 823 clg %r9,BASED(cleanup_table+40) # io_tif
924 clc 8(8,%r12),BASED(cleanup_table_io_tif)
925 jl 0f 824 jl 0f
926 clc 8(8,%r12),BASED(cleanup_table_io_tif+8) 825 clg %r9,BASED(cleanup_table+48) # io_restore
927 jl cleanup_io_tif 826 jl cleanup_io_tif
9280: 827 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 828 jl cleanup_io_restore
9330: 8290: br %r14
934 br %r14 830
935 831
936cleanup_system_call: 832cleanup_system_call:
937 mvc __LC_RETURN_PSW(16),0(%r12) 833 # check if stpt has been executed
938 clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+8) 834 clg %r9,BASED(cleanup_system_call_insn)
939 jh 0f 835 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 836 mvc __LC_SYNC_ENTER_TIMER(8),__LC_ASYNC_ENTER_TIMER
9440: cghi %r12,__LC_MCK_OLD_PSW 837 cghi %r11,__LC_SAVE_AREA_ASYNC
945 la %r12,__LC_SAVE_AREA+80
946 je 0f 838 je 0f
947 la %r12,__LC_SAVE_AREA+40 839 mvc __LC_SYNC_ENTER_TIMER(8),__LC_MCCK_ENTER_TIMER
9480: clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+16) 8400: # check if stmg has been executed
949 jhe cleanup_vtime 841 clg %r9,BASED(cleanup_system_call_insn+8)
950 clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn)
951 jh 0f 842 jh 0f
952 mvc __LC_SAVE_AREA(40),0(%r12) 843 mvc __LC_SAVE_AREA_SYNC(64),0(%r11)
9530: lg %r15,__LC_KERNEL_STACK # problem state -> load ksp 8440: # check if base register setup + TIF bit load has been done
954 aghi %r15,-SP_SIZE # make room for registers & psw 845 clg %r9,BASED(cleanup_system_call_insn+16)
955 stg %r15,32(%r12) 846 jhe 0f
956 stg %r11,0(%r12) 847 # set up saved registers r10 and r12
957 CREATE_STACK_FRAME __LC_SAVE_AREA 848 stg %r10,16(%r11) # r10 last break
958 mvc 8(8,%r12),__LC_THREAD_INFO 849 stg %r12,32(%r11) # r12 thread-info pointer
959 lg %r12,__LC_THREAD_INFO 8500: # check if the user time update has been done
960 mvc SP_PSW(16,%r15),__LC_SVC_OLD_PSW 851 clg %r9,BASED(cleanup_system_call_insn+24)
961 mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC 852 jh 0f
962 oi __TI_flags+7(%r12),_TIF_SYSCALL 853 lg %r15,__LC_EXIT_TIMER
963cleanup_vtime: 854 slg %r15,__LC_SYNC_ENTER_TIMER
964 clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+24) 855 alg %r15,__LC_USER_TIMER
965 jhe cleanup_stime 856 stg %r15,__LC_USER_TIMER
966 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 8570: # check if the system time update has been done
967cleanup_stime: 858 clg %r9,BASED(cleanup_system_call_insn+32)
968 clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+32) 859 jh 0f
969 jh cleanup_update 860 lg %r15,__LC_LAST_UPDATE_TIMER
970 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 861 slg %r15,__LC_EXIT_TIMER
971cleanup_update: 862 alg %r15,__LC_SYSTEM_TIMER
863 stg %r15,__LC_SYSTEM_TIMER
8640: # update accounting time stamp
972 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 865 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
973 srag %r12,%r11,23 866 # do LAST_BREAK
974 lg %r12,__LC_THREAD_INFO 867 lg %r9,16(%r11)
868 srag %r9,%r9,23
975 jz 0f 869 jz 0f
976 stg %r11,__TI_last_break(%r12) 870 mvc __TI_last_break(8,%r12),16(%r11)
9770: mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_system_call+8) 8710: # set up saved register r11
978 la %r12,__LC_RETURN_PSW 872 lg %r15,__LC_KERNEL_STACK
873 aghi %r15,-__PT_SIZE
874 stg %r15,24(%r11) # r11 pt_regs pointer
875 # fill pt_regs
876 mvc __PT_R8(64,%r15),__LC_SAVE_AREA_SYNC
877 stmg %r0,%r7,__PT_R0(%r15)
878 mvc __PT_PSW(16,%r15),__LC_SVC_OLD_PSW
879 mvc __PT_INT_CODE(4,%r15),__LC_SVC_ILC
880 # setup saved register r15
881 aghi %r15,-STACK_FRAME_OVERHEAD
882 stg %r15,56(%r11) # r15 stack pointer
883 # set new psw address and exit
884 larl %r9,sysc_do_svc
979 br %r14 885 br %r14
980cleanup_system_call_insn: 886cleanup_system_call_insn:
981 .quad sysc_saveall
982 .quad system_call 887 .quad system_call
983 .quad sysc_vtime 888 .quad sysc_stmg
984 .quad sysc_stime 889 .quad sysc_per
985 .quad sysc_update 890 .quad sysc_vtime+18
891 .quad sysc_vtime+42
986 892
987cleanup_sysc_tif: 893cleanup_sysc_tif:
988 mvc __LC_RETURN_PSW(8),0(%r12) 894 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 895 br %r14
992 896
993cleanup_sysc_restore: 897cleanup_sysc_restore:
994 clc 8(8,%r12),BASED(cleanup_sysc_restore_insn) 898 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 899 je 0f
1001 mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER 900 lg %r9,24(%r11) # get saved pointer to pt_regs
10020: mvc __LC_RETURN_PSW(16),SP_PSW(%r15) 901 mvc __LC_RETURN_PSW(16),__PT_PSW(%r9)
1003 cghi %r12,__LC_MCK_OLD_PSW 902 mvc 0(64,%r11),__PT_R8(%r9)
1004 la %r12,__LC_SAVE_AREA+80 903 lmg %r0,%r7,__PT_R0(%r9)
1005 je 1f 9040: 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 905 br %r14
1012cleanup_sysc_restore_insn: 906cleanup_sysc_restore_insn:
1013 .quad sysc_done - 4 907 .quad sysc_done - 4
1014 .quad sysc_done - 16
1015 908
1016cleanup_io_tif: 909cleanup_io_tif:
1017 mvc __LC_RETURN_PSW(8),0(%r12) 910 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 911 br %r14
1021 912
1022cleanup_io_restore: 913cleanup_io_restore:
1023 clc 8(8,%r12),BASED(cleanup_io_restore_insn) 914 clg %r9,BASED(cleanup_io_restore_insn)
1024 je 1f 915 je 0f
1025 clc 8(8,%r12),BASED(cleanup_io_restore_insn+8) 916 lg %r9,24(%r11) # get saved r11 pointer to pt_regs
1026 jhe 0f 917 mvc __LC_RETURN_PSW(16),__PT_PSW(%r9)
1027 mvc __LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER 918 ni __LC_RETURN_PSW+1,0xfd # clear wait state bit
10280: mvc __LC_RETURN_PSW(16),SP_PSW(%r15) 919 mvc 0(64,%r11),__PT_R8(%r9)
1029 mvc __LC_SAVE_AREA+80(40),SP_R11(%r15) 920 lmg %r0,%r7,__PT_R0(%r9)
1030 lmg %r0,%r10,SP_R0(%r15) 9210: lmg %r8,%r9,__LC_RETURN_PSW
1031 lg %r15,SP_R15(%r15)
10321: la %r12,__LC_RETURN_PSW
1033 br %r14 922 br %r14
1034cleanup_io_restore_insn: 923cleanup_io_restore_insn:
1035 .quad io_done - 4 924 .quad io_done - 4
1036 .quad io_done - 16
1037 925
1038/* 926/*
1039 * Integer constants 927 * Integer constants
1040 */ 928 */
1041 .align 4 929 .align 8
1042.Lcritical_start: 930.Lcritical_start:
1043 .quad __critical_start 931 .quad __critical_start
1044.Lcritical_end: 932.Lcritical_length:
1045 .quad __critical_end 933 .quad __critical_end - __critical_start
934
1046 935
1047#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) 936#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
1048/* 937/*
@@ -1054,6 +943,7 @@ ENTRY(sie64a)
1054 stmg %r6,%r14,__SF_GPRS(%r15) # save kernel registers 943 stmg %r6,%r14,__SF_GPRS(%r15) # save kernel registers
1055 stg %r2,__SF_EMPTY(%r15) # save control block pointer 944 stg %r2,__SF_EMPTY(%r15) # save control block pointer
1056 stg %r3,__SF_EMPTY+8(%r15) # save guest register save area 945 stg %r3,__SF_EMPTY+8(%r15) # save guest register save area
946 xc __SF_EMPTY+16(8,%r15),__SF_EMPTY+16(%r15) # host id == 0
1057 lmg %r0,%r13,0(%r3) # load guest gprs 0-13 947 lmg %r0,%r13,0(%r3) # load guest gprs 0-13
1058 lg %r14,__LC_THREAD_INFO # pointer thread_info struct 948 lg %r14,__LC_THREAD_INFO # pointer thread_info struct
1059 oi __TI_flags+6(%r14),_TIF_SIE>>8 949 oi __TI_flags+6(%r14),_TIF_SIE>>8
@@ -1070,7 +960,7 @@ sie_gmap:
1070 SPP __SF_EMPTY(%r15) # set guest id 960 SPP __SF_EMPTY(%r15) # set guest id
1071 sie 0(%r14) 961 sie 0(%r14)
1072sie_done: 962sie_done:
1073 SPP __LC_CMF_HPP # set host id 963 SPP __SF_EMPTY+16(%r15) # set host id
1074 lg %r14,__LC_THREAD_INFO # pointer thread_info struct 964 lg %r14,__LC_THREAD_INFO # pointer thread_info struct
1075sie_exit: 965sie_exit:
1076 lctlg %c1,%c1,__LC_USER_ASCE # load primary asce 966 lctlg %c1,%c1,__LC_USER_ASCE # load primary asce
@@ -1093,8 +983,10 @@ sie_fault:
1093 .align 8 983 .align 8
1094.Lsie_loop: 984.Lsie_loop:
1095 .quad sie_loop 985 .quad sie_loop
1096.Lsie_done: 986.Lsie_length:
1097 .quad sie_done 987 .quad sie_done - sie_loop
988.Lhost_id:
989 .quad 0
1098 990
1099 .section __ex_table,"a" 991 .section __ex_table,"a"
1100 .quad sie_loop,sie_fault 992 .quad sie_loop,sie_fault