]> git.hungrycats.org Git - linux/commitdiff
[PATCH] s390: system call restart bug.
authorMartin Schwidefsky <schwidefsky@de.ibm.com>
Fri, 26 Sep 2003 01:01:45 +0000 (18:01 -0700)
committerLinus Torvalds <torvalds@home.osdl.org>
Fri, 26 Sep 2003 01:01:45 +0000 (18:01 -0700)
Fix restarting of system calls done by use of the execute instruction.

arch/s390/kernel/compat_signal.c
arch/s390/kernel/entry.S
arch/s390/kernel/entry64.S
arch/s390/kernel/signal.c
include/asm-s390/ptrace.h

index a128403e4d98a1ae170566136c3a64280cfa9d26..a7e89edfb900a0b4340891f16e2d2efaeb87a9e3 100644 (file)
@@ -579,7 +579,7 @@ handle_signal32(unsigned long sig, siginfo_t *info, sigset_t *oldset,
                        /* fallthrough */
                        case -ERESTARTNOINTR:
                                regs->gprs[2] = regs->orig_gpr2;
-                               regs->psw.addr -= 2;
+                               regs->psw.addr -= regs->ilc;
                }
        }
 
@@ -641,7 +641,12 @@ int do_signal32(struct pt_regs *regs, sigset_t *oldset)
                    regs->gprs[2] == -ERESTARTSYS ||
                    regs->gprs[2] == -ERESTARTNOINTR) {
                        regs->gprs[2] = regs->orig_gpr2;
-                       regs->psw.addr -= 2;
+                       regs->psw.addr -= regs->ilc;
+               }
+               /* Restart the system call with a new system call number */
+               if (regs->gprs[2] == -ERESTART_RESTARTBLOCK) {
+                       regs->gprs[2] = __NR_restart_syscall;
+                       set_thread_flag(TIF_RESTART_SVC);
                }
        }
        return 0;
index 5c2e6861c5c3bc84b8dc6c5391ccd4ad04386d1d..79f75d3383efb7735d5986cc49c2533bb197c294 100644 (file)
@@ -45,8 +45,9 @@ SP_R15       =  STACK_FRAME_OVERHEAD + PT_GPR15
 SP_AREGS     =  STACK_FRAME_OVERHEAD + PT_ACR0
 SP_ORIG_R2   =  STACK_FRAME_OVERHEAD + PT_ORIGGPR2
 /* Now the additional entries */
-SP_TRAP      =  (SP_ORIG_R2+GPR_SIZE)
-SP_SIZE      =  (SP_TRAP+4)
+SP_ILC       =  (SP_ORIG_R2+GPR_SIZE)
+SP_TRAP      =  (SP_ILC+2)
+SP_SIZE      =  (SP_TRAP+2)
 
 _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_RESTART_SVC)
 _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED)
@@ -98,7 +99,8 @@ entry_base:
         stam    %a0,%a15,SP_AREGS(%r15)   # store access registers to kst.
         mvc     SP_AREGS+8(12,%r15),__LC_SAVE_AREA+12 # store ac. regs
         mvc     SP_PSW(8,%r15),\psworg    # move user PSW to stack
-       mvc     SP_TRAP(4,%r15),BASED(.L\psworg) # store trap indication
+       mvc     SP_ILC(2,%r15),__LC_SVC_ILC      # store instruction length
+       mvc     SP_TRAP(2,%r15),BASED(.L\psworg) # store trap indication
         xc      0(4,%r15),0(%r15)         # clear back chain
         .endm
 
@@ -670,11 +672,11 @@ restart_go:
 .Lc_pactive:   .long  PREEMPT_ACTIVE
 .Lc0xff:       .long  0xff
 .Lnr_syscalls: .long  NR_syscalls
-.L0x018:       .long  0x018
-.L0x020:       .long  0x020
-.L0x028:       .long  0x028
-.L0x030:       .long  0x030
-.L0x038:       .long  0x038
+.L0x018:       .word  0x018
+.L0x020:       .word  0x020
+.L0x028:       .word  0x028
+.L0x030:       .word  0x030
+.L0x038:       .word  0x038
 
 /*
  * Symbol constants
index 8140fdf2a9844ab5b8e6527457b2a1dfba85088c..ebeec5dd463613139133d293b4f24b4a5f672cda 100644 (file)
@@ -45,8 +45,9 @@ SP_R15       =  STACK_FRAME_OVERHEAD + PT_GPR15
 SP_AREGS     =  STACK_FRAME_OVERHEAD + PT_ACR0
 SP_ORIG_R2   =  STACK_FRAME_OVERHEAD + PT_ORIGGPR2
 /* Now the additional entries */
-SP_TRAP      =  (SP_ORIG_R2+GPR_SIZE)
-SP_SIZE      =  (SP_TRAP+4)
+SP_ILC       =  (SP_ORIG_R2+GPR_SIZE)
+SP_TRAP      =  (SP_ILC+2)
+SP_SIZE      =  (SP_TRAP+2)
 
 _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_RESTART_SVC)
 _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED)
@@ -86,7 +87,8 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED)
         stam    %a0,%a15,SP_AREGS(%r15)  # store access registers to kst.
         mvc     SP_AREGS+8(12,%r15),__LC_SAVE_AREA+16 # store ac. regs
         mvc     SP_PSW(16,%r15),\psworg  # move user PSW to stack
-       mvc     SP_TRAP(4,%r15),.L\psworg-.Lconst(%r14) # store trap ind.
+       mvc     SP_ILC(2,%r15),__LC_SVC_ILC # store instruction length
+       mvc     SP_TRAP(2,%r15),.L\psworg-.Lconst(%r14) # store trap ind.
         xc      0(8,%r15),0(%r15)        # clear back chain
         .endm
 
@@ -690,9 +692,9 @@ restart_go:
 .Lconst:
 .Lc_ac:        .long  0,0,1
 .Lc_pactive:   .long  PREEMPT_ACTIVE
-.L0x0130:      .long  0x0130
-.L0x0140:      .long  0x0140
-.L0x0150:      .long  0x0150
-.L0x0160:      .long  0x0160
-.L0x0170:      .long  0x0170
+.L0x0130:      .word  0x0130
+.L0x0140:      .word  0x0140
+.L0x0150:      .word  0x0150
+.L0x0160:      .word  0x0160
+.L0x0170:      .word  0x0170
 .Lnr_syscalls: .long  NR_syscalls
index d162702ef65835da329adc75b93d6f586f4881d8..94696fca669db9a24adafb723b73fb25e68bf98b 100644 (file)
@@ -418,7 +418,7 @@ handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
                        /* fallthrough */
                        case -ERESTARTNOINTR:
                                regs->gprs[2] = regs->orig_gpr2;
-                               regs->psw.addr -= 2;
+                               regs->psw.addr -= regs->ilc;
                }
        }
 
@@ -487,7 +487,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
                    regs->gprs[2] == -ERESTARTSYS ||
                    regs->gprs[2] == -ERESTARTNOINTR) {
                        regs->gprs[2] = regs->orig_gpr2;
-                       regs->psw.addr -= 2;
+                       regs->psw.addr -= regs->ilc;
                }
                /* Restart the system call with a new system call number */
                if (regs->gprs[2] == -ERESTART_RESTARTBLOCK) {
index 36d77a6fe7e0c97b9d339ae69ba8c9b02a83ef0f..4169b15a9a99249894ae9743ea5e118d14053867 100644 (file)
@@ -301,7 +301,8 @@ struct pt_regs
        unsigned long gprs[NUM_GPRS];
        unsigned int  acrs[NUM_ACRS];
        unsigned long orig_gpr2;
-       unsigned int  trap;
+       unsigned short ilc;
+       unsigned short trap;
 } __attribute__ ((packed));
 
 /*