patch-2.4.13 linux/arch/s390x/kernel/entry.S

Next file: linux/arch/s390x/kernel/head.S
Previous file: linux/arch/s390x/kernel/debug.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.12/linux/arch/s390x/kernel/entry.S linux/arch/s390x/kernel/entry.S
@@ -89,17 +89,25 @@
  *    R15 - kernel stack pointer
  */
 
-        .macro  SAVE_ALL psworg          # system entry macro
+        .macro  SAVE_ALL psworg,sync     # system entry macro
         stmg    %r14,%r15,__LC_SAVE_AREA
-        stam    %a2,%a4,__LC_SAVE_AREA+16
         tm      \psworg+1,0x01           # test problem state bit
-        jz      0f                       # skip stack setup save
-        lg      %r15,__LC_KERNEL_STACK   # problem state -> load ksp
-        slr     %r14,%r14
-        sar     %a2,%r14                 # set ac.reg. 2 to primary space
-        lhi     %r14,1
-        sar     %a4,%r14                 # set access reg. 4 to home space
-0:      aghi    %r15,-SP_SIZE            # make room for registers & psw
+	stam    %a2,%a4,__LC_SAVE_AREA+16
+	.if	\sync
+        jz      1f                       # skip stack setup save
+	.else
+	jnz	0f			 # from user -> load kernel stack
+	lg	%r14,__LC_ASYNC_STACK	 # are we already on the async. stack ?
+	slgr	%r14,%r15
+	srag	%r14,%r14,14
+	jz	1f
+	lg	%r15,__LC_ASYNC_STACK	 # load async. stack
+	j	1f
+	.endif
+0:	lg      %r15,__LC_KERNEL_STACK   # problem state -> load ksp
+	larl	%r14,.Lc_ac
+	lam	%a2,%a4,0(%r14)
+1:      aghi    %r15,-SP_SIZE            # make room for registers & psw
         nill    %r15,0xfff8              # align stack pointer to 8
         stmg    %r0,%r14,SP_R0(%r15)     # store gprs 0-14 to kernel stack
         stg     %r2,SP_ORIG_R2(%r15)     # store original content of gpr 2
@@ -112,7 +120,7 @@
         xc      0(8,%r15),0(%r15)        # clear back chain
         .endm
 
-        .macro  RESTORE_ALL              # system exit macro
+        .macro  RESTORE_ALL sync         # system exit macro
         mvc     __LC_RETURN_PSW(16),SP_PSW(%r15) # move user PSW to lowcore
         lam     %a0,%a15,SP_AREGS(%r15)  # load the access registers
         lmg     %r0,%r15,SP_R0(%r15)     # load gprs 0-15 of user
@@ -121,8 +129,8 @@
         .endm
 
         .macro  GET_CURRENT
-        lghi    %r9,-16384               # load pointer to task_struct to %r9
-        ngr     %r9,15
+	lg	%r9,__LC_KERNEL_STACK    # load pointer to task_struct to %r9
+	aghi	%r9,-16384
         .endm
 
 
@@ -161,13 +169,32 @@
         br      %r14
 
 /*
+ * do_softirq calling function. We want to run the softirq functions on the
+ * asynchronous interrupt stack.
+ */
+	.global do_call_softirq
+do_call_softirq:
+	stmg	%r12,%r15,48(%r15)
+	lgr	%r12,%r15
+	lg	%r0,__LC_ASYNC_STACK
+	slgr    %r0,%r15
+	srag	%r0,%r0,14
+	je	0f
+	lg	%r15,__LC_ASYNC_STACK
+0:	aghi	%r15,-STACK_FRAME_OVERHEAD
+	stg	%r12,0(%r15)		# store back chain
+	brasl	%r14,do_softirq
+	lmg	%r12,%r15,48(%r12)
+	br	%r14
+	
+/*
  * SVC interrupt handler routine. System calls are synchronous events and
  * are executed with interrupts enabled.
  */
 
 	.globl  system_call
 system_call:
-        SAVE_ALL __LC_SVC_OLD_PSW
+        SAVE_ALL __LC_SVC_OLD_PSW,1
 	mvi     SP_PGM_OLD_ILC(%r15),1  # mark PGM_OLD_ILC as invalid
 pgm_system_call:
         GET_CURRENT               # load pointer to task_struct to R9
@@ -202,7 +229,7 @@
         tm      SP_PGM_OLD_ILC(%r15),0xff
         jz      pgm_svcret
 	stnsm   48(%r15),0xfc         # disable I/O and ext. interrupts
-        RESTORE_ALL
+        RESTORE_ALL 1
 
 #
 # call do_signal before return
@@ -565,9 +592,9 @@
 	.long  SYSCALL(sys_mmap2,sys32_mmap2_wrapper)
 	.long  SYSCALL(sys_ni_syscall,sys32_truncate64_wrapper)
         .long  SYSCALL(sys_ni_syscall,sys32_ftruncate64_wrapper)
-        .long  SYSCALL(sys_ni_syscall,sys32_stat64)     /* 195 */
-        .long  SYSCALL(sys_ni_syscall,sys32_lstat64)   
-        .long  SYSCALL(sys_ni_syscall,sys32_fstat64)    
+        .long  SYSCALL(sys_ni_syscall,sys32_stat64_wrapper)     /* 195 */
+        .long  SYSCALL(sys_ni_syscall,sys32_lstat64_wrapper)   
+        .long  SYSCALL(sys_ni_syscall,sys32_fstat64_wrapper)    
 	.long  SYSCALL(sys_lchown,sys32_lchown_wrapper)
 	.long  SYSCALL(sys_getuid,sys_getuid)
 	.long  SYSCALL(sys_getgid,sys_getgid)         /* 200 */
@@ -592,7 +619,10 @@
         .long  SYSCALL(sys_madvise,sys32_madvise_wrapper)
 	.long  SYSCALL(sys_getdents64,sys32_getdents64_wrapper)/* 220 */
 	.long  SYSCALL(sys_ni_syscall,sys32_fcntl64_wrapper)
-        .rept  255-221
+	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 222 - reserved for posix_acl */
+	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 223 - reserved for posix_acl */
+	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 224 - reserved for posix_acl */
+        .rept  255-224
 	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall)
 	.endr
 
@@ -626,7 +656,7 @@
 	lpswe   __LC_PGM_OLD_PSW
 # it was a single stepped SVC that is causing all the trouble
 pgm_svcper:
-	SAVE_ALL __LC_SVC_OLD_PSW
+	SAVE_ALL __LC_SVC_OLD_PSW,1
         mvc     SP_PGM_OLD_ILC(4,%r15),__LC_PGM_ILC # save program check information
         j       pgm_system_call          # now do the svc
 pgm_svcret:
@@ -636,7 +666,7 @@
         mvi     SP_PGM_OLD_ILC(%r15),1   # mark PGM_OLD_ILC as invalid
 	j       pgm_no_sv
 pgm_sv:
-	SAVE_ALL __LC_PGM_OLD_PSW
+	SAVE_ALL __LC_PGM_OLD_PSW,1
         mvi     SP_PGM_OLD_ILC(%r15),1   # mark PGM_OLD_ILC as invalid
         llgh    %r7,__LC_PGM_ILC         # load instruction length
 	GET_CURRENT
@@ -668,7 +698,7 @@
  */
         .globl io_int_handler
 io_int_handler:
-        SAVE_ALL __LC_IO_OLD_PSW
+        SAVE_ALL __LC_IO_OLD_PSW,0
         GET_CURRENT                    # load pointer to task_struct to R9
         la      %r2,SP_PTREGS(%r15)    # address of register-save area
 	llgh    %r3,__LC_SUBCHANNEL_NR # load subchannel number
@@ -701,7 +731,7 @@
         jnz     io_signal_return
 io_leave:
         stnsm   48(%r15),0xfc          # disable I/O and ext. interrupts
-        RESTORE_ALL
+        RESTORE_ALL 0
 
 #
 # call do_softirq and return from syscall, if interrupt-level
@@ -732,7 +762,7 @@
  */
         .globl  ext_int_handler
 ext_int_handler:
-        SAVE_ALL __LC_EXT_OLD_PSW
+        SAVE_ALL __LC_EXT_OLD_PSW,0
         GET_CURRENT                    # load pointer to task_struct to R9
         la      %r2,SP_PTREGS(%r15)    # address of register-save area
         llgh    %r3,__LC_EXT_INT_CODE  # error code
@@ -760,10 +790,10 @@
  */
         .globl mcck_int_handler
 mcck_int_handler:
-        SAVE_ALL __LC_MCK_OLD_PSW
+        SAVE_ALL __LC_MCK_OLD_PSW,0
 	brasl   %r14,s390_do_machine_check
 mcck_return:
-        RESTORE_ALL
+        RESTORE_ALL 0
 
 #ifdef CONFIG_SMP
 /*
@@ -771,10 +801,10 @@
  */
         .globl restart_int_handler
 restart_int_handler:
-        lg      %r15,__LC_KERNEL_STACK # load ksp
-        lhi     %r10,__LC_CREGS_SAVE_AREA
+        lg      %r15,__LC_SAVE_AREA+120 # load ksp
+        lghi    %r10,__LC_CREGS_SAVE_AREA
         lctlg   %c0,%c15,0(%r10) # get new ctl regs
-        lhi     %r10,__LC_AREGS_SAVE_AREA
+        lghi    %r10,__LC_AREGS_SAVE_AREA
         lam     %a0,%a15,0(%r10)
         stosm   0(%r15),0x04           # now we can turn dat on
         lmg     %r6,%r15,48(%r15)      # load registers from clone
@@ -794,3 +824,8 @@
 restart_go:
 #endif
 
+/*
+ * Integer constants
+ */
+               .align 4
+.Lc_ac:        .long  0,0,1

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)