diff options
Diffstat (limited to 'arch/mips/kernel')
-rw-r--r-- | arch/mips/kernel/Makefile | 2 | ||||
-rw-r--r-- | arch/mips/kernel/entry.S | 5 | ||||
-rw-r--r-- | arch/mips/kernel/head.S | 42 | ||||
-rw-r--r-- | arch/mips/kernel/init_task.c | 22 | ||||
-rw-r--r-- | arch/mips/kernel/irix5sys.h | 2 | ||||
-rw-r--r-- | arch/mips/kernel/irixelf.c | 48 | ||||
-rw-r--r-- | arch/mips/kernel/irixioctl.c | 2 | ||||
-rw-r--r-- | arch/mips/kernel/irixsig.c | 50 | ||||
-rw-r--r-- | arch/mips/kernel/irq.c | 8 | ||||
-rw-r--r-- | arch/mips/kernel/pci.c | 7 | ||||
-rw-r--r-- | arch/mips/kernel/process.c | 11 | ||||
-rw-r--r-- | arch/mips/kernel/ptrace.c | 28 | ||||
-rw-r--r-- | arch/mips/kernel/r2300_switch.S | 5 | ||||
-rw-r--r-- | arch/mips/kernel/r4k_misc.S | 4 | ||||
-rw-r--r-- | arch/mips/kernel/r4k_switch.S | 7 | ||||
-rw-r--r-- | arch/mips/kernel/setup.c | 9 | ||||
-rw-r--r-- | arch/mips/kernel/signal.c | 11 | ||||
-rw-r--r-- | arch/mips/kernel/syscalls.h | 1 | ||||
-rw-r--r-- | arch/mips/kernel/sysirix.c | 223 | ||||
-rw-r--r-- | arch/mips/kernel/time.c | 3 | ||||
-rw-r--r-- | arch/mips/kernel/traps.c | 9 |
21 files changed, 184 insertions, 315 deletions
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index b251d6e1a..21dd3610b 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -9,7 +9,7 @@ .S.o: $(CC) $(CFLAGS) -c $< -o $*.o -all: kernel.o head.o +all: kernel.o head.o init_task.o EXTRA_ASFLAGS = -mips3 -mcpu=r4000 O_TARGET := kernel.o O_OBJS := branch.o process.o signal.o entry.o traps.o ptrace.o vm86.o \ diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S index 8bb8fb41c..682e00cda 100644 --- a/arch/mips/kernel/entry.S +++ b/arch/mips/kernel/entry.S @@ -14,9 +14,11 @@ * and faults that can result in a task-switch. The ISA dependent TLB * code is in arch/mips/<ISA-level>/<cputype>.S */ +#include <linux/config.h> #include <linux/sys.h> #include <asm/asm.h> +#include <asm/current.h> #include <asm/errno.h> #include <asm/mipsregs.h> #include <asm/mipsconfig.h> @@ -53,7 +55,6 @@ reschedule: nop EXPORT(ret_from_sys_call) - lw t0,bh_mask lw t1,bh_active # unused delay slot and t0,t1 @@ -64,7 +65,7 @@ EXPORT(ret_from_sys_call) beqz t1,return # -> yes lw t1,need_resched bnez t1,reschedule - lw s0,current_set + GET_CURRENT(s0) lw t0,task lw a0,TASK_BLOCKED(s0) diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S index a957e16bd..4c3e5bd52 100644 --- a/arch/mips/kernel/head.S +++ b/arch/mips/kernel/head.S @@ -22,6 +22,15 @@ #include <asm/bootinfo.h> #include <asm/cpu.h> +/* + * Get current task pointer + */ +#define GET_CURRENT(reg) \ + lui reg, %hi(kernelsp); \ + lw reg, %lo(kernelsp)(reg); \ + ori reg, 8191; \ + xori reg, 8191 + .text /* * Reserved space for exception handlers. @@ -43,8 +52,7 @@ LEAF(except_vec0_r4000) .set mips3 mfc0 k0, CP0_BADVADDR # Get faulting address - lui k1, %hi(current_set) - lw k1, %lo(current_set)(k1) # get current task ptr + GET_CURRENT(k1) # get current task ptr srl k0, k0, 22 # get pgd only bits lw k1, THREAD_PGDIR(k1) # get task pg_dir sll k0, k0, 2 @@ -71,8 +79,7 @@ LEAF(except_vec0_r4600) .set mips3 mfc0 k0, CP0_BADVADDR - lui k1, %hi(current_set) - lw k1, %lo(current_set)(k1) + GET_CURRENT(k1) # get current task ptr srl k0, k0, 22 lw k1, THREAD_PGDIR(k1) sll k0, k0, 2 @@ -98,8 +105,7 @@ LEAF(except_vec0_r45k_bvahwbug) .set mips3 mfc0 k0, CP0_BADVADDR - lui k1, %hi(current_set) - lw k1, %lo(current_set)(k1) + GET_CURRENT(k1) # get current task ptr srl k0, k0, 22 lw k1, THREAD_PGDIR(k1) sll k0, k0, 2 @@ -129,8 +135,7 @@ LEAF(except_vec0_r4k_mphwbug) .set mips3 mfc0 k0, CP0_BADVADDR - lui k1, %hi(current_set) - lw k1, %lo(current_set)(k1) + GET_CURRENT(k1) # get current task ptr srl k0, k0, 22 lw k1, THREAD_PGDIR(k1) sll k0, k0, 2 @@ -160,8 +165,7 @@ LEAF(except_vec0_r4k_250MHZhwbug) .set mips3 mfc0 k0, CP0_BADVADDR - lui k1, %hi(current_set) - lw k1, %lo(current_set)(k1) + GET_CURRENT(k1) # get current task ptr srl k0, k0, 22 lw k1, THREAD_PGDIR(k1) sll k0, k0, 2 @@ -191,8 +195,7 @@ LEAF(except_vec0_r4k_MP250MHZhwbug) .set mips3 mfc0 k0, CP0_BADVADDR - lui k1, %hi(current_set) - lw k1, %lo(current_set)(k1) + GET_CURRENT(k1) # get current task ptr srl k0, k0, 22 lw k1, THREAD_PGDIR(k1) sll k0, k0, 2 @@ -224,8 +227,7 @@ LEAF(except_vec0_r2300) .set mips1 mfc0 k0, CP0_BADVADDR - lui k1, %hi(current_set) - lw k1, %lo(current_set)(k1) + GET_CURRENT(k1) # get current task ptr srl k0, k0, 22 lw k1, THREAD_PGDIR(k1) sll k0, k0, 2 @@ -403,9 +405,11 @@ probe_done: /* * Stack for kernel and init + * + * Kernelsp will never be referenced for process 0. */ -9: la sp, init_user_stack+(KERNEL_STACK_SIZE-4*SZREG) - la t0, init_kernel_stack+(KERNEL_STACK_SIZE) +9: la sp, init_task_union+(KERNEL_STACK_SIZE-4*SZREG) + la t0, init_task_union+(KERNEL_STACK_SIZE) sw t0, kernelsp /* Disable coprocessors */ @@ -745,9 +749,13 @@ map0_sni_rm200_pci: .org 0x6000 + /* + * init_task_union follows here in the .text segment. + * Keep this aligned to a 8kb boundary! + */ + .data EXPORT(cache_error_buffer) .fill 32*4,1,0 - .data EXPORT(kernelsp) PTR 0 diff --git a/arch/mips/kernel/init_task.c b/arch/mips/kernel/init_task.c new file mode 100644 index 000000000..cc0a19231 --- /dev/null +++ b/arch/mips/kernel/init_task.c @@ -0,0 +1,22 @@ +#include <linux/mm.h> +#include <linux/sched.h> + +#include <asm/pgtable.h> + +static struct vm_area_struct init_mmap = INIT_MMAP; +static struct fs_struct init_fs = INIT_FS; +static struct files_struct init_files = INIT_FILES; +static struct signal_struct init_signals = INIT_SIGNALS; +struct mm_struct init_mm = INIT_MM; + +/* + * Initial task structure. + * + * We need to make sure that this is 8192-byte aligned due to the + * way process stacks are handled. This is done by making sure + * the linker maps this in the .text segment right after head.S, + * and making head.S ensure the proper alignment. + * + * The things we do for performance.. + */ +union task_union init_task_union __attribute__((__section__(".text"))) = { INIT_TASK }; diff --git a/arch/mips/kernel/irix5sys.h b/arch/mips/kernel/irix5sys.h index a20e619e3..be57dc1f5 100644 --- a/arch/mips/kernel/irix5sys.h +++ b/arch/mips/kernel/irix5sys.h @@ -105,7 +105,7 @@ SYS(irix_sgikopt, 3) /* 1083 sys_sgikopt() DC*/ SYS(sys_sysfs, 3) /* 1084 sysfs() ?V*/ SYS(irix_unimp, 0) /* 1085 XXX sys_getmsg() DC*/ SYS(irix_unimp, 0) /* 1086 XXX sys_putmsg() DC*/ -SYS(irix_poll, 3) /* 1087 sys_poll() V*/ +SYS(sys_poll, 3) /* 1087 poll() V*/ SYS(irix_sigreturn, 0) /* 1088 sigreturn() ?V*/ SYS(sys_accept, 3) /* 1089 accept() V*/ SYS(sys_bind, 3) /* 1090 bind() V*/ diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c index 46345b308..d994155d0 100644 --- a/arch/mips/kernel/irixelf.c +++ b/arch/mips/kernel/irixelf.c @@ -1,4 +1,4 @@ -/* $Id: irixelf.c,v 1.8 1996/08/24 03:52:25 dm Exp $ +/* * irixelf.c: Code to load IRIX ELF executables which conform to * the MIPS ABI. * @@ -17,6 +17,7 @@ #include <linux/mman.h> #include <linux/a.out.h> #include <linux/errno.h> +#include <linux/init.h> #include <linux/signal.h> #include <linux/binfmts.h> #include <linux/string.h> @@ -720,16 +721,16 @@ static inline int do_load_irix_binary(struct linux_binprm * bprm, sys_close(elf_exec_fileno); current->personality = PER_IRIX32; - if (current->exec_domain && current->exec_domain->use_count) - (*current->exec_domain->use_count)--; - if (current->binfmt && current->binfmt->use_count) - (*current->binfmt->use_count)--; + if (current->exec_domain && current->exec_domain->module) + __MOD_DEC_USE_COUNT(current->exec_domain->module); + if (current->binfmt && current->binfmt->module) + __MOD_DEC_USE_COUNT(current->binfmt->module); current->exec_domain = lookup_exec_domain(current->personality); current->binfmt = &irix_format; - if (current->exec_domain && current->exec_domain->use_count) - (*current->exec_domain->use_count)++; - if (current->binfmt && current->binfmt->use_count) - (*current->binfmt->use_count)++; + if (current->exec_domain && current->exec_domain->module) + __MOD_INC_USE_COUNT(current->exec_domain->module); + if (current->binfmt && current->binfmt->module) + __MOD_INC_USE_COUNT(current->binfmt->module); current->suid = current->euid = current->fsuid = bprm->e_uid; current->sgid = current->egid = current->fsgid = bprm->e_gid; @@ -1180,20 +1181,20 @@ static int irix_core_dump(long signr, struct pt_regs * regs) notes[0].datasz = sizeof(prstatus); notes[0].data = &prstatus; prstatus.pr_info.si_signo = prstatus.pr_cursig = signr; - copy_sigbits32(&prstatus.pr_sigpend, current->signal); - copy_sigbits32(&prstatus.pr_sighold, current->blocked); + prstatus.pr_sigpend = current->signal; + prstatus.pr_sighold = current->blocked; psinfo.pr_pid = prstatus.pr_pid = current->pid; psinfo.pr_ppid = prstatus.pr_ppid = current->p_pptr->pid; psinfo.pr_pgrp = prstatus.pr_pgrp = current->pgrp; psinfo.pr_sid = prstatus.pr_sid = current->session; - prstatus.pr_utime.tv_sec = CT_TO_SECS(current->utime); - prstatus.pr_utime.tv_usec = CT_TO_USECS(current->utime); - prstatus.pr_stime.tv_sec = CT_TO_SECS(current->stime); - prstatus.pr_stime.tv_usec = CT_TO_USECS(current->stime); - prstatus.pr_cutime.tv_sec = CT_TO_SECS(current->cutime); - prstatus.pr_cutime.tv_usec = CT_TO_USECS(current->cutime); - prstatus.pr_cstime.tv_sec = CT_TO_SECS(current->cstime); - prstatus.pr_cstime.tv_usec = CT_TO_USECS(current->cstime); + prstatus.pr_utime.tv_sec = CT_TO_SECS(current->times.tms_utime); + prstatus.pr_utime.tv_usec = CT_TO_USECS(current->times.tms_utime); + prstatus.pr_stime.tv_sec = CT_TO_SECS(current->times.tms_stime); + prstatus.pr_stime.tv_usec = CT_TO_USECS(current->times.tms_stime); + prstatus.pr_cutime.tv_sec = CT_TO_SECS(current->times.tms_cutime); + prstatus.pr_cutime.tv_usec = CT_TO_USECS(current->times.tms_cutime); + prstatus.pr_cstime.tv_sec = CT_TO_SECS(current->times.tms_cstime); + prstatus.pr_cstime.tv_usec = CT_TO_USECS(current->times.tms_cstime); if (sizeof(elf_gregset_t) != sizeof(struct pt_regs)) { printk("sizeof(elf_gregset_t) (%d) != sizeof(struct pt_regs) " "(%d)\n", sizeof(elf_gregset_t), sizeof(struct pt_regs)); @@ -1339,13 +1340,15 @@ static int irix_core_dump(long signr, struct pt_regs * regs) return has_dumped; } -int init_irix_binfmt(void) { +__initfunc(int init_irix_binfmt(void)) +{ return register_binfmt(&irix_format); } #ifdef MODULE -int init_module(void) { +int init_module(void) +{ /* Install the COFF, ELF and XOUT loaders. * N.B. We *rely* on the table being the right size with the * right number of free slots... @@ -1354,7 +1357,8 @@ int init_module(void) { } -void cleanup_module( void) { +void cleanup_module( void) +{ /* Remove the IRIX ELF loaders. */ unregister_binfmt(&irix_format); } diff --git a/arch/mips/kernel/irixioctl.c b/arch/mips/kernel/irixioctl.c index 3405904fa..e0230f9f0 100644 --- a/arch/mips/kernel/irixioctl.c +++ b/arch/mips/kernel/irixioctl.c @@ -8,6 +8,8 @@ #include <linux/sched.h> #include <linux/fs.h> #include <linux/mm.h> +#include <linux/smp.h> +#include <linux/smp_lock.h> #include <linux/tty.h> #include <asm/uaccess.h> diff --git a/arch/mips/kernel/irixsig.c b/arch/mips/kernel/irixsig.c index 6a5636c76..b2d7cbe49 100644 --- a/arch/mips/kernel/irixsig.c +++ b/arch/mips/kernel/irixsig.c @@ -8,6 +8,8 @@ #include <linux/sched.h> #include <linux/mm.h> #include <linux/errno.h> +#include <linux/smp.h> +#include <linux/smp_lock.h> #include <linux/time.h> #include <asm/ptrace.h> @@ -162,7 +164,10 @@ asmlinkage int do_irix_signal(unsigned long oldmask, struct pt_regs * regs) case SIGCONT: case SIGCHLD: case SIGWINCH: continue; - case SIGSTOP: case SIGTSTP: case SIGTTIN: case SIGTTOU: + case SIGTSTP: case SIGTTIN: case SIGTTOU: + if (is_orphaned_pgrp(current->pgrp)) + continue; + case SIGSTOP: if (current->flags & PF_PTRACED) continue; current->state = TASK_STOPPED; @@ -175,15 +180,19 @@ asmlinkage int do_irix_signal(unsigned long oldmask, struct pt_regs * regs) case SIGQUIT: case SIGILL: case SIGTRAP: case SIGIOT: case SIGFPE: case SIGSEGV: case SIGBUS: + lock_kernel(); if (current->binfmt && current->binfmt->core_dump) { if (current->binfmt->core_dump(signr, regs)) signr |= 0x80; } + unlock_kernel(); /* fall through */ default: current->signal |= _S(signr & 0x7f); current->flags |= PF_SIGNALED; + lock_kernel(); /* 8-( */ do_exit(signr); + unlock_kernel(); } } /* @@ -314,7 +323,7 @@ static inline void check_pending(int signum) spin_lock(¤t->sigmask_lock); if (p->sa_handler == SIG_IGN) { current->signal &= ~_S(signum); - } else if if (p->sa_handler == SIG_DFL) { + } else if (p->sa_handler == SIG_DFL) { if (signum != SIGCONT && signum != SIGCHLD && signum != SIGWINCH) return; current->signal &= ~_S(signum); @@ -347,11 +356,9 @@ asmlinkage int irix_sigaction(int sig, struct sigact_irix5 *new, if(sig == SIGKILL || sig == SIGSTOP) { return -EINVAL; } - new_sa.sa_flags = new->flags; - new_sa.sa_handler = (__sighandler_t) new->handler; - new_sa.sa_mask.__sigbits[1] = new_sa.sa_mask.__sigbits[2] = - new_sa.sa_mask.__sigbits[3] = 0; - new_sa.sa_mask.__sigbits[0] = new->sigset[0]; + __get_user(new_sa.sa_flags, &new->flags); + __get_user(new_sa.sa_handler, &(__sighandler_t) new->handler); + __get_user(new_sa.sa_mask, &new->sigset[0]); if(new_sa.sa_handler != SIG_DFL && new_sa.sa_handler != SIG_IGN) { res = verify_area(VERIFY_READ, new_sa.sa_handler, 1); @@ -368,19 +375,22 @@ asmlinkage int irix_sigaction(int sig, struct sigact_irix5 *new, int res = verify_area(VERIFY_WRITE, old, sizeof(*old)); if(res) return res; - old->flags = p->sa_flags; - old->handler = (void *) p->sa_handler; - old->sigset[1] = old->sigset[2] = old->sigset[3] = 0; - old->sigset[0] = p->sa_mask.__sigbits[0]; - old->_unused0[0] = old->_unused0[1] = 0; + __put_user(p->sa_flags, &old->flags); + __put_user(p->sa_handler, &old->handler); + __put_user(p->sa_mask, &old->sigset[0]); + __put_user(0, &old->sigset[1]); + __put_user(0, &old->sigset[2]); + __put_user(0, &old->sigset[3]); + __put_user(0, &old->_unused0[0]); + __put_user(0, &old->_unused0[1]); } - if(new) { spin_lock_irq(¤t->sig->siglock); *p = new_sa; check_pending(sig); spin_unlock_irq(¤t->sig->siglock); } + return 0; } @@ -640,14 +650,14 @@ repeat: __put_user(p->pid, &info->stuff.procinfo.pid); __put_user((p->exit_code >> 8) & 0xff, &info->stuff.procinfo.procdata.child.status); - __put_user(p->utime, &info->stuff.procinfo.procdata.child.utime); - __put_user(p->stime, &info->stuff.procinfo.procdata.child.stime); + __put_user(p->times.tms_utime, &info->stuff.procinfo.procdata.child.utime); + __put_user(p->times.tms_stime, &info->stuff.procinfo.procdata.child.stime); p->exit_code = 0; retval = 0; goto end_waitsys; case TASK_ZOMBIE: - current->cutime += p->utime + p->cutime; - current->cstime += p->stime + p->cstime; + current->times.tms_cutime += p->times.tms_utime + p->times.tms_cutime; + current->times.tms_cstime += p->times.tms_stime + p->times.tms_cstime; if (ru != NULL) getrusage(p, RUSAGE_BOTH, ru); __put_user(SIGCHLD, &info->sig); @@ -655,9 +665,9 @@ repeat: __put_user(p->pid, &info->stuff.procinfo.pid); __put_user((p->exit_code >> 8) & 0xff, &info->stuff.procinfo.procdata.child.status); - __put_user(p->utime, + __put_user(p->times.tms_utime, &info->stuff.procinfo.procdata.child.utime); - __put_user(p->stime, + __put_user(p->times.tms_stime, &info->stuff.procinfo.procdata.child.stime); retval = 0; if (p->p_opptr != p->p_pptr) { @@ -855,6 +865,8 @@ asmlinkage int irix_sigaltstack(struct irix_sigaltstack *new, out: error = 0; unlock_kernel(); + + return error; } struct irix_procset { diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c index a78bc3417..0896ed1c7 100644 --- a/arch/mips/kernel/irq.c +++ b/arch/mips/kernel/irq.c @@ -13,6 +13,7 @@ */ #include <linux/config.h> #include <linux/errno.h> +#include <linux/init.h> #include <linux/kernel_stat.h> #include <linux/signal.h> #include <linux/sched.h> @@ -154,11 +155,6 @@ asmlinkage void do_IRQ(int irq, struct pt_regs * regs) irq_enter(cpu, irq); kstat.interrupts[irq]++; -#ifdef CONFIG_SGI - prom_printf("Got irq %d, press a key.", irq); - prom_getchar(); - romvec->imode(); -#endif /* slow interrupts run with interrupts enabled */ sti(); action = *(irq + irq_action); @@ -344,7 +340,7 @@ int probe_irq_off (unsigned long irqs) return i; } -void init_IRQ(void) +__initfunc(void init_IRQ(void)) { int i; diff --git a/arch/mips/kernel/pci.c b/arch/mips/kernel/pci.c index e521ecdd9..5e71233af 100644 --- a/arch/mips/kernel/pci.c +++ b/arch/mips/kernel/pci.c @@ -7,6 +7,7 @@ */ #include <linux/bios32.h> #include <linux/config.h> +#include <linux/init.h> #include <linux/kernel.h> #include <linux/pci.h> #include <linux/types.h> @@ -17,7 +18,8 @@ /* * BIOS32 replacement. */ -unsigned long pcibios_init(unsigned long memory_start, unsigned long memory_end) +__initfunc(unsigned long pcibios_init(unsigned long memory_start, + unsigned long memory_end)) { return memory_start; } @@ -112,7 +114,8 @@ const char *pcibios_strerror (int error) * specific implementation. */ unsigned long (*_pcibios_init)(unsigned long memory_start, unsigned long memory_end); -unsigned long pcibios_init(unsigned long memory_start, unsigned long memory_end) +__initfunc(unsigned long pcibios_init(unsigned long memory_start, + unsigned long memory_end)) { return _pcibios_init ? _pcibios_init(memory_start, memory_end) : memory_start; diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index f8b10bdea..08dd13c6c 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -64,16 +64,23 @@ void release_thread(struct task_struct *dead_task) { } +#define roundup(val, rnd) ({ \ + unsigned _v = val; \ + unsigned long _r = rnd; \ + _v = (_v + _r - 1) & ~(_r - 1); \ + _v; \ +}) + int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, struct task_struct * p, struct pt_regs * regs) { struct pt_regs * childregs; long childksp; - childksp = p->kernel_stack_page + KERNEL_STACK_SIZE - 8; + childksp = roundup((unsigned long)p, KERNEL_STACK_SIZE) - 8; /* set up new TSS. */ - childregs = ((struct pt_regs *) (p->kernel_stack_page + PAGE_SIZE)) - 1; + childregs = ((struct pt_regs *) ((unsigned long)p + KERNEL_STACK_SIZE)) - 1; *childregs = *regs; childregs->regs[7] = 0; /* Clear error flag */ if(current->personality == PER_LINUX) { diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c index 41deb8f18..e61911549 100644 --- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c @@ -18,18 +18,6 @@ #include <asm/page.h> #include <asm/system.h> -/* change a pid into a task struct. */ -static inline struct task_struct * get_task(int pid) -{ - int i; - - for (i = 1; i < NR_TASKS; i++) { - if (task[i] != NULL && (task[i]->pid == pid)) - return task[i]; - } - return NULL; -} - /* * This routine gets a long from any process space by following the page * tables. NOTE! You should check that the long isn't on a page boundary, @@ -47,7 +35,7 @@ static unsigned long get_long(struct task_struct * tsk, repeat: pgdir = pgd_offset(vma->vm_mm, addr); if (pgd_none(*pgdir)) { - do_no_page(tsk, vma, addr, 0); + handle_mm_fault(tsk, vma, addr, 0); goto repeat; } if (pgd_bad(*pgdir)) { @@ -57,7 +45,7 @@ repeat: } pgmiddle = pmd_offset(pgdir, addr); if (pmd_none(*pgmiddle)) { - do_no_page(tsk, vma, addr, 0); + handle_mm_fault(tsk, vma, addr, 0); goto repeat; } if (pmd_bad(*pgmiddle)) { @@ -67,7 +55,7 @@ repeat: } pgtable = pte_offset(pgmiddle, addr); if (!pte_present(*pgtable)) { - do_no_page(tsk, vma, addr, 0); + handle_mm_fault(tsk, vma, addr, 0); goto repeat; } page = pte_page(*pgtable); @@ -101,7 +89,7 @@ static void put_long(struct task_struct *tsk, repeat: pgdir = pgd_offset(vma->vm_mm, addr); if (!pgd_present(*pgdir)) { - do_no_page(tsk, vma, addr, 1); + handle_mm_fault(tsk, vma, addr, 1); goto repeat; } if (pgd_bad(*pgdir)) { @@ -111,7 +99,7 @@ repeat: } pgmiddle = pmd_offset(pgdir, addr); if (pmd_none(*pgmiddle)) { - do_no_page(tsk, vma, addr, 1); + handle_mm_fault(tsk, vma, addr, 1); goto repeat; } if (pmd_bad(*pgmiddle)) { @@ -121,12 +109,12 @@ repeat: } pgtable = pte_offset(pgmiddle, addr); if (!pte_present(*pgtable)) { - do_no_page(tsk, vma, addr, 1); + handle_mm_fault(tsk, vma, addr, 1); goto repeat; } page = pte_page(*pgtable); if (!pte_write(*pgtable)) { - do_wp_page(tsk, vma, addr, 1); + handle_mm_fault(tsk, vma, addr, 1); goto repeat; } /* this is a hack for non-kernel-mapped video buffers and similar */ @@ -280,7 +268,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) res = -EPERM; goto out; } - if (!(child = get_task(pid))) { + if (!(child = find_task_by_pid(pid))) { res = -ESRCH; goto out; } diff --git a/arch/mips/kernel/r2300_switch.S b/arch/mips/kernel/r2300_switch.S index 83190514b..901871a31 100644 --- a/arch/mips/kernel/r2300_switch.S +++ b/arch/mips/kernel/r2300_switch.S @@ -9,6 +9,7 @@ #include <asm/asm.h> #include <asm/bootinfo.h> #include <asm/cachectl.h> +#include <asm/current.h> #include <asm/fpregdef.h> #include <asm/mipsconfig.h> #include <asm/mipsregs.h> @@ -31,8 +32,7 @@ MODE_ALIAS = 0x00e0 # uncachable, dirty, valid */ .align 5 LEAF(r2300_resume) - lui t5, %hi(current_set) - lw t0, %lo(current_set)(t5) + GET_CURRENT(t0) mfc0 t1,CP0_STATUS # Save status register addu t0,a1 # Add tss offset sw t1,THREAD_STATUS(t0) @@ -50,7 +50,6 @@ MODE_ALIAS = 0x00e0 # uncachable, dirty, valid 1: FPU_SAVE_16EVEN(t0, t1) 2: - sw a0,%lo(current_set)(t5) # Switch current task addu a0,a1 # Add tss offset lw t0,THREAD_PGDIR(a0) # Switch the root pointer li t1,TLB_ROOT # get PFN diff --git a/arch/mips/kernel/r4k_misc.S b/arch/mips/kernel/r4k_misc.S index 432c65215..5c9ad4d84 100644 --- a/arch/mips/kernel/r4k_misc.S +++ b/arch/mips/kernel/r4k_misc.S @@ -10,6 +10,7 @@ #include <asm/offset.h> #include <asm/bootinfo.h> #include <asm/cachectl.h> +#include <asm/current.h> #include <asm/fpregdef.h> #include <asm/mipsconfig.h> #include <asm/mipsregs.h> @@ -29,9 +30,8 @@ */ #define LOAD_PTE(pte, ptr) \ mfc0 pte, CP0_BADVADDR; \ - lui ptr, %hi(current_set); \ srl pte, pte, 22; \ - lw ptr, %lo(current_set)(ptr); \ + GET_CURRENT(ptr); \ sll pte, pte, 2; \ lw ptr, THREAD_PGDIR(ptr); \ addu ptr, pte, ptr; \ diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S index 78ced5659..97e253028 100644 --- a/arch/mips/kernel/r4k_switch.S +++ b/arch/mips/kernel/r4k_switch.S @@ -1,4 +1,4 @@ -/* $Id: r4k_switch.S,v 1.8 1996/07/10 01:24:20 dm Exp $ +/* * r4k_switch.S: R4xx0 specific task switching code. * * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse @@ -9,6 +9,7 @@ #include <asm/asm.h> #include <asm/bootinfo.h> #include <asm/cachectl.h> +#include <asm/current.h> #include <asm/fpregdef.h> #include <asm/mipsconfig.h> #include <asm/mipsregs.h> @@ -24,8 +25,7 @@ .set mips3 .align 5 LEAF(r4xx0_resume) - lui t5, %hi(current_set) - lw t0, %lo(current_set)(t5) + GET_CURRENT(t0) mfc0 t1, CP0_STATUS nop sw t1, THREAD_STATUS(t0) @@ -43,7 +43,6 @@ 1: FPU_SAVE_16EVEN(t0, t1) # clobbers t1 2: - sw a0, %lo(current_set)(t5) lw a3, TASK_MM(a0) lw a2, THREAD_STATUS(a0) lw a3, MM_CONTEXT(a3) diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 2e2b074f9..7616fa7c6 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -7,6 +7,7 @@ */ #include <linux/config.h> #include <linux/errno.h> +#include <linux/init.h> #include <linux/ioport.h> #include <linux/sched.h> #include <linux/kernel.h> @@ -123,17 +124,17 @@ void (*irq_setup)(void); */ unsigned long isa_slot_offset; -static void default_irq_setup(void) +__initfunc(static void default_irq_setup(void)) { panic("Unknown machtype in init_IRQ"); } -static void default_fd_cacheflush(const void *addr, size_t size) +__initfunc(static void default_fd_cacheflush(const void *addr, size_t size)) { } -void setup_arch(char **cmdline_p, - unsigned long * memory_start_p, unsigned long * memory_end_p) +__initfunc(void setup_arch(char **cmdline_p, + unsigned long * memory_start_p, unsigned long * memory_end_p)) { unsigned long memory_end; tag* atag; diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index 848f0742b..304dc6418 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c @@ -307,7 +307,10 @@ asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs) case SIGCONT: case SIGCHLD: case SIGWINCH: continue; - case SIGSTOP: case SIGTSTP: case SIGTTIN: case SIGTTOU: + case SIGTSTP: case SIGTTIN: case SIGTTOU: + if (is_orphaned_pgrp(current->pgrp)) + continue; + case SIGSTOP: if (current->flags & PF_PTRACED) continue; current->state = TASK_STOPPED; @@ -318,11 +321,15 @@ asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs) schedule(); continue; - case SIGIOT: case SIGFPE: case SIGSEGV: case SIGBUS: + case SIGQUIT: case SIGILL: case SIGTRAP: + case SIGABRT: case SIGFPE: case SIGSEGV: + case SIGBUS: + lock_kernel(); if (current->binfmt && current->binfmt->core_dump) { if (current->binfmt->core_dump(signr, regs)) signr |= 0x80; } + unlock_kernel(); /* fall through */ default: spin_lock_irq(¤t->sigmask_lock); diff --git a/arch/mips/kernel/syscalls.h b/arch/mips/kernel/syscalls.h index 4cf778acb..6c7d3988c 100644 --- a/arch/mips/kernel/syscalls.h +++ b/arch/mips/kernel/syscalls.h @@ -174,6 +174,7 @@ SYS(sys_mlock, 2) SYS(sys_munlock, 2) /* 4155 */ SYS(sys_mlockall, 1) SYS(sys_munlockall, 0) +SYS(sys_nfsservctl, 3) SYS(sys_sched_setparam,2) SYS(sys_sched_getparam,2) SYS(sys_sched_setscheduler,3) /* 4160 */ diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c index 9a4ddca3f..7917664fd 100644 --- a/arch/mips/kernel/sysirix.c +++ b/arch/mips/kernel/sysirix.c @@ -17,6 +17,8 @@ #include <linux/elf.h> #include <linux/msg.h> #include <linux/shm.h> +#include <linux/smp.h> +#include <linux/smp_lock.h> #include <linux/utsname.h> #include <asm/ptrace.h> @@ -24,26 +26,7 @@ #include <asm/pgtable.h> #include <asm/uaccess.h> -/* 2,000 lines of complete and utter shit coming up... */ - -/* Utility routines. */ -static inline struct task_struct *find_process_by_pid(pid_t pid) -{ - struct task_struct *p, *q; - - if (pid == 0) - p = current; - else { - p = 0; - for_each_task(q) { - if (q && q->pid == pid) { - p = q; - break; - } - } - } - return p; -} +/* 2,300 lines of complete and utter shit coming up... */ /* The sysmp commands supported thus far. */ #define MP_PGSIZE 14 /* Return system page size in v1. */ @@ -70,7 +53,6 @@ asmlinkage int irix_sysmp(struct pt_regs *regs) break; } -out: unlock_kernel(); return error; } @@ -114,7 +96,7 @@ asmlinkage int irix_prctl(struct pt_regs *regs) printk("irix_prctl[%s:%d]: Wants PR_ISBLOCKED\n", current->comm, current->pid); - task = find_process_by_pid(regs->regs[base + 5]); + task = find_task_by_pid(regs->regs[base + 5]); if(!task) { error = -ESRCH; break; @@ -233,7 +215,6 @@ asmlinkage int irix_prctl(struct pt_regs *regs) break; } -out: unlock_kernel(); return error; } @@ -658,7 +639,6 @@ asmlinkage int irix_mount(char *dev_name, char *dir_name, unsigned long flags, dev_name, dir_name, flags, type, data, datalen); ret = sys_mount(dev_name, dir_name, type, flags, data); -out: unlock_kernel(); return ret; } @@ -781,22 +761,23 @@ asmlinkage int irix_setpgrp(int flags) printk("returning %d\n", current->pgrp); #endif -out: unlock_kernel(); return error; } asmlinkage int irix_times(struct tms * tbuf) { + int error; + lock_kernel(); if (tbuf) { - int error = verify_area(VERIFY_WRITE,tbuf,sizeof *tbuf); + error = verify_area(VERIFY_WRITE,tbuf,sizeof *tbuf); if (error) goto out; - __put_user(current->utime,&tbuf->tms_utime); - __put_user(current->stime,&tbuf->tms_stime); - __put_user(current->cutime,&tbuf->tms_cutime); - __put_user(current->cstime,&tbuf->tms_cstime); + __put_user(current->times.tms_utime,&tbuf->tms_utime); + __put_user(current->times.tms_stime,&tbuf->tms_stime); + __put_user(current->times.tms_cutime,&tbuf->tms_cutime); + __put_user(current->times.tms_cstime,&tbuf->tms_cstime); } error = 0; @@ -845,169 +826,6 @@ out: return error; } -/* sys_poll() support... */ -#define POLL_ROUND_UP(x,y) (((x)+(y)-1)/(y)) - -#define POLLIN 1 -#define POLLPRI 2 -#define POLLOUT 4 -#define POLLERR 8 -#define POLLHUP 16 -#define POLLNVAL 32 -#define POLLRDNORM 64 -#define POLLWRNORM POLLOUT -#define POLLRDBAND 128 -#define POLLWRBAND 256 - -#define LINUX_POLLIN (POLLRDNORM | POLLRDBAND | POLLIN) -#define LINUX_POLLOUT (POLLWRBAND | POLLWRNORM | POLLOUT) -#define LINUX_POLLERR (POLLERR) - -static inline void free_wait(select_table * p) -{ - struct select_table_entry * entry = p->entry + p->nr; - - while (p->nr > 0) { - p->nr--; - entry--; - remove_wait_queue(entry->wait_address,&entry->wait); - } -} - - -/* Copied directly from fs/select.c */ -static int check(int flag, select_table * wait, struct file * file) -{ - struct inode * inode; - struct file_operations *fops; - int (*select) (struct inode *, struct file *, int, select_table *); - - inode = file->f_inode; - if ((fops = file->f_op) && (select = fops->select)) - return select(inode, file, flag, wait) - || (wait && select(inode, file, flag, NULL)); - if (S_ISREG(inode->i_mode)) - return 1; - return 0; -} - -struct poll { - int fd; - short events; - short revents; -}; - -int irix_poll(struct poll * ufds, size_t nfds, int timeout) -{ - int i,j, count, fdcount, error, retflag; - struct poll * fdpnt; - struct poll * fds, *fds1; - select_table wait_table, *wait; - struct select_table_entry *entry; - - lock_kernel(); - if ((error = verify_area(VERIFY_READ, ufds, nfds*sizeof(struct poll)))) - goto out; - - if (nfds > NR_OPEN) { - error = -EINVAL; - goto out; - } - - if (!(entry = (struct select_table_entry*)__get_free_page(GFP_KERNEL)) - || !(fds = (struct poll *)kmalloc(nfds*sizeof(struct poll), GFP_KERNEL))) { - error = -ENOMEM; - goto out; - } - - copy_from_user(fds, ufds, nfds*sizeof(struct poll)); - - if (timeout < 0) - current->timeout = 0x7fffffff; - else { - current->timeout = jiffies + POLL_ROUND_UP(timeout, (1000/HZ)); - if (current->timeout <= jiffies) - current->timeout = 0; - } - - count = 0; - wait_table.nr = 0; - wait_table.entry = entry; - wait = &wait_table; - - for(fdpnt = fds, j = 0; j < (int)nfds; j++, fdpnt++) { - i = fdpnt->fd; - fdpnt->revents = 0; - if (!current->files->fd[i] || !current->files->fd[i]->f_inode) - fdpnt->revents = POLLNVAL; - } -repeat: - current->state = TASK_INTERRUPTIBLE; - for(fdpnt = fds, j = 0; j < (int)nfds; j++, fdpnt++) { - i = fdpnt->fd; - - if(i < 0) continue; - if (!current->files->fd[i] || !current->files->fd[i]->f_inode) continue; - - if ((fdpnt->events & LINUX_POLLIN) - && check(SEL_IN, wait, current->files->fd[i])) { - retflag = 0; - if (fdpnt->events & POLLIN) - retflag = POLLIN; - if (fdpnt->events & POLLRDNORM) - retflag = POLLRDNORM; - fdpnt->revents |= retflag; - count++; - wait = NULL; - } - - if ((fdpnt->events & LINUX_POLLOUT) && - check(SEL_OUT, wait, current->files->fd[i])) { - fdpnt->revents |= (LINUX_POLLOUT & fdpnt->events); - count++; - wait = NULL; - } - - if (check(SEL_EX, wait, current->files->fd[i])) { - fdpnt->revents |= POLLHUP; - count++; - wait = NULL; - } - } - - if ((current->signal & (~current->blocked))) { - error = -EINTR; - goto out; - } - - wait = NULL; - if (!count && current->timeout > jiffies) { - schedule(); - goto repeat; - } - - free_wait(&wait_table); - free_page((unsigned long) entry); - - /* OK, now copy the revents fields back to user space. */ - fds1 = fds; - fdcount = 0; - for(i=0; i < (int)nfds; i++, ufds++, fds++) { - if (fds->revents) { - fdcount++; - } - put_user(fds->revents, &ufds->revents); - } - kfree(fds1); - current->timeout = 0; - current->state = TASK_RUNNING; - error = fdcount; - -out: - unlock_kernel(); - return error; -} - asmlinkage unsigned long irix_gethostid(void) { lock_kernel(); @@ -1263,7 +1081,6 @@ asmlinkage int irix_BSDsetpgrp(int pid, int pgrp) printk("error = %d\n", error); #endif -out: unlock_kernel(); return error; } @@ -1443,11 +1260,11 @@ asmlinkage int irix_lxstat(int version, char *filename, struct stat *statbuf) if(error) goto out; error = irix_xstat32_xlate(&kb, statbuf); - goto error; + goto out; } case 3: { - sys_newlstat(filename, statbuf); + error = sys_newlstat(filename, statbuf); #ifdef DEBUG_XSTAT printk("error[%d]\n", error); #endif @@ -1456,7 +1273,7 @@ asmlinkage int irix_lxstat(int version, char *filename, struct stat *statbuf) irix_xstat64_xlate(statbuf); error = 0; - goto error; + goto out; } default: @@ -1466,7 +1283,7 @@ asmlinkage int irix_lxstat(int version, char *filename, struct stat *statbuf) out: unlock_kernel(); - return errno; + return error; } extern asmlinkage int sys_newfstat(unsigned int fd, struct stat * statbuf); @@ -2018,13 +1835,13 @@ out: asmlinkage int irix_getmountid(char *fname, unsigned long *midbuf) { - int errno; + int error; lock_kernel(); printk("[%s:%d] irix_getmountid(%s, %p)\n", current->comm, current->pid, fname, midbuf); - errno = verify_area(VERIFY_WRITE, midbuf, (sizeof(unsigned long) * 4)); - if(errno) + error = verify_area(VERIFY_WRITE, midbuf, (sizeof(unsigned long) * 4)); + if(error) goto out; /* @@ -2142,7 +1959,7 @@ asmlinkage int irix_ngetdents(unsigned int fd, void * dirent, unsigned int count buf.error = 0; error = file->f_op->readdir(file->f_inode, file, &buf, irix_filldir32); if (error < 0) - goto out + goto out; lastdirent = buf.previous; if (!lastdirent) { error = buf.error; @@ -2431,6 +2248,8 @@ asmlinkage int irix_fcntl(int fd, int cmd, int arg) asmlinkage int irix_ulimit(int cmd, int arg) { + int retval; + lock_kernel(); switch(cmd) { case 1: diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c index aa4547456..fd57f6d0e 100644 --- a/arch/mips/kernel/time.c +++ b/arch/mips/kernel/time.c @@ -7,6 +7,7 @@ * found in some MIPS systems. */ #include <linux/errno.h> +#include <linux/init.h> #include <linux/sched.h> #include <linux/kernel.h> #include <linux/param.h> @@ -299,7 +300,7 @@ static struct irqaction irq0 = { timer_interrupt, 0, 0, "timer", NULL, NULL}; void (*board_time_init)(struct irqaction *irq); -void time_init(void) +__initfunc(void time_init(void)) { unsigned int year, mon, day, hour, min, sec; int i; diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 17b1f9a28..cdbcacb43 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -17,6 +17,7 @@ * Modified for R3000 by Paul M. Antoine, 1995, 1996 */ #include <linux/config.h> +#include <linux/init.h> #include <linux/mm.h> #include <linux/smp.h> #include <linux/smp_lock.h> @@ -110,10 +111,8 @@ void show_registers(char * str, struct pt_regs * regs, long err) /* * Dump the stack */ - if (STACK_MAGIC != *(u32 *)current->kernel_stack_page) - printk("Corrupted stack page\n"); printk("Process %s (pid: %d, stackpage=%08lx)\nStack: ", - current->comm, current->pid, current->kernel_stack_page); + current->comm, current->pid, (unsigned long)current); for(i=0;i<5;i++) printk("%08x ", *sp++); stack = (int *) sp; @@ -389,7 +388,7 @@ void do_reserved(struct pt_regs *regs) unlock_kernel(); } -static void watch_init(unsigned long cputype) +static inline void watch_init(unsigned long cputype) { switch(cputype) { case CPU_R10000: @@ -427,7 +426,7 @@ extern asmlinkage void r6000_restore_fp_context(struct sigcontext *sc); extern asmlinkage void r4xx0_resume(void *tsk); extern asmlinkage void r2300_resume(void *tsk); -void trap_init(void) +__initfunc(void trap_init(void)) { extern char except_vec0_r4000, except_vec0_r4600, except_vec0_r2300; extern char except_vec1_generic, except_vec2_generic; |