aboutsummaryrefslogtreecommitdiffstats
path: root/arch/frv/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/frv/kernel')
-rw-r--r--arch/frv/kernel/Makefile1
-rw-r--r--arch/frv/kernel/entry.S2
-rw-r--r--arch/frv/kernel/futex.c242
-rw-r--r--arch/frv/kernel/signal.c155
4 files changed, 329 insertions, 71 deletions
diff --git a/arch/frv/kernel/Makefile b/arch/frv/kernel/Makefile
index 981c2c7dec0d..422f30ede575 100644
--- a/arch/frv/kernel/Makefile
+++ b/arch/frv/kernel/Makefile
@@ -20,3 +20,4 @@ obj-$(CONFIG_FUJITSU_MB93493) += irq-mb93493.o
20obj-$(CONFIG_PM) += pm.o cmode.o 20obj-$(CONFIG_PM) += pm.o cmode.o
21obj-$(CONFIG_MB93093_PDK) += pm-mb93093.o 21obj-$(CONFIG_MB93093_PDK) += pm-mb93093.o
22obj-$(CONFIG_SYSCTL) += sysctl.o 22obj-$(CONFIG_SYSCTL) += sysctl.o
23obj-$(CONFIG_FUTEX) += futex.o
diff --git a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S
index ad10ea595459..5f6548388b74 100644
--- a/arch/frv/kernel/entry.S
+++ b/arch/frv/kernel/entry.S
@@ -1076,7 +1076,7 @@ __entry_work_notifysig:
1076 LEDS 0x6410 1076 LEDS 0x6410
1077 ori.p gr4,#0,gr8 1077 ori.p gr4,#0,gr8
1078 call do_notify_resume 1078 call do_notify_resume
1079 bra __entry_return_direct 1079 bra __entry_resume_userspace
1080 1080
1081 # perform syscall entry tracing 1081 # perform syscall entry tracing
1082__syscall_trace_entry: 1082__syscall_trace_entry:
diff --git a/arch/frv/kernel/futex.c b/arch/frv/kernel/futex.c
new file mode 100644
index 000000000000..eae874a970c6
--- /dev/null
+++ b/arch/frv/kernel/futex.c
@@ -0,0 +1,242 @@
1/* futex.c: futex operations
2 *
3 * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#include <linux/futex.h>
13#include <asm/futex.h>
14#include <asm/errno.h>
15#include <asm/uaccess.h>
16
17/*
18 * the various futex operations; MMU fault checking is ignored under no-MMU
19 * conditions
20 */
21static inline int atomic_futex_op_xchg_set(int oparg, int __user *uaddr, int *_oldval)
22{
23 int oldval, ret;
24
25 asm("0: \n"
26 " orcc gr0,gr0,gr0,icc3 \n" /* set ICC3.Z */
27 " ckeq icc3,cc7 \n"
28 "1: ld.p %M0,%1 \n" /* LD.P/ORCR must be atomic */
29 " orcr cc7,cc7,cc3 \n" /* set CC3 to true */
30 "2: cst.p %3,%M0 ,cc3,#1 \n"
31 " corcc gr29,gr29,gr0 ,cc3,#1 \n" /* clear ICC3.Z if store happens */
32 " beq icc3,#0,0b \n"
33 " setlos 0,%2 \n"
34 "3: \n"
35 ".subsection 2 \n"
36 "4: setlos %5,%2 \n"
37 " bra 3b \n"
38 ".previous \n"
39 ".section __ex_table,\"a\" \n"
40 " .balign 8 \n"
41 " .long 1b,4b \n"
42 " .long 2b,4b \n"
43 ".previous"
44 : "+U"(*uaddr), "=&r"(oldval), "=&r"(ret), "=r"(oparg)
45 : "3"(oparg), "i"(-EFAULT)
46 : "memory", "cc7", "cc3", "icc3"
47 );
48
49 *_oldval = oldval;
50 return ret;
51}
52
53static inline int atomic_futex_op_xchg_add(int oparg, int __user *uaddr, int *_oldval)
54{
55 int oldval, ret;
56
57 asm("0: \n"
58 " orcc gr0,gr0,gr0,icc3 \n" /* set ICC3.Z */
59 " ckeq icc3,cc7 \n"
60 "1: ld.p %M0,%1 \n" /* LD.P/ORCR must be atomic */
61 " orcr cc7,cc7,cc3 \n" /* set CC3 to true */
62 " add %1,%3,%3 \n"
63 "2: cst.p %3,%M0 ,cc3,#1 \n"
64 " corcc gr29,gr29,gr0 ,cc3,#1 \n" /* clear ICC3.Z if store happens */
65 " beq icc3,#0,0b \n"
66 " setlos 0,%2 \n"
67 "3: \n"
68 ".subsection 2 \n"
69 "4: setlos %5,%2 \n"
70 " bra 3b \n"
71 ".previous \n"
72 ".section __ex_table,\"a\" \n"
73 " .balign 8 \n"
74 " .long 1b,4b \n"
75 " .long 2b,4b \n"
76 ".previous"
77 : "+U"(*uaddr), "=&r"(oldval), "=&r"(ret), "=r"(oparg)
78 : "3"(oparg), "i"(-EFAULT)
79 : "memory", "cc7", "cc3", "icc3"
80 );
81
82 *_oldval = oldval;
83 return ret;
84}
85
86static inline int atomic_futex_op_xchg_or(int oparg, int __user *uaddr, int *_oldval)
87{
88 int oldval, ret;
89
90 asm("0: \n"
91 " orcc gr0,gr0,gr0,icc3 \n" /* set ICC3.Z */
92 " ckeq icc3,cc7 \n"
93 "1: ld.p %M0,%1 \n" /* LD.P/ORCR must be atomic */
94 " orcr cc7,cc7,cc3 \n" /* set CC3 to true */
95 " or %1,%3,%3 \n"
96 "2: cst.p %3,%M0 ,cc3,#1 \n"
97 " corcc gr29,gr29,gr0 ,cc3,#1 \n" /* clear ICC3.Z if store happens */
98 " beq icc3,#0,0b \n"
99 " setlos 0,%2 \n"
100 "3: \n"
101 ".subsection 2 \n"
102 "4: setlos %5,%2 \n"
103 " bra 3b \n"
104 ".previous \n"
105 ".section __ex_table,\"a\" \n"
106 " .balign 8 \n"
107 " .long 1b,4b \n"
108 " .long 2b,4b \n"
109 ".previous"
110 : "+U"(*uaddr), "=&r"(oldval), "=&r"(ret), "=r"(oparg)
111 : "3"(oparg), "i"(-EFAULT)
112 : "memory", "cc7", "cc3", "icc3"
113 );
114
115 *_oldval = oldval;
116 return ret;
117}
118
119static inline int atomic_futex_op_xchg_and(int oparg, int __user *uaddr, int *_oldval)
120{
121 int oldval, ret;
122
123 asm("0: \n"
124 " orcc gr0,gr0,gr0,icc3 \n" /* set ICC3.Z */
125 " ckeq icc3,cc7 \n"
126 "1: ld.p %M0,%1 \n" /* LD.P/ORCR must be atomic */
127 " orcr cc7,cc7,cc3 \n" /* set CC3 to true */
128 " and %1,%3,%3 \n"
129 "2: cst.p %3,%M0 ,cc3,#1 \n"
130 " corcc gr29,gr29,gr0 ,cc3,#1 \n" /* clear ICC3.Z if store happens */
131 " beq icc3,#0,0b \n"
132 " setlos 0,%2 \n"
133 "3: \n"
134 ".subsection 2 \n"
135 "4: setlos %5,%2 \n"
136 " bra 3b \n"
137 ".previous \n"
138 ".section __ex_table,\"a\" \n"
139 " .balign 8 \n"
140 " .long 1b,4b \n"
141 " .long 2b,4b \n"
142 ".previous"
143 : "+U"(*uaddr), "=&r"(oldval), "=&r"(ret), "=r"(oparg)
144 : "3"(oparg), "i"(-EFAULT)
145 : "memory", "cc7", "cc3", "icc3"
146 );
147
148 *_oldval = oldval;
149 return ret;
150}
151
152static inline int atomic_futex_op_xchg_xor(int oparg, int __user *uaddr, int *_oldval)
153{
154 int oldval, ret;
155
156 asm("0: \n"
157 " orcc gr0,gr0,gr0,icc3 \n" /* set ICC3.Z */
158 " ckeq icc3,cc7 \n"
159 "1: ld.p %M0,%1 \n" /* LD.P/ORCR must be atomic */
160 " orcr cc7,cc7,cc3 \n" /* set CC3 to true */
161 " xor %1,%3,%3 \n"
162 "2: cst.p %3,%M0 ,cc3,#1 \n"
163 " corcc gr29,gr29,gr0 ,cc3,#1 \n" /* clear ICC3.Z if store happens */
164 " beq icc3,#0,0b \n"
165 " setlos 0,%2 \n"
166 "3: \n"
167 ".subsection 2 \n"
168 "4: setlos %5,%2 \n"
169 " bra 3b \n"
170 ".previous \n"
171 ".section __ex_table,\"a\" \n"
172 " .balign 8 \n"
173 " .long 1b,4b \n"
174 " .long 2b,4b \n"
175 ".previous"
176 : "+U"(*uaddr), "=&r"(oldval), "=&r"(ret), "=r"(oparg)
177 : "3"(oparg), "i"(-EFAULT)
178 : "memory", "cc7", "cc3", "icc3"
179 );
180
181 *_oldval = oldval;
182 return ret;
183}
184
185/*****************************************************************************/
186/*
187 * do the futex operations
188 */
189int futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
190{
191 int op = (encoded_op >> 28) & 7;
192 int cmp = (encoded_op >> 24) & 15;
193 int oparg = (encoded_op << 8) >> 20;
194 int cmparg = (encoded_op << 20) >> 20;
195 int oldval = 0, ret;
196
197 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
198 oparg = 1 << oparg;
199
200 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
201 return -EFAULT;
202
203 inc_preempt_count();
204
205 switch (op) {
206 case FUTEX_OP_SET:
207 ret = atomic_futex_op_xchg_set(oparg, uaddr, &oldval);
208 break;
209 case FUTEX_OP_ADD:
210 ret = atomic_futex_op_xchg_add(oparg, uaddr, &oldval);
211 break;
212 case FUTEX_OP_OR:
213 ret = atomic_futex_op_xchg_or(oparg, uaddr, &oldval);
214 break;
215 case FUTEX_OP_ANDN:
216 ret = atomic_futex_op_xchg_and(~oparg, uaddr, &oldval);
217 break;
218 case FUTEX_OP_XOR:
219 ret = atomic_futex_op_xchg_xor(oparg, uaddr, &oldval);
220 break;
221 default:
222 ret = -ENOSYS;
223 break;
224 }
225
226 dec_preempt_count();
227
228 if (!ret) {
229 switch (cmp) {
230 case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
231 case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
232 case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
233 case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
234 case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
235 case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
236 default: ret = -ENOSYS; break;
237 }
238 }
239
240 return ret;
241
242} /* end futex_atomic_op_inuser() */
diff --git a/arch/frv/kernel/signal.c b/arch/frv/kernel/signal.c
index d4ccc0728dfe..5b7146f54fd5 100644
--- a/arch/frv/kernel/signal.c
+++ b/arch/frv/kernel/signal.c
@@ -35,7 +35,7 @@ struct fdpic_func_descriptor {
35 unsigned long GOT; 35 unsigned long GOT;
36}; 36};
37 37
38asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset); 38static int do_signal(sigset_t *oldset);
39 39
40/* 40/*
41 * Atomically swap in the new signal mask, and wait for a signal. 41 * Atomically swap in the new signal mask, and wait for a signal.
@@ -55,7 +55,7 @@ asmlinkage int sys_sigsuspend(int history0, int history1, old_sigset_t mask)
55 while (1) { 55 while (1) {
56 current->state = TASK_INTERRUPTIBLE; 56 current->state = TASK_INTERRUPTIBLE;
57 schedule(); 57 schedule();
58 if (do_signal(__frame, &saveset)) 58 if (do_signal(&saveset))
59 /* return the signal number as the return value of this function 59 /* return the signal number as the return value of this function
60 * - this is an utterly evil hack. syscalls should not invoke do_signal() 60 * - this is an utterly evil hack. syscalls should not invoke do_signal()
61 * as entry.S sets regs->gr8 to the return value of the system call 61 * as entry.S sets regs->gr8 to the return value of the system call
@@ -91,7 +91,7 @@ asmlinkage int sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize)
91 while (1) { 91 while (1) {
92 current->state = TASK_INTERRUPTIBLE; 92 current->state = TASK_INTERRUPTIBLE;
93 schedule(); 93 schedule();
94 if (do_signal(__frame, &saveset)) 94 if (do_signal(&saveset))
95 /* return the signal number as the return value of this function 95 /* return the signal number as the return value of this function
96 * - this is an utterly evil hack. syscalls should not invoke do_signal() 96 * - this is an utterly evil hack. syscalls should not invoke do_signal()
97 * as entry.S sets regs->gr8 to the return value of the system call 97 * as entry.S sets regs->gr8 to the return value of the system call
@@ -276,13 +276,12 @@ static int setup_sigcontext(struct sigcontext __user *sc, unsigned long mask)
276 * Determine which stack to use.. 276 * Determine which stack to use..
277 */ 277 */
278static inline void __user *get_sigframe(struct k_sigaction *ka, 278static inline void __user *get_sigframe(struct k_sigaction *ka,
279 struct pt_regs *regs,
280 size_t frame_size) 279 size_t frame_size)
281{ 280{
282 unsigned long sp; 281 unsigned long sp;
283 282
284 /* Default to using normal stack */ 283 /* Default to using normal stack */
285 sp = regs->sp; 284 sp = __frame->sp;
286 285
287 /* This is the X/Open sanctioned signal stack switching. */ 286 /* This is the X/Open sanctioned signal stack switching. */
288 if (ka->sa.sa_flags & SA_ONSTACK) { 287 if (ka->sa.sa_flags & SA_ONSTACK) {
@@ -291,18 +290,19 @@ static inline void __user *get_sigframe(struct k_sigaction *ka,
291 } 290 }
292 291
293 return (void __user *) ((sp - frame_size) & ~7UL); 292 return (void __user *) ((sp - frame_size) & ~7UL);
293
294} /* end get_sigframe() */ 294} /* end get_sigframe() */
295 295
296/*****************************************************************************/ 296/*****************************************************************************/
297/* 297/*
298 * 298 *
299 */ 299 */
300static void setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, struct pt_regs * regs) 300static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
301{ 301{
302 struct sigframe __user *frame; 302 struct sigframe __user *frame;
303 int rsig; 303 int rsig;
304 304
305 frame = get_sigframe(ka, regs, sizeof(*frame)); 305 frame = get_sigframe(ka, sizeof(*frame));
306 306
307 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 307 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
308 goto give_sigsegv; 308 goto give_sigsegv;
@@ -346,47 +346,51 @@ static void setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, struct p
346 } 346 }
347 347
348 /* set up registers for signal handler */ 348 /* set up registers for signal handler */
349 regs->sp = (unsigned long) frame; 349 __frame->sp = (unsigned long) frame;
350 regs->lr = (unsigned long) &frame->retcode; 350 __frame->lr = (unsigned long) &frame->retcode;
351 regs->gr8 = sig; 351 __frame->gr8 = sig;
352 352
353 if (get_personality & FDPIC_FUNCPTRS) { 353 if (get_personality & FDPIC_FUNCPTRS) {
354 struct fdpic_func_descriptor __user *funcptr = 354 struct fdpic_func_descriptor __user *funcptr =
355 (struct fdpic_func_descriptor *) ka->sa.sa_handler; 355 (struct fdpic_func_descriptor *) ka->sa.sa_handler;
356 __get_user(regs->pc, &funcptr->text); 356 __get_user(__frame->pc, &funcptr->text);
357 __get_user(regs->gr15, &funcptr->GOT); 357 __get_user(__frame->gr15, &funcptr->GOT);
358 } else { 358 } else {
359 regs->pc = (unsigned long) ka->sa.sa_handler; 359 __frame->pc = (unsigned long) ka->sa.sa_handler;
360 regs->gr15 = 0; 360 __frame->gr15 = 0;
361 } 361 }
362 362
363 set_fs(USER_DS); 363 set_fs(USER_DS);
364 364
365 /* the tracer may want to single-step inside the handler */
366 if (test_thread_flag(TIF_SINGLESTEP))
367 ptrace_notify(SIGTRAP);
368
365#if DEBUG_SIG 369#if DEBUG_SIG
366 printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n", 370 printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
367 sig, current->comm, current->pid, frame, regs->pc, frame->pretcode); 371 sig, current->comm, current->pid, frame, __frame->pc,
372 frame->pretcode);
368#endif 373#endif
369 374
370 return; 375 return 1;
371 376
372give_sigsegv: 377give_sigsegv:
373 if (sig == SIGSEGV)
374 ka->sa.sa_handler = SIG_DFL;
375
376 force_sig(SIGSEGV, current); 378 force_sig(SIGSEGV, current);
379 return 0;
380
377} /* end setup_frame() */ 381} /* end setup_frame() */
378 382
379/*****************************************************************************/ 383/*****************************************************************************/
380/* 384/*
381 * 385 *
382 */ 386 */
383static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 387static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
384 sigset_t *set, struct pt_regs * regs) 388 sigset_t *set)
385{ 389{
386 struct rt_sigframe __user *frame; 390 struct rt_sigframe __user *frame;
387 int rsig; 391 int rsig;
388 392
389 frame = get_sigframe(ka, regs, sizeof(*frame)); 393 frame = get_sigframe(ka, sizeof(*frame));
390 394
391 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 395 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
392 goto give_sigsegv; 396 goto give_sigsegv;
@@ -409,7 +413,7 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
409 if (__put_user(0, &frame->uc.uc_flags) || 413 if (__put_user(0, &frame->uc.uc_flags) ||
410 __put_user(0, &frame->uc.uc_link) || 414 __put_user(0, &frame->uc.uc_link) ||
411 __put_user((void*)current->sas_ss_sp, &frame->uc.uc_stack.ss_sp) || 415 __put_user((void*)current->sas_ss_sp, &frame->uc.uc_stack.ss_sp) ||
412 __put_user(sas_ss_flags(regs->sp), &frame->uc.uc_stack.ss_flags) || 416 __put_user(sas_ss_flags(__frame->sp), &frame->uc.uc_stack.ss_flags) ||
413 __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size)) 417 __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size))
414 goto give_sigsegv; 418 goto give_sigsegv;
415 419
@@ -440,34 +444,38 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
440 } 444 }
441 445
442 /* Set up registers for signal handler */ 446 /* Set up registers for signal handler */
443 regs->sp = (unsigned long) frame; 447 __frame->sp = (unsigned long) frame;
444 regs->lr = (unsigned long) &frame->retcode; 448 __frame->lr = (unsigned long) &frame->retcode;
445 regs->gr8 = sig; 449 __frame->gr8 = sig;
446 regs->gr9 = (unsigned long) &frame->info; 450 __frame->gr9 = (unsigned long) &frame->info;
447 451
448 if (get_personality & FDPIC_FUNCPTRS) { 452 if (get_personality & FDPIC_FUNCPTRS) {
449 struct fdpic_func_descriptor *funcptr = 453 struct fdpic_func_descriptor *funcptr =
450 (struct fdpic_func_descriptor __user *) ka->sa.sa_handler; 454 (struct fdpic_func_descriptor __user *) ka->sa.sa_handler;
451 __get_user(regs->pc, &funcptr->text); 455 __get_user(__frame->pc, &funcptr->text);
452 __get_user(regs->gr15, &funcptr->GOT); 456 __get_user(__frame->gr15, &funcptr->GOT);
453 } else { 457 } else {
454 regs->pc = (unsigned long) ka->sa.sa_handler; 458 __frame->pc = (unsigned long) ka->sa.sa_handler;
455 regs->gr15 = 0; 459 __frame->gr15 = 0;
456 } 460 }
457 461
458 set_fs(USER_DS); 462 set_fs(USER_DS);
459 463
464 /* the tracer may want to single-step inside the handler */
465 if (test_thread_flag(TIF_SINGLESTEP))
466 ptrace_notify(SIGTRAP);
467
460#if DEBUG_SIG 468#if DEBUG_SIG
461 printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n", 469 printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
462 sig, current->comm, current->pid, frame, regs->pc, frame->pretcode); 470 sig, current->comm, current->pid, frame, __frame->pc,
471 frame->pretcode);
463#endif 472#endif
464 473
465 return; 474 return 1;
466 475
467give_sigsegv: 476give_sigsegv:
468 if (sig == SIGSEGV)
469 ka->sa.sa_handler = SIG_DFL;
470 force_sig(SIGSEGV, current); 477 force_sig(SIGSEGV, current);
478 return 0;
471 479
472} /* end setup_rt_frame() */ 480} /* end setup_rt_frame() */
473 481
@@ -475,43 +483,51 @@ give_sigsegv:
475/* 483/*
476 * OK, we're invoking a handler 484 * OK, we're invoking a handler
477 */ 485 */
478static void handle_signal(unsigned long sig, siginfo_t *info, 486static int handle_signal(unsigned long sig, siginfo_t *info,
479 struct k_sigaction *ka, sigset_t *oldset, 487 struct k_sigaction *ka, sigset_t *oldset)
480 struct pt_regs *regs)
481{ 488{
489 int ret;
490
482 /* Are we from a system call? */ 491 /* Are we from a system call? */
483 if (in_syscall(regs)) { 492 if (in_syscall(__frame)) {
484 /* If so, check system call restarting.. */ 493 /* If so, check system call restarting.. */
485 switch (regs->gr8) { 494 switch (__frame->gr8) {
486 case -ERESTART_RESTARTBLOCK: 495 case -ERESTART_RESTARTBLOCK:
487 case -ERESTARTNOHAND: 496 case -ERESTARTNOHAND:
488 regs->gr8 = -EINTR; 497 __frame->gr8 = -EINTR;
489 break; 498 break;
490 499
491 case -ERESTARTSYS: 500 case -ERESTARTSYS:
492 if (!(ka->sa.sa_flags & SA_RESTART)) { 501 if (!(ka->sa.sa_flags & SA_RESTART)) {
493 regs->gr8 = -EINTR; 502 __frame->gr8 = -EINTR;
494 break; 503 break;
495 } 504 }
505
496 /* fallthrough */ 506 /* fallthrough */
497 case -ERESTARTNOINTR: 507 case -ERESTARTNOINTR:
498 regs->gr8 = regs->orig_gr8; 508 __frame->gr8 = __frame->orig_gr8;
499 regs->pc -= 4; 509 __frame->pc -= 4;
500 } 510 }
501 } 511 }
502 512
503 /* Set up the stack frame */ 513 /* Set up the stack frame */
504 if (ka->sa.sa_flags & SA_SIGINFO) 514 if (ka->sa.sa_flags & SA_SIGINFO)
505 setup_rt_frame(sig, ka, info, oldset, regs); 515 ret = setup_rt_frame(sig, ka, info, oldset);
506 else 516 else
507 setup_frame(sig, ka, oldset, regs); 517 ret = setup_frame(sig, ka, oldset);
518
519 if (ret) {
520 spin_lock_irq(&current->sighand->siglock);
521 sigorsets(&current->blocked, &current->blocked,
522 &ka->sa.sa_mask);
523 if (!(ka->sa.sa_flags & SA_NODEFER))
524 sigaddset(&current->blocked, sig);
525 recalc_sigpending();
526 spin_unlock_irq(&current->sighand->siglock);
527 }
528
529 return ret;
508 530
509 spin_lock_irq(&current->sighand->siglock);
510 sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
511 if (!(ka->sa.sa_flags & SA_NODEFER))
512 sigaddset(&current->blocked, sig);
513 recalc_sigpending();
514 spin_unlock_irq(&current->sighand->siglock);
515} /* end handle_signal() */ 531} /* end handle_signal() */
516 532
517/*****************************************************************************/ 533/*****************************************************************************/
@@ -520,7 +536,7 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
520 * want to handle. Thus you cannot kill init even with a SIGKILL even by 536 * want to handle. Thus you cannot kill init even with a SIGKILL even by
521 * mistake. 537 * mistake.
522 */ 538 */
523int do_signal(struct pt_regs *regs, sigset_t *oldset) 539static int do_signal(sigset_t *oldset)
524{ 540{
525 struct k_sigaction ka; 541 struct k_sigaction ka;
526 siginfo_t info; 542 siginfo_t info;
@@ -532,7 +548,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
532 * kernel mode. Just return without doing anything 548 * kernel mode. Just return without doing anything
533 * if so. 549 * if so.
534 */ 550 */
535 if (!user_mode(regs)) 551 if (!user_mode(__frame))
536 return 1; 552 return 1;
537 553
538 if (try_to_freeze()) 554 if (try_to_freeze())
@@ -541,30 +557,29 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
541 if (!oldset) 557 if (!oldset)
542 oldset = &current->blocked; 558 oldset = &current->blocked;
543 559
544 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 560 signr = get_signal_to_deliver(&info, &ka, __frame, NULL);
545 if (signr > 0) { 561 if (signr > 0)
546 handle_signal(signr, &info, &ka, oldset, regs); 562 return handle_signal(signr, &info, &ka, oldset);
547 return 1;
548 }
549 563
550 no_signal: 564no_signal:
551 /* Did we come from a system call? */ 565 /* Did we come from a system call? */
552 if (regs->syscallno >= 0) { 566 if (__frame->syscallno >= 0) {
553 /* Restart the system call - no handlers present */ 567 /* Restart the system call - no handlers present */
554 if (regs->gr8 == -ERESTARTNOHAND || 568 if (__frame->gr8 == -ERESTARTNOHAND ||
555 regs->gr8 == -ERESTARTSYS || 569 __frame->gr8 == -ERESTARTSYS ||
556 regs->gr8 == -ERESTARTNOINTR) { 570 __frame->gr8 == -ERESTARTNOINTR) {
557 regs->gr8 = regs->orig_gr8; 571 __frame->gr8 = __frame->orig_gr8;
558 regs->pc -= 4; 572 __frame->pc -= 4;
559 } 573 }
560 574
561 if (regs->gr8 == -ERESTART_RESTARTBLOCK){ 575 if (__frame->gr8 == -ERESTART_RESTARTBLOCK){
562 regs->gr8 = __NR_restart_syscall; 576 __frame->gr8 = __NR_restart_syscall;
563 regs->pc -= 4; 577 __frame->pc -= 4;
564 } 578 }
565 } 579 }
566 580
567 return 0; 581 return 0;
582
568} /* end do_signal() */ 583} /* end do_signal() */
569 584
570/*****************************************************************************/ 585/*****************************************************************************/
@@ -580,6 +595,6 @@ asmlinkage void do_notify_resume(__u32 thread_info_flags)
580 595
581 /* deal with pending signal delivery */ 596 /* deal with pending signal delivery */
582 if (thread_info_flags & _TIF_SIGPENDING) 597 if (thread_info_flags & _TIF_SIGPENDING)
583 do_signal(__frame, NULL); 598 do_signal(NULL);
584 599
585} /* end do_notify_resume() */ 600} /* end do_notify_resume() */