[S390] virtual cpu accounting vs. machine checks.
[linux-2.6] / arch / s390 / kernel / entry.S
1 /*
2  *  arch/s390/kernel/entry.S
3  *    S390 low-level entry points.
4  *
5  *    Copyright (C) IBM Corp. 1999,2006
6  *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
7  *               Hartmut Penner (hp@de.ibm.com),
8  *               Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
9  *               Heiko Carstens <heiko.carstens@de.ibm.com>
10  */
11
12 #include <linux/sys.h>
13 #include <linux/linkage.h>
14 #include <linux/config.h>
15 #include <asm/cache.h>
16 #include <asm/lowcore.h>
17 #include <asm/errno.h>
18 #include <asm/ptrace.h>
19 #include <asm/thread_info.h>
20 #include <asm/asm-offsets.h>
21 #include <asm/unistd.h>
22 #include <asm/page.h>
23
24 /*
25  * Stack layout for the system_call stack entry.
26  * The first few entries are identical to the user_regs_struct.
27  */
28 SP_PTREGS    =  STACK_FRAME_OVERHEAD
29 SP_ARGS      =  STACK_FRAME_OVERHEAD + __PT_ARGS
30 SP_PSW       =  STACK_FRAME_OVERHEAD + __PT_PSW
31 SP_R0        =  STACK_FRAME_OVERHEAD + __PT_GPRS
32 SP_R1        =  STACK_FRAME_OVERHEAD + __PT_GPRS + 4
33 SP_R2        =  STACK_FRAME_OVERHEAD + __PT_GPRS + 8
34 SP_R3        =  STACK_FRAME_OVERHEAD + __PT_GPRS + 12
35 SP_R4        =  STACK_FRAME_OVERHEAD + __PT_GPRS + 16
36 SP_R5        =  STACK_FRAME_OVERHEAD + __PT_GPRS + 20
37 SP_R6        =  STACK_FRAME_OVERHEAD + __PT_GPRS + 24
38 SP_R7        =  STACK_FRAME_OVERHEAD + __PT_GPRS + 28
39 SP_R8        =  STACK_FRAME_OVERHEAD + __PT_GPRS + 32
40 SP_R9        =  STACK_FRAME_OVERHEAD + __PT_GPRS + 36
41 SP_R10       =  STACK_FRAME_OVERHEAD + __PT_GPRS + 40
42 SP_R11       =  STACK_FRAME_OVERHEAD + __PT_GPRS + 44
43 SP_R12       =  STACK_FRAME_OVERHEAD + __PT_GPRS + 48
44 SP_R13       =  STACK_FRAME_OVERHEAD + __PT_GPRS + 52
45 SP_R14       =  STACK_FRAME_OVERHEAD + __PT_GPRS + 56
46 SP_R15       =  STACK_FRAME_OVERHEAD + __PT_GPRS + 60
47 SP_ORIG_R2   =  STACK_FRAME_OVERHEAD + __PT_ORIG_GPR2
48 SP_ILC       =  STACK_FRAME_OVERHEAD + __PT_ILC
49 SP_TRAP      =  STACK_FRAME_OVERHEAD + __PT_TRAP
50 SP_SIZE      =  STACK_FRAME_OVERHEAD + __PT_SIZE
51
52 _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \
53                  _TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_SINGLE_STEP )
54 _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \
55                  _TIF_MCCK_PENDING)
56
57 STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER
58 STACK_SIZE  = 1 << STACK_SHIFT
59
60 #define BASED(name) name-system_call(%r13)
61
62 /*
63  * Register usage in interrupt handlers:
64  *    R9  - pointer to current task structure
65  *    R13 - pointer to literal pool
66  *    R14 - return register for function calls
67  *    R15 - kernel stack pointer
68  */
69
70         .macro  STORE_TIMER lc_offset
71 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
72         stpt    \lc_offset
73 #endif
74         .endm
75
76 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
77         .macro  UPDATE_VTIME lc_from,lc_to,lc_sum
78         lm      %r10,%r11,\lc_from
79         sl      %r10,\lc_to
80         sl      %r11,\lc_to+4
81         bc      3,BASED(0f)
82         sl      %r10,BASED(.Lc_1)
83 0:      al      %r10,\lc_sum
84         al      %r11,\lc_sum+4
85         bc      12,BASED(1f)
86         al      %r10,BASED(.Lc_1)
87 1:      stm     %r10,%r11,\lc_sum
88         .endm
89 #endif
90
91         .macro  SAVE_ALL_BASE savearea
92         stm     %r12,%r15,\savearea
93         l       %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13
94         .endm
95
96         .macro  SAVE_ALL_SYNC psworg,savearea
97         la      %r12,\psworg
98         tm      \psworg+1,0x01          # test problem state bit
99         bz      BASED(2f)               # skip stack setup save
100         l       %r15,__LC_KERNEL_STACK  # problem state -> load ksp
101 #ifdef CONFIG_CHECK_STACK
102         b       BASED(3f)
103 2:      tml     %r15,STACK_SIZE - CONFIG_STACK_GUARD
104         bz      BASED(stack_overflow)
105 3:
106 #endif
107 2:
108         .endm
109
110         .macro  SAVE_ALL_ASYNC psworg,savearea
111         la      %r12,\psworg
112         tm      \psworg+1,0x01          # test problem state bit
113         bnz     BASED(1f)               # from user -> load async stack
114         clc     \psworg+4(4),BASED(.Lcritical_end)
115         bhe     BASED(0f)
116         clc     \psworg+4(4),BASED(.Lcritical_start)
117         bl      BASED(0f)
118         l       %r14,BASED(.Lcleanup_critical)
119         basr    %r14,%r14
120         tm      1(%r12),0x01            # retest problem state after cleanup
121         bnz     BASED(1f)
122 0:      l       %r14,__LC_ASYNC_STACK   # are we already on the async stack ?
123         slr     %r14,%r15
124         sra     %r14,STACK_SHIFT
125         be      BASED(2f)
126 1:      l       %r15,__LC_ASYNC_STACK
127 #ifdef CONFIG_CHECK_STACK
128         b       BASED(3f)
129 2:      tml     %r15,STACK_SIZE - CONFIG_STACK_GUARD
130         bz      BASED(stack_overflow)
131 3:
132 #endif
133 2:
134         .endm
135
136         .macro  CREATE_STACK_FRAME psworg,savearea
137         s       %r15,BASED(.Lc_spsize)  # make room for registers & psw
138         mvc     SP_PSW(8,%r15),0(%r12)  # move user PSW to stack
139         la      %r12,\psworg
140         st      %r2,SP_ORIG_R2(%r15)    # store original content of gpr 2
141         icm     %r12,12,__LC_SVC_ILC
142         stm     %r0,%r11,SP_R0(%r15)    # store gprs %r0-%r11 to kernel stack
143         st      %r12,SP_ILC(%r15)
144         mvc     SP_R12(16,%r15),\savearea # move %r12-%r15 to stack
145         la      %r12,0
146         st      %r12,__SF_BACKCHAIN(%r15)       # clear back chain
147         .endm
148
149         .macro  RESTORE_ALL psworg,sync
150         mvc     \psworg(8),SP_PSW(%r15) # move user PSW to lowcore
151         .if !\sync
152         ni      \psworg+1,0xfd          # clear wait state bit
153         .endif
154         lm      %r0,%r15,SP_R0(%r15)    # load gprs 0-15 of user
155         STORE_TIMER __LC_EXIT_TIMER
156         lpsw    \psworg                 # back to caller
157         .endm
158
159 /*
160  * Scheduler resume function, called by switch_to
161  *  gpr2 = (task_struct *) prev
162  *  gpr3 = (task_struct *) next
163  * Returns:
164  *  gpr2 = prev
165  */
166         .globl  __switch_to
167 __switch_to:
168         basr    %r1,0
169 __switch_to_base:
170         tm      __THREAD_per(%r3),0xe8          # new process is using per ?
171         bz      __switch_to_noper-__switch_to_base(%r1) # if not we're fine
172         stctl   %c9,%c11,__SF_EMPTY(%r15)       # We are using per stuff
173         clc     __THREAD_per(12,%r3),__SF_EMPTY(%r15)
174         be      __switch_to_noper-__switch_to_base(%r1) # we got away w/o bashing TLB's
175         lctl    %c9,%c11,__THREAD_per(%r3)      # Nope we didn't
176 __switch_to_noper:
177         l       %r4,__THREAD_info(%r2)          # get thread_info of prev
178         tm      __TI_flags+3(%r4),_TIF_MCCK_PENDING # machine check pending?
179         bz      __switch_to_no_mcck-__switch_to_base(%r1)
180         ni      __TI_flags+3(%r4),255-_TIF_MCCK_PENDING # clear flag in prev
181         l       %r4,__THREAD_info(%r3)          # get thread_info of next
182         oi      __TI_flags+3(%r4),_TIF_MCCK_PENDING # set it in next
183 __switch_to_no_mcck:
184         stm     %r6,%r15,__SF_GPRS(%r15)# store __switch_to registers of prev task
185         st      %r15,__THREAD_ksp(%r2)  # store kernel stack to prev->tss.ksp
186         l       %r15,__THREAD_ksp(%r3)  # load kernel stack from next->tss.ksp
187         lm      %r6,%r15,__SF_GPRS(%r15)# load __switch_to registers of next task
188         st      %r3,__LC_CURRENT        # __LC_CURRENT = current task struct
189         lctl    %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4
190         l       %r3,__THREAD_info(%r3)  # load thread_info from task struct
191         st      %r3,__LC_THREAD_INFO
192         ahi     %r3,STACK_SIZE
193         st      %r3,__LC_KERNEL_STACK   # __LC_KERNEL_STACK = new kernel stack
194         br      %r14
195
196 __critical_start:
197 /*
198  * SVC interrupt handler routine. System calls are synchronous events and
199  * are executed with interrupts enabled.
200  */
201
202         .globl  system_call
203 system_call:
204         STORE_TIMER __LC_SYNC_ENTER_TIMER
205 sysc_saveall:
206         SAVE_ALL_BASE __LC_SAVE_AREA
207         SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
208         CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
209         lh      %r7,0x8a          # get svc number from lowcore
210 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
211 sysc_vtime:
212         tm      SP_PSW+1(%r15),0x01     # interrupting from user ?
213         bz      BASED(sysc_do_svc)
214         UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
215 sysc_stime:
216         UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
217 sysc_update:
218         mvc     __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
219 #endif
220 sysc_do_svc:
221         l       %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
222         sla     %r7,2             # *4 and test for svc 0
223         bnz     BASED(sysc_nr_ok) # svc number > 0
224         # svc 0: system call number in %r1
225         cl      %r1,BASED(.Lnr_syscalls)
226         bnl     BASED(sysc_nr_ok)
227         lr      %r7,%r1           # copy svc number to %r7
228         sla     %r7,2             # *4
229 sysc_nr_ok:
230         mvc     SP_ARGS(4,%r15),SP_R7(%r15)
231 sysc_do_restart:
232         tm      __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
233         l       %r8,sys_call_table-system_call(%r7,%r13) # get system call addr.
234         bnz     BASED(sysc_tracesys)
235         basr    %r14,%r8          # call sys_xxxx
236         st      %r2,SP_R2(%r15)   # store return value (change R2 on stack)
237                                   # ATTENTION: check sys_execve_glue before
238                                   # changing anything here !!
239
240 sysc_return:
241         tm      SP_PSW+1(%r15),0x01     # returning to user ?
242         bno     BASED(sysc_leave)
243         tm      __TI_flags+3(%r9),_TIF_WORK_SVC
244         bnz     BASED(sysc_work)  # there is work to do (signals etc.)
245 sysc_leave:
246         RESTORE_ALL __LC_RETURN_PSW,1
247
248 #
249 # recheck if there is more work to do
250 #
251 sysc_work_loop:
252         tm      __TI_flags+3(%r9),_TIF_WORK_SVC
253         bz      BASED(sysc_leave)      # there is no work to do
254 #
255 # One of the work bits is on. Find out which one.
256 #
257 sysc_work:
258         tm      __TI_flags+3(%r9),_TIF_MCCK_PENDING
259         bo      BASED(sysc_mcck_pending)
260         tm      __TI_flags+3(%r9),_TIF_NEED_RESCHED
261         bo      BASED(sysc_reschedule)
262         tm      __TI_flags+3(%r9),(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)
263         bnz     BASED(sysc_sigpending)
264         tm      __TI_flags+3(%r9),_TIF_RESTART_SVC
265         bo      BASED(sysc_restart)
266         tm      __TI_flags+3(%r9),_TIF_SINGLE_STEP
267         bo      BASED(sysc_singlestep)
268         b       BASED(sysc_leave)
269
270 #
271 # _TIF_NEED_RESCHED is set, call schedule
272 #       
273 sysc_reschedule:        
274         l       %r1,BASED(.Lschedule)
275         la      %r14,BASED(sysc_work_loop)
276         br      %r1                    # call scheduler
277
278 #
279 # _TIF_MCCK_PENDING is set, call handler
280 #
281 sysc_mcck_pending:
282         l       %r1,BASED(.Ls390_handle_mcck)
283         la      %r14,BASED(sysc_work_loop)
284         br      %r1                     # TIF bit will be cleared by handler
285
286 #
287 # _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal
288 #
289 sysc_sigpending:     
290         ni      __TI_flags+3(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP
291         la      %r2,SP_PTREGS(%r15)    # load pt_regs
292         l       %r1,BASED(.Ldo_signal)
293         basr    %r14,%r1               # call do_signal
294         tm      __TI_flags+3(%r9),_TIF_RESTART_SVC
295         bo      BASED(sysc_restart)
296         tm      __TI_flags+3(%r9),_TIF_SINGLE_STEP
297         bo      BASED(sysc_singlestep)
298         b       BASED(sysc_work_loop)
299
300 #
301 # _TIF_RESTART_SVC is set, set up registers and restart svc
302 #
303 sysc_restart:
304         ni      __TI_flags+3(%r9),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC
305         l       %r7,SP_R2(%r15)        # load new svc number
306         sla     %r7,2
307         mvc     SP_R2(4,%r15),SP_ORIG_R2(%r15) # restore first argument
308         lm      %r2,%r6,SP_R2(%r15)    # load svc arguments
309         b       BASED(sysc_do_restart) # restart svc
310
311 #
312 # _TIF_SINGLE_STEP is set, call do_single_step
313 #
314 sysc_singlestep:
315         ni      __TI_flags+3(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP
316         mvi     SP_TRAP+1(%r15),0x28    # set trap indication to pgm check
317         la      %r2,SP_PTREGS(%r15)     # address of register-save area
318         l       %r1,BASED(.Lhandle_per) # load adr. of per handler
319         la      %r14,BASED(sysc_return) # load adr. of system return
320         br      %r1                     # branch to do_single_step
321
322 #
323 # call trace before and after sys_call
324 #
325 sysc_tracesys:
326         l       %r1,BASED(.Ltrace)
327         la      %r2,SP_PTREGS(%r15)    # load pt_regs
328         la      %r3,0
329         srl     %r7,2
330         st      %r7,SP_R2(%r15)
331         basr    %r14,%r1
332         clc     SP_R2(4,%r15),BASED(.Lnr_syscalls)
333         bnl     BASED(sysc_tracenogo)
334         l       %r7,SP_R2(%r15)        # strace might have changed the 
335         sll     %r7,2                  #  system call
336         l       %r8,sys_call_table-system_call(%r7,%r13)
337 sysc_tracego:
338         lm      %r3,%r6,SP_R3(%r15)
339         l       %r2,SP_ORIG_R2(%r15)
340         basr    %r14,%r8          # call sys_xxx
341         st      %r2,SP_R2(%r15)   # store return value
342 sysc_tracenogo:
343         tm      __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
344         bz      BASED(sysc_return)
345         l       %r1,BASED(.Ltrace)
346         la      %r2,SP_PTREGS(%r15)    # load pt_regs
347         la      %r3,1
348         la      %r14,BASED(sysc_return)
349         br      %r1
350
351 #
352 # a new process exits the kernel with ret_from_fork
353 #
354         .globl  ret_from_fork
355 ret_from_fork:
356         l       %r13,__LC_SVC_NEW_PSW+4
357         l       %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
358         tm      SP_PSW+1(%r15),0x01     # forking a kernel thread ?
359         bo      BASED(0f)
360         st      %r15,SP_R15(%r15)       # store stack pointer for new kthread
361 0:      l       %r1,BASED(.Lschedtail)
362         basr    %r14,%r1
363         stosm   __SF_EMPTY(%r15),0x03     # reenable interrupts
364         b       BASED(sysc_return)
365
366 #
367 # clone, fork, vfork, exec and sigreturn need glue,
368 # because they all expect pt_regs as parameter,
369 # but are called with different parameter.
370 # return-address is set up above
371 #
372 sys_clone_glue: 
373         la      %r2,SP_PTREGS(%r15)    # load pt_regs
374         l       %r1,BASED(.Lclone)
375         br      %r1                   # branch to sys_clone
376
377 sys_fork_glue:  
378         la      %r2,SP_PTREGS(%r15)    # load pt_regs
379         l       %r1,BASED(.Lfork)
380         br      %r1                   # branch to sys_fork
381
382 sys_vfork_glue: 
383         la      %r2,SP_PTREGS(%r15)    # load pt_regs
384         l       %r1,BASED(.Lvfork)
385         br      %r1                   # branch to sys_vfork
386
387 sys_execve_glue:        
388         la      %r2,SP_PTREGS(%r15)   # load pt_regs
389         l       %r1,BASED(.Lexecve)
390         lr      %r12,%r14             # save return address
391         basr    %r14,%r1              # call sys_execve
392         ltr     %r2,%r2               # check if execve failed
393         bnz     0(%r12)               # it did fail -> store result in gpr2
394         b       4(%r12)               # SKIP ST 2,SP_R2(15) after BASR 14,8
395                                       # in system_call/sysc_tracesys
396
397 sys_sigreturn_glue:     
398         la      %r2,SP_PTREGS(%r15)   # load pt_regs as parameter
399         l       %r1,BASED(.Lsigreturn)
400         br      %r1                   # branch to sys_sigreturn
401
402 sys_rt_sigreturn_glue:     
403         la      %r2,SP_PTREGS(%r15)   # load pt_regs as parameter
404         l       %r1,BASED(.Lrt_sigreturn)
405         br      %r1                   # branch to sys_sigreturn
406
407 sys_sigaltstack_glue:
408         la      %r4,SP_PTREGS(%r15)   # load pt_regs as parameter
409         l       %r1,BASED(.Lsigaltstack)
410         br      %r1                   # branch to sys_sigreturn
411
412
413 /*
414  * Program check handler routine
415  */
416
417         .globl  pgm_check_handler
418 pgm_check_handler:
419 /*
420  * First we need to check for a special case:
421  * Single stepping an instruction that disables the PER event mask will
422  * cause a PER event AFTER the mask has been set. Example: SVC or LPSW.
423  * For a single stepped SVC the program check handler gets control after
424  * the SVC new PSW has been loaded. But we want to execute the SVC first and
425  * then handle the PER event. Therefore we update the SVC old PSW to point
426  * to the pgm_check_handler and branch to the SVC handler after we checked
427  * if we have to load the kernel stack register.
428  * For every other possible cause for PER event without the PER mask set
429  * we just ignore the PER event (FIXME: is there anything we have to do
430  * for LPSW?).
431  */
432         STORE_TIMER __LC_SYNC_ENTER_TIMER
433         SAVE_ALL_BASE __LC_SAVE_AREA
434         tm      __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception
435         bnz     BASED(pgm_per)           # got per exception -> special case
436         SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA
437         CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA
438 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
439         tm      SP_PSW+1(%r15),0x01     # interrupting from user ?
440         bz      BASED(pgm_no_vtime)
441         UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
442         UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
443         mvc     __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
444 pgm_no_vtime:
445 #endif
446         l       %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
447         l       %r3,__LC_PGM_ILC         # load program interruption code
448         la      %r8,0x7f
449         nr      %r8,%r3
450 pgm_do_call:
451         l       %r7,BASED(.Ljump_table)
452         sll     %r8,2
453         l       %r7,0(%r8,%r7)           # load address of handler routine
454         la      %r2,SP_PTREGS(%r15)      # address of register-save area
455         la      %r14,BASED(sysc_return)
456         br      %r7                      # branch to interrupt-handler
457
458 #
459 # handle per exception
460 #
461 pgm_per:
462         tm      __LC_PGM_OLD_PSW,0x40    # test if per event recording is on
463         bnz     BASED(pgm_per_std)       # ok, normal per event from user space
464 # ok its one of the special cases, now we need to find out which one
465         clc     __LC_PGM_OLD_PSW(8),__LC_SVC_NEW_PSW
466         be      BASED(pgm_svcper)
467 # no interesting special case, ignore PER event
468         lm      %r12,%r15,__LC_SAVE_AREA
469         lpsw    0x28
470
471 #
472 # Normal per exception
473 #
474 pgm_per_std:
475         SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA
476         CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA
477 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
478         tm      SP_PSW+1(%r15),0x01     # interrupting from user ?
479         bz      BASED(pgm_no_vtime2)
480         UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
481         UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
482         mvc     __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
483 pgm_no_vtime2:
484 #endif
485         l       %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
486         l       %r1,__TI_task(%r9)
487         mvc     __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID
488         mvc     __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS
489         mvc     __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
490         oi      __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
491         l       %r3,__LC_PGM_ILC         # load program interruption code
492         la      %r8,0x7f
493         nr      %r8,%r3                  # clear per-event-bit and ilc
494         be      BASED(sysc_return)       # only per or per+check ?
495         b       BASED(pgm_do_call)
496
497 #
498 # it was a single stepped SVC that is causing all the trouble
499 #
500 pgm_svcper:
501         SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
502         CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
503 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
504         tm      SP_PSW+1(%r15),0x01     # interrupting from user ?
505         bz      BASED(pgm_no_vtime3)
506         UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
507         UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
508         mvc     __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
509 pgm_no_vtime3:
510 #endif
511         lh      %r7,0x8a                # get svc number from lowcore
512         l       %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
513         l       %r1,__TI_task(%r9)
514         mvc     __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID
515         mvc     __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS
516         mvc     __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
517         oi      __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
518         stosm   __SF_EMPTY(%r15),0x03   # reenable interrupts
519         b       BASED(sysc_do_svc)
520
521 /*
522  * IO interrupt handler routine
523  */
524
525         .globl io_int_handler
526 io_int_handler:
527         STORE_TIMER __LC_ASYNC_ENTER_TIMER
528         stck    __LC_INT_CLOCK
529         SAVE_ALL_BASE __LC_SAVE_AREA+16
530         SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+16
531         CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+16
532 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
533         tm      SP_PSW+1(%r15),0x01     # interrupting from user ?
534         bz      BASED(io_no_vtime)
535         UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER
536         UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
537         mvc     __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER
538 io_no_vtime:
539 #endif
540         l       %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
541         l       %r1,BASED(.Ldo_IRQ)        # load address of do_IRQ
542         la      %r2,SP_PTREGS(%r15) # address of register-save area
543         basr    %r14,%r1          # branch to standard irq handler
544
545 io_return:
546         tm      SP_PSW+1(%r15),0x01    # returning to user ?
547 #ifdef CONFIG_PREEMPT
548         bno     BASED(io_preempt)      # no -> check for preemptive scheduling
549 #else
550         bno     BASED(io_leave)        # no-> skip resched & signal
551 #endif
552         tm      __TI_flags+3(%r9),_TIF_WORK_INT
553         bnz     BASED(io_work)         # there is work to do (signals etc.)
554 io_leave:
555         RESTORE_ALL __LC_RETURN_PSW,0
556 io_done:
557
558 #ifdef CONFIG_PREEMPT
559 io_preempt:
560         icm     %r0,15,__TI_precount(%r9)
561         bnz     BASED(io_leave)
562         l       %r1,SP_R15(%r15)
563         s       %r1,BASED(.Lc_spsize)
564         mvc     SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
565         xc      __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain
566         lr      %r15,%r1
567 io_resume_loop:
568         tm      __TI_flags+3(%r9),_TIF_NEED_RESCHED
569         bno     BASED(io_leave)
570         mvc     __TI_precount(4,%r9),BASED(.Lc_pactive)
571         stosm   __SF_EMPTY(%r15),0x03  # reenable interrupts
572         l       %r1,BASED(.Lschedule)
573         basr    %r14,%r1               # call schedule
574         stnsm   __SF_EMPTY(%r15),0xfc  # disable I/O and ext. interrupts
575         xc      __TI_precount(4,%r9),__TI_precount(%r9)
576         b       BASED(io_resume_loop)
577 #endif
578
579 #
580 # switch to kernel stack, then check the TIF bits
581 #
582 io_work:
583         l       %r1,__LC_KERNEL_STACK
584         s       %r1,BASED(.Lc_spsize)
585         mvc     SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
586         xc      __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain
587         lr      %r15,%r1
588 #
589 # One of the work bits is on. Find out which one.
590 # Checked are: _TIF_SIGPENDING, _TIF_RESTORE_SIGMASK, _TIF_NEED_RESCHED
591 #               and _TIF_MCCK_PENDING
592 #
593 io_work_loop:
594         tm      __TI_flags+3(%r9),_TIF_MCCK_PENDING
595         bo      BASED(io_mcck_pending)
596         tm      __TI_flags+3(%r9),_TIF_NEED_RESCHED
597         bo      BASED(io_reschedule)
598         tm      __TI_flags+3(%r9),(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)
599         bnz     BASED(io_sigpending)
600         b       BASED(io_leave)
601
602 #
603 # _TIF_MCCK_PENDING is set, call handler
604 #
605 io_mcck_pending:
606         l       %r1,BASED(.Ls390_handle_mcck)
607         la      %r14,BASED(io_work_loop)
608         br      %r1                    # TIF bit will be cleared by handler
609
610 #
611 # _TIF_NEED_RESCHED is set, call schedule
612 #       
613 io_reschedule:        
614         l       %r1,BASED(.Lschedule)
615         stosm   __SF_EMPTY(%r15),0x03  # reenable interrupts
616         basr    %r14,%r1               # call scheduler
617         stnsm   __SF_EMPTY(%r15),0xfc  # disable I/O and ext. interrupts
618         tm      __TI_flags+3(%r9),_TIF_WORK_INT
619         bz      BASED(io_leave)        # there is no work to do
620         b       BASED(io_work_loop)
621
622 #
623 # _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal
624 #
625 io_sigpending:     
626         stosm   __SF_EMPTY(%r15),0x03  # reenable interrupts
627         la      %r2,SP_PTREGS(%r15)    # load pt_regs
628         l       %r1,BASED(.Ldo_signal)
629         basr    %r14,%r1               # call do_signal
630         stnsm   __SF_EMPTY(%r15),0xfc  # disable I/O and ext. interrupts
631         b       BASED(io_work_loop)
632
633 /*
634  * External interrupt handler routine
635  */
636
637         .globl  ext_int_handler
638 ext_int_handler:
639         STORE_TIMER __LC_ASYNC_ENTER_TIMER
640         stck    __LC_INT_CLOCK
641         SAVE_ALL_BASE __LC_SAVE_AREA+16
642         SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16
643         CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16
644 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
645         tm      SP_PSW+1(%r15),0x01     # interrupting from user ?
646         bz      BASED(ext_no_vtime)
647         UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER
648         UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
649         mvc     __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER
650 ext_no_vtime:
651 #endif
652         l       %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
653         la      %r2,SP_PTREGS(%r15)    # address of register-save area
654         lh      %r3,__LC_EXT_INT_CODE  # get interruption code
655         l       %r1,BASED(.Ldo_extint)
656         basr    %r14,%r1
657         b       BASED(io_return)
658
659 __critical_end:
660
661 /*
662  * Machine check handler routines
663  */
664
665         .globl mcck_int_handler
666 mcck_int_handler:
667         spt     __LC_CPU_TIMER_SAVE_AREA        # revalidate cpu timer
668         lm      %r0,%r15,__LC_GPREGS_SAVE_AREA  # revalidate gprs
669         SAVE_ALL_BASE __LC_SAVE_AREA+32
670         la      %r12,__LC_MCK_OLD_PSW
671         tm      __LC_MCCK_CODE,0x80     # system damage?
672         bo      BASED(mcck_int_main)    # yes -> rest of mcck code invalid
673 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
674         mvc     __LC_SAVE_AREA+52(8),__LC_ASYNC_ENTER_TIMER
675         mvc     __LC_ASYNC_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA
676         tm      __LC_MCCK_CODE+5,0x02   # stored cpu timer value valid?
677         bo      BASED(1f)
678         la      %r14,__LC_SYNC_ENTER_TIMER
679         clc     0(8,%r14),__LC_ASYNC_ENTER_TIMER
680         bl      BASED(0f)
681         la      %r14,__LC_ASYNC_ENTER_TIMER
682 0:      clc     0(8,%r14),__LC_EXIT_TIMER
683         bl      BASED(0f)
684         la      %r14,__LC_EXIT_TIMER
685 0:      clc     0(8,%r14),__LC_LAST_UPDATE_TIMER
686         bl      BASED(0f)
687         la      %r14,__LC_LAST_UPDATE_TIMER
688 0:      spt     0(%r14)
689         mvc     __LC_ASYNC_ENTER_TIMER(8),0(%r14)
690 1:
691 #endif
692         tm      __LC_MCCK_CODE+2,0x09   # mwp + ia of old psw valid?
693         bno     BASED(mcck_int_main)    # no -> skip cleanup critical
694         tm      __LC_MCK_OLD_PSW+1,0x01 # test problem state bit
695         bnz     BASED(mcck_int_main)    # from user -> load async stack
696         clc     __LC_MCK_OLD_PSW+4(4),BASED(.Lcritical_end)
697         bhe     BASED(mcck_int_main)
698         clc     __LC_MCK_OLD_PSW+4(4),BASED(.Lcritical_start)
699         bl      BASED(mcck_int_main)
700         l       %r14,BASED(.Lcleanup_critical)
701         basr    %r14,%r14
702 mcck_int_main:
703         l       %r14,__LC_PANIC_STACK   # are we already on the panic stack?
704         slr     %r14,%r15
705         sra     %r14,PAGE_SHIFT
706         be      BASED(0f)
707         l       %r15,__LC_PANIC_STACK   # load panic stack
708 0:      CREATE_STACK_FRAME __LC_MCK_OLD_PSW,__LC_SAVE_AREA+32
709 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
710         tm      __LC_MCCK_CODE+2,0x08   # mwp of old psw valid?
711         bno     BASED(mcck_no_vtime)    # no -> skip cleanup critical
712         tm      SP_PSW+1(%r15),0x01     # interrupting from user ?
713         bz      BASED(mcck_no_vtime)
714         UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER
715         UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
716         mvc     __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER
717 mcck_no_vtime:
718 #endif
719         l       %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
720         la      %r2,SP_PTREGS(%r15)     # load pt_regs
721         l       %r1,BASED(.Ls390_mcck)
722         basr    %r14,%r1                # call machine check handler
723         tm      SP_PSW+1(%r15),0x01     # returning to user ?
724         bno     BASED(mcck_return)
725         l       %r1,__LC_KERNEL_STACK   # switch to kernel stack
726         s       %r1,BASED(.Lc_spsize)
727         mvc     SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
728         xc      __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain
729         lr      %r15,%r1
730         stosm   __SF_EMPTY(%r15),0x04   # turn dat on
731         tm      __TI_flags+3(%r9),_TIF_MCCK_PENDING
732         bno     BASED(mcck_return)
733         l       %r1,BASED(.Ls390_handle_mcck)
734         basr    %r14,%r1                # call machine check handler
735 mcck_return:
736         mvc     __LC_RETURN_MCCK_PSW(8),SP_PSW(%r15) # move return PSW
737         ni      __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit
738 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
739         mvc     __LC_ASYNC_ENTER_TIMER(8),__LC_SAVE_AREA+52
740         tm      __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ?
741         bno     BASED(0f)
742         lm      %r0,%r15,SP_R0(%r15)    # load gprs 0-15
743         stpt    __LC_EXIT_TIMER
744         lpsw    __LC_RETURN_MCCK_PSW    # back to caller
745 0:
746 #endif
747         lm      %r0,%r15,SP_R0(%r15)    # load gprs 0-15
748         lpsw    __LC_RETURN_MCCK_PSW    # back to caller
749
750         RESTORE_ALL __LC_RETURN_MCCK_PSW,0
751
752 #ifdef CONFIG_SMP
753 /*
754  * Restart interruption handler, kick starter for additional CPUs
755  */
756         .globl restart_int_handler
757 restart_int_handler:
758         l       %r15,__LC_SAVE_AREA+60 # load ksp
759         lctl    %c0,%c15,__LC_CREGS_SAVE_AREA # get new ctl regs
760         lam     %a0,%a15,__LC_AREGS_SAVE_AREA
761         lm      %r6,%r15,__SF_GPRS(%r15) # load registers from clone
762         stosm   __SF_EMPTY(%r15),0x04    # now we can turn dat on
763         basr    %r14,0
764         l       %r14,restart_addr-.(%r14)
765         br      %r14                   # branch to start_secondary
766 restart_addr:
767         .long   start_secondary
768 #else
769 /*
770  * If we do not run with SMP enabled, let the new CPU crash ...
771  */
772         .globl restart_int_handler
773 restart_int_handler:
774         basr    %r1,0
775 restart_base:
776         lpsw    restart_crash-restart_base(%r1)
777         .align 8
778 restart_crash:
779         .long  0x000a0000,0x00000000
780 restart_go:
781 #endif
782
783 #ifdef CONFIG_CHECK_STACK
784 /*
785  * The synchronous or the asynchronous stack overflowed. We are dead.
786  * No need to properly save the registers, we are going to panic anyway.
787  * Setup a pt_regs so that show_trace can provide a good call trace.
788  */
789 stack_overflow:
790         l       %r15,__LC_PANIC_STACK   # change to panic stack
791         sl      %r15,BASED(.Lc_spsize)
792         mvc     SP_PSW(8,%r15),0(%r12)  # move user PSW to stack
793         stm     %r0,%r11,SP_R0(%r15)    # store gprs %r0-%r11 to kernel stack
794         la      %r1,__LC_SAVE_AREA
795         ch      %r12,BASED(.L0x020)     # old psw addr == __LC_SVC_OLD_PSW ?
796         be      BASED(0f)
797         ch      %r12,BASED(.L0x028)     # old psw addr == __LC_PGM_OLD_PSW ?
798         be      BASED(0f)
799         la      %r1,__LC_SAVE_AREA+16
800 0:      mvc     SP_R12(16,%r15),0(%r1)  # move %r12-%r15 to stack
801         xc      __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear back chain
802         l       %r1,BASED(1f)           # branch to kernel_stack_overflow
803         la      %r2,SP_PTREGS(%r15)     # load pt_regs
804         br      %r1
805 1:      .long  kernel_stack_overflow
806 #endif
807
808 cleanup_table_system_call:
809         .long   system_call + 0x80000000, sysc_do_svc + 0x80000000
810 cleanup_table_sysc_return:
811         .long   sysc_return + 0x80000000, sysc_leave + 0x80000000
812 cleanup_table_sysc_leave:
813         .long   sysc_leave + 0x80000000, sysc_work_loop + 0x80000000
814 cleanup_table_sysc_work_loop:
815         .long   sysc_work_loop + 0x80000000, sysc_reschedule + 0x80000000
816 cleanup_table_io_return:
817         .long   io_return + 0x80000000, io_leave + 0x80000000
818 cleanup_table_io_leave:
819         .long   io_leave + 0x80000000, io_done + 0x80000000
820 cleanup_table_io_work_loop:
821         .long   io_work_loop + 0x80000000, io_mcck_pending + 0x80000000
822
823 cleanup_critical:
824         clc     4(4,%r12),BASED(cleanup_table_system_call)
825         bl      BASED(0f)
826         clc     4(4,%r12),BASED(cleanup_table_system_call+4)
827         bl      BASED(cleanup_system_call)
828 0:
829         clc     4(4,%r12),BASED(cleanup_table_sysc_return)
830         bl      BASED(0f)
831         clc     4(4,%r12),BASED(cleanup_table_sysc_return+4)
832         bl      BASED(cleanup_sysc_return)
833 0:
834         clc     4(4,%r12),BASED(cleanup_table_sysc_leave)
835         bl      BASED(0f)
836         clc     4(4,%r12),BASED(cleanup_table_sysc_leave+4)
837         bl      BASED(cleanup_sysc_leave)
838 0:
839         clc     4(4,%r12),BASED(cleanup_table_sysc_work_loop)
840         bl      BASED(0f)
841         clc     4(4,%r12),BASED(cleanup_table_sysc_work_loop+4)
842         bl      BASED(cleanup_sysc_return)
843 0:
844         clc     4(4,%r12),BASED(cleanup_table_io_return)
845         bl      BASED(0f)
846         clc     4(4,%r12),BASED(cleanup_table_io_return+4)
847         bl      BASED(cleanup_io_return)
848 0:
849         clc     4(4,%r12),BASED(cleanup_table_io_leave)
850         bl      BASED(0f)
851         clc     4(4,%r12),BASED(cleanup_table_io_leave+4)
852         bl      BASED(cleanup_io_leave)
853 0:
854         clc     4(4,%r12),BASED(cleanup_table_io_work_loop)
855         bl      BASED(0f)
856         clc     4(4,%r12),BASED(cleanup_table_io_work_loop+4)
857         bl      BASED(cleanup_io_return)
858 0:
859         br      %r14
860
861 cleanup_system_call:
862         mvc     __LC_RETURN_PSW(8),0(%r12)
863         c       %r12,BASED(.Lmck_old_psw)
864         be      BASED(0f)
865         la      %r12,__LC_SAVE_AREA+16
866         b       BASED(1f)
867 0:      la      %r12,__LC_SAVE_AREA+32
868 1:
869 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
870         clc     __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+4)
871         bh      BASED(0f)
872         mvc     __LC_SYNC_ENTER_TIMER(8),__LC_ASYNC_ENTER_TIMER
873 0:      clc     __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+8)
874         bhe     BASED(cleanup_vtime)
875 #endif
876         clc     __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn)
877         bh      BASED(0f)
878         mvc     __LC_SAVE_AREA(16),0(%r12)
879 0:      st      %r13,4(%r12)
880         st      %r12,__LC_SAVE_AREA+48  # argh
881         SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
882         CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
883         l       %r12,__LC_SAVE_AREA+48  # argh
884         st      %r15,12(%r12)
885         lh      %r7,0x8a
886 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
887 cleanup_vtime:
888         clc     __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+12)
889         bhe     BASED(cleanup_stime)
890         tm      SP_PSW+1(%r15),0x01     # interrupting from user ?
891         bz      BASED(cleanup_novtime)
892         UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
893 cleanup_stime:
894         clc     __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+16)
895         bh      BASED(cleanup_update)
896         UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
897 cleanup_update:
898         mvc     __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
899 cleanup_novtime:
900 #endif
901         mvc     __LC_RETURN_PSW+4(4),BASED(cleanup_table_system_call+4)
902         la      %r12,__LC_RETURN_PSW
903         br      %r14
904 cleanup_system_call_insn:
905         .long   sysc_saveall + 0x80000000
906 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
907         .long   system_call + 0x80000000
908         .long   sysc_vtime + 0x80000000
909         .long   sysc_stime + 0x80000000
910         .long   sysc_update + 0x80000000
911 #endif
912
913 cleanup_sysc_return:
914         mvc     __LC_RETURN_PSW(4),0(%r12)
915         mvc     __LC_RETURN_PSW+4(4),BASED(cleanup_table_sysc_return)
916         la      %r12,__LC_RETURN_PSW
917         br      %r14
918
919 cleanup_sysc_leave:
920         clc     4(4,%r12),BASED(cleanup_sysc_leave_insn)
921         be      BASED(2f)
922 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
923         mvc     __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER
924         clc     4(4,%r12),BASED(cleanup_sysc_leave_insn+4)
925         be      BASED(2f)
926 #endif
927         mvc     __LC_RETURN_PSW(8),SP_PSW(%r15)
928         c       %r12,BASED(.Lmck_old_psw)
929         bne     BASED(0f)
930         mvc     __LC_SAVE_AREA+32(16),SP_R12(%r15)
931         b       BASED(1f)
932 0:      mvc     __LC_SAVE_AREA+16(16),SP_R12(%r15)
933 1:      lm      %r0,%r11,SP_R0(%r15)
934         l       %r15,SP_R15(%r15)
935 2:      la      %r12,__LC_RETURN_PSW
936         br      %r14
937 cleanup_sysc_leave_insn:
938 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
939         .long   sysc_leave + 14 + 0x80000000
940 #endif
941         .long   sysc_leave + 10 + 0x80000000
942
943 cleanup_io_return:
944         mvc     __LC_RETURN_PSW(4),0(%r12)
945         mvc     __LC_RETURN_PSW+4(4),BASED(cleanup_table_io_work_loop)
946         la      %r12,__LC_RETURN_PSW
947         br      %r14
948
949 cleanup_io_leave:
950         clc     4(4,%r12),BASED(cleanup_io_leave_insn)
951         be      BASED(2f)
952 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
953         mvc     __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER
954         clc     4(4,%r12),BASED(cleanup_io_leave_insn+4)
955         be      BASED(2f)
956 #endif
957         mvc     __LC_RETURN_PSW(8),SP_PSW(%r15)
958         c       %r12,BASED(.Lmck_old_psw)
959         bne     BASED(0f)
960         mvc     __LC_SAVE_AREA+32(16),SP_R12(%r15)
961         b       BASED(1f)
962 0:      mvc     __LC_SAVE_AREA+16(16),SP_R12(%r15)
963 1:      lm      %r0,%r11,SP_R0(%r15)
964         l       %r15,SP_R15(%r15)
965 2:      la      %r12,__LC_RETURN_PSW
966         br      %r14
967 cleanup_io_leave_insn:
968 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
969         .long   io_leave + 18 + 0x80000000
970 #endif
971         .long   io_leave + 14 + 0x80000000
972
973 /*
974  * Integer constants
975  */
976                .align 4
977 .Lc_spsize:    .long  SP_SIZE
978 .Lc_overhead:  .long  STACK_FRAME_OVERHEAD
979 .Lc_pactive:   .long  PREEMPT_ACTIVE
980 .Lnr_syscalls: .long  NR_syscalls
981 .L0x018:       .short 0x018
982 .L0x020:       .short 0x020
983 .L0x028:       .short 0x028
984 .L0x030:       .short 0x030
985 .L0x038:       .short 0x038
986 .Lc_1:         .long  1
987
988 /*
989  * Symbol constants
990  */
991 .Ls390_mcck:   .long  s390_do_machine_check
992 .Ls390_handle_mcck:
993                .long  s390_handle_mcck
994 .Lmck_old_psw: .long  __LC_MCK_OLD_PSW
995 .Ldo_IRQ:      .long  do_IRQ
996 .Ldo_extint:   .long  do_extint
997 .Ldo_signal:   .long  do_signal
998 .Lhandle_per:  .long  do_single_step
999 .Ljump_table:  .long  pgm_check_table
1000 .Lschedule:    .long  schedule
1001 .Lclone:       .long  sys_clone
1002 .Lexecve:      .long  sys_execve
1003 .Lfork:        .long  sys_fork
1004 .Lrt_sigreturn:.long  sys_rt_sigreturn
1005 .Lrt_sigsuspend:
1006                .long  sys_rt_sigsuspend
1007 .Lsigreturn:   .long  sys_sigreturn
1008 .Lsigsuspend:  .long  sys_sigsuspend
1009 .Lsigaltstack: .long  sys_sigaltstack
1010 .Ltrace:       .long  syscall_trace
1011 .Lvfork:       .long  sys_vfork
1012 .Lschedtail:   .long  schedule_tail
1013
1014 .Lcritical_start:
1015                .long  __critical_start + 0x80000000
1016 .Lcritical_end:
1017                .long  __critical_end + 0x80000000
1018 .Lcleanup_critical:
1019                .long  cleanup_critical
1020
1021 #define SYSCALL(esa,esame,emu)  .long esa
1022         .globl  sys_call_table
1023 sys_call_table:
1024 #include "syscalls.S"
1025 #undef SYSCALL
1026