summaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1997-06-01 03:16:17 +0000
committerRalf Baechle <ralf@linux-mips.org>1997-06-01 03:16:17 +0000
commitd8d9b8f76f22b7a16a83e261e64f89ee611f49df (patch)
tree3067bc130b80d52808e6390c9fc7fc087ec1e33c /arch/mips/kernel
parent19c9bba94152148523ba0f7ef7cffe3d45656b11 (diff)
Initial revision
Diffstat (limited to 'arch/mips/kernel')
-rw-r--r--arch/mips/kernel/Makefile2
-rw-r--r--arch/mips/kernel/entry.S5
-rw-r--r--arch/mips/kernel/head.S42
-rw-r--r--arch/mips/kernel/init_task.c22
-rw-r--r--arch/mips/kernel/irix5sys.h2
-rw-r--r--arch/mips/kernel/irixelf.c48
-rw-r--r--arch/mips/kernel/irixioctl.c2
-rw-r--r--arch/mips/kernel/irixsig.c50
-rw-r--r--arch/mips/kernel/irq.c8
-rw-r--r--arch/mips/kernel/pci.c7
-rw-r--r--arch/mips/kernel/process.c11
-rw-r--r--arch/mips/kernel/ptrace.c28
-rw-r--r--arch/mips/kernel/r2300_switch.S5
-rw-r--r--arch/mips/kernel/r4k_misc.S4
-rw-r--r--arch/mips/kernel/r4k_switch.S7
-rw-r--r--arch/mips/kernel/setup.c9
-rw-r--r--arch/mips/kernel/signal.c11
-rw-r--r--arch/mips/kernel/syscalls.h1
-rw-r--r--arch/mips/kernel/sysirix.c223
-rw-r--r--arch/mips/kernel/time.c3
-rw-r--r--arch/mips/kernel/traps.c9
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(&current->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(&current->sig->siglock);
*p = new_sa;
check_pending(sig);
spin_unlock_irq(&current->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(&current->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;