]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/suse-2.6.27.31/patches.trace/s390-syscall-get-nr.diff
Add a patch to fix Intel E100 wake-on-lan problems.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.trace / s390-syscall-get-nr.diff
1 Subject: [PATCH] fix syscall_get_nr.
2
3 From: Martin Schwidefsky <schwidefsky@de.ibm.com>
4
5 syscall_get_nr() currently returns a valid result only if the call
6 chain of the traced process includes do_syscall_trace_enter(). But
7 collect_syscall() can be called for any sleeping task, the result of
8 syscall_get_nr() in general is completely bogus.
9
10 To make syscall_get_nr() work for any sleeping task the traps field
11 in pt_regs is replace with svcnr - the system call number the process
12 is executing. If svcnr == 0 the process is not on a system call path.
13
14 Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
15 Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
16 Acked-by: John Jolly <jjolly@novell.com>
17 ---
18
19 arch/s390/include/asm/ptrace.h | 2 +-
20 arch/s390/include/asm/syscall.h | 4 +---
21 arch/s390/kernel/asm-offsets.c | 2 +-
22 arch/s390/kernel/compat_signal.c | 2 +-
23 arch/s390/kernel/entry.S | 21 +++++++++++----------
24 arch/s390/kernel/entry64.S | 23 ++++++++++-------------
25 arch/s390/kernel/ptrace.c | 2 +-
26 arch/s390/kernel/signal.c | 6 +++---
27 8 files changed, 29 insertions(+), 33 deletions(-)
28
29 --- a/arch/s390/include/asm/ptrace.h
30 +++ b/arch/s390/include/asm/ptrace.h
31 @@ -321,8 +321,8 @@ struct pt_regs
32 psw_t psw;
33 unsigned long gprs[NUM_GPRS];
34 unsigned long orig_gpr2;
35 + unsigned short svcnr;
36 unsigned short ilc;
37 - unsigned short trap;
38 };
39 #endif
40
41 --- a/arch/s390/include/asm/syscall.h
42 +++ b/arch/s390/include/asm/syscall.h
43 @@ -17,9 +17,7 @@
44 static inline long syscall_get_nr(struct task_struct *task,
45 struct pt_regs *regs)
46 {
47 - if (regs->trap != __LC_SVC_OLD_PSW)
48 - return -1;
49 - return regs->gprs[2];
50 + return regs->svcnr ? regs->svcnr : -1;
51 }
52
53 static inline void syscall_rollback(struct task_struct *task,
54 --- a/arch/s390/kernel/asm-offsets.c
55 +++ b/arch/s390/kernel/asm-offsets.c
56 @@ -32,7 +32,7 @@ int main(void)
57 DEFINE(__PT_GPRS, offsetof(struct pt_regs, gprs));
58 DEFINE(__PT_ORIG_GPR2, offsetof(struct pt_regs, orig_gpr2));
59 DEFINE(__PT_ILC, offsetof(struct pt_regs, ilc));
60 - DEFINE(__PT_TRAP, offsetof(struct pt_regs, trap));
61 + DEFINE(__PT_SVCNR, offsetof(struct pt_regs, svcnr));
62 DEFINE(__PT_SIZE, sizeof(struct pt_regs));
63 BLANK();
64 DEFINE(__SF_BACKCHAIN, offsetof(struct stack_frame, back_chain));
65 --- a/arch/s390/kernel/compat_signal.c
66 +++ b/arch/s390/kernel/compat_signal.c
67 @@ -340,7 +340,7 @@ static int restore_sigregs32(struct pt_r
68 return err;
69
70 restore_fp_regs(&current->thread.fp_regs);
71 - regs->trap = -1; /* disable syscall checks */
72 + regs->svcnr = 0; /* disable syscall checks */
73 return 0;
74 }
75
76 --- a/arch/s390/kernel/entry64.S
77 +++ b/arch/s390/kernel/entry64.S
78 @@ -46,7 +46,7 @@ SP_R14 = STACK_FRAME_OVERHEAD + __P
79 SP_R15 = STACK_FRAME_OVERHEAD + __PT_GPRS + 120
80 SP_ORIG_R2 = STACK_FRAME_OVERHEAD + __PT_ORIG_GPR2
81 SP_ILC = STACK_FRAME_OVERHEAD + __PT_ILC
82 -SP_TRAP = STACK_FRAME_OVERHEAD + __PT_TRAP
83 +SP_SVCNR = STACK_FRAME_OVERHEAD + __PT_SVCNR
84 SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE
85
86 STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER
87 @@ -168,11 +168,10 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_
88 .macro CREATE_STACK_FRAME psworg,savearea
89 aghi %r15,-SP_SIZE # make room for registers & psw
90 mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack
91 - la %r12,\psworg
92 stg %r2,SP_ORIG_R2(%r15) # store original content of gpr 2
93 - icm %r12,12,__LC_SVC_ILC
94 + icm %r12,3,__LC_SVC_ILC
95 stmg %r0,%r11,SP_R0(%r15) # store gprs %r0-%r11 to kernel stack
96 - st %r12,SP_ILC(%r15)
97 + st %r12,SP_SVCNR(%r15)
98 mvc SP_R12(32,%r15),\savearea # move %r12-%r15 to stack
99 la %r12,0
100 stg %r12,__SF_BACKCHAIN(%r15)
101 @@ -247,16 +246,17 @@ sysc_update:
102 #endif
103 sysc_do_svc:
104 lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
105 - slag %r7,%r7,2 # *4 and test for svc 0
106 + ltgr %r7,%r7 # test for svc 0
107 jnz sysc_nr_ok
108 # svc 0: system call number in %r1
109 cl %r1,BASED(.Lnr_syscalls)
110 jnl sysc_nr_ok
111 lgfr %r7,%r1 # clear high word in r1
112 - slag %r7,%r7,2 # svc 0: system call number in %r1
113 sysc_nr_ok:
114 mvc SP_ARGS(8,%r15),SP_R7(%r15)
115 sysc_do_restart:
116 + sth %r7,SP_SVCNR(%r15)
117 + sllg %r7,%r7,2 # svc number * 4
118 larl %r10,sys_call_table
119 #ifdef CONFIG_COMPAT
120 tm __TI_flags+5(%r9),(_TIF_31BIT>>16) # running in 31 bit mode ?
121 @@ -360,7 +360,6 @@ sysc_notify_resume:
122 sysc_restart:
123 ni __TI_flags+7(%r9),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC
124 lg %r7,SP_R2(%r15) # load new svc number
125 - slag %r7,%r7,2 # *4
126 mvc SP_R2(8,%r15),SP_ORIG_R2(%r15) # restore first argument
127 lmg %r2,%r6,SP_R2(%r15) # load svc arguments
128 j sysc_do_restart # restart svc
129 @@ -369,9 +368,8 @@ sysc_restart:
130 # _TIF_SINGLE_STEP is set, call do_single_step
131 #
132 sysc_singlestep:
133 - ni __TI_flags+7(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP
134 - lhi %r0,__LC_PGM_OLD_PSW
135 - sth %r0,SP_TRAP(%r15) # set trap indication to pgm check
136 + ni __TI_flags+7(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP
137 + xc SP_SVCNR(2,%r15),SP_SVCNR(%r15) # clear svc number
138 la %r2,SP_PTREGS(%r15) # address of register-save area
139 larl %r14,sysc_return # load adr. of system return
140 jg do_single_step # branch to do_sigtrap
141 @@ -389,7 +387,7 @@ sysc_tracesys:
142 lghi %r0,NR_syscalls
143 clgr %r0,%r2
144 jnh sysc_tracenogo
145 - slag %r7,%r2,2 # *4
146 + sllg %r7,%r2,2 # svc number *4
147 lgf %r8,0(%r7,%r10)
148 sysc_tracego:
149 lmg %r3,%r6,SP_R3(%r15)
150 @@ -564,8 +562,7 @@ pgm_svcper:
151 # per was called from kernel, must be kprobes
152 #
153 kernel_per:
154 - lhi %r0,__LC_PGM_OLD_PSW
155 - sth %r0,SP_TRAP(%r15) # set trap indication to pgm check
156 + xc SP_SVCNR(2,%r15),SP_SVCNR(%r15) # clear svc number
157 la %r2,SP_PTREGS(%r15) # address of register-save area
158 larl %r14,sysc_restore # load adr. of system ret, no work
159 jg do_single_step # branch to do_single_step
160 --- a/arch/s390/kernel/entry.S
161 +++ b/arch/s390/kernel/entry.S
162 @@ -46,7 +46,7 @@ SP_R14 = STACK_FRAME_OVERHEAD + __P
163 SP_R15 = STACK_FRAME_OVERHEAD + __PT_GPRS + 60
164 SP_ORIG_R2 = STACK_FRAME_OVERHEAD + __PT_ORIG_GPR2
165 SP_ILC = STACK_FRAME_OVERHEAD + __PT_ILC
166 -SP_TRAP = STACK_FRAME_OVERHEAD + __PT_TRAP
167 +SP_SVCNR = STACK_FRAME_OVERHEAD + __PT_SVCNR
168 SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE
169
170 _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
171 @@ -180,11 +180,10 @@ STACK_SIZE = 1 << STACK_SHIFT
172 .macro CREATE_STACK_FRAME psworg,savearea
173 s %r15,BASED(.Lc_spsize) # make room for registers & psw
174 mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack
175 - la %r12,\psworg
176 st %r2,SP_ORIG_R2(%r15) # store original content of gpr 2
177 - icm %r12,12,__LC_SVC_ILC
178 + icm %r12,3,__LC_SVC_ILC
179 stm %r0,%r11,SP_R0(%r15) # store gprs %r0-%r11 to kernel stack
180 - st %r12,SP_ILC(%r15)
181 + st %r12,SP_SVCNR(%r15)
182 mvc SP_R12(16,%r15),\savearea # move %r12-%r15 to stack
183 la %r12,0
184 st %r12,__SF_BACKCHAIN(%r15) # clear back chain
185 @@ -261,16 +260,17 @@ sysc_update:
186 #endif
187 sysc_do_svc:
188 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
189 - sla %r7,2 # *4 and test for svc 0
190 + ltr %r7,%r7 # test for svc 0
191 bnz BASED(sysc_nr_ok) # svc number > 0
192 # svc 0: system call number in %r1
193 cl %r1,BASED(.Lnr_syscalls)
194 bnl BASED(sysc_nr_ok)
195 lr %r7,%r1 # copy svc number to %r7
196 - sla %r7,2 # *4
197 sysc_nr_ok:
198 mvc SP_ARGS(4,%r15),SP_R7(%r15)
199 sysc_do_restart:
200 + sth %r7,SP_SVCNR(%r15)
201 + sll %r7,2 # svc number *4
202 l %r8,BASED(.Lsysc_table)
203 tm __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
204 l %r8,0(%r7,%r8) # get system call addr.
205 @@ -373,7 +373,6 @@ sysc_notify_resume:
206 sysc_restart:
207 ni __TI_flags+3(%r9),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC
208 l %r7,SP_R2(%r15) # load new svc number
209 - sla %r7,2
210 mvc SP_R2(4,%r15),SP_ORIG_R2(%r15) # restore first argument
211 lm %r2,%r6,SP_R2(%r15) # load svc arguments
212 b BASED(sysc_do_restart) # restart svc
213 @@ -383,7 +382,8 @@ sysc_restart:
214 #
215 sysc_singlestep:
216 ni __TI_flags+3(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP
217 - mvi SP_TRAP+1(%r15),0x28 # set trap indication to pgm check
218 + mvi SP_SVCNR(%r15),0xff # set trap indication to pgm check
219 + mvi SP_SVCNR+1(%r15),0xff
220 la %r2,SP_PTREGS(%r15) # address of register-save area
221 l %r1,BASED(.Lhandle_per) # load adr. of per handler
222 la %r14,BASED(sysc_return) # load adr. of system return
223 @@ -404,7 +404,7 @@ sysc_tracesys:
224 bnl BASED(sysc_tracenogo)
225 l %r8,BASED(.Lsysc_table)
226 lr %r7,%r2
227 - sll %r7,2 # *4
228 + sll %r7,2 # svc number *4
229 l %r8,0(%r7,%r8)
230 sysc_tracego:
231 lm %r3,%r6,SP_R3(%r15)
232 @@ -583,7 +583,8 @@ pgm_svcper:
233 # per was called from kernel, must be kprobes
234 #
235 kernel_per:
236 - mvi SP_TRAP+1(%r15),0x28 # set trap indication to pgm check
237 + mvi SP_SVCNR(%r15),0xff # set trap indication to pgm check
238 + mvi SP_SVCNR+1(%r15),0xff
239 la %r2,SP_PTREGS(%r15) # address of register-save area
240 l %r1,BASED(.Lhandle_per) # load adr. of per handler
241 la %r14,BASED(sysc_restore)# load adr. of system return
242 --- a/arch/s390/kernel/ptrace.c
243 +++ b/arch/s390/kernel/ptrace.c
244 @@ -671,7 +671,7 @@ asmlinkage long do_syscall_trace_enter(s
245 * debugger stored an invalid system call number. Skip
246 * the system call and the system call restart handling.
247 */
248 - regs->trap = -1;
249 + regs->svcnr = 0;
250 ret = -1;
251 }
252
253 --- a/arch/s390/kernel/signal.c
254 +++ b/arch/s390/kernel/signal.c
255 @@ -157,7 +157,7 @@ static int restore_sigregs(struct pt_reg
256 current->thread.fp_regs.fpc &= FPC_VALID_MASK;
257
258 restore_fp_regs(&current->thread.fp_regs);
259 - regs->trap = -1; /* disable syscall checks */
260 + regs->svcnr = 0; /* disable syscall checks */
261 return 0;
262 }
263
264 @@ -442,7 +442,7 @@ void do_signal(struct pt_regs *regs)
265 oldset = &current->blocked;
266
267 /* Are we from a system call? */
268 - if (regs->trap == __LC_SVC_OLD_PSW) {
269 + if (regs->svcnr) {
270 continue_addr = regs->psw.addr;
271 restart_addr = continue_addr - regs->ilc;
272 retval = regs->gprs[2];
273 @@ -459,7 +459,7 @@ void do_signal(struct pt_regs *regs)
274 case -ERESTART_RESTARTBLOCK:
275 regs->gprs[2] = -EINTR;
276 }
277 - regs->trap = -1; /* Don't deal with this again. */
278 + regs->svcnr = 0; /* Don't deal with this again. */
279 }
280
281 /* Get signal to deliver. When running under ptrace, at this point