aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/irixsig.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2005-03-01 14:22:29 -0500
committerRalf Baechle <ralf@linux-mips.org>2005-10-29 14:30:50 -0400
commitfe00f943e0ef98b4057abcc2940d631a975b43cd (patch)
treec036ab8269ac86485130a083330229a01d319557 /arch/mips/kernel/irixsig.c
parent14f18b7f7e58de9a34c4b5fd38d5f73f22fba7ac (diff)
Sparseify MIPS.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/kernel/irixsig.c')
-rw-r--r--arch/mips/kernel/irixsig.c408
1 files changed, 215 insertions, 193 deletions
diff --git a/arch/mips/kernel/irixsig.c b/arch/mips/kernel/irixsig.c
index eff89322ba5..908e6368420 100644
--- a/arch/mips/kernel/irixsig.c
+++ b/arch/mips/kernel/irixsig.c
@@ -76,36 +76,39 @@ static inline void dump_irix5_sigctx(struct sigctx_irix5 *c)
76} 76}
77#endif 77#endif
78 78
79static void setup_irix_frame(struct k_sigaction *ka, struct pt_regs *regs, 79static int setup_irix_frame(struct k_sigaction *ka, struct pt_regs *regs,
80 int signr, sigset_t *oldmask) 80 int signr, sigset_t *oldmask)
81{ 81{
82 struct sigctx_irix5 __user *ctx;
82 unsigned long sp; 83 unsigned long sp;
83 struct sigctx_irix5 *ctx; 84 int error, i;
84 int i;
85 85
86 sp = regs->regs[29]; 86 sp = regs->regs[29];
87 sp -= sizeof(struct sigctx_irix5); 87 sp -= sizeof(struct sigctx_irix5);
88 sp &= ~(0xf); 88 sp &= ~(0xf);
89 ctx = (struct sigctx_irix5 *) sp; 89 ctx = (struct sigctx_irix5 __user *) sp;
90 if (!access_ok(VERIFY_WRITE, ctx, sizeof(*ctx))) 90 if (!access_ok(VERIFY_WRITE, ctx, sizeof(*ctx)))
91 goto segv_and_exit; 91 goto segv_and_exit;
92 92
93 __put_user(0, &ctx->weird_fpu_thing); 93 error = __put_user(0, &ctx->weird_fpu_thing);
94 __put_user(~(0x00000001), &ctx->rmask); 94 error |= __put_user(~(0x00000001), &ctx->rmask);
95 __put_user(0, &ctx->regs[0]); 95 error |= __put_user(0, &ctx->regs[0]);
96 for(i = 1; i < 32; i++) 96 for(i = 1; i < 32; i++)
97 __put_user((u64) regs->regs[i], &ctx->regs[i]); 97 error |= __put_user((u64) regs->regs[i], &ctx->regs[i]);
98
99 error |= __put_user((u64) regs->hi, &ctx->hi);
100 error |= __put_user((u64) regs->lo, &ctx->lo);
101 error |= __put_user((u64) regs->cp0_epc, &ctx->pc);
102 error |= __put_user(!!used_math(), &ctx->usedfp);
103 error |= __put_user((u64) regs->cp0_cause, &ctx->cp0_cause);
104 error |= __put_user((u64) regs->cp0_badvaddr, &ctx->cp0_badvaddr);
98 105
99 __put_user((u64) regs->hi, &ctx->hi); 106 error |= __put_user(0, &ctx->sstk_flags); /* XXX sigstack unimp... todo... */
100 __put_user((u64) regs->lo, &ctx->lo);
101 __put_user((u64) regs->cp0_epc, &ctx->pc);
102 __put_user(!!used_math(), &ctx->usedfp);
103 __put_user((u64) regs->cp0_cause, &ctx->cp0_cause);
104 __put_user((u64) regs->cp0_badvaddr, &ctx->cp0_badvaddr);
105 107
106 __put_user(0, &ctx->sstk_flags); /* XXX sigstack unimp... todo... */ 108 error |= __copy_to_user(&ctx->sigset, oldmask, sizeof(irix_sigset_t)) ? -EFAULT : 0;
107 109
108 __copy_to_user(&ctx->sigset, oldmask, sizeof(irix_sigset_t)); 110 if (error)
111 goto segv_and_exit;
109 112
110#ifdef DEBUG_SIG 113#ifdef DEBUG_SIG
111 dump_irix5_sigctx(ctx); 114 dump_irix5_sigctx(ctx);
@@ -117,13 +120,14 @@ static void setup_irix_frame(struct k_sigaction *ka, struct pt_regs *regs,
117 regs->regs[7] = (unsigned long) ka->sa.sa_handler; 120 regs->regs[7] = (unsigned long) ka->sa.sa_handler;
118 regs->regs[25] = regs->cp0_epc = (unsigned long) ka->sa_restorer; 121 regs->regs[25] = regs->cp0_epc = (unsigned long) ka->sa_restorer;
119 122
120 return; 123 return 1;
121 124
122segv_and_exit: 125segv_and_exit:
123 force_sigsegv(signr, current); 126 force_sigsegv(signr, current);
127 return 0;
124} 128}
125 129
126static void inline 130static int inline
127setup_irix_rt_frame(struct k_sigaction * ka, struct pt_regs *regs, 131setup_irix_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
128 int signr, sigset_t *oldmask, siginfo_t *info) 132 int signr, sigset_t *oldmask, siginfo_t *info)
129{ 133{
@@ -131,9 +135,11 @@ setup_irix_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
131 do_exit(SIGSEGV); 135 do_exit(SIGSEGV);
132} 136}
133 137
134static inline void handle_signal(unsigned long sig, siginfo_t *info, 138static inline int handle_signal(unsigned long sig, siginfo_t *info,
135 struct k_sigaction *ka, sigset_t *oldset, struct pt_regs * regs) 139 struct k_sigaction *ka, sigset_t *oldset, struct pt_regs * regs)
136{ 140{
141 int ret;
142
137 switch(regs->regs[0]) { 143 switch(regs->regs[0]) {
138 case ERESTARTNOHAND: 144 case ERESTARTNOHAND:
139 regs->regs[2] = EINTR; 145 regs->regs[2] = EINTR;
@@ -151,9 +157,9 @@ static inline void handle_signal(unsigned long sig, siginfo_t *info,
151 regs->regs[0] = 0; /* Don't deal with this again. */ 157 regs->regs[0] = 0; /* Don't deal with this again. */
152 158
153 if (ka->sa.sa_flags & SA_SIGINFO) 159 if (ka->sa.sa_flags & SA_SIGINFO)
154 setup_irix_rt_frame(ka, regs, sig, oldset, info); 160 ret = setup_irix_rt_frame(ka, regs, sig, oldset, info);
155 else 161 else
156 setup_irix_frame(ka, regs, sig, oldset); 162 ret = setup_irix_frame(ka, regs, sig, oldset);
157 163
158 spin_lock_irq(&current->sighand->siglock); 164 spin_lock_irq(&current->sighand->siglock);
159 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 165 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
@@ -161,6 +167,8 @@ static inline void handle_signal(unsigned long sig, siginfo_t *info,
161 sigaddset(&current->blocked,sig); 167 sigaddset(&current->blocked,sig);
162 recalc_sigpending(); 168 recalc_sigpending();
163 spin_unlock_irq(&current->sighand->siglock); 169 spin_unlock_irq(&current->sighand->siglock);
170
171 return ret;
164} 172}
165 173
166asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs) 174asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs)
@@ -184,10 +192,8 @@ asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs)
184 oldset = &current->blocked; 192 oldset = &current->blocked;
185 193
186 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 194 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
187 if (signr > 0) { 195 if (signr > 0)
188 handle_signal(signr, &info, &ka, oldset, regs); 196 return handle_signal(signr, &info, &ka, oldset, regs);
189 return 1;
190 }
191 197
192no_signal: 198no_signal:
193 /* 199 /*
@@ -208,10 +214,11 @@ no_signal:
208asmlinkage void 214asmlinkage void
209irix_sigreturn(struct pt_regs *regs) 215irix_sigreturn(struct pt_regs *regs)
210{ 216{
211 struct sigctx_irix5 *context, *magic; 217 struct sigctx_irix5 __user *context, *magic;
212 unsigned long umask, mask; 218 unsigned long umask, mask;
213 u64 *fregs; 219 u64 *fregs;
214 int sig, i, base = 0; 220 u32 usedfp;
221 int error, sig, i, base = 0;
215 sigset_t blocked; 222 sigset_t blocked;
216 223
217 /* Always make any pending restarted system calls return -EINTR */ 224 /* Always make any pending restarted system calls return -EINTR */
@@ -220,8 +227,8 @@ irix_sigreturn(struct pt_regs *regs)
220 if (regs->regs[2] == 1000) 227 if (regs->regs[2] == 1000)
221 base = 1; 228 base = 1;
222 229
223 context = (struct sigctx_irix5 *) regs->regs[base + 4]; 230 context = (struct sigctx_irix5 __user *) regs->regs[base + 4];
224 magic = (struct sigctx_irix5 *) regs->regs[base + 5]; 231 magic = (struct sigctx_irix5 __user *) regs->regs[base + 5];
225 sig = (int) regs->regs[base + 6]; 232 sig = (int) regs->regs[base + 6];
226#ifdef DEBUG_SIG 233#ifdef DEBUG_SIG
227 printk("[%s:%d] IRIX sigreturn(scp[%p],ucp[%p],sig[%d])\n", 234 printk("[%s:%d] IRIX sigreturn(scp[%p],ucp[%p],sig[%d])\n",
@@ -236,25 +243,31 @@ irix_sigreturn(struct pt_regs *regs)
236 dump_irix5_sigctx(context); 243 dump_irix5_sigctx(context);
237#endif 244#endif
238 245
239 __get_user(regs->cp0_epc, &context->pc); 246 error = __get_user(regs->cp0_epc, &context->pc);
240 umask = context->rmask; mask = 2; 247 error |= __get_user(umask, &context->rmask);
248
249 mask = 2;
241 for (i = 1; i < 32; i++, mask <<= 1) { 250 for (i = 1; i < 32; i++, mask <<= 1) {
242 if(umask & mask) 251 if (umask & mask)
243 __get_user(regs->regs[i], &context->regs[i]); 252 error |= __get_user(regs->regs[i], &context->regs[i]);
244 } 253 }
245 __get_user(regs->hi, &context->hi); 254 error |= __get_user(regs->hi, &context->hi);
246 __get_user(regs->lo, &context->lo); 255 error |= __get_user(regs->lo, &context->lo);
247 256
248 if ((umask & 1) && context->usedfp) { 257 error |= __get_user(usedfp, &context->usedfp);
258 if ((umask & 1) && usedfp) {
249 fregs = (u64 *) &current->thread.fpu; 259 fregs = (u64 *) &current->thread.fpu;
260
250 for(i = 0; i < 32; i++) 261 for(i = 0; i < 32; i++)
251 fregs[i] = (u64) context->fpregs[i]; 262 error |= __get_user(fregs[i], &context->fpregs[i]);
252 __get_user(current->thread.fpu.hard.fcr31, &context->fpcsr); 263 error |= __get_user(current->thread.fpu.hard.fcr31, &context->fpcsr);
253 } 264 }
254 265
255 /* XXX do sigstack crapola here... XXX */ 266 /* XXX do sigstack crapola here... XXX */
256 267
257 if (__copy_from_user(&blocked, &context->sigset, sizeof(blocked))) 268 error |= __copy_from_user(&blocked, &context->sigset, sizeof(blocked)) ? -EFAULT : 0;
269
270 if (error)
258 goto badframe; 271 goto badframe;
259 272
260 sigdelsetmask(&blocked, ~_BLOCKABLE); 273 sigdelsetmask(&blocked, ~_BLOCKABLE);
@@ -296,8 +309,8 @@ static inline void dump_sigact_irix5(struct sigact_irix5 *p)
296#endif 309#endif
297 310
298asmlinkage int 311asmlinkage int
299irix_sigaction(int sig, const struct sigaction *act, 312irix_sigaction(int sig, const struct sigaction __user *act,
300 struct sigaction *oact, void *trampoline) 313 struct sigaction __user *oact, void __user *trampoline)
301{ 314{
302 struct k_sigaction new_ka, old_ka; 315 struct k_sigaction new_ka, old_ka;
303 int ret; 316 int ret;
@@ -311,12 +324,16 @@ irix_sigaction(int sig, const struct sigaction *act,
311#endif 324#endif
312 if (act) { 325 if (act) {
313 sigset_t mask; 326 sigset_t mask;
314 if (!access_ok(VERIFY_READ, act, sizeof(*act)) || 327 int err;
315 __get_user(new_ka.sa.sa_handler, &act->sa_handler) || 328
316 __get_user(new_ka.sa.sa_flags, &act->sa_flags)) 329 if (!access_ok(VERIFY_READ, act, sizeof(*act)))
317 return -EFAULT; 330 return -EFAULT;
331 err = __get_user(new_ka.sa.sa_handler, &act->sa_handler);
332 err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
318 333
319 __copy_from_user(&mask, &act->sa_mask, sizeof(sigset_t)); 334 err |= __copy_from_user(&mask, &act->sa_mask, sizeof(sigset_t)) ? -EFAULT : 0;
335 if (err)
336 return err;
320 337
321 /* 338 /*
322 * Hmmm... methinks IRIX libc always passes a valid trampoline 339 * Hmmm... methinks IRIX libc always passes a valid trampoline
@@ -330,30 +347,37 @@ irix_sigaction(int sig, const struct sigaction *act,
330 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); 347 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
331 348
332 if (!ret && oact) { 349 if (!ret && oact) {
333 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || 350 int err;
334 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || 351
335 __put_user(old_ka.sa.sa_flags, &oact->sa_flags)) 352 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
353 return -EFAULT;
354
355 err = __put_user(old_ka.sa.sa_handler, &oact->sa_handler);
356 err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
357 err |= __copy_to_user(&oact->sa_mask, &old_ka.sa.sa_mask,
358 sizeof(sigset_t)) ? -EFAULT : 0;
359 if (err)
336 return -EFAULT; 360 return -EFAULT;
337 __copy_to_user(&old_ka.sa.sa_mask, &oact->sa_mask,
338 sizeof(sigset_t));
339 } 361 }
340 362
341 return ret; 363 return ret;
342} 364}
343 365
344asmlinkage int irix_sigpending(irix_sigset_t *set) 366asmlinkage int irix_sigpending(irix_sigset_t __user *set)
345{ 367{
346 return do_sigpending(set, sizeof(*set)); 368 return do_sigpending(set, sizeof(*set));
347} 369}
348 370
349asmlinkage int irix_sigprocmask(int how, irix_sigset_t *new, irix_sigset_t *old) 371asmlinkage int irix_sigprocmask(int how, irix_sigset_t __user *new,
372 irix_sigset_t __user *old)
350{ 373{
351 sigset_t oldbits, newbits; 374 sigset_t oldbits, newbits;
352 375
353 if (new) { 376 if (new) {
354 if (!access_ok(VERIFY_READ, new, sizeof(*new))) 377 if (!access_ok(VERIFY_READ, new, sizeof(*new)))
355 return -EFAULT; 378 return -EFAULT;
356 __copy_from_user(&newbits, new, sizeof(unsigned long)*4); 379 if (__copy_from_user(&newbits, new, sizeof(unsigned long)*4))
380 return -EFAULT;
357 sigdelsetmask(&newbits, ~_BLOCKABLE); 381 sigdelsetmask(&newbits, ~_BLOCKABLE);
358 382
359 spin_lock_irq(&current->sighand->siglock); 383 spin_lock_irq(&current->sighand->siglock);
@@ -381,20 +405,19 @@ asmlinkage int irix_sigprocmask(int how, irix_sigset_t *new, irix_sigset_t *old)
381 recalc_sigpending(); 405 recalc_sigpending();
382 spin_unlock_irq(&current->sighand->siglock); 406 spin_unlock_irq(&current->sighand->siglock);
383 } 407 }
384 if(old) { 408 if (old)
385 if (!access_ok(VERIFY_WRITE, old, sizeof(*old))) 409 return copy_to_user(old, &current->blocked,
386 return -EFAULT; 410 sizeof(unsigned long)*4) ? -EFAULT : 0;
387 __copy_to_user(old, &current->blocked, sizeof(unsigned long)*4);
388 }
389 411
390 return 0; 412 return 0;
391} 413}
392 414
393asmlinkage int irix_sigsuspend(struct pt_regs *regs) 415asmlinkage int irix_sigsuspend(struct pt_regs *regs)
394{ 416{
395 sigset_t *uset, saveset, newset; 417 sigset_t saveset, newset;
418 sigset_t __user *uset;
396 419
397 uset = (sigset_t *) regs->regs[4]; 420 uset = (sigset_t __user *) regs->regs[4];
398 if (copy_from_user(&newset, uset, sizeof(sigset_t))) 421 if (copy_from_user(&newset, uset, sizeof(sigset_t)))
399 return -EFAULT; 422 return -EFAULT;
400 sigdelsetmask(&newset, ~_BLOCKABLE); 423 sigdelsetmask(&newset, ~_BLOCKABLE);
@@ -440,12 +463,13 @@ struct irix5_siginfo {
440 } stuff; 463 } stuff;
441}; 464};
442 465
443asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info, 466asmlinkage int irix_sigpoll_sys(unsigned long __user *set,
444 struct timespec *tp) 467 struct irix5_siginfo __user *info, struct timespec __user *tp)
445{ 468{
446 long expire = MAX_SCHEDULE_TIMEOUT; 469 long expire = MAX_SCHEDULE_TIMEOUT;
447 sigset_t kset; 470 sigset_t kset;
448 int i, sig, error, timeo = 0; 471 int i, sig, error, timeo = 0;
472 struct timespec ktp;
449 473
450#ifdef DEBUG_SIG 474#ifdef DEBUG_SIG
451 printk("[%s:%d] irix_sigpoll_sys(%p,%p,%p)\n", 475 printk("[%s:%d] irix_sigpoll_sys(%p,%p,%p)\n",
@@ -456,14 +480,8 @@ asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info,
456 if (!set) 480 if (!set)
457 return -EINVAL; 481 return -EINVAL;
458 482
459 if (!access_ok(VERIFY_READ, set, sizeof(kset))) { 483 if (copy_from_user(&kset, set, sizeof(set)))
460 error = -EFAULT; 484 return -EFAULT;
461 goto out;
462 }
463
464 __copy_from_user(&kset, set, sizeof(set));
465 if (error)
466 goto out;
467 485
468 if (info && clear_user(info, sizeof(*info))) { 486 if (info && clear_user(info, sizeof(*info))) {
469 error = -EFAULT; 487 error = -EFAULT;
@@ -471,19 +489,21 @@ asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info,
471 } 489 }
472 490
473 if (tp) { 491 if (tp) {
474 if (!access_ok(VERIFY_READ, tp, sizeof(*tp))) 492 if (copy_from_user(&ktp, tp, sizeof(*tp)))
475 return -EFAULT; 493 return -EFAULT;
476 if (!tp->tv_sec && !tp->tv_nsec) { 494
477 error = -EINVAL; 495 if (!ktp.tv_sec && !ktp.tv_nsec)
478 goto out; 496 return -EINVAL;
479 } 497
480 expire = timespec_to_jiffies(tp) + (tp->tv_sec||tp->tv_nsec); 498 expire = timespec_to_jiffies(&ktp) +
499 (ktp.tv_sec || ktp.tv_nsec);
481 } 500 }
482 501
483 while(1) { 502 while(1) {
484 long tmp = 0; 503 long tmp = 0;
485 504
486 expire = schedule_timeout_interruptible(expire); 505 current->state = TASK_INTERRUPTIBLE;
506 expire = schedule_timeout(expire);
487 507
488 for (i=0; i<=4; i++) 508 for (i=0; i<=4; i++)
489 tmp |= (current->pending.signal.sig[i] & kset.sig[i]); 509 tmp |= (current->pending.signal.sig[i] & kset.sig[i]);
@@ -500,15 +520,14 @@ asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info,
500 if (timeo) 520 if (timeo)
501 return -EAGAIN; 521 return -EAGAIN;
502 522
503 for(sig = 1; i <= 65 /* IRIX_NSIG */; sig++) { 523 for (sig = 1; i <= 65 /* IRIX_NSIG */; sig++) {
504 if (sigismember (&kset, sig)) 524 if (sigismember (&kset, sig))
505 continue; 525 continue;
506 if (sigismember (&current->pending.signal, sig)) { 526 if (sigismember (&current->pending.signal, sig)) {
507 /* XXX need more than this... */ 527 /* XXX need more than this... */
508 if (info) 528 if (info)
509 info->sig = sig; 529 return copy_to_user(&info->sig, &sig, sizeof(sig));
510 error = 0; 530 return 0;
511 goto out;
512 } 531 }
513 } 532 }
514 533
@@ -534,8 +553,9 @@ extern int getrusage(struct task_struct *, int, struct rusage __user *);
534 553
535#define W_MASK (W_EXITED | W_TRAPPED | W_STOPPED | W_CONT | W_NOHANG) 554#define W_MASK (W_EXITED | W_TRAPPED | W_STOPPED | W_CONT | W_NOHANG)
536 555
537asmlinkage int irix_waitsys(int type, int pid, struct irix5_siginfo *info, 556asmlinkage int irix_waitsys(int type, int pid,
538 int options, struct rusage *ru) 557 struct irix5_siginfo __user *info, int options,
558 struct rusage __user *ru)
539{ 559{
540 int flag, retval; 560 int flag, retval;
541 DECLARE_WAITQUEUE(wait, current); 561 DECLARE_WAITQUEUE(wait, current);
@@ -543,28 +563,22 @@ asmlinkage int irix_waitsys(int type, int pid, struct irix5_siginfo *info,
543 struct task_struct *p; 563 struct task_struct *p;
544 struct list_head *_p; 564 struct list_head *_p;
545 565
546 if (!info) { 566 if (!info)
547 retval = -EINVAL; 567 return -EINVAL;
548 goto out; 568
549 } 569 if (!access_ok(VERIFY_WRITE, info, sizeof(*info)))
550 if (!access_ok(VERIFY_WRITE, info, sizeof(*info))) { 570 return -EFAULT;
551 retval = -EFAULT; 571
552 goto out; 572 if (ru)
553 } 573 if (!access_ok(VERIFY_WRITE, ru, sizeof(*ru)))
554 if (ru) { 574 return -EFAULT;
555 if (!access_ok(VERIFY_WRITE, ru, sizeof(*ru))) { 575
556 retval = -EFAULT; 576 if (options & ~W_MASK)
557 goto out; 577 return -EINVAL;
558 } 578
559 } 579 if (type != IRIX_P_PID && type != IRIX_P_PGID && type != IRIX_P_ALL)
560 if (options & ~(W_MASK)) { 580 return -EINVAL;
561 retval = -EINVAL; 581
562 goto out;
563 }
564 if (type != IRIX_P_PID && type != IRIX_P_PGID && type != IRIX_P_ALL) {
565 retval = -EINVAL;
566 goto out;
567 }
568 add_wait_queue(&current->signal->wait_chldexit, &wait); 582 add_wait_queue(&current->signal->wait_chldexit, &wait);
569repeat: 583repeat:
570 flag = 0; 584 flag = 0;
@@ -595,18 +609,20 @@ repeat:
595 add_parent(p, p->parent); 609 add_parent(p, p->parent);
596 write_unlock_irq(&tasklist_lock); 610 write_unlock_irq(&tasklist_lock);
597 retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0; 611 retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0;
598 if (!retval && ru) { 612 if (retval)
599 retval |= __put_user(SIGCHLD, &info->sig); 613 goto end_waitsys;
600 retval |= __put_user(0, &info->code); 614
601 retval |= __put_user(p->pid, &info->stuff.procinfo.pid); 615 retval = __put_user(SIGCHLD, &info->sig);
602 retval |= __put_user((p->exit_code >> 8) & 0xff, 616 retval |= __put_user(0, &info->code);
603 &info->stuff.procinfo.procdata.child.status); 617 retval |= __put_user(p->pid, &info->stuff.procinfo.pid);
604 retval |= __put_user(p->utime, &info->stuff.procinfo.procdata.child.utime); 618 retval |= __put_user((p->exit_code >> 8) & 0xff,
605 retval |= __put_user(p->stime, &info->stuff.procinfo.procdata.child.stime); 619 &info->stuff.procinfo.procdata.child.status);
606 } 620 retval |= __put_user(p->utime, &info->stuff.procinfo.procdata.child.utime);
607 if (!retval) { 621 retval |= __put_user(p->stime, &info->stuff.procinfo.procdata.child.stime);
608 p->exit_code = 0; 622 if (retval)
609 } 623 goto end_waitsys;
624
625 p->exit_code = 0;
610 goto end_waitsys; 626 goto end_waitsys;
611 627
612 case EXIT_ZOMBIE: 628 case EXIT_ZOMBIE:
@@ -614,16 +630,18 @@ repeat:
614 current->signal->cstime += p->stime + p->signal->cstime; 630 current->signal->cstime += p->stime + p->signal->cstime;
615 if (ru != NULL) 631 if (ru != NULL)
616 getrusage(p, RUSAGE_BOTH, ru); 632 getrusage(p, RUSAGE_BOTH, ru);
617 __put_user(SIGCHLD, &info->sig); 633 retval = __put_user(SIGCHLD, &info->sig);
618 __put_user(1, &info->code); /* CLD_EXITED */ 634 retval |= __put_user(1, &info->code); /* CLD_EXITED */
619 __put_user(p->pid, &info->stuff.procinfo.pid); 635 retval |= __put_user(p->pid, &info->stuff.procinfo.pid);
620 __put_user((p->exit_code >> 8) & 0xff, 636 retval |= __put_user((p->exit_code >> 8) & 0xff,
621 &info->stuff.procinfo.procdata.child.status); 637 &info->stuff.procinfo.procdata.child.status);
622 __put_user(p->utime, 638 retval |= __put_user(p->utime,
623 &info->stuff.procinfo.procdata.child.utime); 639 &info->stuff.procinfo.procdata.child.utime);
624 __put_user(p->stime, 640 retval |= __put_user(p->stime,
625 &info->stuff.procinfo.procdata.child.stime); 641 &info->stuff.procinfo.procdata.child.stime);
626 retval = 0; 642 if (retval)
643 return retval;
644
627 if (p->real_parent != p->parent) { 645 if (p->real_parent != p->parent) {
628 write_lock_irq(&tasklist_lock); 646 write_lock_irq(&tasklist_lock);
629 remove_parent(p); 647 remove_parent(p);
@@ -656,7 +674,6 @@ end_waitsys:
656 current->state = TASK_RUNNING; 674 current->state = TASK_RUNNING;
657 remove_wait_queue(&current->signal->wait_chldexit, &wait); 675 remove_wait_queue(&current->signal->wait_chldexit, &wait);
658 676
659out:
660 return retval; 677 return retval;
661} 678}
662 679
@@ -675,39 +692,39 @@ struct irix5_context {
675 692
676asmlinkage int irix_getcontext(struct pt_regs *regs) 693asmlinkage int irix_getcontext(struct pt_regs *regs)
677{ 694{
678 int i, base = 0; 695 int error, i, base = 0;
679 struct irix5_context *ctx; 696 struct irix5_context __user *ctx;
680 unsigned long flags; 697 unsigned long flags;
681 698
682 if (regs->regs[2] == 1000) 699 if (regs->regs[2] == 1000)
683 base = 1; 700 base = 1;
684 ctx = (struct irix5_context *) regs->regs[base + 4]; 701 ctx = (struct irix5_context __user *) regs->regs[base + 4];
685 702
686#ifdef DEBUG_SIG 703#ifdef DEBUG_SIG
687 printk("[%s:%d] irix_getcontext(%p)\n", 704 printk("[%s:%d] irix_getcontext(%p)\n",
688 current->comm, current->pid, ctx); 705 current->comm, current->pid, ctx);
689#endif 706#endif
690 707
691 if (!access_ok(VERIFY_WRITE, ctx, sizeof(*ctx))) 708 if (!access_ok(VERIFY_WRITE, ctx, sizeof(*ctx)));
692 return -EFAULT; 709 return -EFAULT;
693 710
694 __put_user(current->thread.irix_oldctx, &ctx->link); 711 error = __put_user(current->thread.irix_oldctx, &ctx->link);
695 712
696 __copy_to_user(&ctx->sigmask, &current->blocked, sizeof(irix_sigset_t)); 713 error |= __copy_to_user(&ctx->sigmask, &current->blocked, sizeof(irix_sigset_t)) ? -EFAULT : 0;
697 714
698 /* XXX Do sigstack stuff someday... */ 715 /* XXX Do sigstack stuff someday... */
699 __put_user(0, &ctx->stack.sp); 716 error |= __put_user(0, &ctx->stack.sp);
700 __put_user(0, &ctx->stack.size); 717 error |= __put_user(0, &ctx->stack.size);
701 __put_user(0, &ctx->stack.flags); 718 error |= __put_user(0, &ctx->stack.flags);
702 719
703 __put_user(0, &ctx->weird_graphics_thing); 720 error |= __put_user(0, &ctx->weird_graphics_thing);
704 __put_user(0, &ctx->regs[0]); 721 error |= __put_user(0, &ctx->regs[0]);
705 for (i = 1; i < 32; i++) 722 for (i = 1; i < 32; i++)
706 __put_user(regs->regs[i], &ctx->regs[i]); 723 error |= __put_user(regs->regs[i], &ctx->regs[i]);
707 __put_user(regs->lo, &ctx->regs[32]); 724 error |= __put_user(regs->lo, &ctx->regs[32]);
708 __put_user(regs->hi, &ctx->regs[33]); 725 error |= __put_user(regs->hi, &ctx->regs[33]);
709 __put_user(regs->cp0_cause, &ctx->regs[34]); 726 error |= __put_user(regs->cp0_cause, &ctx->regs[34]);
710 __put_user(regs->cp0_epc, &ctx->regs[35]); 727 error |= __put_user(regs->cp0_epc, &ctx->regs[35]);
711 728
712 flags = 0x0f; 729 flags = 0x0f;
713 if (!used_math()) { 730 if (!used_math()) {
@@ -716,119 +733,124 @@ asmlinkage int irix_getcontext(struct pt_regs *regs)
716 /* XXX wheee... */ 733 /* XXX wheee... */
717 printk("Wheee, no code for saving IRIX FPU context yet.\n"); 734 printk("Wheee, no code for saving IRIX FPU context yet.\n");
718 } 735 }
719 __put_user(flags, &ctx->flags); 736 error |= __put_user(flags, &ctx->flags);
720 737
721 return 0; 738 return error;
722} 739}
723 740
724asmlinkage unsigned long irix_setcontext(struct pt_regs *regs) 741asmlinkage void irix_setcontext(struct pt_regs *regs)
725{ 742{
726 int error, base = 0; 743 struct irix5_context __user *ctx;
727 struct irix5_context *ctx; 744 int err, base = 0;
745 u32 flags;
728 746
729 if(regs->regs[2] == 1000) 747 if (regs->regs[2] == 1000)
730 base = 1; 748 base = 1;
731 ctx = (struct irix5_context *) regs->regs[base + 4]; 749 ctx = (struct irix5_context __user *) regs->regs[base + 4];
732 750
733#ifdef DEBUG_SIG 751#ifdef DEBUG_SIG
734 printk("[%s:%d] irix_setcontext(%p)\n", 752 printk("[%s:%d] irix_setcontext(%p)\n",
735 current->comm, current->pid, ctx); 753 current->comm, current->pid, ctx);
736#endif 754#endif
737 755
738 if (!access_ok(VERIFY_READ, ctx, sizeof(*ctx))) { 756 if (!access_ok(VERIFY_READ, ctx, sizeof(*ctx)))
739 error = -EFAULT; 757 goto segv_and_exit;
740 goto out;
741 }
742 758
743 if (ctx->flags & 0x02) { 759 err = __get_user(flags, &ctx->flags);
760 if (flags & 0x02) {
744 /* XXX sigstack garbage, todo... */ 761 /* XXX sigstack garbage, todo... */
745 printk("Wheee, cannot do sigstack stuff in setcontext\n"); 762 printk("Wheee, cannot do sigstack stuff in setcontext\n");
746 } 763 }
747 764
748 if (ctx->flags & 0x04) { 765 if (flags & 0x04) {
749 int i; 766 int i;
750 767
751 /* XXX extra control block stuff... todo... */ 768 /* XXX extra control block stuff... todo... */
752 for(i = 1; i < 32; i++) 769 for (i = 1; i < 32; i++)
753 regs->regs[i] = ctx->regs[i]; 770 err |= __get_user(regs->regs[i], &ctx->regs[i]);
754 regs->lo = ctx->regs[32]; 771 err |= __get_user(regs->lo, &ctx->regs[32]);
755 regs->hi = ctx->regs[33]; 772 err |= __get_user(regs->hi, &ctx->regs[33]);
756 regs->cp0_epc = ctx->regs[35]; 773 err |= __get_user(regs->cp0_epc, &ctx->regs[35]);
757 } 774 }
758 775
759 if (ctx->flags & 0x08) { 776 if (flags & 0x08)
760 /* XXX fpu context, blah... */ 777 /* XXX fpu context, blah... */
761 printk("Wheee, cannot restore FPU context yet...\n"); 778 printk(KERN_ERR "Wheee, cannot restore FPU context yet...\n");
762 }
763 current->thread.irix_oldctx = ctx->link;
764 error = regs->regs[2];
765 779
766out: 780 err |= __get_user(current->thread.irix_oldctx, &ctx->link);
767 return error; 781 if (err)
782 goto segv_and_exit;
783
784 /*
785 * Don't let your children do this ...
786 */
787 if (current_thread_info()->flags & TIF_SYSCALL_TRACE)
788 do_syscall_trace(regs, 1);
789 __asm__ __volatile__(
790 "move\t$29,%0\n\t"
791 "j\tsyscall_exit"
792 :/* no outputs */
793 :"r" (&regs));
794 /* Unreached */
795
796segv_and_exit:
797 force_sigsegv(SIGSEGV, current);
768} 798}
769 799
770struct irix_sigstack { unsigned long sp; int status; }; 800struct irix_sigstack {
801 unsigned long sp;
802 int status;
803};
771 804
772asmlinkage int irix_sigstack(struct irix_sigstack *new, struct irix_sigstack *old) 805asmlinkage int irix_sigstack(struct irix_sigstack __user *new,
806 struct irix_sigstack __user *old)
773{ 807{
774 int error = -EFAULT;
775
776#ifdef DEBUG_SIG 808#ifdef DEBUG_SIG
777 printk("[%s:%d] irix_sigstack(%p,%p)\n", 809 printk("[%s:%d] irix_sigstack(%p,%p)\n",
778 current->comm, current->pid, new, old); 810 current->comm, current->pid, new, old);
779#endif 811#endif
780 if(new) { 812 if (new) {
781 if (!access_ok(VERIFY_READ, new, sizeof(*new))) 813 if (!access_ok(VERIFY_READ, new, sizeof(*new)))
782 goto out; 814 return -EFAULT;
783 } 815 }
784 816
785 if(old) { 817 if (old) {
786 if (!access_ok(VERIFY_WRITE, old, sizeof(*old))) 818 if (!access_ok(VERIFY_WRITE, old, sizeof(*old)))
787 goto out; 819 return -EFAULT;
788 } 820 }
789 error = 0;
790 821
791out: 822 return 0;
792 return error;
793} 823}
794 824
795struct irix_sigaltstack { unsigned long sp; int size; int status; }; 825struct irix_sigaltstack { unsigned long sp; int size; int status; };
796 826
797asmlinkage int irix_sigaltstack(struct irix_sigaltstack *new, 827asmlinkage int irix_sigaltstack(struct irix_sigaltstack __user *new,
798 struct irix_sigaltstack *old) 828 struct irix_sigaltstack __user *old)
799{ 829{
800 int error = -EFAULT;
801
802#ifdef DEBUG_SIG 830#ifdef DEBUG_SIG
803 printk("[%s:%d] irix_sigaltstack(%p,%p)\n", 831 printk("[%s:%d] irix_sigaltstack(%p,%p)\n",
804 current->comm, current->pid, new, old); 832 current->comm, current->pid, new, old);
805#endif 833#endif
806 if (new) { 834 if (new)
807 if (!access_ok(VERIFY_READ, new, sizeof(*new))) 835 if (!access_ok(VERIFY_READ, new, sizeof(*new)))
808 goto out; 836 return -EFAULT;
809 }
810 837
811 if (old) { 838 if (old) {
812 if (!access_ok(VERIFY_WRITE, old, sizeof(*old))) 839 if (!access_ok(VERIFY_WRITE, old, sizeof(*old)))
813 goto out; 840 return -EFAULT;
814 } 841 }
815 error = 0;
816
817out:
818 error = 0;
819 842
820 return error; 843 return 0;
821} 844}
822 845
823struct irix_procset { 846struct irix_procset {
824 int cmd, ltype, lid, rtype, rid; 847 int cmd, ltype, lid, rtype, rid;
825}; 848};
826 849
827asmlinkage int irix_sigsendset(struct irix_procset *pset, int sig) 850asmlinkage int irix_sigsendset(struct irix_procset __user *pset, int sig)
828{ 851{
829 if (!access_ok(VERIFY_READ, pset, sizeof(*pset))) 852 if (!access_ok(VERIFY_READ, pset, sizeof(*pset)))
830 return -EFAULT; 853 return -EFAULT;
831
832#ifdef DEBUG_SIG 854#ifdef DEBUG_SIG
833 printk("[%s:%d] irix_sigsendset([%d,%d,%d,%d,%d],%d)\n", 855 printk("[%s:%d] irix_sigsendset([%d,%d,%d,%d,%d],%d)\n",
834 current->comm, current->pid, 856 current->comm, current->pid,