Commit b18c1e47 authored by Martin Schwidefsky's avatar Martin Schwidefsky Committed by Linus Torvalds

[PATCH] s390: system call restart bug.

Fix restarting of system calls done by use of the execute instruction.
parent 04886c76
...@@ -579,7 +579,7 @@ handle_signal32(unsigned long sig, siginfo_t *info, sigset_t *oldset, ...@@ -579,7 +579,7 @@ handle_signal32(unsigned long sig, siginfo_t *info, sigset_t *oldset,
/* fallthrough */ /* fallthrough */
case -ERESTARTNOINTR: case -ERESTARTNOINTR:
regs->gprs[2] = regs->orig_gpr2; 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) ...@@ -641,7 +641,12 @@ int do_signal32(struct pt_regs *regs, sigset_t *oldset)
regs->gprs[2] == -ERESTARTSYS || regs->gprs[2] == -ERESTARTSYS ||
regs->gprs[2] == -ERESTARTNOINTR) { regs->gprs[2] == -ERESTARTNOINTR) {
regs->gprs[2] = regs->orig_gpr2; 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; return 0;
......
...@@ -45,8 +45,9 @@ SP_R15 = STACK_FRAME_OVERHEAD + PT_GPR15 ...@@ -45,8 +45,9 @@ SP_R15 = STACK_FRAME_OVERHEAD + PT_GPR15
SP_AREGS = STACK_FRAME_OVERHEAD + PT_ACR0 SP_AREGS = STACK_FRAME_OVERHEAD + PT_ACR0
SP_ORIG_R2 = STACK_FRAME_OVERHEAD + PT_ORIGGPR2 SP_ORIG_R2 = STACK_FRAME_OVERHEAD + PT_ORIGGPR2
/* Now the additional entries */ /* Now the additional entries */
SP_TRAP = (SP_ORIG_R2+GPR_SIZE) SP_ILC = (SP_ORIG_R2+GPR_SIZE)
SP_SIZE = (SP_TRAP+4) SP_TRAP = (SP_ILC+2)
SP_SIZE = (SP_TRAP+2)
_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_RESTART_SVC) _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_RESTART_SVC)
_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED) _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED)
...@@ -98,7 +99,8 @@ entry_base: ...@@ -98,7 +99,8 @@ entry_base:
stam %a0,%a15,SP_AREGS(%r15) # store access registers to kst. 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_AREGS+8(12,%r15),__LC_SAVE_AREA+12 # store ac. regs
mvc SP_PSW(8,%r15),\psworg # move user PSW to stack 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 xc 0(4,%r15),0(%r15) # clear back chain
.endm .endm
...@@ -670,11 +672,11 @@ restart_go: ...@@ -670,11 +672,11 @@ restart_go:
.Lc_pactive: .long PREEMPT_ACTIVE .Lc_pactive: .long PREEMPT_ACTIVE
.Lc0xff: .long 0xff .Lc0xff: .long 0xff
.Lnr_syscalls: .long NR_syscalls .Lnr_syscalls: .long NR_syscalls
.L0x018: .long 0x018 .L0x018: .word 0x018
.L0x020: .long 0x020 .L0x020: .word 0x020
.L0x028: .long 0x028 .L0x028: .word 0x028
.L0x030: .long 0x030 .L0x030: .word 0x030
.L0x038: .long 0x038 .L0x038: .word 0x038
/* /*
* Symbol constants * Symbol constants
......
...@@ -45,8 +45,9 @@ SP_R15 = STACK_FRAME_OVERHEAD + PT_GPR15 ...@@ -45,8 +45,9 @@ SP_R15 = STACK_FRAME_OVERHEAD + PT_GPR15
SP_AREGS = STACK_FRAME_OVERHEAD + PT_ACR0 SP_AREGS = STACK_FRAME_OVERHEAD + PT_ACR0
SP_ORIG_R2 = STACK_FRAME_OVERHEAD + PT_ORIGGPR2 SP_ORIG_R2 = STACK_FRAME_OVERHEAD + PT_ORIGGPR2
/* Now the additional entries */ /* Now the additional entries */
SP_TRAP = (SP_ORIG_R2+GPR_SIZE) SP_ILC = (SP_ORIG_R2+GPR_SIZE)
SP_SIZE = (SP_TRAP+4) SP_TRAP = (SP_ILC+2)
SP_SIZE = (SP_TRAP+2)
_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_RESTART_SVC) _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_RESTART_SVC)
_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED) _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED)
...@@ -86,7 +87,8 @@ _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. 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_AREGS+8(12,%r15),__LC_SAVE_AREA+16 # store ac. regs
mvc SP_PSW(16,%r15),\psworg # move user PSW to stack 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 xc 0(8,%r15),0(%r15) # clear back chain
.endm .endm
...@@ -690,9 +692,9 @@ restart_go: ...@@ -690,9 +692,9 @@ restart_go:
.Lconst: .Lconst:
.Lc_ac: .long 0,0,1 .Lc_ac: .long 0,0,1
.Lc_pactive: .long PREEMPT_ACTIVE .Lc_pactive: .long PREEMPT_ACTIVE
.L0x0130: .long 0x0130 .L0x0130: .word 0x0130
.L0x0140: .long 0x0140 .L0x0140: .word 0x0140
.L0x0150: .long 0x0150 .L0x0150: .word 0x0150
.L0x0160: .long 0x0160 .L0x0160: .word 0x0160
.L0x0170: .long 0x0170 .L0x0170: .word 0x0170
.Lnr_syscalls: .long NR_syscalls .Lnr_syscalls: .long NR_syscalls
...@@ -418,7 +418,7 @@ handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset, ...@@ -418,7 +418,7 @@ handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
/* fallthrough */ /* fallthrough */
case -ERESTARTNOINTR: case -ERESTARTNOINTR:
regs->gprs[2] = regs->orig_gpr2; 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) ...@@ -487,7 +487,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
regs->gprs[2] == -ERESTARTSYS || regs->gprs[2] == -ERESTARTSYS ||
regs->gprs[2] == -ERESTARTNOINTR) { regs->gprs[2] == -ERESTARTNOINTR) {
regs->gprs[2] = regs->orig_gpr2; 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 */ /* Restart the system call with a new system call number */
if (regs->gprs[2] == -ERESTART_RESTARTBLOCK) { if (regs->gprs[2] == -ERESTART_RESTARTBLOCK) {
......
...@@ -301,7 +301,8 @@ struct pt_regs ...@@ -301,7 +301,8 @@ struct pt_regs
unsigned long gprs[NUM_GPRS]; unsigned long gprs[NUM_GPRS];
unsigned int acrs[NUM_ACRS]; unsigned int acrs[NUM_ACRS];
unsigned long orig_gpr2; unsigned long orig_gpr2;
unsigned int trap; unsigned short ilc;
unsigned short trap;
} __attribute__ ((packed)); } __attribute__ ((packed));
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment