aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel')
-rw-r--r--arch/mips/kernel/binfmt_elfn32.c5
-rw-r--r--arch/mips/kernel/binfmt_elfo32.c5
-rw-r--r--arch/mips/kernel/irq-mv6434x.c8
-rw-r--r--arch/mips/kernel/linux32.c76
-rw-r--r--arch/mips/kernel/scall32-o32.S2
-rw-r--r--arch/mips/kernel/scall64-n32.S6
-rw-r--r--arch/mips/kernel/scall64-o32.S4
-rw-r--r--arch/mips/kernel/setup.c3
-rw-r--r--arch/mips/kernel/signal32.c74
-rw-r--r--arch/mips/kernel/signal_n32.c33
-rw-r--r--arch/mips/kernel/smp.c22
-rw-r--r--arch/mips/kernel/smp_mt.c13
-rw-r--r--arch/mips/kernel/time.c5
-rw-r--r--arch/mips/kernel/traps.c4
-rw-r--r--arch/mips/kernel/vmlinux.lds.S4
15 files changed, 136 insertions, 128 deletions
diff --git a/arch/mips/kernel/binfmt_elfn32.c b/arch/mips/kernel/binfmt_elfn32.c
index d8e2674a1543..4a9f1ecefaf2 100644
--- a/arch/mips/kernel/binfmt_elfn32.c
+++ b/arch/mips/kernel/binfmt_elfn32.c
@@ -103,8 +103,9 @@ jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value)
103 * one divide. 103 * one divide.
104 */ 104 */
105 u64 nsec = (u64)jiffies * TICK_NSEC; 105 u64 nsec = (u64)jiffies * TICK_NSEC;
106 value->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &value->tv_usec); 106 long rem;
107 value->tv_usec /= NSEC_PER_USEC; 107 value->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &rem);
108 value->tv_usec = rem / NSEC_PER_USEC;
108} 109}
109 110
110#define ELF_CORE_EFLAGS EF_MIPS_ABI2 111#define ELF_CORE_EFLAGS EF_MIPS_ABI2
diff --git a/arch/mips/kernel/binfmt_elfo32.c b/arch/mips/kernel/binfmt_elfo32.c
index cec5f327e360..e31813779895 100644
--- a/arch/mips/kernel/binfmt_elfo32.c
+++ b/arch/mips/kernel/binfmt_elfo32.c
@@ -105,8 +105,9 @@ jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value)
105 * one divide. 105 * one divide.
106 */ 106 */
107 u64 nsec = (u64)jiffies * TICK_NSEC; 107 u64 nsec = (u64)jiffies * TICK_NSEC;
108 value->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &value->tv_usec); 108 long rem;
109 value->tv_usec /= NSEC_PER_USEC; 109 value->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &rem);
110 value->tv_usec = rem / NSEC_PER_USEC;
110} 111}
111 112
112#undef ELF_CORE_COPY_REGS 113#undef ELF_CORE_COPY_REGS
diff --git a/arch/mips/kernel/irq-mv6434x.c b/arch/mips/kernel/irq-mv6434x.c
index 0ac067f45cf5..0613f1f36b1b 100644
--- a/arch/mips/kernel/irq-mv6434x.c
+++ b/arch/mips/kernel/irq-mv6434x.c
@@ -11,12 +11,14 @@
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/interrupt.h> 12#include <linux/interrupt.h>
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <asm/ptrace.h>
15#include <linux/sched.h>
16#include <linux/kernel_stat.h> 14#include <linux/kernel_stat.h>
15#include <linux/mv643xx.h>
16#include <linux/sched.h>
17
18#include <asm/ptrace.h>
17#include <asm/io.h> 19#include <asm/io.h>
18#include <asm/irq.h> 20#include <asm/irq.h>
19#include <linux/mv643xx.h> 21#include <asm/marvell.h>
20 22
21static unsigned int irq_base; 23static unsigned int irq_base;
22 24
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c
index 60353f5acc48..e00e5f6e7fdd 100644
--- a/arch/mips/kernel/linux32.c
+++ b/arch/mips/kernel/linux32.c
@@ -161,60 +161,6 @@ out:
161 return error; 161 return error;
162} 162}
163 163
164struct dirent32 {
165 unsigned int d_ino;
166 unsigned int d_off;
167 unsigned short d_reclen;
168 char d_name[NAME_MAX + 1];
169};
170
171static void
172xlate_dirent(void *dirent64, void *dirent32, long n)
173{
174 long off;
175 struct dirent *dirp;
176 struct dirent32 *dirp32;
177
178 off = 0;
179 while (off < n) {
180 dirp = (struct dirent *)(dirent64 + off);
181 dirp32 = (struct dirent32 *)(dirent32 + off);
182 off += dirp->d_reclen;
183 dirp32->d_ino = dirp->d_ino;
184 dirp32->d_off = (unsigned int)dirp->d_off;
185 dirp32->d_reclen = dirp->d_reclen;
186 strncpy(dirp32->d_name, dirp->d_name, dirp->d_reclen - ((3 * 4) + 2));
187 }
188 return;
189}
190
191asmlinkage long
192sys32_getdents(unsigned int fd, void * dirent32, unsigned int count)
193{
194 long n;
195 void *dirent64;
196
197 dirent64 = (void *)((unsigned long)(dirent32 + (sizeof(long) - 1)) & ~(sizeof(long) - 1));
198 if ((n = sys_getdents(fd, dirent64, count - (dirent64 - dirent32))) < 0)
199 return(n);
200 xlate_dirent(dirent64, dirent32, n);
201 return(n);
202}
203
204asmlinkage int old_readdir(unsigned int fd, void * dirent, unsigned int count);
205
206asmlinkage int
207sys32_readdir(unsigned int fd, void * dirent32, unsigned int count)
208{
209 int n;
210 struct dirent dirent64;
211
212 if ((n = old_readdir(fd, &dirent64, count)) < 0)
213 return(n);
214 xlate_dirent(&dirent64, dirent32, dirent64.d_reclen);
215 return(n);
216}
217
218asmlinkage int 164asmlinkage int
219sys32_waitpid(compat_pid_t pid, unsigned int *stat_addr, int options) 165sys32_waitpid(compat_pid_t pid, unsigned int *stat_addr, int options)
220{ 166{
@@ -230,6 +176,9 @@ sysn32_waitid(int which, compat_pid_t pid,
230 long ret; 176 long ret;
231 mm_segment_t old_fs = get_fs(); 177 mm_segment_t old_fs = get_fs();
232 178
179 if (!access_ok(VERIFY_WRITE, uinfo, sizeof(*uinfo)))
180 return -EFAULT;
181
233 set_fs (KERNEL_DS); 182 set_fs (KERNEL_DS);
234 ret = sys_waitid(which, pid, uinfo, options, 183 ret = sys_waitid(which, pid, uinfo, options,
235 uru ? (struct rusage __user *) &ru : NULL); 184 uru ? (struct rusage __user *) &ru : NULL);
@@ -1450,25 +1399,6 @@ sys32_timer_create(u32 clock, struct sigevent32 __user *se32, timer_t __user *ti
1450 return sys_timer_create(clock, p, timer_id); 1399 return sys_timer_create(clock, p, timer_id);
1451} 1400}
1452 1401
1453asmlinkage long
1454sysn32_rt_sigtimedwait(const sigset_t __user *uthese,
1455 siginfo_t __user *uinfo,
1456 const struct compat_timespec __user *uts32,
1457 size_t sigsetsize)
1458{
1459 struct timespec __user *uts = NULL;
1460
1461 if (uts32) {
1462 struct timespec ts;
1463 uts = compat_alloc_user_space(sizeof(struct timespec));
1464 if (get_user(ts.tv_sec, &uts32->tv_sec) ||
1465 get_user(ts.tv_nsec, &uts32->tv_nsec) ||
1466 copy_to_user (uts, &ts, sizeof (ts)))
1467 return -EFAULT;
1468 }
1469 return sys_rt_sigtimedwait(uthese, uinfo, uts, sigsetsize);
1470}
1471
1472save_static_function(sys32_clone); 1402save_static_function(sys32_clone);
1473__attribute_used__ noinline static int 1403__attribute_used__ noinline static int
1474_sys32_clone(nabi_no_regargs struct pt_regs regs) 1404_sys32_clone(nabi_no_regargs struct pt_regs regs)
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S
index d83e033dbc87..2f2dc54b2e26 100644
--- a/arch/mips/kernel/scall32-o32.S
+++ b/arch/mips/kernel/scall32-o32.S
@@ -626,7 +626,7 @@ einval: li v0, -EINVAL
626 sys sys_fstatat64 4 626 sys sys_fstatat64 4
627 sys sys_unlinkat 3 627 sys sys_unlinkat 3
628 sys sys_renameat 4 /* 4295 */ 628 sys sys_renameat 4 /* 4295 */
629 sys sys_linkat 4 629 sys sys_linkat 5
630 sys sys_symlinkat 3 630 sys sys_symlinkat 3
631 sys sys_readlinkat 4 631 sys sys_readlinkat 4
632 sys sys_fchmodat 3 632 sys sys_fchmodat 3
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index bc4980cefc8b..02c8267e45e7 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -195,7 +195,7 @@ EXPORT(sysn32_call_table)
195 PTR sys_fdatasync 195 PTR sys_fdatasync
196 PTR sys_truncate 196 PTR sys_truncate
197 PTR sys_ftruncate /* 6075 */ 197 PTR sys_ftruncate /* 6075 */
198 PTR sys32_getdents 198 PTR compat_sys_getdents
199 PTR sys_getcwd 199 PTR sys_getcwd
200 PTR sys_chdir 200 PTR sys_chdir
201 PTR sys_fchdir 201 PTR sys_fchdir
@@ -245,9 +245,9 @@ EXPORT(sysn32_call_table)
245 PTR sys_capget 245 PTR sys_capget
246 PTR sys_capset 246 PTR sys_capset
247 PTR sys32_rt_sigpending /* 6125 */ 247 PTR sys32_rt_sigpending /* 6125 */
248 PTR sysn32_rt_sigtimedwait 248 PTR compat_sys_rt_sigtimedwait
249 PTR sys_rt_sigqueueinfo 249 PTR sys_rt_sigqueueinfo
250 PTR sys32_rt_sigsuspend 250 PTR sysn32_rt_sigsuspend
251 PTR sys32_sigaltstack 251 PTR sys32_sigaltstack
252 PTR compat_sys_utime /* 6130 */ 252 PTR compat_sys_utime /* 6130 */
253 PTR sys_mknod 253 PTR sys_mknod
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
index 5b0414018c9a..797e0d874889 100644
--- a/arch/mips/kernel/scall64-o32.S
+++ b/arch/mips/kernel/scall64-o32.S
@@ -293,7 +293,7 @@ sys_call_table:
293 PTR sys_uselib 293 PTR sys_uselib
294 PTR sys_swapon 294 PTR sys_swapon
295 PTR sys_reboot 295 PTR sys_reboot
296 PTR sys32_readdir 296 PTR compat_sys_old_readdir
297 PTR old_mmap /* 4090 */ 297 PTR old_mmap /* 4090 */
298 PTR sys_munmap 298 PTR sys_munmap
299 PTR sys_truncate 299 PTR sys_truncate
@@ -345,7 +345,7 @@ sys_call_table:
345 PTR sys_setfsuid 345 PTR sys_setfsuid
346 PTR sys_setfsgid 346 PTR sys_setfsgid
347 PTR sys32_llseek /* 4140 */ 347 PTR sys32_llseek /* 4140 */
348 PTR sys32_getdents 348 PTR compat_sys_getdents
349 PTR compat_sys_select 349 PTR compat_sys_select
350 PTR sys_flock 350 PTR sys_flock
351 PTR sys_msync 351 PTR sys_msync
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index d86affa21278..d9293c558e41 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -540,6 +540,9 @@ void __init setup_arch(char **cmdline_p)
540 sparse_init(); 540 sparse_init();
541 paging_init(); 541 paging_init();
542 resource_init(); 542 resource_init();
543#ifdef CONFIG_SMP
544 plat_smp_setup();
545#endif
543} 546}
544 547
545int __init fpu_disable(char *s) 548int __init fpu_disable(char *s)
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
index 8a8b8dd90417..237cd8a2cd32 100644
--- a/arch/mips/kernel/signal32.c
+++ b/arch/mips/kernel/signal32.c
@@ -4,7 +4,7 @@
4 * for more details. 4 * for more details.
5 * 5 *
6 * Copyright (C) 1991, 1992 Linus Torvalds 6 * Copyright (C) 1991, 1992 Linus Torvalds
7 * Copyright (C) 1994 - 2000 Ralf Baechle 7 * Copyright (C) 1994 - 2000, 2006 Ralf Baechle
8 * Copyright (C) 1999, 2000 Silicon Graphics, Inc. 8 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
9 */ 9 */
10#include <linux/cache.h> 10#include <linux/cache.h>
@@ -106,8 +106,6 @@ typedef struct compat_siginfo {
106 106
107#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 107#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
108 108
109extern int do_signal32(sigset_t *oldset, struct pt_regs *regs);
110
111/* 32-bit compatibility types */ 109/* 32-bit compatibility types */
112 110
113#define _NSIG_BPW32 32 111#define _NSIG_BPW32 32
@@ -198,7 +196,7 @@ __attribute_used__ noinline static int
198_sys32_sigsuspend(nabi_no_regargs struct pt_regs regs) 196_sys32_sigsuspend(nabi_no_regargs struct pt_regs regs)
199{ 197{
200 compat_sigset_t *uset; 198 compat_sigset_t *uset;
201 sigset_t newset, saveset; 199 sigset_t newset;
202 200
203 uset = (compat_sigset_t *) regs.regs[4]; 201 uset = (compat_sigset_t *) regs.regs[4];
204 if (get_sigset(&newset, uset)) 202 if (get_sigset(&newset, uset))
@@ -206,19 +204,15 @@ _sys32_sigsuspend(nabi_no_regargs struct pt_regs regs)
206 sigdelsetmask(&newset, ~_BLOCKABLE); 204 sigdelsetmask(&newset, ~_BLOCKABLE);
207 205
208 spin_lock_irq(&current->sighand->siglock); 206 spin_lock_irq(&current->sighand->siglock);
209 saveset = current->blocked; 207 current->saved_sigmask = current->blocked;
210 current->blocked = newset; 208 current->blocked = newset;
211 recalc_sigpending(); 209 recalc_sigpending();
212 spin_unlock_irq(&current->sighand->siglock); 210 spin_unlock_irq(&current->sighand->siglock);
213 211
214 regs.regs[2] = EINTR; 212 current->state = TASK_INTERRUPTIBLE;
215 regs.regs[7] = 1; 213 schedule();
216 while (1) { 214 set_thread_flag(TIF_RESTORE_SIGMASK);
217 current->state = TASK_INTERRUPTIBLE; 215 return -ERESTARTNOHAND;
218 schedule();
219 if (do_signal32(&saveset, &regs))
220 return -EINTR;
221 }
222} 216}
223 217
224save_static_function(sys32_rt_sigsuspend); 218save_static_function(sys32_rt_sigsuspend);
@@ -226,8 +220,8 @@ __attribute_used__ noinline static int
226_sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs) 220_sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
227{ 221{
228 compat_sigset_t *uset; 222 compat_sigset_t *uset;
229 sigset_t newset, saveset; 223 sigset_t newset;
230 size_t sigsetsize; 224 size_t sigsetsize;
231 225
232 /* XXX Don't preclude handling different sized sigset_t's. */ 226 /* XXX Don't preclude handling different sized sigset_t's. */
233 sigsetsize = regs.regs[5]; 227 sigsetsize = regs.regs[5];
@@ -240,19 +234,15 @@ _sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
240 sigdelsetmask(&newset, ~_BLOCKABLE); 234 sigdelsetmask(&newset, ~_BLOCKABLE);
241 235
242 spin_lock_irq(&current->sighand->siglock); 236 spin_lock_irq(&current->sighand->siglock);
243 saveset = current->blocked; 237 current->saved_sigmask = current->blocked;
244 current->blocked = newset; 238 current->blocked = newset;
245 recalc_sigpending(); 239 recalc_sigpending();
246 spin_unlock_irq(&current->sighand->siglock); 240 spin_unlock_irq(&current->sighand->siglock);
247 241
248 regs.regs[2] = EINTR; 242 current->state = TASK_INTERRUPTIBLE;
249 regs.regs[7] = 1; 243 schedule();
250 while (1) { 244 set_thread_flag(TIF_RESTORE_SIGMASK);
251 current->state = TASK_INTERRUPTIBLE; 245 return -ERESTARTNOHAND;
252 schedule();
253 if (do_signal32(&saveset, &regs))
254 return -EINTR;
255 }
256} 246}
257 247
258asmlinkage int sys32_sigaction(int sig, const struct sigaction32 *act, 248asmlinkage int sys32_sigaction(int sig, const struct sigaction32 *act,
@@ -783,7 +773,7 @@ static inline int handle_signal(unsigned long sig, siginfo_t *info,
783 regs->regs[2] = EINTR; 773 regs->regs[2] = EINTR;
784 break; 774 break;
785 case ERESTARTSYS: 775 case ERESTARTSYS:
786 if(!(ka->sa.sa_flags & SA_RESTART)) { 776 if (!(ka->sa.sa_flags & SA_RESTART)) {
787 regs->regs[2] = EINTR; 777 regs->regs[2] = EINTR;
788 break; 778 break;
789 } 779 }
@@ -810,9 +800,10 @@ static inline int handle_signal(unsigned long sig, siginfo_t *info,
810 return ret; 800 return ret;
811} 801}
812 802
813int do_signal32(sigset_t *oldset, struct pt_regs *regs) 803void do_signal32(struct pt_regs *regs)
814{ 804{
815 struct k_sigaction ka; 805 struct k_sigaction ka;
806 sigset_t *oldset;
816 siginfo_t info; 807 siginfo_t info;
817 int signr; 808 int signr;
818 809
@@ -822,17 +813,30 @@ int do_signal32(sigset_t *oldset, struct pt_regs *regs)
822 * if so. 813 * if so.
823 */ 814 */
824 if (!user_mode(regs)) 815 if (!user_mode(regs))
825 return 1; 816 return;
826 817
827 if (try_to_freeze()) 818 if (try_to_freeze())
828 goto no_signal; 819 goto no_signal;
829 820
830 if (!oldset) 821 if (test_thread_flag(TIF_RESTORE_SIGMASK))
822 oldset = &current->saved_sigmask;
823 else
831 oldset = &current->blocked; 824 oldset = &current->blocked;
832 825
833 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 826 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
834 if (signr > 0) 827 if (signr > 0) {
835 return handle_signal(signr, &info, &ka, oldset, regs); 828 /* Whee! Actually deliver the signal. */
829 if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
830 /*
831 * A signal was successfully delivered; the saved
832 * sigmask will have been stored in the signal frame,
833 * and will be restored by sigreturn, so we can simply
834 * clear the TIF_RESTORE_SIGMASK flag.
835 */
836 if (test_thread_flag(TIF_RESTORE_SIGMASK))
837 clear_thread_flag(TIF_RESTORE_SIGMASK);
838 }
839 }
836 840
837no_signal: 841no_signal:
838 /* 842 /*
@@ -853,7 +857,15 @@ no_signal:
853 regs->cp0_epc -= 4; 857 regs->cp0_epc -= 4;
854 } 858 }
855 } 859 }
856 return 0; 860
861 /*
862 * If there's no signal to deliver, we just put the saved sigmask
863 * back
864 */
865 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
866 clear_thread_flag(TIF_RESTORE_SIGMASK);
867 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
868 }
857} 869}
858 870
859asmlinkage int sys32_rt_sigaction(int sig, const struct sigaction32 *act, 871asmlinkage int sys32_rt_sigaction(int sig, const struct sigaction32 *act,
diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c
index 5a3776096f07..3e168c08a3a8 100644
--- a/arch/mips/kernel/signal_n32.c
+++ b/arch/mips/kernel/signal_n32.c
@@ -81,6 +81,39 @@ struct rt_sigframe_n32 {
81#endif 81#endif
82}; 82};
83 83
84extern void sigset_from_compat (sigset_t *set, compat_sigset_t *compat);
85
86save_static_function(sysn32_rt_sigsuspend);
87__attribute_used__ noinline static int
88_sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
89{
90 compat_sigset_t __user *unewset, uset;
91 size_t sigsetsize;
92 sigset_t newset;
93
94 /* XXX Don't preclude handling different sized sigset_t's. */
95 sigsetsize = regs.regs[5];
96 if (sigsetsize != sizeof(sigset_t))
97 return -EINVAL;
98
99 unewset = (compat_sigset_t __user *) regs.regs[4];
100 if (copy_from_user(&uset, unewset, sizeof(uset)))
101 return -EFAULT;
102 sigset_from_compat (&newset, &uset);
103 sigdelsetmask(&newset, ~_BLOCKABLE);
104
105 spin_lock_irq(&current->sighand->siglock);
106 current->saved_sigmask = current->blocked;
107 current->blocked = newset;
108 recalc_sigpending();
109 spin_unlock_irq(&current->sighand->siglock);
110
111 current->state = TASK_INTERRUPTIBLE;
112 schedule();
113 set_thread_flag(TIF_RESTORE_SIGMASK);
114 return -ERESTARTNOHAND;
115}
116
84save_static_function(sysn32_rt_sigreturn); 117save_static_function(sysn32_rt_sigreturn);
85__attribute_used__ noinline static void 118__attribute_used__ noinline static void
86_sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) 119_sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index 25472fcaf715..06ed90752424 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -29,6 +29,7 @@
29#include <linux/timex.h> 29#include <linux/timex.h>
30#include <linux/sched.h> 30#include <linux/sched.h>
31#include <linux/cpumask.h> 31#include <linux/cpumask.h>
32#include <linux/cpu.h>
32 33
33#include <asm/atomic.h> 34#include <asm/atomic.h>
34#include <asm/cpu.h> 35#include <asm/cpu.h>
@@ -235,7 +236,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
235 init_new_context(current, &init_mm); 236 init_new_context(current, &init_mm);
236 current_thread_info()->cpu = 0; 237 current_thread_info()->cpu = 0;
237 smp_tune_scheduling(); 238 smp_tune_scheduling();
238 prom_prepare_cpus(max_cpus); 239 plat_prepare_cpus(max_cpus);
239} 240}
240 241
241/* preload SMP state for boot cpu */ 242/* preload SMP state for boot cpu */
@@ -424,6 +425,25 @@ void flush_tlb_one(unsigned long vaddr)
424 local_flush_tlb_one(vaddr); 425 local_flush_tlb_one(vaddr);
425} 426}
426 427
428static DEFINE_PER_CPU(struct cpu, cpu_devices);
429
430static int __init topology_init(void)
431{
432 int cpu;
433 int ret;
434
435 for_each_cpu(cpu) {
436 ret = register_cpu(&per_cpu(cpu_devices, cpu), cpu, NULL);
437 if (ret)
438 printk(KERN_WARNING "topology_init: register_cpu %d "
439 "failed (%d)\n", cpu, ret);
440 }
441
442 return 0;
443}
444
445subsys_initcall(topology_init);
446
427EXPORT_SYMBOL(flush_tlb_page); 447EXPORT_SYMBOL(flush_tlb_page);
428EXPORT_SYMBOL(flush_tlb_one); 448EXPORT_SYMBOL(flush_tlb_one);
429EXPORT_SYMBOL(cpu_data); 449EXPORT_SYMBOL(cpu_data);
diff --git a/arch/mips/kernel/smp_mt.c b/arch/mips/kernel/smp_mt.c
index c930364830d0..993b8bf56aaf 100644
--- a/arch/mips/kernel/smp_mt.c
+++ b/arch/mips/kernel/smp_mt.c
@@ -143,7 +143,7 @@ static struct irqaction irq_call = {
143 * Make sure all CPU's are in a sensible state before we boot any of the 143 * Make sure all CPU's are in a sensible state before we boot any of the
144 * secondarys 144 * secondarys
145 */ 145 */
146void prom_prepare_cpus(unsigned int max_cpus) 146void plat_smp_setup(void)
147{ 147{
148 unsigned long val; 148 unsigned long val;
149 int i, num; 149 int i, num;
@@ -179,11 +179,9 @@ void prom_prepare_cpus(unsigned int max_cpus)
179 write_vpe_c0_vpeconf0(tmp); 179 write_vpe_c0_vpeconf0(tmp);
180 180
181 /* Record this as available CPU */ 181 /* Record this as available CPU */
182 if (i < max_cpus) { 182 cpu_set(i, phys_cpu_present_map);
183 cpu_set(i, phys_cpu_present_map); 183 __cpu_number_map[i] = ++num;
184 __cpu_number_map[i] = ++num; 184 __cpu_logical_map[num] = i;
185 __cpu_logical_map[num] = i;
186 }
187 } 185 }
188 186
189 /* disable multi-threading with TC's */ 187 /* disable multi-threading with TC's */
@@ -241,7 +239,10 @@ void prom_prepare_cpus(unsigned int max_cpus)
241 set_vi_handler (MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch); 239 set_vi_handler (MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch);
242 set_vi_handler (MIPS_CPU_IPI_CALL_IRQ, ipi_call_dispatch); 240 set_vi_handler (MIPS_CPU_IPI_CALL_IRQ, ipi_call_dispatch);
243 } 241 }
242}
244 243
244void __init plat_prepare_cpus(unsigned int max_cpus)
245{
245 cpu_ipi_resched_irq = MIPSCPU_INT_BASE + MIPS_CPU_IPI_RESCHED_IRQ; 246 cpu_ipi_resched_irq = MIPSCPU_INT_BASE + MIPS_CPU_IPI_RESCHED_IRQ;
246 cpu_ipi_call_irq = MIPSCPU_INT_BASE + MIPS_CPU_IPI_CALL_IRQ; 247 cpu_ipi_call_irq = MIPSCPU_INT_BASE + MIPS_CPU_IPI_CALL_IRQ;
247 248
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
index 7050b4ffffcd..42c94c771afb 100644
--- a/arch/mips/kernel/time.c
+++ b/arch/mips/kernel/time.c
@@ -163,7 +163,7 @@ void do_gettimeofday(struct timeval *tv)
163 unsigned long seq; 163 unsigned long seq;
164 unsigned long lost; 164 unsigned long lost;
165 unsigned long usec, sec; 165 unsigned long usec, sec;
166 unsigned long max_ntp_tick = tick_usec - tickadj; 166 unsigned long max_ntp_tick;
167 167
168 do { 168 do {
169 seq = read_seqbegin(&xtime_lock); 169 seq = read_seqbegin(&xtime_lock);
@@ -178,12 +178,13 @@ void do_gettimeofday(struct timeval *tv)
178 * Better to lose some accuracy than have time go backwards.. 178 * Better to lose some accuracy than have time go backwards..
179 */ 179 */
180 if (unlikely(time_adjust < 0)) { 180 if (unlikely(time_adjust < 0)) {
181 max_ntp_tick = (USEC_PER_SEC / HZ) - tickadj;
181 usec = min(usec, max_ntp_tick); 182 usec = min(usec, max_ntp_tick);
182 183
183 if (lost) 184 if (lost)
184 usec += lost * max_ntp_tick; 185 usec += lost * max_ntp_tick;
185 } else if (unlikely(lost)) 186 } else if (unlikely(lost))
186 usec += lost * tick_usec; 187 usec += lost * (USEC_PER_SEC / HZ);
187 188
188 sec = xtime.tv_sec; 189 sec = xtime.tv_sec;
189 usec += (xtime.tv_nsec / 1000); 190 usec += (xtime.tv_nsec / 1000);
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index c9d2b5147ca3..005debbfbe84 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -3,7 +3,7 @@
3 * License. See the file "COPYING" in the main directory of this archive 3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details. 4 * for more details.
5 * 5 *
6 * Copyright (C) 1994 - 1999, 2000, 01 Ralf Baechle 6 * Copyright (C) 1994 - 1999, 2000, 01, 06 Ralf Baechle
7 * Copyright (C) 1995, 1996 Paul M. Antoine 7 * Copyright (C) 1995, 1996 Paul M. Antoine
8 * Copyright (C) 1998 Ulf Carlsson 8 * Copyright (C) 1998 Ulf Carlsson
9 * Copyright (C) 1999 Silicon Graphics, Inc. 9 * Copyright (C) 1999 Silicon Graphics, Inc.
@@ -548,6 +548,8 @@ asmlinkage void do_ov(struct pt_regs *regs)
548{ 548{
549 siginfo_t info; 549 siginfo_t info;
550 550
551 die_if_kernel("Integer overflow", regs);
552
551 info.si_code = FPE_INTOVF; 553 info.si_code = FPE_INTOVF;
552 info.si_signo = SIGFPE; 554 info.si_signo = SIGFPE;
553 info.si_errno = 0; 555 info.si_errno = 0;
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S
index ff699dbb99f7..2ad0cedf29fe 100644
--- a/arch/mips/kernel/vmlinux.lds.S
+++ b/arch/mips/kernel/vmlinux.lds.S
@@ -106,6 +106,9 @@ SECTIONS
106 .con_initcall.init : { *(.con_initcall.init) } 106 .con_initcall.init : { *(.con_initcall.init) }
107 __con_initcall_end = .; 107 __con_initcall_end = .;
108 SECURITY_INIT 108 SECURITY_INIT
109 /* .exit.text is discarded at runtime, not link time, to deal with
110 references from .rodata */
111 .exit.text : { *(.exit.text) }
109 . = ALIGN(_PAGE_SIZE); 112 . = ALIGN(_PAGE_SIZE);
110 __initramfs_start = .; 113 __initramfs_start = .;
111 .init.ramfs : { *(.init.ramfs) } 114 .init.ramfs : { *(.init.ramfs) }
@@ -133,7 +136,6 @@ SECTIONS
133 136
134 /* Sections to be discarded */ 137 /* Sections to be discarded */
135 /DISCARD/ : { 138 /DISCARD/ : {
136 *(.exit.text)
137 *(.exit.data) 139 *(.exit.data)
138 *(.exitcall.exit) 140 *(.exitcall.exit)
139 141