Loading arch/mips/Makefile +15 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,21 @@ ifdef CONFIG_CROSSCOMPILE CROSS_COMPILE := $(tool-prefix) endif CHECKFLAGS-y += -D__linux__ -D__mips__ \ -D_ABIO32=1 \ -D_ABIN32=2 \ -D_ABI64=3 CHECKFLAGS-$(CONFIG_32BIT) += -D_MIPS_SIM=_ABIO32 \ -D_MIPS_SZLONG=32 \ -D__PTRDIFF_TYPE__=int CHECKFLAGS-$(CONFIG_64BIT) += -m64 -D_MIPS_SIM=_ABI64 \ -D_MIPS_SZLONG=64 \ -D__PTRDIFF_TYPE__="long int" CHECKFLAGS-$(CONFIG_CPU_BIG_ENDIAN) += -D__MIPSEB__ CHECKFLAGS-$(CONFIG_CPU_LITTLE_ENDIAN) += -D__MIPSEL__ CHECKFLAGS = $(CHECKFLAGS-y) ifdef CONFIG_BUILD_ELF64 gas-abi = 64 ld-emul = $(64bit-emul) Loading arch/mips/kernel/i8259.c +1 −1 Original line number Diff line number Diff line Loading @@ -321,7 +321,7 @@ void __init init_i8259_irqs (void) for (i = 0; i < 16; i++) { irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].action = NULL; irq_desc[i].depth = 1; irq_desc[i].handler = &i8259A_irq_type; } Loading arch/mips/kernel/irixelf.c +7 −7 Original line number Diff line number Diff line Loading @@ -147,7 +147,7 @@ static void padzero(unsigned long elf_bss) nbyte = elf_bss & (PAGE_SIZE-1); if (nbyte) { nbyte = PAGE_SIZE - nbyte; clear_user((void *) elf_bss, nbyte); clear_user((void __user *) elf_bss, nbyte); } } Loading Loading @@ -878,10 +878,10 @@ static int load_irix_library(struct file *file) * phdrs there are in the USER_PHDRP array. We return the vaddr the * first phdr was successfully mapped to. */ unsigned long irix_mapelf(int fd, struct elf_phdr *user_phdrp, int cnt) unsigned long irix_mapelf(int fd, struct elf_phdr __user *user_phdrp, int cnt) { unsigned long type, vaddr, filesz, offset, flags; struct elf_phdr *hp; struct elf_phdr __user *hp; struct file *filp; int i, retval; Loading Loading @@ -968,9 +968,9 @@ unsigned long irix_mapelf(int fd, struct elf_phdr *user_phdrp, int cnt) /* These are the only things you should do on a core-file: use only these * functions to write out all the necessary info. */ static int dump_write(struct file *file, const void *addr, int nr) static int dump_write(struct file *file, const void __user *addr, int nr) { return file->f_op->write(file, (const char *) addr, nr, &file->f_pos) == nr; return file->f_op->write(file, (const char __user *) addr, nr, &file->f_pos) == nr; } static int dump_seek(struct file *file, off_t off) Loading Loading @@ -1204,7 +1204,7 @@ static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file) len = current->mm->arg_end - current->mm->arg_start; len = len >= ELF_PRARGSZ ? ELF_PRARGSZ : len; (void *) copy_from_user(&psinfo.pr_psargs, (const char *)current->mm->arg_start, len); (const char __user *)current->mm->arg_start, len); for (i = 0; i < len; i++) if (psinfo.pr_psargs[i] == 0) psinfo.pr_psargs[i] = ' '; Loading Loading @@ -1301,7 +1301,7 @@ static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file) #ifdef DEBUG printk("elf_core_dump: writing %08lx %lx\n", addr, len); #endif DUMP_WRITE((void *)addr, len); DUMP_WRITE((void __user *)addr, len); } if ((off_t) file->f_pos != offset) { Loading arch/mips/kernel/irixinv.c +4 −3 Original line number Diff line number Diff line Loading @@ -30,10 +30,10 @@ void add_to_inventory (int class, int type, int controller, int unit, int state) inventory_items++; } int dump_inventory_to_user (void *userbuf, int size) int dump_inventory_to_user (void __user *userbuf, int size) { inventory_t *inv = &inventory [0]; inventory_t *user = userbuf; inventory_t __user *user = userbuf; int v; if (!access_ok(VERIFY_WRITE, userbuf, size)) Loading @@ -41,7 +41,8 @@ int dump_inventory_to_user (void *userbuf, int size) for (v = 0; v < inventory_items; v++){ inv = &inventory [v]; copy_to_user (user, inv, sizeof (inventory_t)); if (copy_to_user (user, inv, sizeof (inventory_t))) return -EFAULT; user++; } return inventory_items * sizeof (inventory_t); Loading arch/mips/kernel/irixsig.c +215 −193 Original line number Diff line number Diff line Loading @@ -76,36 +76,39 @@ static inline void dump_irix5_sigctx(struct sigctx_irix5 *c) } #endif static void setup_irix_frame(struct k_sigaction *ka, struct pt_regs *regs, static int setup_irix_frame(struct k_sigaction *ka, struct pt_regs *regs, int signr, sigset_t *oldmask) { struct sigctx_irix5 __user *ctx; unsigned long sp; struct sigctx_irix5 *ctx; int i; int error, i; sp = regs->regs[29]; sp -= sizeof(struct sigctx_irix5); sp &= ~(0xf); ctx = (struct sigctx_irix5 *) sp; ctx = (struct sigctx_irix5 __user *) sp; if (!access_ok(VERIFY_WRITE, ctx, sizeof(*ctx))) goto segv_and_exit; __put_user(0, &ctx->weird_fpu_thing); __put_user(~(0x00000001), &ctx->rmask); __put_user(0, &ctx->regs[0]); error = __put_user(0, &ctx->weird_fpu_thing); error |= __put_user(~(0x00000001), &ctx->rmask); error |= __put_user(0, &ctx->regs[0]); for(i = 1; i < 32; i++) __put_user((u64) regs->regs[i], &ctx->regs[i]); error |= __put_user((u64) regs->regs[i], &ctx->regs[i]); error |= __put_user((u64) regs->hi, &ctx->hi); error |= __put_user((u64) regs->lo, &ctx->lo); error |= __put_user((u64) regs->cp0_epc, &ctx->pc); error |= __put_user(!!used_math(), &ctx->usedfp); error |= __put_user((u64) regs->cp0_cause, &ctx->cp0_cause); error |= __put_user((u64) regs->cp0_badvaddr, &ctx->cp0_badvaddr); __put_user((u64) regs->hi, &ctx->hi); __put_user((u64) regs->lo, &ctx->lo); __put_user((u64) regs->cp0_epc, &ctx->pc); __put_user(!!used_math(), &ctx->usedfp); __put_user((u64) regs->cp0_cause, &ctx->cp0_cause); __put_user((u64) regs->cp0_badvaddr, &ctx->cp0_badvaddr); error |= __put_user(0, &ctx->sstk_flags); /* XXX sigstack unimp... todo... */ __put_user(0, &ctx->sstk_flags); /* XXX sigstack unimp... todo... */ error |= __copy_to_user(&ctx->sigset, oldmask, sizeof(irix_sigset_t)) ? -EFAULT : 0; __copy_to_user(&ctx->sigset, oldmask, sizeof(irix_sigset_t)); if (error) goto segv_and_exit; #ifdef DEBUG_SIG dump_irix5_sigctx(ctx); Loading @@ -117,13 +120,14 @@ static void setup_irix_frame(struct k_sigaction *ka, struct pt_regs *regs, regs->regs[7] = (unsigned long) ka->sa.sa_handler; regs->regs[25] = regs->cp0_epc = (unsigned long) ka->sa_restorer; return; return 1; segv_and_exit: force_sigsegv(signr, current); return 0; } static void inline static int inline setup_irix_rt_frame(struct k_sigaction * ka, struct pt_regs *regs, int signr, sigset_t *oldmask, siginfo_t *info) { Loading @@ -131,9 +135,11 @@ setup_irix_rt_frame(struct k_sigaction * ka, struct pt_regs *regs, do_exit(SIGSEGV); } static inline void handle_signal(unsigned long sig, siginfo_t *info, static inline int handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, sigset_t *oldset, struct pt_regs * regs) { int ret; switch(regs->regs[0]) { case ERESTARTNOHAND: regs->regs[2] = EINTR; Loading @@ -151,9 +157,9 @@ static inline void handle_signal(unsigned long sig, siginfo_t *info, regs->regs[0] = 0; /* Don't deal with this again. */ if (ka->sa.sa_flags & SA_SIGINFO) setup_irix_rt_frame(ka, regs, sig, oldset, info); ret = setup_irix_rt_frame(ka, regs, sig, oldset, info); else setup_irix_frame(ka, regs, sig, oldset); ret = setup_irix_frame(ka, regs, sig, oldset); spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); Loading @@ -161,6 +167,8 @@ static inline void handle_signal(unsigned long sig, siginfo_t *info, sigaddset(¤t->blocked,sig); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); return ret; } asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs) Loading @@ -184,10 +192,8 @@ asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs) oldset = ¤t->blocked; signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { handle_signal(signr, &info, &ka, oldset, regs); return 1; } if (signr > 0) return handle_signal(signr, &info, &ka, oldset, regs); no_signal: /* Loading @@ -208,10 +214,11 @@ asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs) asmlinkage void irix_sigreturn(struct pt_regs *regs) { struct sigctx_irix5 *context, *magic; struct sigctx_irix5 __user *context, *magic; unsigned long umask, mask; u64 *fregs; int sig, i, base = 0; u32 usedfp; int error, sig, i, base = 0; sigset_t blocked; /* Always make any pending restarted system calls return -EINTR */ Loading @@ -220,8 +227,8 @@ irix_sigreturn(struct pt_regs *regs) if (regs->regs[2] == 1000) base = 1; context = (struct sigctx_irix5 *) regs->regs[base + 4]; magic = (struct sigctx_irix5 *) regs->regs[base + 5]; context = (struct sigctx_irix5 __user *) regs->regs[base + 4]; magic = (struct sigctx_irix5 __user *) regs->regs[base + 5]; sig = (int) regs->regs[base + 6]; #ifdef DEBUG_SIG printk("[%s:%d] IRIX sigreturn(scp[%p],ucp[%p],sig[%d])\n", Loading @@ -236,25 +243,31 @@ irix_sigreturn(struct pt_regs *regs) dump_irix5_sigctx(context); #endif __get_user(regs->cp0_epc, &context->pc); umask = context->rmask; mask = 2; error = __get_user(regs->cp0_epc, &context->pc); error |= __get_user(umask, &context->rmask); mask = 2; for (i = 1; i < 32; i++, mask <<= 1) { if (umask & mask) __get_user(regs->regs[i], &context->regs[i]); error |= __get_user(regs->regs[i], &context->regs[i]); } __get_user(regs->hi, &context->hi); __get_user(regs->lo, &context->lo); error |= __get_user(regs->hi, &context->hi); error |= __get_user(regs->lo, &context->lo); if ((umask & 1) && context->usedfp) { error |= __get_user(usedfp, &context->usedfp); if ((umask & 1) && usedfp) { fregs = (u64 *) ¤t->thread.fpu; for(i = 0; i < 32; i++) fregs[i] = (u64) context->fpregs[i]; __get_user(current->thread.fpu.hard.fcr31, &context->fpcsr); error |= __get_user(fregs[i], &context->fpregs[i]); error |= __get_user(current->thread.fpu.hard.fcr31, &context->fpcsr); } /* XXX do sigstack crapola here... XXX */ if (__copy_from_user(&blocked, &context->sigset, sizeof(blocked))) error |= __copy_from_user(&blocked, &context->sigset, sizeof(blocked)) ? -EFAULT : 0; if (error) goto badframe; sigdelsetmask(&blocked, ~_BLOCKABLE); Loading Loading @@ -296,8 +309,8 @@ static inline void dump_sigact_irix5(struct sigact_irix5 *p) #endif asmlinkage int irix_sigaction(int sig, const struct sigaction *act, struct sigaction *oact, void *trampoline) irix_sigaction(int sig, const struct sigaction __user *act, struct sigaction __user *oact, void __user *trampoline) { struct k_sigaction new_ka, old_ka; int ret; Loading @@ -311,12 +324,16 @@ irix_sigaction(int sig, const struct sigaction *act, #endif if (act) { sigset_t mask; if (!access_ok(VERIFY_READ, act, sizeof(*act)) || __get_user(new_ka.sa.sa_handler, &act->sa_handler) || __get_user(new_ka.sa.sa_flags, &act->sa_flags)) int err; if (!access_ok(VERIFY_READ, act, sizeof(*act))) return -EFAULT; err = __get_user(new_ka.sa.sa_handler, &act->sa_handler); err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags); __copy_from_user(&mask, &act->sa_mask, sizeof(sigset_t)); err |= __copy_from_user(&mask, &act->sa_mask, sizeof(sigset_t)) ? -EFAULT : 0; if (err) return err; /* * Hmmm... methinks IRIX libc always passes a valid trampoline Loading @@ -330,30 +347,37 @@ irix_sigaction(int sig, const struct sigaction *act, ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); if (!ret && oact) { if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || __put_user(old_ka.sa.sa_flags, &oact->sa_flags)) int err; if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact))) return -EFAULT; err = __put_user(old_ka.sa.sa_handler, &oact->sa_handler); err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags); err |= __copy_to_user(&oact->sa_mask, &old_ka.sa.sa_mask, sizeof(sigset_t)) ? -EFAULT : 0; if (err) return -EFAULT; __copy_to_user(&old_ka.sa.sa_mask, &oact->sa_mask, sizeof(sigset_t)); } return ret; } asmlinkage int irix_sigpending(irix_sigset_t *set) asmlinkage int irix_sigpending(irix_sigset_t __user *set) { return do_sigpending(set, sizeof(*set)); } asmlinkage int irix_sigprocmask(int how, irix_sigset_t *new, irix_sigset_t *old) asmlinkage int irix_sigprocmask(int how, irix_sigset_t __user *new, irix_sigset_t __user *old) { sigset_t oldbits, newbits; if (new) { if (!access_ok(VERIFY_READ, new, sizeof(*new))) return -EFAULT; __copy_from_user(&newbits, new, sizeof(unsigned long)*4); if (__copy_from_user(&newbits, new, sizeof(unsigned long)*4)) return -EFAULT; sigdelsetmask(&newbits, ~_BLOCKABLE); spin_lock_irq(¤t->sighand->siglock); Loading Loading @@ -381,20 +405,19 @@ asmlinkage int irix_sigprocmask(int how, irix_sigset_t *new, irix_sigset_t *old) recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); } if(old) { if (!access_ok(VERIFY_WRITE, old, sizeof(*old))) return -EFAULT; __copy_to_user(old, ¤t->blocked, sizeof(unsigned long)*4); } if (old) return copy_to_user(old, ¤t->blocked, sizeof(unsigned long)*4) ? -EFAULT : 0; return 0; } asmlinkage int irix_sigsuspend(struct pt_regs *regs) { sigset_t *uset, saveset, newset; sigset_t saveset, newset; sigset_t __user *uset; uset = (sigset_t *) regs->regs[4]; uset = (sigset_t __user *) regs->regs[4]; if (copy_from_user(&newset, uset, sizeof(sigset_t))) return -EFAULT; sigdelsetmask(&newset, ~_BLOCKABLE); Loading Loading @@ -440,12 +463,13 @@ struct irix5_siginfo { } stuff; }; asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info, struct timespec *tp) asmlinkage int irix_sigpoll_sys(unsigned long __user *set, struct irix5_siginfo __user *info, struct timespec __user *tp) { long expire = MAX_SCHEDULE_TIMEOUT; sigset_t kset; int i, sig, error, timeo = 0; struct timespec ktp; #ifdef DEBUG_SIG printk("[%s:%d] irix_sigpoll_sys(%p,%p,%p)\n", Loading @@ -456,14 +480,8 @@ asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info, if (!set) return -EINVAL; if (!access_ok(VERIFY_READ, set, sizeof(kset))) { error = -EFAULT; goto out; } __copy_from_user(&kset, set, sizeof(set)); if (error) goto out; if (copy_from_user(&kset, set, sizeof(set))) return -EFAULT; if (info && clear_user(info, sizeof(*info))) { error = -EFAULT; Loading @@ -471,19 +489,21 @@ asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info, } if (tp) { if (!access_ok(VERIFY_READ, tp, sizeof(*tp))) if (copy_from_user(&ktp, tp, sizeof(*tp))) return -EFAULT; if (!tp->tv_sec && !tp->tv_nsec) { error = -EINVAL; goto out; } expire = timespec_to_jiffies(tp) + (tp->tv_sec||tp->tv_nsec); if (!ktp.tv_sec && !ktp.tv_nsec) return -EINVAL; expire = timespec_to_jiffies(&ktp) + (ktp.tv_sec || ktp.tv_nsec); } while(1) { long tmp = 0; expire = schedule_timeout_interruptible(expire); current->state = TASK_INTERRUPTIBLE; expire = schedule_timeout(expire); for (i=0; i<=4; i++) tmp |= (current->pending.signal.sig[i] & kset.sig[i]); Loading @@ -506,9 +526,8 @@ asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info, if (sigismember (¤t->pending.signal, sig)) { /* XXX need more than this... */ if (info) info->sig = sig; error = 0; goto out; return copy_to_user(&info->sig, &sig, sizeof(sig)); return 0; } } Loading @@ -534,8 +553,9 @@ extern int getrusage(struct task_struct *, int, struct rusage __user *); #define W_MASK (W_EXITED | W_TRAPPED | W_STOPPED | W_CONT | W_NOHANG) asmlinkage int irix_waitsys(int type, int pid, struct irix5_siginfo *info, int options, struct rusage *ru) asmlinkage int irix_waitsys(int type, int pid, struct irix5_siginfo __user *info, int options, struct rusage __user *ru) { int flag, retval; DECLARE_WAITQUEUE(wait, current); Loading @@ -543,28 +563,22 @@ asmlinkage int irix_waitsys(int type, int pid, struct irix5_siginfo *info, struct task_struct *p; struct list_head *_p; if (!info) { retval = -EINVAL; goto out; } if (!access_ok(VERIFY_WRITE, info, sizeof(*info))) { retval = -EFAULT; goto out; } if (ru) { if (!access_ok(VERIFY_WRITE, ru, sizeof(*ru))) { retval = -EFAULT; goto out; } } if (options & ~(W_MASK)) { retval = -EINVAL; goto out; } if (type != IRIX_P_PID && type != IRIX_P_PGID && type != IRIX_P_ALL) { retval = -EINVAL; goto out; } if (!info) return -EINVAL; if (!access_ok(VERIFY_WRITE, info, sizeof(*info))) return -EFAULT; if (ru) if (!access_ok(VERIFY_WRITE, ru, sizeof(*ru))) return -EFAULT; if (options & ~W_MASK) return -EINVAL; if (type != IRIX_P_PID && type != IRIX_P_PGID && type != IRIX_P_ALL) return -EINVAL; add_wait_queue(¤t->signal->wait_chldexit, &wait); repeat: flag = 0; Loading Loading @@ -595,18 +609,20 @@ asmlinkage int irix_waitsys(int type, int pid, struct irix5_siginfo *info, add_parent(p, p->parent); write_unlock_irq(&tasklist_lock); retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0; if (!retval && ru) { retval |= __put_user(SIGCHLD, &info->sig); if (retval) goto end_waitsys; retval = __put_user(SIGCHLD, &info->sig); retval |= __put_user(0, &info->code); retval |= __put_user(p->pid, &info->stuff.procinfo.pid); retval |= __put_user((p->exit_code >> 8) & 0xff, &info->stuff.procinfo.procdata.child.status); retval |= __put_user(p->utime, &info->stuff.procinfo.procdata.child.utime); retval |= __put_user(p->stime, &info->stuff.procinfo.procdata.child.stime); } if (!retval) { if (retval) goto end_waitsys; p->exit_code = 0; } goto end_waitsys; case EXIT_ZOMBIE: Loading @@ -614,16 +630,18 @@ asmlinkage int irix_waitsys(int type, int pid, struct irix5_siginfo *info, current->signal->cstime += p->stime + p->signal->cstime; if (ru != NULL) getrusage(p, RUSAGE_BOTH, ru); __put_user(SIGCHLD, &info->sig); __put_user(1, &info->code); /* CLD_EXITED */ __put_user(p->pid, &info->stuff.procinfo.pid); __put_user((p->exit_code >> 8) & 0xff, retval = __put_user(SIGCHLD, &info->sig); retval |= __put_user(1, &info->code); /* CLD_EXITED */ retval |= __put_user(p->pid, &info->stuff.procinfo.pid); retval |= __put_user((p->exit_code >> 8) & 0xff, &info->stuff.procinfo.procdata.child.status); __put_user(p->utime, retval |= __put_user(p->utime, &info->stuff.procinfo.procdata.child.utime); __put_user(p->stime, retval |= __put_user(p->stime, &info->stuff.procinfo.procdata.child.stime); retval = 0; if (retval) return retval; if (p->real_parent != p->parent) { write_lock_irq(&tasklist_lock); remove_parent(p); Loading Loading @@ -656,7 +674,6 @@ asmlinkage int irix_waitsys(int type, int pid, struct irix5_siginfo *info, current->state = TASK_RUNNING; remove_wait_queue(¤t->signal->wait_chldexit, &wait); out: return retval; } Loading @@ -675,39 +692,39 @@ struct irix5_context { asmlinkage int irix_getcontext(struct pt_regs *regs) { int i, base = 0; struct irix5_context *ctx; int error, i, base = 0; struct irix5_context __user *ctx; unsigned long flags; if (regs->regs[2] == 1000) base = 1; ctx = (struct irix5_context *) regs->regs[base + 4]; ctx = (struct irix5_context __user *) regs->regs[base + 4]; #ifdef DEBUG_SIG printk("[%s:%d] irix_getcontext(%p)\n", current->comm, current->pid, ctx); #endif if (!access_ok(VERIFY_WRITE, ctx, sizeof(*ctx))) if (!access_ok(VERIFY_WRITE, ctx, sizeof(*ctx))); return -EFAULT; __put_user(current->thread.irix_oldctx, &ctx->link); error = __put_user(current->thread.irix_oldctx, &ctx->link); __copy_to_user(&ctx->sigmask, ¤t->blocked, sizeof(irix_sigset_t)); error |= __copy_to_user(&ctx->sigmask, ¤t->blocked, sizeof(irix_sigset_t)) ? -EFAULT : 0; /* XXX Do sigstack stuff someday... */ __put_user(0, &ctx->stack.sp); __put_user(0, &ctx->stack.size); __put_user(0, &ctx->stack.flags); error |= __put_user(0, &ctx->stack.sp); error |= __put_user(0, &ctx->stack.size); error |= __put_user(0, &ctx->stack.flags); __put_user(0, &ctx->weird_graphics_thing); __put_user(0, &ctx->regs[0]); error |= __put_user(0, &ctx->weird_graphics_thing); error |= __put_user(0, &ctx->regs[0]); for (i = 1; i < 32; i++) __put_user(regs->regs[i], &ctx->regs[i]); __put_user(regs->lo, &ctx->regs[32]); __put_user(regs->hi, &ctx->regs[33]); __put_user(regs->cp0_cause, &ctx->regs[34]); __put_user(regs->cp0_epc, &ctx->regs[35]); error |= __put_user(regs->regs[i], &ctx->regs[i]); error |= __put_user(regs->lo, &ctx->regs[32]); error |= __put_user(regs->hi, &ctx->regs[33]); error |= __put_user(regs->cp0_cause, &ctx->regs[34]); error |= __put_user(regs->cp0_epc, &ctx->regs[35]); flags = 0x0f; if (!used_math()) { Loading @@ -716,119 +733,124 @@ asmlinkage int irix_getcontext(struct pt_regs *regs) /* XXX wheee... */ printk("Wheee, no code for saving IRIX FPU context yet.\n"); } __put_user(flags, &ctx->flags); error |= __put_user(flags, &ctx->flags); return 0; return error; } asmlinkage unsigned long irix_setcontext(struct pt_regs *regs) asmlinkage void irix_setcontext(struct pt_regs *regs) { int error, base = 0; struct irix5_context *ctx; struct irix5_context __user *ctx; int err, base = 0; u32 flags; if (regs->regs[2] == 1000) base = 1; ctx = (struct irix5_context *) regs->regs[base + 4]; ctx = (struct irix5_context __user *) regs->regs[base + 4]; #ifdef DEBUG_SIG printk("[%s:%d] irix_setcontext(%p)\n", current->comm, current->pid, ctx); #endif if (!access_ok(VERIFY_READ, ctx, sizeof(*ctx))) { error = -EFAULT; goto out; } if (!access_ok(VERIFY_READ, ctx, sizeof(*ctx))) goto segv_and_exit; if (ctx->flags & 0x02) { err = __get_user(flags, &ctx->flags); if (flags & 0x02) { /* XXX sigstack garbage, todo... */ printk("Wheee, cannot do sigstack stuff in setcontext\n"); } if (ctx->flags & 0x04) { if (flags & 0x04) { int i; /* XXX extra control block stuff... todo... */ for (i = 1; i < 32; i++) regs->regs[i] = ctx->regs[i]; regs->lo = ctx->regs[32]; regs->hi = ctx->regs[33]; regs->cp0_epc = ctx->regs[35]; err |= __get_user(regs->regs[i], &ctx->regs[i]); err |= __get_user(regs->lo, &ctx->regs[32]); err |= __get_user(regs->hi, &ctx->regs[33]); err |= __get_user(regs->cp0_epc, &ctx->regs[35]); } if (ctx->flags & 0x08) { if (flags & 0x08) /* XXX fpu context, blah... */ printk("Wheee, cannot restore FPU context yet...\n"); } current->thread.irix_oldctx = ctx->link; error = regs->regs[2]; printk(KERN_ERR "Wheee, cannot restore FPU context yet...\n"); out: return error; err |= __get_user(current->thread.irix_oldctx, &ctx->link); if (err) goto segv_and_exit; /* * Don't let your children do this ... */ if (current_thread_info()->flags & TIF_SYSCALL_TRACE) do_syscall_trace(regs, 1); __asm__ __volatile__( "move\t$29,%0\n\t" "j\tsyscall_exit" :/* no outputs */ :"r" (®s)); /* Unreached */ segv_and_exit: force_sigsegv(SIGSEGV, current); } struct irix_sigstack { unsigned long sp; int status; }; struct irix_sigstack { unsigned long sp; int status; }; asmlinkage int irix_sigstack(struct irix_sigstack *new, struct irix_sigstack *old) asmlinkage int irix_sigstack(struct irix_sigstack __user *new, struct irix_sigstack __user *old) { int error = -EFAULT; #ifdef DEBUG_SIG printk("[%s:%d] irix_sigstack(%p,%p)\n", current->comm, current->pid, new, old); #endif if (new) { if (!access_ok(VERIFY_READ, new, sizeof(*new))) goto out; return -EFAULT; } if (old) { if (!access_ok(VERIFY_WRITE, old, sizeof(*old))) goto out; return -EFAULT; } error = 0; out: return error; return 0; } struct irix_sigaltstack { unsigned long sp; int size; int status; }; asmlinkage int irix_sigaltstack(struct irix_sigaltstack *new, struct irix_sigaltstack *old) asmlinkage int irix_sigaltstack(struct irix_sigaltstack __user *new, struct irix_sigaltstack __user *old) { int error = -EFAULT; #ifdef DEBUG_SIG printk("[%s:%d] irix_sigaltstack(%p,%p)\n", current->comm, current->pid, new, old); #endif if (new) { if (new) if (!access_ok(VERIFY_READ, new, sizeof(*new))) goto out; } return -EFAULT; if (old) { if (!access_ok(VERIFY_WRITE, old, sizeof(*old))) goto out; return -EFAULT; } error = 0; out: error = 0; return error; return 0; } struct irix_procset { int cmd, ltype, lid, rtype, rid; }; asmlinkage int irix_sigsendset(struct irix_procset *pset, int sig) asmlinkage int irix_sigsendset(struct irix_procset __user *pset, int sig) { if (!access_ok(VERIFY_READ, pset, sizeof(*pset))) return -EFAULT; #ifdef DEBUG_SIG printk("[%s:%d] irix_sigsendset([%d,%d,%d,%d,%d],%d)\n", current->comm, current->pid, Loading Loading
arch/mips/Makefile +15 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,21 @@ ifdef CONFIG_CROSSCOMPILE CROSS_COMPILE := $(tool-prefix) endif CHECKFLAGS-y += -D__linux__ -D__mips__ \ -D_ABIO32=1 \ -D_ABIN32=2 \ -D_ABI64=3 CHECKFLAGS-$(CONFIG_32BIT) += -D_MIPS_SIM=_ABIO32 \ -D_MIPS_SZLONG=32 \ -D__PTRDIFF_TYPE__=int CHECKFLAGS-$(CONFIG_64BIT) += -m64 -D_MIPS_SIM=_ABI64 \ -D_MIPS_SZLONG=64 \ -D__PTRDIFF_TYPE__="long int" CHECKFLAGS-$(CONFIG_CPU_BIG_ENDIAN) += -D__MIPSEB__ CHECKFLAGS-$(CONFIG_CPU_LITTLE_ENDIAN) += -D__MIPSEL__ CHECKFLAGS = $(CHECKFLAGS-y) ifdef CONFIG_BUILD_ELF64 gas-abi = 64 ld-emul = $(64bit-emul) Loading
arch/mips/kernel/i8259.c +1 −1 Original line number Diff line number Diff line Loading @@ -321,7 +321,7 @@ void __init init_i8259_irqs (void) for (i = 0; i < 16; i++) { irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].action = NULL; irq_desc[i].depth = 1; irq_desc[i].handler = &i8259A_irq_type; } Loading
arch/mips/kernel/irixelf.c +7 −7 Original line number Diff line number Diff line Loading @@ -147,7 +147,7 @@ static void padzero(unsigned long elf_bss) nbyte = elf_bss & (PAGE_SIZE-1); if (nbyte) { nbyte = PAGE_SIZE - nbyte; clear_user((void *) elf_bss, nbyte); clear_user((void __user *) elf_bss, nbyte); } } Loading Loading @@ -878,10 +878,10 @@ static int load_irix_library(struct file *file) * phdrs there are in the USER_PHDRP array. We return the vaddr the * first phdr was successfully mapped to. */ unsigned long irix_mapelf(int fd, struct elf_phdr *user_phdrp, int cnt) unsigned long irix_mapelf(int fd, struct elf_phdr __user *user_phdrp, int cnt) { unsigned long type, vaddr, filesz, offset, flags; struct elf_phdr *hp; struct elf_phdr __user *hp; struct file *filp; int i, retval; Loading Loading @@ -968,9 +968,9 @@ unsigned long irix_mapelf(int fd, struct elf_phdr *user_phdrp, int cnt) /* These are the only things you should do on a core-file: use only these * functions to write out all the necessary info. */ static int dump_write(struct file *file, const void *addr, int nr) static int dump_write(struct file *file, const void __user *addr, int nr) { return file->f_op->write(file, (const char *) addr, nr, &file->f_pos) == nr; return file->f_op->write(file, (const char __user *) addr, nr, &file->f_pos) == nr; } static int dump_seek(struct file *file, off_t off) Loading Loading @@ -1204,7 +1204,7 @@ static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file) len = current->mm->arg_end - current->mm->arg_start; len = len >= ELF_PRARGSZ ? ELF_PRARGSZ : len; (void *) copy_from_user(&psinfo.pr_psargs, (const char *)current->mm->arg_start, len); (const char __user *)current->mm->arg_start, len); for (i = 0; i < len; i++) if (psinfo.pr_psargs[i] == 0) psinfo.pr_psargs[i] = ' '; Loading Loading @@ -1301,7 +1301,7 @@ static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file) #ifdef DEBUG printk("elf_core_dump: writing %08lx %lx\n", addr, len); #endif DUMP_WRITE((void *)addr, len); DUMP_WRITE((void __user *)addr, len); } if ((off_t) file->f_pos != offset) { Loading
arch/mips/kernel/irixinv.c +4 −3 Original line number Diff line number Diff line Loading @@ -30,10 +30,10 @@ void add_to_inventory (int class, int type, int controller, int unit, int state) inventory_items++; } int dump_inventory_to_user (void *userbuf, int size) int dump_inventory_to_user (void __user *userbuf, int size) { inventory_t *inv = &inventory [0]; inventory_t *user = userbuf; inventory_t __user *user = userbuf; int v; if (!access_ok(VERIFY_WRITE, userbuf, size)) Loading @@ -41,7 +41,8 @@ int dump_inventory_to_user (void *userbuf, int size) for (v = 0; v < inventory_items; v++){ inv = &inventory [v]; copy_to_user (user, inv, sizeof (inventory_t)); if (copy_to_user (user, inv, sizeof (inventory_t))) return -EFAULT; user++; } return inventory_items * sizeof (inventory_t); Loading
arch/mips/kernel/irixsig.c +215 −193 Original line number Diff line number Diff line Loading @@ -76,36 +76,39 @@ static inline void dump_irix5_sigctx(struct sigctx_irix5 *c) } #endif static void setup_irix_frame(struct k_sigaction *ka, struct pt_regs *regs, static int setup_irix_frame(struct k_sigaction *ka, struct pt_regs *regs, int signr, sigset_t *oldmask) { struct sigctx_irix5 __user *ctx; unsigned long sp; struct sigctx_irix5 *ctx; int i; int error, i; sp = regs->regs[29]; sp -= sizeof(struct sigctx_irix5); sp &= ~(0xf); ctx = (struct sigctx_irix5 *) sp; ctx = (struct sigctx_irix5 __user *) sp; if (!access_ok(VERIFY_WRITE, ctx, sizeof(*ctx))) goto segv_and_exit; __put_user(0, &ctx->weird_fpu_thing); __put_user(~(0x00000001), &ctx->rmask); __put_user(0, &ctx->regs[0]); error = __put_user(0, &ctx->weird_fpu_thing); error |= __put_user(~(0x00000001), &ctx->rmask); error |= __put_user(0, &ctx->regs[0]); for(i = 1; i < 32; i++) __put_user((u64) regs->regs[i], &ctx->regs[i]); error |= __put_user((u64) regs->regs[i], &ctx->regs[i]); error |= __put_user((u64) regs->hi, &ctx->hi); error |= __put_user((u64) regs->lo, &ctx->lo); error |= __put_user((u64) regs->cp0_epc, &ctx->pc); error |= __put_user(!!used_math(), &ctx->usedfp); error |= __put_user((u64) regs->cp0_cause, &ctx->cp0_cause); error |= __put_user((u64) regs->cp0_badvaddr, &ctx->cp0_badvaddr); __put_user((u64) regs->hi, &ctx->hi); __put_user((u64) regs->lo, &ctx->lo); __put_user((u64) regs->cp0_epc, &ctx->pc); __put_user(!!used_math(), &ctx->usedfp); __put_user((u64) regs->cp0_cause, &ctx->cp0_cause); __put_user((u64) regs->cp0_badvaddr, &ctx->cp0_badvaddr); error |= __put_user(0, &ctx->sstk_flags); /* XXX sigstack unimp... todo... */ __put_user(0, &ctx->sstk_flags); /* XXX sigstack unimp... todo... */ error |= __copy_to_user(&ctx->sigset, oldmask, sizeof(irix_sigset_t)) ? -EFAULT : 0; __copy_to_user(&ctx->sigset, oldmask, sizeof(irix_sigset_t)); if (error) goto segv_and_exit; #ifdef DEBUG_SIG dump_irix5_sigctx(ctx); Loading @@ -117,13 +120,14 @@ static void setup_irix_frame(struct k_sigaction *ka, struct pt_regs *regs, regs->regs[7] = (unsigned long) ka->sa.sa_handler; regs->regs[25] = regs->cp0_epc = (unsigned long) ka->sa_restorer; return; return 1; segv_and_exit: force_sigsegv(signr, current); return 0; } static void inline static int inline setup_irix_rt_frame(struct k_sigaction * ka, struct pt_regs *regs, int signr, sigset_t *oldmask, siginfo_t *info) { Loading @@ -131,9 +135,11 @@ setup_irix_rt_frame(struct k_sigaction * ka, struct pt_regs *regs, do_exit(SIGSEGV); } static inline void handle_signal(unsigned long sig, siginfo_t *info, static inline int handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, sigset_t *oldset, struct pt_regs * regs) { int ret; switch(regs->regs[0]) { case ERESTARTNOHAND: regs->regs[2] = EINTR; Loading @@ -151,9 +157,9 @@ static inline void handle_signal(unsigned long sig, siginfo_t *info, regs->regs[0] = 0; /* Don't deal with this again. */ if (ka->sa.sa_flags & SA_SIGINFO) setup_irix_rt_frame(ka, regs, sig, oldset, info); ret = setup_irix_rt_frame(ka, regs, sig, oldset, info); else setup_irix_frame(ka, regs, sig, oldset); ret = setup_irix_frame(ka, regs, sig, oldset); spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); Loading @@ -161,6 +167,8 @@ static inline void handle_signal(unsigned long sig, siginfo_t *info, sigaddset(¤t->blocked,sig); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); return ret; } asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs) Loading @@ -184,10 +192,8 @@ asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs) oldset = ¤t->blocked; signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { handle_signal(signr, &info, &ka, oldset, regs); return 1; } if (signr > 0) return handle_signal(signr, &info, &ka, oldset, regs); no_signal: /* Loading @@ -208,10 +214,11 @@ asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs) asmlinkage void irix_sigreturn(struct pt_regs *regs) { struct sigctx_irix5 *context, *magic; struct sigctx_irix5 __user *context, *magic; unsigned long umask, mask; u64 *fregs; int sig, i, base = 0; u32 usedfp; int error, sig, i, base = 0; sigset_t blocked; /* Always make any pending restarted system calls return -EINTR */ Loading @@ -220,8 +227,8 @@ irix_sigreturn(struct pt_regs *regs) if (regs->regs[2] == 1000) base = 1; context = (struct sigctx_irix5 *) regs->regs[base + 4]; magic = (struct sigctx_irix5 *) regs->regs[base + 5]; context = (struct sigctx_irix5 __user *) regs->regs[base + 4]; magic = (struct sigctx_irix5 __user *) regs->regs[base + 5]; sig = (int) regs->regs[base + 6]; #ifdef DEBUG_SIG printk("[%s:%d] IRIX sigreturn(scp[%p],ucp[%p],sig[%d])\n", Loading @@ -236,25 +243,31 @@ irix_sigreturn(struct pt_regs *regs) dump_irix5_sigctx(context); #endif __get_user(regs->cp0_epc, &context->pc); umask = context->rmask; mask = 2; error = __get_user(regs->cp0_epc, &context->pc); error |= __get_user(umask, &context->rmask); mask = 2; for (i = 1; i < 32; i++, mask <<= 1) { if (umask & mask) __get_user(regs->regs[i], &context->regs[i]); error |= __get_user(regs->regs[i], &context->regs[i]); } __get_user(regs->hi, &context->hi); __get_user(regs->lo, &context->lo); error |= __get_user(regs->hi, &context->hi); error |= __get_user(regs->lo, &context->lo); if ((umask & 1) && context->usedfp) { error |= __get_user(usedfp, &context->usedfp); if ((umask & 1) && usedfp) { fregs = (u64 *) ¤t->thread.fpu; for(i = 0; i < 32; i++) fregs[i] = (u64) context->fpregs[i]; __get_user(current->thread.fpu.hard.fcr31, &context->fpcsr); error |= __get_user(fregs[i], &context->fpregs[i]); error |= __get_user(current->thread.fpu.hard.fcr31, &context->fpcsr); } /* XXX do sigstack crapola here... XXX */ if (__copy_from_user(&blocked, &context->sigset, sizeof(blocked))) error |= __copy_from_user(&blocked, &context->sigset, sizeof(blocked)) ? -EFAULT : 0; if (error) goto badframe; sigdelsetmask(&blocked, ~_BLOCKABLE); Loading Loading @@ -296,8 +309,8 @@ static inline void dump_sigact_irix5(struct sigact_irix5 *p) #endif asmlinkage int irix_sigaction(int sig, const struct sigaction *act, struct sigaction *oact, void *trampoline) irix_sigaction(int sig, const struct sigaction __user *act, struct sigaction __user *oact, void __user *trampoline) { struct k_sigaction new_ka, old_ka; int ret; Loading @@ -311,12 +324,16 @@ irix_sigaction(int sig, const struct sigaction *act, #endif if (act) { sigset_t mask; if (!access_ok(VERIFY_READ, act, sizeof(*act)) || __get_user(new_ka.sa.sa_handler, &act->sa_handler) || __get_user(new_ka.sa.sa_flags, &act->sa_flags)) int err; if (!access_ok(VERIFY_READ, act, sizeof(*act))) return -EFAULT; err = __get_user(new_ka.sa.sa_handler, &act->sa_handler); err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags); __copy_from_user(&mask, &act->sa_mask, sizeof(sigset_t)); err |= __copy_from_user(&mask, &act->sa_mask, sizeof(sigset_t)) ? -EFAULT : 0; if (err) return err; /* * Hmmm... methinks IRIX libc always passes a valid trampoline Loading @@ -330,30 +347,37 @@ irix_sigaction(int sig, const struct sigaction *act, ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); if (!ret && oact) { if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || __put_user(old_ka.sa.sa_flags, &oact->sa_flags)) int err; if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact))) return -EFAULT; err = __put_user(old_ka.sa.sa_handler, &oact->sa_handler); err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags); err |= __copy_to_user(&oact->sa_mask, &old_ka.sa.sa_mask, sizeof(sigset_t)) ? -EFAULT : 0; if (err) return -EFAULT; __copy_to_user(&old_ka.sa.sa_mask, &oact->sa_mask, sizeof(sigset_t)); } return ret; } asmlinkage int irix_sigpending(irix_sigset_t *set) asmlinkage int irix_sigpending(irix_sigset_t __user *set) { return do_sigpending(set, sizeof(*set)); } asmlinkage int irix_sigprocmask(int how, irix_sigset_t *new, irix_sigset_t *old) asmlinkage int irix_sigprocmask(int how, irix_sigset_t __user *new, irix_sigset_t __user *old) { sigset_t oldbits, newbits; if (new) { if (!access_ok(VERIFY_READ, new, sizeof(*new))) return -EFAULT; __copy_from_user(&newbits, new, sizeof(unsigned long)*4); if (__copy_from_user(&newbits, new, sizeof(unsigned long)*4)) return -EFAULT; sigdelsetmask(&newbits, ~_BLOCKABLE); spin_lock_irq(¤t->sighand->siglock); Loading Loading @@ -381,20 +405,19 @@ asmlinkage int irix_sigprocmask(int how, irix_sigset_t *new, irix_sigset_t *old) recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); } if(old) { if (!access_ok(VERIFY_WRITE, old, sizeof(*old))) return -EFAULT; __copy_to_user(old, ¤t->blocked, sizeof(unsigned long)*4); } if (old) return copy_to_user(old, ¤t->blocked, sizeof(unsigned long)*4) ? -EFAULT : 0; return 0; } asmlinkage int irix_sigsuspend(struct pt_regs *regs) { sigset_t *uset, saveset, newset; sigset_t saveset, newset; sigset_t __user *uset; uset = (sigset_t *) regs->regs[4]; uset = (sigset_t __user *) regs->regs[4]; if (copy_from_user(&newset, uset, sizeof(sigset_t))) return -EFAULT; sigdelsetmask(&newset, ~_BLOCKABLE); Loading Loading @@ -440,12 +463,13 @@ struct irix5_siginfo { } stuff; }; asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info, struct timespec *tp) asmlinkage int irix_sigpoll_sys(unsigned long __user *set, struct irix5_siginfo __user *info, struct timespec __user *tp) { long expire = MAX_SCHEDULE_TIMEOUT; sigset_t kset; int i, sig, error, timeo = 0; struct timespec ktp; #ifdef DEBUG_SIG printk("[%s:%d] irix_sigpoll_sys(%p,%p,%p)\n", Loading @@ -456,14 +480,8 @@ asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info, if (!set) return -EINVAL; if (!access_ok(VERIFY_READ, set, sizeof(kset))) { error = -EFAULT; goto out; } __copy_from_user(&kset, set, sizeof(set)); if (error) goto out; if (copy_from_user(&kset, set, sizeof(set))) return -EFAULT; if (info && clear_user(info, sizeof(*info))) { error = -EFAULT; Loading @@ -471,19 +489,21 @@ asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info, } if (tp) { if (!access_ok(VERIFY_READ, tp, sizeof(*tp))) if (copy_from_user(&ktp, tp, sizeof(*tp))) return -EFAULT; if (!tp->tv_sec && !tp->tv_nsec) { error = -EINVAL; goto out; } expire = timespec_to_jiffies(tp) + (tp->tv_sec||tp->tv_nsec); if (!ktp.tv_sec && !ktp.tv_nsec) return -EINVAL; expire = timespec_to_jiffies(&ktp) + (ktp.tv_sec || ktp.tv_nsec); } while(1) { long tmp = 0; expire = schedule_timeout_interruptible(expire); current->state = TASK_INTERRUPTIBLE; expire = schedule_timeout(expire); for (i=0; i<=4; i++) tmp |= (current->pending.signal.sig[i] & kset.sig[i]); Loading @@ -506,9 +526,8 @@ asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info, if (sigismember (¤t->pending.signal, sig)) { /* XXX need more than this... */ if (info) info->sig = sig; error = 0; goto out; return copy_to_user(&info->sig, &sig, sizeof(sig)); return 0; } } Loading @@ -534,8 +553,9 @@ extern int getrusage(struct task_struct *, int, struct rusage __user *); #define W_MASK (W_EXITED | W_TRAPPED | W_STOPPED | W_CONT | W_NOHANG) asmlinkage int irix_waitsys(int type, int pid, struct irix5_siginfo *info, int options, struct rusage *ru) asmlinkage int irix_waitsys(int type, int pid, struct irix5_siginfo __user *info, int options, struct rusage __user *ru) { int flag, retval; DECLARE_WAITQUEUE(wait, current); Loading @@ -543,28 +563,22 @@ asmlinkage int irix_waitsys(int type, int pid, struct irix5_siginfo *info, struct task_struct *p; struct list_head *_p; if (!info) { retval = -EINVAL; goto out; } if (!access_ok(VERIFY_WRITE, info, sizeof(*info))) { retval = -EFAULT; goto out; } if (ru) { if (!access_ok(VERIFY_WRITE, ru, sizeof(*ru))) { retval = -EFAULT; goto out; } } if (options & ~(W_MASK)) { retval = -EINVAL; goto out; } if (type != IRIX_P_PID && type != IRIX_P_PGID && type != IRIX_P_ALL) { retval = -EINVAL; goto out; } if (!info) return -EINVAL; if (!access_ok(VERIFY_WRITE, info, sizeof(*info))) return -EFAULT; if (ru) if (!access_ok(VERIFY_WRITE, ru, sizeof(*ru))) return -EFAULT; if (options & ~W_MASK) return -EINVAL; if (type != IRIX_P_PID && type != IRIX_P_PGID && type != IRIX_P_ALL) return -EINVAL; add_wait_queue(¤t->signal->wait_chldexit, &wait); repeat: flag = 0; Loading Loading @@ -595,18 +609,20 @@ asmlinkage int irix_waitsys(int type, int pid, struct irix5_siginfo *info, add_parent(p, p->parent); write_unlock_irq(&tasklist_lock); retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0; if (!retval && ru) { retval |= __put_user(SIGCHLD, &info->sig); if (retval) goto end_waitsys; retval = __put_user(SIGCHLD, &info->sig); retval |= __put_user(0, &info->code); retval |= __put_user(p->pid, &info->stuff.procinfo.pid); retval |= __put_user((p->exit_code >> 8) & 0xff, &info->stuff.procinfo.procdata.child.status); retval |= __put_user(p->utime, &info->stuff.procinfo.procdata.child.utime); retval |= __put_user(p->stime, &info->stuff.procinfo.procdata.child.stime); } if (!retval) { if (retval) goto end_waitsys; p->exit_code = 0; } goto end_waitsys; case EXIT_ZOMBIE: Loading @@ -614,16 +630,18 @@ asmlinkage int irix_waitsys(int type, int pid, struct irix5_siginfo *info, current->signal->cstime += p->stime + p->signal->cstime; if (ru != NULL) getrusage(p, RUSAGE_BOTH, ru); __put_user(SIGCHLD, &info->sig); __put_user(1, &info->code); /* CLD_EXITED */ __put_user(p->pid, &info->stuff.procinfo.pid); __put_user((p->exit_code >> 8) & 0xff, retval = __put_user(SIGCHLD, &info->sig); retval |= __put_user(1, &info->code); /* CLD_EXITED */ retval |= __put_user(p->pid, &info->stuff.procinfo.pid); retval |= __put_user((p->exit_code >> 8) & 0xff, &info->stuff.procinfo.procdata.child.status); __put_user(p->utime, retval |= __put_user(p->utime, &info->stuff.procinfo.procdata.child.utime); __put_user(p->stime, retval |= __put_user(p->stime, &info->stuff.procinfo.procdata.child.stime); retval = 0; if (retval) return retval; if (p->real_parent != p->parent) { write_lock_irq(&tasklist_lock); remove_parent(p); Loading Loading @@ -656,7 +674,6 @@ asmlinkage int irix_waitsys(int type, int pid, struct irix5_siginfo *info, current->state = TASK_RUNNING; remove_wait_queue(¤t->signal->wait_chldexit, &wait); out: return retval; } Loading @@ -675,39 +692,39 @@ struct irix5_context { asmlinkage int irix_getcontext(struct pt_regs *regs) { int i, base = 0; struct irix5_context *ctx; int error, i, base = 0; struct irix5_context __user *ctx; unsigned long flags; if (regs->regs[2] == 1000) base = 1; ctx = (struct irix5_context *) regs->regs[base + 4]; ctx = (struct irix5_context __user *) regs->regs[base + 4]; #ifdef DEBUG_SIG printk("[%s:%d] irix_getcontext(%p)\n", current->comm, current->pid, ctx); #endif if (!access_ok(VERIFY_WRITE, ctx, sizeof(*ctx))) if (!access_ok(VERIFY_WRITE, ctx, sizeof(*ctx))); return -EFAULT; __put_user(current->thread.irix_oldctx, &ctx->link); error = __put_user(current->thread.irix_oldctx, &ctx->link); __copy_to_user(&ctx->sigmask, ¤t->blocked, sizeof(irix_sigset_t)); error |= __copy_to_user(&ctx->sigmask, ¤t->blocked, sizeof(irix_sigset_t)) ? -EFAULT : 0; /* XXX Do sigstack stuff someday... */ __put_user(0, &ctx->stack.sp); __put_user(0, &ctx->stack.size); __put_user(0, &ctx->stack.flags); error |= __put_user(0, &ctx->stack.sp); error |= __put_user(0, &ctx->stack.size); error |= __put_user(0, &ctx->stack.flags); __put_user(0, &ctx->weird_graphics_thing); __put_user(0, &ctx->regs[0]); error |= __put_user(0, &ctx->weird_graphics_thing); error |= __put_user(0, &ctx->regs[0]); for (i = 1; i < 32; i++) __put_user(regs->regs[i], &ctx->regs[i]); __put_user(regs->lo, &ctx->regs[32]); __put_user(regs->hi, &ctx->regs[33]); __put_user(regs->cp0_cause, &ctx->regs[34]); __put_user(regs->cp0_epc, &ctx->regs[35]); error |= __put_user(regs->regs[i], &ctx->regs[i]); error |= __put_user(regs->lo, &ctx->regs[32]); error |= __put_user(regs->hi, &ctx->regs[33]); error |= __put_user(regs->cp0_cause, &ctx->regs[34]); error |= __put_user(regs->cp0_epc, &ctx->regs[35]); flags = 0x0f; if (!used_math()) { Loading @@ -716,119 +733,124 @@ asmlinkage int irix_getcontext(struct pt_regs *regs) /* XXX wheee... */ printk("Wheee, no code for saving IRIX FPU context yet.\n"); } __put_user(flags, &ctx->flags); error |= __put_user(flags, &ctx->flags); return 0; return error; } asmlinkage unsigned long irix_setcontext(struct pt_regs *regs) asmlinkage void irix_setcontext(struct pt_regs *regs) { int error, base = 0; struct irix5_context *ctx; struct irix5_context __user *ctx; int err, base = 0; u32 flags; if (regs->regs[2] == 1000) base = 1; ctx = (struct irix5_context *) regs->regs[base + 4]; ctx = (struct irix5_context __user *) regs->regs[base + 4]; #ifdef DEBUG_SIG printk("[%s:%d] irix_setcontext(%p)\n", current->comm, current->pid, ctx); #endif if (!access_ok(VERIFY_READ, ctx, sizeof(*ctx))) { error = -EFAULT; goto out; } if (!access_ok(VERIFY_READ, ctx, sizeof(*ctx))) goto segv_and_exit; if (ctx->flags & 0x02) { err = __get_user(flags, &ctx->flags); if (flags & 0x02) { /* XXX sigstack garbage, todo... */ printk("Wheee, cannot do sigstack stuff in setcontext\n"); } if (ctx->flags & 0x04) { if (flags & 0x04) { int i; /* XXX extra control block stuff... todo... */ for (i = 1; i < 32; i++) regs->regs[i] = ctx->regs[i]; regs->lo = ctx->regs[32]; regs->hi = ctx->regs[33]; regs->cp0_epc = ctx->regs[35]; err |= __get_user(regs->regs[i], &ctx->regs[i]); err |= __get_user(regs->lo, &ctx->regs[32]); err |= __get_user(regs->hi, &ctx->regs[33]); err |= __get_user(regs->cp0_epc, &ctx->regs[35]); } if (ctx->flags & 0x08) { if (flags & 0x08) /* XXX fpu context, blah... */ printk("Wheee, cannot restore FPU context yet...\n"); } current->thread.irix_oldctx = ctx->link; error = regs->regs[2]; printk(KERN_ERR "Wheee, cannot restore FPU context yet...\n"); out: return error; err |= __get_user(current->thread.irix_oldctx, &ctx->link); if (err) goto segv_and_exit; /* * Don't let your children do this ... */ if (current_thread_info()->flags & TIF_SYSCALL_TRACE) do_syscall_trace(regs, 1); __asm__ __volatile__( "move\t$29,%0\n\t" "j\tsyscall_exit" :/* no outputs */ :"r" (®s)); /* Unreached */ segv_and_exit: force_sigsegv(SIGSEGV, current); } struct irix_sigstack { unsigned long sp; int status; }; struct irix_sigstack { unsigned long sp; int status; }; asmlinkage int irix_sigstack(struct irix_sigstack *new, struct irix_sigstack *old) asmlinkage int irix_sigstack(struct irix_sigstack __user *new, struct irix_sigstack __user *old) { int error = -EFAULT; #ifdef DEBUG_SIG printk("[%s:%d] irix_sigstack(%p,%p)\n", current->comm, current->pid, new, old); #endif if (new) { if (!access_ok(VERIFY_READ, new, sizeof(*new))) goto out; return -EFAULT; } if (old) { if (!access_ok(VERIFY_WRITE, old, sizeof(*old))) goto out; return -EFAULT; } error = 0; out: return error; return 0; } struct irix_sigaltstack { unsigned long sp; int size; int status; }; asmlinkage int irix_sigaltstack(struct irix_sigaltstack *new, struct irix_sigaltstack *old) asmlinkage int irix_sigaltstack(struct irix_sigaltstack __user *new, struct irix_sigaltstack __user *old) { int error = -EFAULT; #ifdef DEBUG_SIG printk("[%s:%d] irix_sigaltstack(%p,%p)\n", current->comm, current->pid, new, old); #endif if (new) { if (new) if (!access_ok(VERIFY_READ, new, sizeof(*new))) goto out; } return -EFAULT; if (old) { if (!access_ok(VERIFY_WRITE, old, sizeof(*old))) goto out; return -EFAULT; } error = 0; out: error = 0; return error; return 0; } struct irix_procset { int cmd, ltype, lid, rtype, rid; }; asmlinkage int irix_sigsendset(struct irix_procset *pset, int sig) asmlinkage int irix_sigsendset(struct irix_procset __user *pset, int sig) { if (!access_ok(VERIFY_READ, pset, sizeof(*pset))) return -EFAULT; #ifdef DEBUG_SIG printk("[%s:%d] irix_sigsendset([%d,%d,%d,%d,%d],%d)\n", current->comm, current->pid, Loading