Loading...
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * S390 low-level entry points.
4 *
5 * Copyright IBM Corp. 1999, 2012
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 */
10
11#include <linux/init.h>
12#include <linux/linkage.h>
13#include <asm/asm-extable.h>
14#include <asm/alternative-asm.h>
15#include <asm/processor.h>
16#include <asm/cache.h>
17#include <asm/dwarf.h>
18#include <asm/errno.h>
19#include <asm/ptrace.h>
20#include <asm/thread_info.h>
21#include <asm/asm-offsets.h>
22#include <asm/unistd.h>
23#include <asm/page.h>
24#include <asm/sigp.h>
25#include <asm/irq.h>
26#include <asm/vx-insn.h>
27#include <asm/setup.h>
28#include <asm/nmi.h>
29#include <asm/export.h>
30#include <asm/nospec-insn.h>
31
32STACK_SHIFT = PAGE_SHIFT + THREAD_SIZE_ORDER
33STACK_SIZE = 1 << STACK_SHIFT
34STACK_INIT = STACK_SIZE - STACK_FRAME_OVERHEAD - __PT_SIZE
35
36_LPP_OFFSET = __LC_LPP
37
38 .macro STBEAR address
39 ALTERNATIVE "nop", ".insn s,0xb2010000,\address", 193
40 .endm
41
42 .macro LBEAR address
43 ALTERNATIVE "nop", ".insn s,0xb2000000,\address", 193
44 .endm
45
46 .macro LPSWEY address,lpswe
47 ALTERNATIVE "b \lpswe; nopr", ".insn siy,0xeb0000000071,\address,0", 193
48 .endm
49
50 .macro MBEAR reg
51 ALTERNATIVE "brcl 0,0", __stringify(mvc __PT_LAST_BREAK(8,\reg),__LC_LAST_BREAK), 193
52 .endm
53
54 .macro CHECK_STACK savearea
55#ifdef CONFIG_CHECK_STACK
56 tml %r15,STACK_SIZE - CONFIG_STACK_GUARD
57 lghi %r14,\savearea
58 jz stack_overflow
59#endif
60 .endm
61
62 .macro CHECK_VMAP_STACK savearea,oklabel
63#ifdef CONFIG_VMAP_STACK
64 lgr %r14,%r15
65 nill %r14,0x10000 - STACK_SIZE
66 oill %r14,STACK_INIT
67 clg %r14,__LC_KERNEL_STACK
68 je \oklabel
69 clg %r14,__LC_ASYNC_STACK
70 je \oklabel
71 clg %r14,__LC_MCCK_STACK
72 je \oklabel
73 clg %r14,__LC_NODAT_STACK
74 je \oklabel
75 clg %r14,__LC_RESTART_STACK
76 je \oklabel
77 lghi %r14,\savearea
78 j stack_overflow
79#else
80 j \oklabel
81#endif
82 .endm
83
84 /*
85 * The TSTMSK macro generates a test-under-mask instruction by
86 * calculating the memory offset for the specified mask value.
87 * Mask value can be any constant. The macro shifts the mask
88 * value to calculate the memory offset for the test-under-mask
89 * instruction.
90 */
91 .macro TSTMSK addr, mask, size=8, bytepos=0
92 .if (\bytepos < \size) && (\mask >> 8)
93 .if (\mask & 0xff)
94 .error "Mask exceeds byte boundary"
95 .endif
96 TSTMSK \addr, "(\mask >> 8)", \size, "(\bytepos + 1)"
97 .exitm
98 .endif
99 .ifeq \mask
100 .error "Mask must not be zero"
101 .endif
102 off = \size - \bytepos - 1
103 tm off+\addr, \mask
104 .endm
105
106 .macro BPOFF
107 ALTERNATIVE "nop", ".insn rrf,0xb2e80000,0,0,12,0", 82
108 .endm
109
110 .macro BPON
111 ALTERNATIVE "nop", ".insn rrf,0xb2e80000,0,0,13,0", 82
112 .endm
113
114 .macro BPENTER tif_ptr,tif_mask
115 ALTERNATIVE "TSTMSK \tif_ptr,\tif_mask; jz .+8; .insn rrf,0xb2e80000,0,0,13,0", \
116 "j .+12; nop; nop", 82
117 .endm
118
119 .macro BPEXIT tif_ptr,tif_mask
120 TSTMSK \tif_ptr,\tif_mask
121 ALTERNATIVE "jz .+8; .insn rrf,0xb2e80000,0,0,12,0", \
122 "jnz .+8; .insn rrf,0xb2e80000,0,0,13,0", 82
123 .endm
124
125#if IS_ENABLED(CONFIG_KVM)
126 /*
127 * The OUTSIDE macro jumps to the provided label in case the value
128 * in the provided register is outside of the provided range. The
129 * macro is useful for checking whether a PSW stored in a register
130 * pair points inside or outside of a block of instructions.
131 * @reg: register to check
132 * @start: start of the range
133 * @end: end of the range
134 * @outside_label: jump here if @reg is outside of [@start..@end)
135 */
136 .macro OUTSIDE reg,start,end,outside_label
137 lgr %r14,\reg
138 larl %r13,\start
139 slgr %r14,%r13
140#ifdef CONFIG_AS_IS_LLVM
141 clgfrl %r14,.Lrange_size\@
142#else
143 clgfi %r14,\end - \start
144#endif
145 jhe \outside_label
146#ifdef CONFIG_AS_IS_LLVM
147 .section .rodata, "a"
148 .align 4
149.Lrange_size\@:
150 .long \end - \start
151 .previous
152#endif
153 .endm
154
155 .macro SIEEXIT
156 lg %r9,__SF_SIE_CONTROL(%r15) # get control block pointer
157 ni __SIE_PROG0C+3(%r9),0xfe # no longer in SIE
158 lctlg %c1,%c1,__LC_KERNEL_ASCE # load primary asce
159 larl %r9,sie_exit # skip forward to sie_exit
160 .endm
161#endif
162
163 GEN_BR_THUNK %r14
164
165 .section .kprobes.text, "ax"
166.Ldummy:
167 /*
168 * This nop exists only in order to avoid that __bpon starts at
169 * the beginning of the kprobes text section. In that case we would
170 * have several symbols at the same address. E.g. objdump would take
171 * an arbitrary symbol name when disassembling this code.
172 * With the added nop in between the __bpon symbol is unique
173 * again.
174 */
175 nop 0
176
177ENTRY(__bpon)
178 .globl __bpon
179 BPON
180 BR_EX %r14
181ENDPROC(__bpon)
182
183/*
184 * Scheduler resume function, called by switch_to
185 * gpr2 = (task_struct *) prev
186 * gpr3 = (task_struct *) next
187 * Returns:
188 * gpr2 = prev
189 */
190ENTRY(__switch_to)
191 stmg %r6,%r15,__SF_GPRS(%r15) # store gprs of prev task
192 lghi %r4,__TASK_stack
193 lghi %r1,__TASK_thread
194 llill %r5,STACK_INIT
195 stg %r15,__THREAD_ksp(%r1,%r2) # store kernel stack of prev
196 lg %r15,0(%r4,%r3) # start of kernel stack of next
197 agr %r15,%r5 # end of kernel stack of next
198 stg %r3,__LC_CURRENT # store task struct of next
199 stg %r15,__LC_KERNEL_STACK # store end of kernel stack
200 lg %r15,__THREAD_ksp(%r1,%r3) # load kernel stack of next
201 aghi %r3,__TASK_pid
202 mvc __LC_CURRENT_PID(4,%r0),0(%r3) # store pid of next
203 lmg %r6,%r15,__SF_GPRS(%r15) # load gprs of next task
204 ALTERNATIVE "nop", "lpp _LPP_OFFSET", 40
205 BR_EX %r14
206ENDPROC(__switch_to)
207
208#if IS_ENABLED(CONFIG_KVM)
209/*
210 * __sie64a calling convention:
211 * %r2 pointer to sie control block phys
212 * %r3 pointer to sie control block virt
213 * %r4 guest register save area
214 */
215ENTRY(__sie64a)
216 stmg %r6,%r14,__SF_GPRS(%r15) # save kernel registers
217 lg %r12,__LC_CURRENT
218 stg %r2,__SF_SIE_CONTROL_PHYS(%r15) # save sie block physical..
219 stg %r3,__SF_SIE_CONTROL(%r15) # ...and virtual addresses
220 stg %r4,__SF_SIE_SAVEAREA(%r15) # save guest register save area
221 xc __SF_SIE_REASON(8,%r15),__SF_SIE_REASON(%r15) # reason code = 0
222 mvc __SF_SIE_FLAGS(8,%r15),__TI_flags(%r12) # copy thread flags
223 lmg %r0,%r13,0(%r4) # load guest gprs 0-13
224 lg %r14,__LC_GMAP # get gmap pointer
225 ltgr %r14,%r14
226 jz .Lsie_gmap
227 lctlg %c1,%c1,__GMAP_ASCE(%r14) # load primary asce
228.Lsie_gmap:
229 lg %r14,__SF_SIE_CONTROL(%r15) # get control block pointer
230 oi __SIE_PROG0C+3(%r14),1 # we are going into SIE now
231 tm __SIE_PROG20+3(%r14),3 # last exit...
232 jnz .Lsie_skip
233 TSTMSK __LC_CPU_FLAGS,_CIF_FPU
234 jo .Lsie_skip # exit if fp/vx regs changed
235 lg %r14,__SF_SIE_CONTROL_PHYS(%r15) # get sie block phys addr
236 BPEXIT __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
237.Lsie_entry:
238 sie 0(%r14)
239# Let the next instruction be NOP to avoid triggering a machine check
240# and handling it in a guest as result of the instruction execution.
241 nopr 7
242.Lsie_leave:
243 BPOFF
244 BPENTER __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
245.Lsie_skip:
246 lg %r14,__SF_SIE_CONTROL(%r15) # get control block pointer
247 ni __SIE_PROG0C+3(%r14),0xfe # no longer in SIE
248 lctlg %c1,%c1,__LC_KERNEL_ASCE # load primary asce
249.Lsie_done:
250# some program checks are suppressing. C code (e.g. do_protection_exception)
251# will rewind the PSW by the ILC, which is often 4 bytes in case of SIE. There
252# are some corner cases (e.g. runtime instrumentation) where ILC is unpredictable.
253# Other instructions between __sie64a and .Lsie_done should not cause program
254# interrupts. So lets use 3 nops as a landing pad for all possible rewinds.
255.Lrewind_pad6:
256 nopr 7
257.Lrewind_pad4:
258 nopr 7
259.Lrewind_pad2:
260 nopr 7
261 .globl sie_exit
262sie_exit:
263 lg %r14,__SF_SIE_SAVEAREA(%r15) # load guest register save area
264 stmg %r0,%r13,0(%r14) # save guest gprs 0-13
265 xgr %r0,%r0 # clear guest registers to
266 xgr %r1,%r1 # prevent speculative use
267 xgr %r3,%r3
268 xgr %r4,%r4
269 xgr %r5,%r5
270 lmg %r6,%r14,__SF_GPRS(%r15) # restore kernel registers
271 lg %r2,__SF_SIE_REASON(%r15) # return exit reason code
272 BR_EX %r14
273.Lsie_fault:
274 lghi %r14,-EFAULT
275 stg %r14,__SF_SIE_REASON(%r15) # set exit reason code
276 j sie_exit
277
278 EX_TABLE(.Lrewind_pad6,.Lsie_fault)
279 EX_TABLE(.Lrewind_pad4,.Lsie_fault)
280 EX_TABLE(.Lrewind_pad2,.Lsie_fault)
281 EX_TABLE(sie_exit,.Lsie_fault)
282ENDPROC(__sie64a)
283EXPORT_SYMBOL(__sie64a)
284EXPORT_SYMBOL(sie_exit)
285#endif
286
287/*
288 * SVC interrupt handler routine. System calls are synchronous events and
289 * are entered with interrupts disabled.
290 */
291
292ENTRY(system_call)
293 stpt __LC_SYS_ENTER_TIMER
294 stmg %r8,%r15,__LC_SAVE_AREA_SYNC
295 BPOFF
296 lghi %r14,0
297.Lsysc_per:
298 STBEAR __LC_LAST_BREAK
299 lctlg %c1,%c1,__LC_KERNEL_ASCE
300 lg %r12,__LC_CURRENT
301 lg %r15,__LC_KERNEL_STACK
302 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
303 stmg %r0,%r7,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
304 BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
305 # clear user controlled register to prevent speculative use
306 xgr %r0,%r0
307 xgr %r1,%r1
308 xgr %r4,%r4
309 xgr %r5,%r5
310 xgr %r6,%r6
311 xgr %r7,%r7
312 xgr %r8,%r8
313 xgr %r9,%r9
314 xgr %r10,%r10
315 xgr %r11,%r11
316 la %r2,STACK_FRAME_OVERHEAD(%r15) # pointer to pt_regs
317 mvc __PT_R8(64,%r2),__LC_SAVE_AREA_SYNC
318 MBEAR %r2
319 lgr %r3,%r14
320 brasl %r14,__do_syscall
321 lctlg %c1,%c1,__LC_USER_ASCE
322 mvc __LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15)
323 BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP
324 LBEAR STACK_FRAME_OVERHEAD+__PT_LAST_BREAK(%r15)
325 lmg %r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
326 stpt __LC_EXIT_TIMER
327 LPSWEY __LC_RETURN_PSW,__LC_RETURN_LPSWE
328ENDPROC(system_call)
329
330#
331# a new process exits the kernel with ret_from_fork
332#
333ENTRY(ret_from_fork)
334 lgr %r3,%r11
335 brasl %r14,__ret_from_fork
336 lctlg %c1,%c1,__LC_USER_ASCE
337 mvc __LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15)
338 BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP
339 LBEAR STACK_FRAME_OVERHEAD+__PT_LAST_BREAK(%r15)
340 lmg %r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
341 stpt __LC_EXIT_TIMER
342 LPSWEY __LC_RETURN_PSW,__LC_RETURN_LPSWE
343ENDPROC(ret_from_fork)
344
345/*
346 * Program check handler routine
347 */
348
349ENTRY(pgm_check_handler)
350 stpt __LC_SYS_ENTER_TIMER
351 BPOFF
352 stmg %r8,%r15,__LC_SAVE_AREA_SYNC
353 lg %r12,__LC_CURRENT
354 lghi %r10,0
355 lmg %r8,%r9,__LC_PGM_OLD_PSW
356 tmhh %r8,0x0001 # coming from user space?
357 jno .Lpgm_skip_asce
358 lctlg %c1,%c1,__LC_KERNEL_ASCE
359 j 3f # -> fault in user space
360.Lpgm_skip_asce:
361#if IS_ENABLED(CONFIG_KVM)
362 # cleanup critical section for program checks in __sie64a
363 OUTSIDE %r9,.Lsie_gmap,.Lsie_done,1f
364 SIEEXIT
365 lghi %r10,_PIF_GUEST_FAULT
366#endif
3671: tmhh %r8,0x4000 # PER bit set in old PSW ?
368 jnz 2f # -> enabled, can't be a double fault
369 tm __LC_PGM_ILC+3,0x80 # check for per exception
370 jnz .Lpgm_svcper # -> single stepped svc
3712: CHECK_STACK __LC_SAVE_AREA_SYNC
372 aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
373 # CHECK_VMAP_STACK branches to stack_overflow or 4f
374 CHECK_VMAP_STACK __LC_SAVE_AREA_SYNC,4f
3753: BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
376 lg %r15,__LC_KERNEL_STACK
3774: la %r11,STACK_FRAME_OVERHEAD(%r15)
378 stg %r10,__PT_FLAGS(%r11)
379 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
380 stmg %r0,%r7,__PT_R0(%r11)
381 mvc __PT_R8(64,%r11),__LC_SAVE_AREA_SYNC
382 mvc __PT_LAST_BREAK(8,%r11),__LC_PGM_LAST_BREAK
383 stmg %r8,%r9,__PT_PSW(%r11)
384
385 # clear user controlled registers to prevent speculative use
386 xgr %r0,%r0
387 xgr %r1,%r1
388 xgr %r3,%r3
389 xgr %r4,%r4
390 xgr %r5,%r5
391 xgr %r6,%r6
392 xgr %r7,%r7
393 lgr %r2,%r11
394 brasl %r14,__do_pgm_check
395 tmhh %r8,0x0001 # returning to user space?
396 jno .Lpgm_exit_kernel
397 lctlg %c1,%c1,__LC_USER_ASCE
398 BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP
399 stpt __LC_EXIT_TIMER
400.Lpgm_exit_kernel:
401 mvc __LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15)
402 LBEAR STACK_FRAME_OVERHEAD+__PT_LAST_BREAK(%r15)
403 lmg %r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
404 LPSWEY __LC_RETURN_PSW,__LC_RETURN_LPSWE
405
406#
407# single stepped system call
408#
409.Lpgm_svcper:
410 mvc __LC_RETURN_PSW(8),__LC_SVC_NEW_PSW
411 larl %r14,.Lsysc_per
412 stg %r14,__LC_RETURN_PSW+8
413 lghi %r14,1
414 LBEAR __LC_PGM_LAST_BREAK
415 LPSWEY __LC_RETURN_PSW,__LC_RETURN_LPSWE # branch to .Lsysc_per
416ENDPROC(pgm_check_handler)
417
418/*
419 * Interrupt handler macro used for external and IO interrupts.
420 */
421.macro INT_HANDLER name,lc_old_psw,handler
422ENTRY(\name)
423 stckf __LC_INT_CLOCK
424 stpt __LC_SYS_ENTER_TIMER
425 STBEAR __LC_LAST_BREAK
426 BPOFF
427 stmg %r8,%r15,__LC_SAVE_AREA_ASYNC
428 lg %r12,__LC_CURRENT
429 lmg %r8,%r9,\lc_old_psw
430 tmhh %r8,0x0001 # interrupting from user ?
431 jnz 1f
432#if IS_ENABLED(CONFIG_KVM)
433 OUTSIDE %r9,.Lsie_gmap,.Lsie_done,0f
434 BPENTER __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
435 SIEEXIT
436#endif
4370: CHECK_STACK __LC_SAVE_AREA_ASYNC
438 aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
439 j 2f
4401: BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
441 lctlg %c1,%c1,__LC_KERNEL_ASCE
442 lg %r15,__LC_KERNEL_STACK
4432: xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
444 la %r11,STACK_FRAME_OVERHEAD(%r15)
445 stmg %r0,%r7,__PT_R0(%r11)
446 # clear user controlled registers to prevent speculative use
447 xgr %r0,%r0
448 xgr %r1,%r1
449 xgr %r3,%r3
450 xgr %r4,%r4
451 xgr %r5,%r5
452 xgr %r6,%r6
453 xgr %r7,%r7
454 xgr %r10,%r10
455 xc __PT_FLAGS(8,%r11),__PT_FLAGS(%r11)
456 mvc __PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC
457 MBEAR %r11
458 stmg %r8,%r9,__PT_PSW(%r11)
459 lgr %r2,%r11 # pass pointer to pt_regs
460 brasl %r14,\handler
461 mvc __LC_RETURN_PSW(16),__PT_PSW(%r11)
462 tmhh %r8,0x0001 # returning to user ?
463 jno 2f
464 lctlg %c1,%c1,__LC_USER_ASCE
465 BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP
466 stpt __LC_EXIT_TIMER
4672: LBEAR __PT_LAST_BREAK(%r11)
468 lmg %r0,%r15,__PT_R0(%r11)
469 LPSWEY __LC_RETURN_PSW,__LC_RETURN_LPSWE
470ENDPROC(\name)
471.endm
472
473INT_HANDLER ext_int_handler,__LC_EXT_OLD_PSW,do_ext_irq
474INT_HANDLER io_int_handler,__LC_IO_OLD_PSW,do_io_irq
475
476/*
477 * Load idle PSW.
478 */
479ENTRY(psw_idle)
480 stg %r14,(__SF_GPRS+8*8)(%r15)
481 stg %r3,__SF_EMPTY(%r15)
482 larl %r1,psw_idle_exit
483 stg %r1,__SF_EMPTY+8(%r15)
484 larl %r1,smp_cpu_mtid
485 llgf %r1,0(%r1)
486 ltgr %r1,%r1
487 jz .Lpsw_idle_stcctm
488 .insn rsy,0xeb0000000017,%r1,5,__MT_CYCLES_ENTER(%r2)
489.Lpsw_idle_stcctm:
490 oi __LC_CPU_FLAGS+7,_CIF_ENABLED_WAIT
491 BPON
492 stckf __CLOCK_IDLE_ENTER(%r2)
493 stpt __TIMER_IDLE_ENTER(%r2)
494 lpswe __SF_EMPTY(%r15)
495.globl psw_idle_exit
496psw_idle_exit:
497 BR_EX %r14
498ENDPROC(psw_idle)
499
500/*
501 * Machine check handler routines
502 */
503ENTRY(mcck_int_handler)
504 stckf __LC_MCCK_CLOCK
505 BPOFF
506 la %r1,4095 # validate r1
507 spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # validate cpu timer
508 LBEAR __LC_LAST_BREAK_SAVE_AREA-4095(%r1) # validate bear
509 lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# validate gprs
510 lg %r12,__LC_CURRENT
511 lmg %r8,%r9,__LC_MCK_OLD_PSW
512 TSTMSK __LC_MCCK_CODE,MCCK_CODE_SYSTEM_DAMAGE
513 jo .Lmcck_panic # yes -> rest of mcck code invalid
514 TSTMSK __LC_MCCK_CODE,MCCK_CODE_CR_VALID
515 jno .Lmcck_panic # control registers invalid -> panic
516 la %r14,4095
517 lctlg %c0,%c15,__LC_CREGS_SAVE_AREA-4095(%r14) # validate ctl regs
518 ptlb
519 lghi %r14,__LC_CPU_TIMER_SAVE_AREA
520 mvc __LC_MCCK_ENTER_TIMER(8),0(%r14)
521 TSTMSK __LC_MCCK_CODE,MCCK_CODE_CPU_TIMER_VALID
522 jo 3f
523 la %r14,__LC_SYS_ENTER_TIMER
524 clc 0(8,%r14),__LC_EXIT_TIMER
525 jl 1f
526 la %r14,__LC_EXIT_TIMER
5271: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER
528 jl 2f
529 la %r14,__LC_LAST_UPDATE_TIMER
5302: spt 0(%r14)
531 mvc __LC_MCCK_ENTER_TIMER(8),0(%r14)
5323: TSTMSK __LC_MCCK_CODE,MCCK_CODE_PSW_MWP_VALID
533 jno .Lmcck_panic
534 tmhh %r8,0x0001 # interrupting from user ?
535 jnz .Lmcck_user
536 TSTMSK __LC_MCCK_CODE,MCCK_CODE_PSW_IA_VALID
537 jno .Lmcck_panic
538#if IS_ENABLED(CONFIG_KVM)
539 OUTSIDE %r9,.Lsie_gmap,.Lsie_done,.Lmcck_stack
540 OUTSIDE %r9,.Lsie_entry,.Lsie_leave,4f
541 oi __LC_CPU_FLAGS+7, _CIF_MCCK_GUEST
5424: BPENTER __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
543 SIEEXIT
544 j .Lmcck_stack
545#endif
546.Lmcck_user:
547 BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
548.Lmcck_stack:
549 lg %r15,__LC_MCCK_STACK
550 la %r11,STACK_FRAME_OVERHEAD(%r15)
551 stctg %c1,%c1,__PT_CR1(%r11)
552 lctlg %c1,%c1,__LC_KERNEL_ASCE
553 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
554 lghi %r14,__LC_GPREGS_SAVE_AREA+64
555 stmg %r0,%r7,__PT_R0(%r11)
556 # clear user controlled registers to prevent speculative use
557 xgr %r0,%r0
558 xgr %r1,%r1
559 xgr %r3,%r3
560 xgr %r4,%r4
561 xgr %r5,%r5
562 xgr %r6,%r6
563 xgr %r7,%r7
564 xgr %r10,%r10
565 mvc __PT_R8(64,%r11),0(%r14)
566 stmg %r8,%r9,__PT_PSW(%r11)
567 xc __PT_FLAGS(8,%r11),__PT_FLAGS(%r11)
568 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
569 lgr %r2,%r11 # pass pointer to pt_regs
570 brasl %r14,s390_do_machine_check
571 cghi %r2,0
572 je .Lmcck_return
573 lg %r1,__LC_KERNEL_STACK # switch to kernel stack
574 mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
575 xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
576 la %r11,STACK_FRAME_OVERHEAD(%r1)
577 lgr %r2,%r11
578 lgr %r15,%r1
579 brasl %r14,s390_handle_mcck
580.Lmcck_return:
581 lctlg %c1,%c1,__PT_CR1(%r11)
582 lmg %r0,%r10,__PT_R0(%r11)
583 mvc __LC_RETURN_MCCK_PSW(16),__PT_PSW(%r11) # move return PSW
584 tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ?
585 jno 0f
586 BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP
587 stpt __LC_EXIT_TIMER
5880: ALTERNATIVE "nop", __stringify(lghi %r12,__LC_LAST_BREAK_SAVE_AREA),193
589 LBEAR 0(%r12)
590 lmg %r11,%r15,__PT_R11(%r11)
591 LPSWEY __LC_RETURN_MCCK_PSW,__LC_RETURN_MCCK_LPSWE
592
593.Lmcck_panic:
594 /*
595 * Iterate over all possible CPU addresses in the range 0..0xffff
596 * and stop each CPU using signal processor. Use compare and swap
597 * to allow just one CPU-stopper and prevent concurrent CPUs from
598 * stopping each other while leaving the others running.
599 */
600 lhi %r5,0
601 lhi %r6,1
602 larl %r7,.Lstop_lock
603 cs %r5,%r6,0(%r7) # single CPU-stopper only
604 jnz 4f
605 larl %r7,.Lthis_cpu
606 stap 0(%r7) # this CPU address
607 lh %r4,0(%r7)
608 nilh %r4,0
609 lhi %r0,1
610 sll %r0,16 # CPU counter
611 lhi %r3,0 # next CPU address
6120: cr %r3,%r4
613 je 2f
6141: sigp %r1,%r3,SIGP_STOP # stop next CPU
615 brc SIGP_CC_BUSY,1b
6162: ahi %r3,1
617 brct %r0,0b
6183: sigp %r1,%r4,SIGP_STOP # stop this CPU
619 brc SIGP_CC_BUSY,3b
6204: j 4b
621ENDPROC(mcck_int_handler)
622
623ENTRY(restart_int_handler)
624 ALTERNATIVE "nop", "lpp _LPP_OFFSET", 40
625 stg %r15,__LC_SAVE_AREA_RESTART
626 TSTMSK __LC_RESTART_FLAGS,RESTART_FLAG_CTLREGS,4
627 jz 0f
628 la %r15,4095
629 lctlg %c0,%c15,__LC_CREGS_SAVE_AREA-4095(%r15)
6300: larl %r15,.Lstosm_tmp
631 stosm 0(%r15),0x04 # turn dat on, keep irqs off
632 lg %r15,__LC_RESTART_STACK
633 xc STACK_FRAME_OVERHEAD(__PT_SIZE,%r15),STACK_FRAME_OVERHEAD(%r15)
634 stmg %r0,%r14,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
635 mvc STACK_FRAME_OVERHEAD+__PT_R15(8,%r15),__LC_SAVE_AREA_RESTART
636 mvc STACK_FRAME_OVERHEAD+__PT_PSW(16,%r15),__LC_RST_OLD_PSW
637 xc 0(STACK_FRAME_OVERHEAD,%r15),0(%r15)
638 lg %r1,__LC_RESTART_FN # load fn, parm & source cpu
639 lg %r2,__LC_RESTART_DATA
640 lgf %r3,__LC_RESTART_SOURCE
641 ltgr %r3,%r3 # test source cpu address
642 jm 1f # negative -> skip source stop
6430: sigp %r4,%r3,SIGP_SENSE # sigp sense to source cpu
644 brc 10,0b # wait for status stored
6451: basr %r14,%r1 # call function
646 stap __SF_EMPTY(%r15) # store cpu address
647 llgh %r3,__SF_EMPTY(%r15)
6482: sigp %r4,%r3,SIGP_STOP # sigp stop to current cpu
649 brc 2,2b
6503: j 3b
651ENDPROC(restart_int_handler)
652
653 .section .kprobes.text, "ax"
654
655#if defined(CONFIG_CHECK_STACK) || defined(CONFIG_VMAP_STACK)
656/*
657 * The synchronous or the asynchronous stack overflowed. We are dead.
658 * No need to properly save the registers, we are going to panic anyway.
659 * Setup a pt_regs so that show_trace can provide a good call trace.
660 */
661ENTRY(stack_overflow)
662 lg %r15,__LC_NODAT_STACK # change to panic stack
663 la %r11,STACK_FRAME_OVERHEAD(%r15)
664 stmg %r0,%r7,__PT_R0(%r11)
665 stmg %r8,%r9,__PT_PSW(%r11)
666 mvc __PT_R8(64,%r11),0(%r14)
667 stg %r10,__PT_ORIG_GPR2(%r11) # store last break to orig_gpr2
668 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
669 lgr %r2,%r11 # pass pointer to pt_regs
670 jg kernel_stack_overflow
671ENDPROC(stack_overflow)
672#endif
673
674 .section .data, "aw"
675 .align 4
676.Lstop_lock: .long 0
677.Lthis_cpu: .short 0
678.Lstosm_tmp: .byte 0
679 .section .rodata, "a"
680#define SYSCALL(esame,emu) .quad __s390x_ ## esame
681 .globl sys_call_table
682sys_call_table:
683#include "asm/syscall_table.h"
684#undef SYSCALL
685
686#ifdef CONFIG_COMPAT
687
688#define SYSCALL(esame,emu) .quad __s390_ ## emu
689 .globl sys_call_table_emu
690sys_call_table_emu:
691#include "asm/syscall_table.h"
692#undef SYSCALL
693#endif
1/*
2 * arch/s390/kernel/entry.S
3 * S390 low-level entry points.
4 *
5 * Copyright (C) IBM Corp. 1999,2012
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/init.h>
13#include <linux/linkage.h>
14#include <asm/cache.h>
15#include <asm/errno.h>
16#include <asm/ptrace.h>
17#include <asm/thread_info.h>
18#include <asm/asm-offsets.h>
19#include <asm/unistd.h>
20#include <asm/page.h>
21
22__PT_R0 = __PT_GPRS
23__PT_R1 = __PT_GPRS + 4
24__PT_R2 = __PT_GPRS + 8
25__PT_R3 = __PT_GPRS + 12
26__PT_R4 = __PT_GPRS + 16
27__PT_R5 = __PT_GPRS + 20
28__PT_R6 = __PT_GPRS + 24
29__PT_R7 = __PT_GPRS + 28
30__PT_R8 = __PT_GPRS + 32
31__PT_R9 = __PT_GPRS + 36
32__PT_R10 = __PT_GPRS + 40
33__PT_R11 = __PT_GPRS + 44
34__PT_R12 = __PT_GPRS + 48
35__PT_R13 = __PT_GPRS + 524
36__PT_R14 = __PT_GPRS + 56
37__PT_R15 = __PT_GPRS + 60
38
39_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
40 _TIF_MCCK_PENDING | _TIF_PER_TRAP )
41_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
42 _TIF_MCCK_PENDING)
43_TIF_TRACE = (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SECCOMP | \
44 _TIF_SYSCALL_TRACEPOINT)
45
46STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER
47STACK_SIZE = 1 << STACK_SHIFT
48
49#define BASED(name) name-system_call(%r13)
50
51 .macro TRACE_IRQS_ON
52#ifdef CONFIG_TRACE_IRQFLAGS
53 basr %r2,%r0
54 l %r1,BASED(.Lhardirqs_on)
55 basr %r14,%r1 # call trace_hardirqs_on_caller
56#endif
57 .endm
58
59 .macro TRACE_IRQS_OFF
60#ifdef CONFIG_TRACE_IRQFLAGS
61 basr %r2,%r0
62 l %r1,BASED(.Lhardirqs_off)
63 basr %r14,%r1 # call trace_hardirqs_off_caller
64#endif
65 .endm
66
67 .macro LOCKDEP_SYS_EXIT
68#ifdef CONFIG_LOCKDEP
69 tm __PT_PSW+1(%r11),0x01 # returning to user ?
70 jz .+10
71 l %r1,BASED(.Llockdep_sys_exit)
72 basr %r14,%r1 # call lockdep_sys_exit
73#endif
74 .endm
75
76 .macro CHECK_STACK stacksize,savearea
77#ifdef CONFIG_CHECK_STACK
78 tml %r15,\stacksize - CONFIG_STACK_GUARD
79 la %r14,\savearea
80 jz stack_overflow
81#endif
82 .endm
83
84 .macro SWITCH_ASYNC savearea,stack,shift
85 tmh %r8,0x0001 # interrupting from user ?
86 jnz 1f
87 lr %r14,%r9
88 sl %r14,BASED(.Lcritical_start)
89 cl %r14,BASED(.Lcritical_length)
90 jhe 0f
91 la %r11,\savearea # inside critical section, do cleanup
92 bras %r14,cleanup_critical
93 tmh %r8,0x0001 # retest problem state after cleanup
94 jnz 1f
950: l %r14,\stack # are we already on the target stack?
96 slr %r14,%r15
97 sra %r14,\shift
98 jnz 1f
99 CHECK_STACK 1<<\shift,\savearea
100 j 2f
1011: l %r15,\stack # load target stack
1022: ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
103 la %r11,STACK_FRAME_OVERHEAD(%r15)
104 .endm
105
106 .macro ADD64 high,low,timer
107 al \high,\timer
108 al \low,4+\timer
109 brc 12,.+8
110 ahi \high,1
111 .endm
112
113 .macro SUB64 high,low,timer
114 sl \high,\timer
115 sl \low,4+\timer
116 brc 3,.+8
117 ahi \high,-1
118 .endm
119
120 .macro UPDATE_VTIME high,low,enter_timer
121 lm \high,\low,__LC_EXIT_TIMER
122 SUB64 \high,\low,\enter_timer
123 ADD64 \high,\low,__LC_USER_TIMER
124 stm \high,\low,__LC_USER_TIMER
125 lm \high,\low,__LC_LAST_UPDATE_TIMER
126 SUB64 \high,\low,__LC_EXIT_TIMER
127 ADD64 \high,\low,__LC_SYSTEM_TIMER
128 stm \high,\low,__LC_SYSTEM_TIMER
129 mvc __LC_LAST_UPDATE_TIMER(8),\enter_timer
130 .endm
131
132 .macro REENABLE_IRQS
133 st %r8,__LC_RETURN_PSW
134 ni __LC_RETURN_PSW,0xbf
135 ssm __LC_RETURN_PSW
136 .endm
137
138 .section .kprobes.text, "ax"
139
140/*
141 * Scheduler resume function, called by switch_to
142 * gpr2 = (task_struct *) prev
143 * gpr3 = (task_struct *) next
144 * Returns:
145 * gpr2 = prev
146 */
147ENTRY(__switch_to)
148 stm %r6,%r15,__SF_GPRS(%r15) # store gprs of prev task
149 st %r15,__THREAD_ksp(%r2) # store kernel stack of prev
150 l %r4,__THREAD_info(%r2) # get thread_info of prev
151 l %r5,__THREAD_info(%r3) # get thread_info of next
152 lr %r15,%r5
153 ahi %r15,STACK_SIZE # end of kernel stack of next
154 st %r3,__LC_CURRENT # store task struct of next
155 st %r5,__LC_THREAD_INFO # store thread info of next
156 st %r15,__LC_KERNEL_STACK # store end of kernel stack
157 lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4
158 mvc __LC_CURRENT_PID(4,%r0),__TASK_pid(%r3) # store pid of next
159 l %r15,__THREAD_ksp(%r3) # load kernel stack of next
160 tm __TI_flags+3(%r4),_TIF_MCCK_PENDING # machine check pending?
161 jz 0f
162 ni __TI_flags+3(%r4),255-_TIF_MCCK_PENDING # clear flag in prev
163 oi __TI_flags+3(%r5),_TIF_MCCK_PENDING # set it in next
1640: lm %r6,%r15,__SF_GPRS(%r15) # load gprs of next task
165 br %r14
166
167__critical_start:
168/*
169 * SVC interrupt handler routine. System calls are synchronous events and
170 * are executed with interrupts enabled.
171 */
172
173ENTRY(system_call)
174 stpt __LC_SYNC_ENTER_TIMER
175sysc_stm:
176 stm %r8,%r15,__LC_SAVE_AREA_SYNC
177 l %r12,__LC_THREAD_INFO
178 l %r13,__LC_SVC_NEW_PSW+4
179sysc_per:
180 l %r15,__LC_KERNEL_STACK
181 ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
182 la %r11,STACK_FRAME_OVERHEAD(%r15) # pointer to pt_regs
183sysc_vtime:
184 UPDATE_VTIME %r8,%r9,__LC_SYNC_ENTER_TIMER
185 stm %r0,%r7,__PT_R0(%r11)
186 mvc __PT_R8(32,%r11),__LC_SAVE_AREA_SYNC
187 mvc __PT_PSW(8,%r11),__LC_SVC_OLD_PSW
188 mvc __PT_INT_CODE(4,%r11),__LC_SVC_ILC
189sysc_do_svc:
190 oi __TI_flags+3(%r12),_TIF_SYSCALL
191 lh %r8,__PT_INT_CODE+2(%r11)
192 sla %r8,2 # shift and test for svc0
193 jnz sysc_nr_ok
194 # svc 0: system call number in %r1
195 cl %r1,BASED(.Lnr_syscalls)
196 jnl sysc_nr_ok
197 sth %r1,__PT_INT_CODE+2(%r11)
198 lr %r8,%r1
199 sla %r8,2
200sysc_nr_ok:
201 l %r10,BASED(.Lsys_call_table) # 31 bit system call table
202 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
203 st %r2,__PT_ORIG_GPR2(%r11)
204 st %r7,STACK_FRAME_OVERHEAD(%r15)
205 l %r9,0(%r8,%r10) # get system call addr.
206 tm __TI_flags+2(%r12),_TIF_TRACE >> 8
207 jnz sysc_tracesys
208 basr %r14,%r9 # call sys_xxxx
209 st %r2,__PT_R2(%r11) # store return value
210
211sysc_return:
212 LOCKDEP_SYS_EXIT
213sysc_tif:
214 tm __PT_PSW+1(%r11),0x01 # returning to user ?
215 jno sysc_restore
216 tm __TI_flags+3(%r12),_TIF_WORK_SVC
217 jnz sysc_work # check for work
218 ni __TI_flags+3(%r12),255-_TIF_SYSCALL
219sysc_restore:
220 mvc __LC_RETURN_PSW(8),__PT_PSW(%r11)
221 stpt __LC_EXIT_TIMER
222 lm %r0,%r15,__PT_R0(%r11)
223 lpsw __LC_RETURN_PSW
224sysc_done:
225
226#
227# One of the work bits is on. Find out which one.
228#
229sysc_work:
230 tm __TI_flags+3(%r12),_TIF_MCCK_PENDING
231 jo sysc_mcck_pending
232 tm __TI_flags+3(%r12),_TIF_NEED_RESCHED
233 jo sysc_reschedule
234 tm __TI_flags+3(%r12),_TIF_SIGPENDING
235 jo sysc_sigpending
236 tm __TI_flags+3(%r12),_TIF_NOTIFY_RESUME
237 jo sysc_notify_resume
238 tm __TI_flags+3(%r12),_TIF_PER_TRAP
239 jo sysc_singlestep
240 j sysc_return # beware of critical section cleanup
241
242#
243# _TIF_NEED_RESCHED is set, call schedule
244#
245sysc_reschedule:
246 l %r1,BASED(.Lschedule)
247 la %r14,BASED(sysc_return)
248 br %r1 # call schedule
249
250#
251# _TIF_MCCK_PENDING is set, call handler
252#
253sysc_mcck_pending:
254 l %r1,BASED(.Lhandle_mcck)
255 la %r14,BASED(sysc_return)
256 br %r1 # TIF bit will be cleared by handler
257
258#
259# _TIF_SIGPENDING is set, call do_signal
260#
261sysc_sigpending:
262 ni __TI_flags+3(%r12),255-_TIF_PER_TRAP # clear TIF_PER_TRAP
263 lr %r2,%r11 # pass pointer to pt_regs
264 l %r1,BASED(.Ldo_signal)
265 basr %r14,%r1 # call do_signal
266 tm __TI_flags+3(%r12),_TIF_SYSCALL
267 jno sysc_return
268 lm %r2,%r7,__PT_R2(%r11) # load svc arguments
269 xr %r8,%r8 # svc 0 returns -ENOSYS
270 clc __PT_INT_CODE+2(2,%r11),BASED(.Lnr_syscalls+2)
271 jnl sysc_nr_ok # invalid svc number -> do svc 0
272 lh %r8,__PT_INT_CODE+2(%r11) # load new svc number
273 sla %r8,2
274 j sysc_nr_ok # restart svc
275
276#
277# _TIF_NOTIFY_RESUME is set, call do_notify_resume
278#
279sysc_notify_resume:
280 lr %r2,%r11 # pass pointer to pt_regs
281 l %r1,BASED(.Ldo_notify_resume)
282 la %r14,BASED(sysc_return)
283 br %r1 # call do_notify_resume
284
285#
286# _TIF_PER_TRAP is set, call do_per_trap
287#
288sysc_singlestep:
289 ni __TI_flags+3(%r12),255-(_TIF_SYSCALL | _TIF_PER_TRAP)
290 lr %r2,%r11 # pass pointer to pt_regs
291 l %r1,BASED(.Ldo_per_trap)
292 la %r14,BASED(sysc_return)
293 br %r1 # call do_per_trap
294
295#
296# call tracehook_report_syscall_entry/tracehook_report_syscall_exit before
297# and after the system call
298#
299sysc_tracesys:
300 l %r1,BASED(.Ltrace_enter)
301 lr %r2,%r11 # pass pointer to pt_regs
302 la %r3,0
303 xr %r0,%r0
304 icm %r0,3,__PT_INT_CODE+2(%r11)
305 st %r0,__PT_R2(%r11)
306 basr %r14,%r1 # call do_syscall_trace_enter
307 cl %r2,BASED(.Lnr_syscalls)
308 jnl sysc_tracenogo
309 lr %r8,%r2
310 sll %r8,2
311 l %r9,0(%r8,%r10)
312sysc_tracego:
313 lm %r3,%r7,__PT_R3(%r11)
314 st %r7,STACK_FRAME_OVERHEAD(%r15)
315 l %r2,__PT_ORIG_GPR2(%r11)
316 basr %r14,%r9 # call sys_xxx
317 st %r2,__PT_R2(%r11) # store return value
318sysc_tracenogo:
319 tm __TI_flags+2(%r12),_TIF_TRACE >> 8
320 jz sysc_return
321 l %r1,BASED(.Ltrace_exit)
322 lr %r2,%r11 # pass pointer to pt_regs
323 la %r14,BASED(sysc_return)
324 br %r1 # call do_syscall_trace_exit
325
326#
327# a new process exits the kernel with ret_from_fork
328#
329ENTRY(ret_from_fork)
330 la %r11,STACK_FRAME_OVERHEAD(%r15)
331 l %r12,__LC_THREAD_INFO
332 l %r13,__LC_SVC_NEW_PSW+4
333 tm __PT_PSW+1(%r11),0x01 # forking a kernel thread ?
334 jo 0f
335 st %r15,__PT_R15(%r11) # store stack pointer for new kthread
3360: l %r1,BASED(.Lschedule_tail)
337 basr %r14,%r1 # call schedule_tail
338 TRACE_IRQS_ON
339 ssm __LC_SVC_NEW_PSW # reenable interrupts
340 j sysc_tracenogo
341
342#
343# kernel_execve function needs to deal with pt_regs that is not
344# at the usual place
345#
346ENTRY(kernel_execve)
347 stm %r12,%r15,48(%r15)
348 lr %r14,%r15
349 l %r13,__LC_SVC_NEW_PSW+4
350 ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
351 st %r14,__SF_BACKCHAIN(%r15)
352 la %r12,STACK_FRAME_OVERHEAD(%r15)
353 xc 0(__PT_SIZE,%r12),0(%r12)
354 l %r1,BASED(.Ldo_execve)
355 lr %r5,%r12
356 basr %r14,%r1 # call do_execve
357 ltr %r2,%r2
358 je 0f
359 ahi %r15,(STACK_FRAME_OVERHEAD + __PT_SIZE)
360 lm %r12,%r15,48(%r15)
361 br %r14
362 # execve succeeded.
3630: ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
364 l %r15,__LC_KERNEL_STACK # load ksp
365 ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
366 la %r11,STACK_FRAME_OVERHEAD(%r15)
367 mvc 0(__PT_SIZE,%r11),0(%r12) # copy pt_regs
368 l %r12,__LC_THREAD_INFO
369 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
370 ssm __LC_SVC_NEW_PSW # reenable interrupts
371 l %r1,BASED(.Lexecve_tail)
372 basr %r14,%r1 # call execve_tail
373 j sysc_return
374
375/*
376 * Program check handler routine
377 */
378
379ENTRY(pgm_check_handler)
380 stpt __LC_SYNC_ENTER_TIMER
381 stm %r8,%r15,__LC_SAVE_AREA_SYNC
382 l %r12,__LC_THREAD_INFO
383 l %r13,__LC_SVC_NEW_PSW+4
384 lm %r8,%r9,__LC_PGM_OLD_PSW
385 tmh %r8,0x0001 # test problem state bit
386 jnz 1f # -> fault in user space
387 tmh %r8,0x4000 # PER bit set in old PSW ?
388 jnz 0f # -> enabled, can't be a double fault
389 tm __LC_PGM_ILC+3,0x80 # check for per exception
390 jnz pgm_svcper # -> single stepped svc
3910: CHECK_STACK STACK_SIZE,__LC_SAVE_AREA_SYNC
392 j 2f
3931: UPDATE_VTIME %r14,%r15,__LC_SYNC_ENTER_TIMER
394 l %r15,__LC_KERNEL_STACK
3952: ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
396 la %r11,STACK_FRAME_OVERHEAD(%r15)
397 stm %r0,%r7,__PT_R0(%r11)
398 mvc __PT_R8(32,%r11),__LC_SAVE_AREA_SYNC
399 stm %r8,%r9,__PT_PSW(%r11)
400 mvc __PT_INT_CODE(4,%r11),__LC_PGM_ILC
401 mvc __PT_INT_PARM_LONG(4,%r11),__LC_TRANS_EXC_CODE
402 tm __LC_PGM_ILC+3,0x80 # check for per exception
403 jz 0f
404 l %r1,__TI_task(%r12)
405 tmh %r8,0x0001 # kernel per event ?
406 jz pgm_kprobe
407 oi __TI_flags+3(%r12),_TIF_PER_TRAP
408 mvc __THREAD_per_address(4,%r1),__LC_PER_ADDRESS
409 mvc __THREAD_per_cause(2,%r1),__LC_PER_CAUSE
410 mvc __THREAD_per_paid(1,%r1),__LC_PER_PAID
4110: REENABLE_IRQS
412 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
413 l %r1,BASED(.Ljump_table)
414 la %r10,0x7f
415 n %r10,__PT_INT_CODE(%r11)
416 je sysc_return
417 sll %r10,2
418 l %r1,0(%r10,%r1) # load address of handler routine
419 lr %r2,%r11 # pass pointer to pt_regs
420 basr %r14,%r1 # branch to interrupt-handler
421 j sysc_return
422
423#
424# PER event in supervisor state, must be kprobes
425#
426pgm_kprobe:
427 REENABLE_IRQS
428 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
429 l %r1,BASED(.Ldo_per_trap)
430 lr %r2,%r11 # pass pointer to pt_regs
431 basr %r14,%r1 # call do_per_trap
432 j sysc_return
433
434#
435# single stepped system call
436#
437pgm_svcper:
438 oi __TI_flags+3(%r12),_TIF_PER_TRAP
439 mvc __LC_RETURN_PSW(4),__LC_SVC_NEW_PSW
440 mvc __LC_RETURN_PSW+4(4),BASED(.Lsysc_per)
441 lpsw __LC_RETURN_PSW # branch to sysc_per and enable irqs
442
443/*
444 * IO interrupt handler routine
445 */
446
447ENTRY(io_int_handler)
448 stck __LC_INT_CLOCK
449 stpt __LC_ASYNC_ENTER_TIMER
450 stm %r8,%r15,__LC_SAVE_AREA_ASYNC
451 l %r12,__LC_THREAD_INFO
452 l %r13,__LC_SVC_NEW_PSW+4
453 lm %r8,%r9,__LC_IO_OLD_PSW
454 tmh %r8,0x0001 # interrupting from user ?
455 jz io_skip
456 UPDATE_VTIME %r14,%r15,__LC_ASYNC_ENTER_TIMER
457io_skip:
458 SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT
459 stm %r0,%r7,__PT_R0(%r11)
460 mvc __PT_R8(32,%r11),__LC_SAVE_AREA_ASYNC
461 stm %r8,%r9,__PT_PSW(%r11)
462 TRACE_IRQS_OFF
463 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
464 l %r1,BASED(.Ldo_IRQ)
465 lr %r2,%r11 # pass pointer to pt_regs
466 basr %r14,%r1 # call do_IRQ
467io_return:
468 LOCKDEP_SYS_EXIT
469 TRACE_IRQS_ON
470io_tif:
471 tm __TI_flags+3(%r12),_TIF_WORK_INT
472 jnz io_work # there is work to do (signals etc.)
473io_restore:
474 mvc __LC_RETURN_PSW(8),__PT_PSW(%r11)
475 stpt __LC_EXIT_TIMER
476 lm %r0,%r15,__PT_R0(%r11)
477 lpsw __LC_RETURN_PSW
478io_done:
479
480#
481# There is work todo, find out in which context we have been interrupted:
482# 1) if we return to user space we can do all _TIF_WORK_INT work
483# 2) if we return to kernel code and preemptive scheduling is enabled check
484# the preemption counter and if it is zero call preempt_schedule_irq
485# Before any work can be done, a switch to the kernel stack is required.
486#
487io_work:
488 tm __PT_PSW+1(%r11),0x01 # returning to user ?
489 jo io_work_user # yes -> do resched & signal
490#ifdef CONFIG_PREEMPT
491 # check for preemptive scheduling
492 icm %r0,15,__TI_precount(%r12)
493 jnz io_restore # preemption disabled
494 tm __TI_flags+3(%r12),_TIF_NEED_RESCHED
495 jno io_restore
496 # switch to kernel stack
497 l %r1,__PT_R15(%r11)
498 ahi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
499 mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
500 xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1)
501 la %r11,STACK_FRAME_OVERHEAD(%r1)
502 lr %r15,%r1
503 # TRACE_IRQS_ON already done at io_return, call
504 # TRACE_IRQS_OFF to keep things symmetrical
505 TRACE_IRQS_OFF
506 l %r1,BASED(.Lpreempt_irq)
507 basr %r14,%r1 # call preempt_schedule_irq
508 j io_return
509#else
510 j io_restore
511#endif
512
513#
514# Need to do work before returning to userspace, switch to kernel stack
515#
516io_work_user:
517 l %r1,__LC_KERNEL_STACK
518 ahi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
519 mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
520 xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1)
521 la %r11,STACK_FRAME_OVERHEAD(%r1)
522 lr %r15,%r1
523
524#
525# One of the work bits is on. Find out which one.
526# Checked are: _TIF_SIGPENDING, _TIF_NOTIFY_RESUME, _TIF_NEED_RESCHED
527# and _TIF_MCCK_PENDING
528#
529io_work_tif:
530 tm __TI_flags+3(%r12),_TIF_MCCK_PENDING
531 jo io_mcck_pending
532 tm __TI_flags+3(%r12),_TIF_NEED_RESCHED
533 jo io_reschedule
534 tm __TI_flags+3(%r12),_TIF_SIGPENDING
535 jo io_sigpending
536 tm __TI_flags+3(%r12),_TIF_NOTIFY_RESUME
537 jo io_notify_resume
538 j io_return # beware of critical section cleanup
539
540#
541# _TIF_MCCK_PENDING is set, call handler
542#
543io_mcck_pending:
544 # TRACE_IRQS_ON already done at io_return
545 l %r1,BASED(.Lhandle_mcck)
546 basr %r14,%r1 # TIF bit will be cleared by handler
547 TRACE_IRQS_OFF
548 j io_return
549
550#
551# _TIF_NEED_RESCHED is set, call schedule
552#
553io_reschedule:
554 # TRACE_IRQS_ON already done at io_return
555 l %r1,BASED(.Lschedule)
556 ssm __LC_SVC_NEW_PSW # reenable interrupts
557 basr %r14,%r1 # call scheduler
558 ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
559 TRACE_IRQS_OFF
560 j io_return
561
562#
563# _TIF_SIGPENDING is set, call do_signal
564#
565io_sigpending:
566 # TRACE_IRQS_ON already done at io_return
567 l %r1,BASED(.Ldo_signal)
568 ssm __LC_SVC_NEW_PSW # reenable interrupts
569 lr %r2,%r11 # pass pointer to pt_regs
570 basr %r14,%r1 # call do_signal
571 ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
572 TRACE_IRQS_OFF
573 j io_return
574
575#
576# _TIF_SIGPENDING is set, call do_signal
577#
578io_notify_resume:
579 # TRACE_IRQS_ON already done at io_return
580 l %r1,BASED(.Ldo_notify_resume)
581 ssm __LC_SVC_NEW_PSW # reenable interrupts
582 lr %r2,%r11 # pass pointer to pt_regs
583 basr %r14,%r1 # call do_notify_resume
584 ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
585 TRACE_IRQS_OFF
586 j io_return
587
588/*
589 * External interrupt handler routine
590 */
591
592ENTRY(ext_int_handler)
593 stck __LC_INT_CLOCK
594 stpt __LC_ASYNC_ENTER_TIMER
595 stm %r8,%r15,__LC_SAVE_AREA_ASYNC
596 l %r12,__LC_THREAD_INFO
597 l %r13,__LC_SVC_NEW_PSW+4
598 lm %r8,%r9,__LC_EXT_OLD_PSW
599 tmh %r8,0x0001 # interrupting from user ?
600 jz ext_skip
601 UPDATE_VTIME %r14,%r15,__LC_ASYNC_ENTER_TIMER
602ext_skip:
603 SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT
604 stm %r0,%r7,__PT_R0(%r11)
605 mvc __PT_R8(32,%r11),__LC_SAVE_AREA_ASYNC
606 stm %r8,%r9,__PT_PSW(%r11)
607 TRACE_IRQS_OFF
608 lr %r2,%r11 # pass pointer to pt_regs
609 l %r3,__LC_EXT_CPU_ADDR # get cpu address + interruption code
610 l %r4,__LC_EXT_PARAMS # get external parameters
611 l %r1,BASED(.Ldo_extint)
612 basr %r14,%r1 # call do_extint
613 j io_return
614
615/*
616 * Load idle PSW. The second "half" of this function is in cleanup_idle.
617 */
618ENTRY(psw_idle)
619 st %r4,__SF_EMPTY(%r15)
620 basr %r1,0
621 la %r1,psw_idle_lpsw+4-.(%r1)
622 st %r1,__SF_EMPTY+4(%r15)
623 oi __SF_EMPTY+4(%r15),0x80
624 la %r1,.Lvtimer_max-psw_idle_lpsw-4(%r1)
625 stck __IDLE_ENTER(%r2)
626 ltr %r5,%r5
627 stpt __VQ_IDLE_ENTER(%r3)
628 jz psw_idle_lpsw
629 spt 0(%r1)
630psw_idle_lpsw:
631 lpsw __SF_EMPTY(%r15)
632 br %r14
633psw_idle_end:
634
635__critical_end:
636
637/*
638 * Machine check handler routines
639 */
640
641ENTRY(mcck_int_handler)
642 stck __LC_MCCK_CLOCK
643 spt __LC_CPU_TIMER_SAVE_AREA # revalidate cpu timer
644 lm %r0,%r15,__LC_GPREGS_SAVE_AREA # revalidate gprs
645 l %r12,__LC_THREAD_INFO
646 l %r13,__LC_SVC_NEW_PSW+4
647 lm %r8,%r9,__LC_MCK_OLD_PSW
648 tm __LC_MCCK_CODE,0x80 # system damage?
649 jo mcck_panic # yes -> rest of mcck code invalid
650 la %r14,__LC_CPU_TIMER_SAVE_AREA
651 mvc __LC_MCCK_ENTER_TIMER(8),0(%r14)
652 tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid?
653 jo 3f
654 la %r14,__LC_SYNC_ENTER_TIMER
655 clc 0(8,%r14),__LC_ASYNC_ENTER_TIMER
656 jl 0f
657 la %r14,__LC_ASYNC_ENTER_TIMER
6580: clc 0(8,%r14),__LC_EXIT_TIMER
659 jl 1f
660 la %r14,__LC_EXIT_TIMER
6611: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER
662 jl 2f
663 la %r14,__LC_LAST_UPDATE_TIMER
6642: spt 0(%r14)
665 mvc __LC_MCCK_ENTER_TIMER(8),0(%r14)
6663: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid?
667 jno mcck_panic # no -> skip cleanup critical
668 tm %r8,0x0001 # interrupting from user ?
669 jz mcck_skip
670 UPDATE_VTIME %r14,%r15,__LC_MCCK_ENTER_TIMER
671mcck_skip:
672 SWITCH_ASYNC __LC_GPREGS_SAVE_AREA+32,__LC_PANIC_STACK,PAGE_SHIFT
673 mvc __PT_R0(64,%r11),__LC_GPREGS_SAVE_AREA
674 stm %r8,%r9,__PT_PSW(%r11)
675 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
676 l %r1,BASED(.Ldo_machine_check)
677 lr %r2,%r11 # pass pointer to pt_regs
678 basr %r14,%r1 # call s390_do_machine_check
679 tm __PT_PSW+1(%r11),0x01 # returning to user ?
680 jno mcck_return
681 l %r1,__LC_KERNEL_STACK # switch to kernel stack
682 ahi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
683 mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
684 xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1)
685 la %r11,STACK_FRAME_OVERHEAD(%r15)
686 lr %r15,%r1
687 ssm __LC_PGM_NEW_PSW # turn dat on, keep irqs off
688 tm __TI_flags+3(%r12),_TIF_MCCK_PENDING
689 jno mcck_return
690 TRACE_IRQS_OFF
691 l %r1,BASED(.Lhandle_mcck)
692 basr %r14,%r1 # call s390_handle_mcck
693 TRACE_IRQS_ON
694mcck_return:
695 mvc __LC_RETURN_MCCK_PSW(8),__PT_PSW(%r11) # move return PSW
696 tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ?
697 jno 0f
698 lm %r0,%r15,__PT_R0(%r11)
699 stpt __LC_EXIT_TIMER
700 lpsw __LC_RETURN_MCCK_PSW
7010: lm %r0,%r15,__PT_R0(%r11)
702 lpsw __LC_RETURN_MCCK_PSW
703
704mcck_panic:
705 l %r14,__LC_PANIC_STACK
706 slr %r14,%r15
707 sra %r14,PAGE_SHIFT
708 jz 0f
709 l %r15,__LC_PANIC_STACK
7100: ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
711 j mcck_skip
712
713#
714# PSW restart interrupt handler
715#
716ENTRY(restart_int_handler)
717 st %r15,__LC_SAVE_AREA_RESTART
718 l %r15,__LC_RESTART_STACK
719 ahi %r15,-__PT_SIZE # create pt_regs on stack
720 xc 0(__PT_SIZE,%r15),0(%r15)
721 stm %r0,%r14,__PT_R0(%r15)
722 mvc __PT_R15(4,%r15),__LC_SAVE_AREA_RESTART
723 mvc __PT_PSW(8,%r15),__LC_RST_OLD_PSW # store restart old psw
724 ahi %r15,-STACK_FRAME_OVERHEAD # create stack frame on stack
725 xc 0(STACK_FRAME_OVERHEAD,%r15),0(%r15)
726 lm %r1,%r3,__LC_RESTART_FN # load fn, parm & source cpu
727 ltr %r3,%r3 # test source cpu address
728 jm 1f # negative -> skip source stop
7290: sigp %r4,%r3,1 # sigp sense to source cpu
730 brc 10,0b # wait for status stored
7311: basr %r14,%r1 # call function
732 stap __SF_EMPTY(%r15) # store cpu address
733 lh %r3,__SF_EMPTY(%r15)
7342: sigp %r4,%r3,5 # sigp stop to current cpu
735 brc 2,2b
7363: j 3b
737
738 .section .kprobes.text, "ax"
739
740#ifdef CONFIG_CHECK_STACK
741/*
742 * The synchronous or the asynchronous stack overflowed. We are dead.
743 * No need to properly save the registers, we are going to panic anyway.
744 * Setup a pt_regs so that show_trace can provide a good call trace.
745 */
746stack_overflow:
747 l %r15,__LC_PANIC_STACK # change to panic stack
748 ahi %r15,-__PT_SIZE # create pt_regs
749 stm %r0,%r7,__PT_R0(%r15)
750 stm %r8,%r9,__PT_PSW(%r15)
751 mvc __PT_R8(32,%r11),0(%r14)
752 lr %r15,%r11
753 ahi %r15,-STACK_FRAME_OVERHEAD
754 l %r1,BASED(1f)
755 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
756 lr %r2,%r11 # pass pointer to pt_regs
757 br %r1 # branch to kernel_stack_overflow
7581: .long kernel_stack_overflow
759#endif
760
761cleanup_table:
762 .long system_call + 0x80000000
763 .long sysc_do_svc + 0x80000000
764 .long sysc_tif + 0x80000000
765 .long sysc_restore + 0x80000000
766 .long sysc_done + 0x80000000
767 .long io_tif + 0x80000000
768 .long io_restore + 0x80000000
769 .long io_done + 0x80000000
770 .long psw_idle + 0x80000000
771 .long psw_idle_end + 0x80000000
772
773cleanup_critical:
774 cl %r9,BASED(cleanup_table) # system_call
775 jl 0f
776 cl %r9,BASED(cleanup_table+4) # sysc_do_svc
777 jl cleanup_system_call
778 cl %r9,BASED(cleanup_table+8) # sysc_tif
779 jl 0f
780 cl %r9,BASED(cleanup_table+12) # sysc_restore
781 jl cleanup_sysc_tif
782 cl %r9,BASED(cleanup_table+16) # sysc_done
783 jl cleanup_sysc_restore
784 cl %r9,BASED(cleanup_table+20) # io_tif
785 jl 0f
786 cl %r9,BASED(cleanup_table+24) # io_restore
787 jl cleanup_io_tif
788 cl %r9,BASED(cleanup_table+28) # io_done
789 jl cleanup_io_restore
790 cl %r9,BASED(cleanup_table+32) # psw_idle
791 jl 0f
792 cl %r9,BASED(cleanup_table+36) # psw_idle_end
793 jl cleanup_idle
7940: br %r14
795
796cleanup_system_call:
797 # check if stpt has been executed
798 cl %r9,BASED(cleanup_system_call_insn)
799 jh 0f
800 mvc __LC_SYNC_ENTER_TIMER(8),__LC_ASYNC_ENTER_TIMER
801 chi %r11,__LC_SAVE_AREA_ASYNC
802 je 0f
803 mvc __LC_SYNC_ENTER_TIMER(8),__LC_MCCK_ENTER_TIMER
8040: # check if stm has been executed
805 cl %r9,BASED(cleanup_system_call_insn+4)
806 jh 0f
807 mvc __LC_SAVE_AREA_SYNC(32),0(%r11)
8080: # set up saved registers r12, and r13
809 st %r12,16(%r11) # r12 thread-info pointer
810 st %r13,20(%r11) # r13 literal-pool pointer
811 # check if the user time calculation has been done
812 cl %r9,BASED(cleanup_system_call_insn+8)
813 jh 0f
814 l %r10,__LC_EXIT_TIMER
815 l %r15,__LC_EXIT_TIMER+4
816 SUB64 %r10,%r15,__LC_SYNC_ENTER_TIMER
817 ADD64 %r10,%r15,__LC_USER_TIMER
818 st %r10,__LC_USER_TIMER
819 st %r15,__LC_USER_TIMER+4
8200: # check if the system time calculation has been done
821 cl %r9,BASED(cleanup_system_call_insn+12)
822 jh 0f
823 l %r10,__LC_LAST_UPDATE_TIMER
824 l %r15,__LC_LAST_UPDATE_TIMER+4
825 SUB64 %r10,%r15,__LC_EXIT_TIMER
826 ADD64 %r10,%r15,__LC_SYSTEM_TIMER
827 st %r10,__LC_SYSTEM_TIMER
828 st %r15,__LC_SYSTEM_TIMER+4
8290: # update accounting time stamp
830 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
831 # set up saved register 11
832 l %r15,__LC_KERNEL_STACK
833 ahi %r15,-__PT_SIZE
834 st %r15,12(%r11) # r11 pt_regs pointer
835 # fill pt_regs
836 mvc __PT_R8(32,%r15),__LC_SAVE_AREA_SYNC
837 stm %r0,%r7,__PT_R0(%r15)
838 mvc __PT_PSW(8,%r15),__LC_SVC_OLD_PSW
839 mvc __PT_INT_CODE(4,%r15),__LC_SVC_ILC
840 # setup saved register 15
841 ahi %r15,-STACK_FRAME_OVERHEAD
842 st %r15,28(%r11) # r15 stack pointer
843 # set new psw address and exit
844 l %r9,BASED(cleanup_table+4) # sysc_do_svc + 0x80000000
845 br %r14
846cleanup_system_call_insn:
847 .long system_call + 0x80000000
848 .long sysc_stm + 0x80000000
849 .long sysc_vtime + 0x80000000 + 36
850 .long sysc_vtime + 0x80000000 + 76
851
852cleanup_sysc_tif:
853 l %r9,BASED(cleanup_table+8) # sysc_tif + 0x80000000
854 br %r14
855
856cleanup_sysc_restore:
857 cl %r9,BASED(cleanup_sysc_restore_insn)
858 jhe 0f
859 l %r9,12(%r11) # get saved pointer to pt_regs
860 mvc __LC_RETURN_PSW(8),__PT_PSW(%r9)
861 mvc 0(32,%r11),__PT_R8(%r9)
862 lm %r0,%r7,__PT_R0(%r9)
8630: lm %r8,%r9,__LC_RETURN_PSW
864 br %r14
865cleanup_sysc_restore_insn:
866 .long sysc_done - 4 + 0x80000000
867
868cleanup_io_tif:
869 l %r9,BASED(cleanup_table+20) # io_tif + 0x80000000
870 br %r14
871
872cleanup_io_restore:
873 cl %r9,BASED(cleanup_io_restore_insn)
874 jhe 0f
875 l %r9,12(%r11) # get saved r11 pointer to pt_regs
876 mvc __LC_RETURN_PSW(8),__PT_PSW(%r9)
877 mvc 0(32,%r11),__PT_R8(%r9)
878 lm %r0,%r7,__PT_R0(%r9)
8790: lm %r8,%r9,__LC_RETURN_PSW
880 br %r14
881cleanup_io_restore_insn:
882 .long io_done - 4 + 0x80000000
883
884cleanup_idle:
885 # copy interrupt clock & cpu timer
886 mvc __IDLE_EXIT(8,%r2),__LC_INT_CLOCK
887 mvc __VQ_IDLE_EXIT(8,%r3),__LC_ASYNC_ENTER_TIMER
888 chi %r11,__LC_SAVE_AREA_ASYNC
889 je 0f
890 mvc __IDLE_EXIT(8,%r2),__LC_MCCK_CLOCK
891 mvc __VQ_IDLE_EXIT(8,%r3),__LC_MCCK_ENTER_TIMER
8920: # check if stck has been executed
893 cl %r9,BASED(cleanup_idle_insn)
894 jhe 1f
895 mvc __IDLE_ENTER(8,%r2),__IDLE_EXIT(%r2)
896 mvc __VQ_IDLE_ENTER(8,%r3),__VQ_IDLE_EXIT(%r3)
897 j 2f
8981: # check if the cpu timer has been reprogrammed
899 ltr %r5,%r5
900 jz 2f
901 spt __VQ_IDLE_ENTER(%r3)
9022: # account system time going idle
903 lm %r9,%r10,__LC_STEAL_TIMER
904 ADD64 %r9,%r10,__IDLE_ENTER(%r2)
905 SUB64 %r9,%r10,__LC_LAST_UPDATE_CLOCK
906 stm %r9,%r10,__LC_STEAL_TIMER
907 mvc __LC_LAST_UPDATE_CLOCK(8),__IDLE_EXIT(%r2)
908 lm %r9,%r10,__LC_SYSTEM_TIMER
909 ADD64 %r9,%r10,__LC_LAST_UPDATE_TIMER
910 SUB64 %r9,%r10,__VQ_IDLE_ENTER(%r3)
911 stm %r9,%r10,__LC_SYSTEM_TIMER
912 mvc __LC_LAST_UPDATE_TIMER(8),__VQ_IDLE_EXIT(%r3)
913 # prepare return psw
914 n %r8,BASED(cleanup_idle_wait) # clear wait state bit
915 l %r9,24(%r11) # return from psw_idle
916 br %r14
917cleanup_idle_insn:
918 .long psw_idle_lpsw + 0x80000000
919cleanup_idle_wait:
920 .long 0xfffdffff
921
922/*
923 * Integer constants
924 */
925 .align 4
926.Lnr_syscalls:
927 .long NR_syscalls
928.Lvtimer_max:
929 .quad 0x7fffffffffffffff
930
931/*
932 * Symbol constants
933 */
934.Ldo_machine_check: .long s390_do_machine_check
935.Lhandle_mcck: .long s390_handle_mcck
936.Ldo_IRQ: .long do_IRQ
937.Ldo_extint: .long do_extint
938.Ldo_signal: .long do_signal
939.Ldo_notify_resume: .long do_notify_resume
940.Ldo_per_trap: .long do_per_trap
941.Ldo_execve: .long do_execve
942.Lexecve_tail: .long execve_tail
943.Ljump_table: .long pgm_check_table
944.Lschedule: .long schedule
945#ifdef CONFIG_PREEMPT
946.Lpreempt_irq: .long preempt_schedule_irq
947#endif
948.Ltrace_enter: .long do_syscall_trace_enter
949.Ltrace_exit: .long do_syscall_trace_exit
950.Lschedule_tail: .long schedule_tail
951.Lsys_call_table: .long sys_call_table
952.Lsysc_per: .long sysc_per + 0x80000000
953#ifdef CONFIG_TRACE_IRQFLAGS
954.Lhardirqs_on: .long trace_hardirqs_on_caller
955.Lhardirqs_off: .long trace_hardirqs_off_caller
956#endif
957#ifdef CONFIG_LOCKDEP
958.Llockdep_sys_exit: .long lockdep_sys_exit
959#endif
960.Lcritical_start: .long __critical_start + 0x80000000
961.Lcritical_length: .long __critical_end - __critical_start
962
963 .section .rodata, "a"
964#define SYSCALL(esa,esame,emu) .long esa
965 .globl sys_call_table
966sys_call_table:
967#include "syscalls.S"
968#undef SYSCALL