aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel')
-rw-r--r--arch/mips/kernel/Makefile7
-rw-r--r--arch/mips/kernel/asm-offsets.c5
-rw-r--r--arch/mips/kernel/cpu-probe.c3
-rw-r--r--arch/mips/kernel/early_printk.c40
-rw-r--r--arch/mips/kernel/entry.S6
-rw-r--r--arch/mips/kernel/genex.S47
-rw-r--r--arch/mips/kernel/i8259.c17
-rw-r--r--arch/mips/kernel/kspd.c27
-rw-r--r--arch/mips/kernel/linux32.c231
-rw-r--r--arch/mips/kernel/machine_kexec.c4
-rw-r--r--arch/mips/kernel/mips_ksyms.c1
-rw-r--r--arch/mips/kernel/process.c39
-rw-r--r--arch/mips/kernel/ptrace.c10
-rw-r--r--arch/mips/kernel/r4k_fpu.S16
-rw-r--r--arch/mips/kernel/rtlx.c253
-rw-r--r--arch/mips/kernel/scall32-o32.S2
-rw-r--r--arch/mips/kernel/scall64-64.S5
-rw-r--r--arch/mips/kernel/scall64-n32.S9
-rw-r--r--arch/mips/kernel/scall64-o32.S8
-rw-r--r--arch/mips/kernel/setup.c12
-rw-r--r--arch/mips/kernel/signal-common.h12
-rw-r--r--arch/mips/kernel/signal.c136
-rw-r--r--arch/mips/kernel/signal32.c225
-rw-r--r--arch/mips/kernel/signal_n32.c14
-rw-r--r--arch/mips/kernel/smp.c25
-rw-r--r--arch/mips/kernel/smtc.c84
-rw-r--r--arch/mips/kernel/traps.c88
-rw-r--r--arch/mips/kernel/unaligned.c2
-rw-r--r--arch/mips/kernel/vpe.c7
29 files changed, 616 insertions, 719 deletions
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 1bf2c8448912..49246264cc7c 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -53,9 +53,9 @@ obj-$(CONFIG_MIPS_BOARDS_GEN) += irq-msc01.o
53obj-$(CONFIG_32BIT) += scall32-o32.o 53obj-$(CONFIG_32BIT) += scall32-o32.o
54obj-$(CONFIG_64BIT) += scall64-64.o 54obj-$(CONFIG_64BIT) += scall64-64.o
55obj-$(CONFIG_BINFMT_IRIX) += binfmt_irix.o 55obj-$(CONFIG_BINFMT_IRIX) += binfmt_irix.o
56obj-$(CONFIG_MIPS32_COMPAT) += linux32.o signal32.o 56obj-$(CONFIG_MIPS32_COMPAT) += linux32.o ptrace32.o signal32.o
57obj-$(CONFIG_MIPS32_N32) += binfmt_elfn32.o scall64-n32.o signal_n32.o 57obj-$(CONFIG_MIPS32_N32) += binfmt_elfn32.o scall64-n32.o signal_n32.o
58obj-$(CONFIG_MIPS32_O32) += binfmt_elfo32.o scall64-o32.o ptrace32.o 58obj-$(CONFIG_MIPS32_O32) += binfmt_elfo32.o scall64-o32.o
59 59
60obj-$(CONFIG_KGDB) += gdb-low.o gdb-stub.o 60obj-$(CONFIG_KGDB) += gdb-low.o gdb-stub.o
61obj-$(CONFIG_PROC_FS) += proc.o 61obj-$(CONFIG_PROC_FS) += proc.o
@@ -65,7 +65,6 @@ obj-$(CONFIG_64BIT) += cpu-bugs64.o
65obj-$(CONFIG_I8253) += i8253.o 65obj-$(CONFIG_I8253) += i8253.o
66 66
67obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o 67obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
68obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
68 69
69CFLAGS_cpu-bugs64.o = $(shell if $(CC) $(CFLAGS) -Wa,-mdaddi -c -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-DHAVE_AS_SET_DADDI"; fi) 70CFLAGS_cpu-bugs64.o = $(shell if $(CC) $(CFLAGS) -Wa,-mdaddi -c -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-DHAVE_AS_SET_DADDI"; fi)
70
71EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c
index c0b089d47181..761a779d5c4f 100644
--- a/arch/mips/kernel/asm-offsets.c
+++ b/arch/mips/kernel/asm-offsets.c
@@ -64,6 +64,9 @@ void output_ptreg_defines(void)
64 offset("#define PT_R31 ", struct pt_regs, regs[31]); 64 offset("#define PT_R31 ", struct pt_regs, regs[31]);
65 offset("#define PT_LO ", struct pt_regs, lo); 65 offset("#define PT_LO ", struct pt_regs, lo);
66 offset("#define PT_HI ", struct pt_regs, hi); 66 offset("#define PT_HI ", struct pt_regs, hi);
67#ifdef CONFIG_CPU_HAS_SMARTMIPS
68 offset("#define PT_ACX ", struct pt_regs, acx);
69#endif
67 offset("#define PT_EPC ", struct pt_regs, cp0_epc); 70 offset("#define PT_EPC ", struct pt_regs, cp0_epc);
68 offset("#define PT_BVADDR ", struct pt_regs, cp0_badvaddr); 71 offset("#define PT_BVADDR ", struct pt_regs, cp0_badvaddr);
69 offset("#define PT_STATUS ", struct pt_regs, cp0_status); 72 offset("#define PT_STATUS ", struct pt_regs, cp0_status);
@@ -99,7 +102,6 @@ void output_thread_info_defines(void)
99 offset("#define TI_ADDR_LIMIT ", struct thread_info, addr_limit); 102 offset("#define TI_ADDR_LIMIT ", struct thread_info, addr_limit);
100 offset("#define TI_RESTART_BLOCK ", struct thread_info, restart_block); 103 offset("#define TI_RESTART_BLOCK ", struct thread_info, restart_block);
101 offset("#define TI_REGS ", struct thread_info, regs); 104 offset("#define TI_REGS ", struct thread_info, regs);
102 constant("#define _THREAD_SIZE_ORDER ", THREAD_SIZE_ORDER);
103 constant("#define _THREAD_SIZE ", THREAD_SIZE); 105 constant("#define _THREAD_SIZE ", THREAD_SIZE);
104 constant("#define _THREAD_MASK ", THREAD_MASK); 106 constant("#define _THREAD_MASK ", THREAD_MASK);
105 linefeed; 107 linefeed;
@@ -246,6 +248,7 @@ void output_sc_defines(void)
246 text("/* Linux sigcontext offsets. */"); 248 text("/* Linux sigcontext offsets. */");
247 offset("#define SC_REGS ", struct sigcontext, sc_regs); 249 offset("#define SC_REGS ", struct sigcontext, sc_regs);
248 offset("#define SC_FPREGS ", struct sigcontext, sc_fpregs); 250 offset("#define SC_FPREGS ", struct sigcontext, sc_fpregs);
251 offset("#define SC_ACX ", struct sigcontext, sc_acx);
249 offset("#define SC_MDHI ", struct sigcontext, sc_mdhi); 252 offset("#define SC_MDHI ", struct sigcontext, sc_mdhi);
250 offset("#define SC_MDLO ", struct sigcontext, sc_mdlo); 253 offset("#define SC_MDLO ", struct sigcontext, sc_mdlo);
251 offset("#define SC_PC ", struct sigcontext, sc_pc); 254 offset("#define SC_PC ", struct sigcontext, sc_pc);
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index f59ef271d247..ab755ea26c6a 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -16,6 +16,7 @@
16#include <linux/ptrace.h> 16#include <linux/ptrace.h>
17#include <linux/stddef.h> 17#include <linux/stddef.h>
18 18
19#include <asm/bugs.h>
19#include <asm/cpu.h> 20#include <asm/cpu.h>
20#include <asm/fpu.h> 21#include <asm/fpu.h>
21#include <asm/mipsregs.h> 22#include <asm/mipsregs.h>
@@ -97,7 +98,7 @@ static void au1k_wait(void)
97 98
98static int __initdata nowait = 0; 99static int __initdata nowait = 0;
99 100
100int __init wait_disable(char *s) 101static int __init wait_disable(char *s)
101{ 102{
102 nowait = 1; 103 nowait = 1;
103 104
diff --git a/arch/mips/kernel/early_printk.c b/arch/mips/kernel/early_printk.c
new file mode 100644
index 000000000000..304efdc5682f
--- /dev/null
+++ b/arch/mips/kernel/early_printk.c
@@ -0,0 +1,40 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2002, 2003, 06, 07 Ralf Baechle (ralf@linux-mips.org)
7 * Copyright (C) 2007 MIPS Technologies, Inc.
8 * written by Ralf Baechle (ralf@linux-mips.org)
9 */
10#include <linux/console.h>
11#include <linux/init.h>
12
13extern void prom_putchar(char);
14
15static void early_console_write(struct console *con, const char *s, unsigned n)
16{
17 while (n-- && *s) {
18 if (*s == '\n')
19 prom_putchar('\r');
20 prom_putchar(*s);
21 s++;
22 }
23}
24
25static struct console early_console = {
26 .name = "early",
27 .write = early_console_write,
28 .flags = CON_PRINTBUFFER | CON_BOOT,
29 .index = -1
30};
31
32void __init setup_early_printk(void)
33{
34 register_console(&early_console);
35}
36
37void __init disable_early_printk(void)
38{
39 unregister_console(&early_console);
40}
diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S
index 0b78fcbf044a..686249c5c328 100644
--- a/arch/mips/kernel/entry.S
+++ b/arch/mips/kernel/entry.S
@@ -121,7 +121,11 @@ FEXPORT(restore_partial) # restore partial frame
121 SAVE_AT 121 SAVE_AT
122 SAVE_TEMP 122 SAVE_TEMP
123 LONG_L v0, PT_STATUS(sp) 123 LONG_L v0, PT_STATUS(sp)
124 and v0, 1 124#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
125 and v0, ST0_IEP
126#else
127 and v0, ST0_IE
128#endif
125 beqz v0, 1f 129 beqz v0, 1f
126 jal trace_hardirqs_on 130 jal trace_hardirqs_on
127 b 2f 131 b 2f
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S
index aacd4a005c5f..297bd56c2347 100644
--- a/arch/mips/kernel/genex.S
+++ b/arch/mips/kernel/genex.S
@@ -128,6 +128,37 @@ handle_vcei:
128 128
129 .align 5 129 .align 5
130NESTED(handle_int, PT_SIZE, sp) 130NESTED(handle_int, PT_SIZE, sp)
131#ifdef CONFIG_TRACE_IRQFLAGS
132 /*
133 * Check to see if the interrupted code has just disabled
134 * interrupts and ignore this interrupt for now if so.
135 *
136 * local_irq_disable() disables interrupts and then calls
137 * trace_hardirqs_off() to track the state. If an interrupt is taken
138 * after interrupts are disabled but before the state is updated
139 * it will appear to restore_all that it is incorrectly returning with
140 * interrupts disabled
141 */
142 .set push
143 .set noat
144 mfc0 k0, CP0_STATUS
145#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
146 and k0, ST0_IEP
147 bnez k0, 1f
148
149 mfc0 k0, EP0_EPC
150 .set noreorder
151 j k0
152 rfe
153#else
154 and k0, ST0_IE
155 bnez k0, 1f
156
157 eret
158#endif
1591:
160 .set pop
161#endif
131 SAVE_ALL 162 SAVE_ALL
132 CLI 163 CLI
133 TRACE_IRQS_OFF 164 TRACE_IRQS_OFF
@@ -181,13 +212,13 @@ NESTED(except_vec_vi, 0, sp)
181 * during service by SMTC kernel, we also want to 212 * during service by SMTC kernel, we also want to
182 * pass the IM value to be cleared. 213 * pass the IM value to be cleared.
183 */ 214 */
184EXPORT(except_vec_vi_mori) 215FEXPORT(except_vec_vi_mori)
185 ori a0, $0, 0 216 ori a0, $0, 0
186#endif /* CONFIG_MIPS_MT_SMTC */ 217#endif /* CONFIG_MIPS_MT_SMTC */
187EXPORT(except_vec_vi_lui) 218FEXPORT(except_vec_vi_lui)
188 lui v0, 0 /* Patched */ 219 lui v0, 0 /* Patched */
189 j except_vec_vi_handler 220 j except_vec_vi_handler
190EXPORT(except_vec_vi_ori) 221FEXPORT(except_vec_vi_ori)
191 ori v0, 0 /* Patched */ 222 ori v0, 0 /* Patched */
192 .set pop 223 .set pop
193 END(except_vec_vi) 224 END(except_vec_vi)
@@ -220,7 +251,17 @@ NESTED(except_vec_vi_handler, 0, sp)
220 _ehb 251 _ehb
221#endif /* CONFIG_MIPS_MT_SMTC */ 252#endif /* CONFIG_MIPS_MT_SMTC */
222 CLI 253 CLI
254#ifdef CONFIG_TRACE_IRQFLAGS
255 move s0, v0
256#ifdef CONFIG_MIPS_MT_SMTC
257 move s1, a0
258#endif
223 TRACE_IRQS_OFF 259 TRACE_IRQS_OFF
260#ifdef CONFIG_MIPS_MT_SMTC
261 move a0, s1
262#endif
263 move v0, s0
264#endif
224 265
225 LONG_L s0, TI_REGS($28) 266 LONG_L s0, TI_REGS($28)
226 LONG_S sp, TI_REGS($28) 267 LONG_S sp, TI_REGS($28)
diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c
index b33ba6cd7f5b..2345160e63fc 100644
--- a/arch/mips/kernel/i8259.c
+++ b/arch/mips/kernel/i8259.c
@@ -28,7 +28,7 @@
28 * moves to arch independent land 28 * moves to arch independent land
29 */ 29 */
30 30
31static int i8259A_auto_eoi; 31static int i8259A_auto_eoi = -1;
32DEFINE_SPINLOCK(i8259A_lock); 32DEFINE_SPINLOCK(i8259A_lock);
33/* some platforms call this... */ 33/* some platforms call this... */
34void mask_and_ack_8259A(unsigned int); 34void mask_and_ack_8259A(unsigned int);
@@ -216,7 +216,8 @@ spurious_8259A_irq:
216 216
217static int i8259A_resume(struct sys_device *dev) 217static int i8259A_resume(struct sys_device *dev)
218{ 218{
219 init_8259A(i8259A_auto_eoi); 219 if (i8259A_auto_eoi >= 0)
220 init_8259A(i8259A_auto_eoi);
220 return 0; 221 return 0;
221} 222}
222 223
@@ -226,8 +227,10 @@ static int i8259A_shutdown(struct sys_device *dev)
226 * the kernel initialization code can get it 227 * the kernel initialization code can get it
227 * out of. 228 * out of.
228 */ 229 */
229 outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */ 230 if (i8259A_auto_eoi >= 0) {
230 outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-1 */ 231 outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */
232 outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-1 */
233 }
231 return 0; 234 return 0;
232} 235}
233 236
@@ -252,7 +255,7 @@ static int __init i8259A_init_sysfs(void)
252 255
253device_initcall(i8259A_init_sysfs); 256device_initcall(i8259A_init_sysfs);
254 257
255void __init init_8259A(int auto_eoi) 258void init_8259A(int auto_eoi)
256{ 259{
257 unsigned long flags; 260 unsigned long flags;
258 261
@@ -325,8 +328,8 @@ void __init init_i8259_irqs (void)
325{ 328{
326 int i; 329 int i;
327 330
328 request_resource(&ioport_resource, &pic1_io_resource); 331 insert_resource(&ioport_resource, &pic1_io_resource);
329 request_resource(&ioport_resource, &pic2_io_resource); 332 insert_resource(&ioport_resource, &pic2_io_resource);
330 333
331 init_8259A(0); 334 init_8259A(0);
332 335
diff --git a/arch/mips/kernel/kspd.c b/arch/mips/kernel/kspd.c
index 5929f883e46b..c6580018c94b 100644
--- a/arch/mips/kernel/kspd.c
+++ b/arch/mips/kernel/kspd.c
@@ -17,6 +17,7 @@
17 */ 17 */
18#include <linux/kernel.h> 18#include <linux/kernel.h>
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/sched.h>
20#include <linux/unistd.h> 21#include <linux/unistd.h>
21#include <linux/file.h> 22#include <linux/file.h>
22#include <linux/fs.h> 23#include <linux/fs.h>
@@ -70,6 +71,7 @@ static int sp_stopping = 0;
70#define MTSP_SYSCALL_GETTIME (MTSP_SYSCALL_BASE + 7) 71#define MTSP_SYSCALL_GETTIME (MTSP_SYSCALL_BASE + 7)
71#define MTSP_SYSCALL_PIPEFREQ (MTSP_SYSCALL_BASE + 8) 72#define MTSP_SYSCALL_PIPEFREQ (MTSP_SYSCALL_BASE + 8)
72#define MTSP_SYSCALL_GETTOD (MTSP_SYSCALL_BASE + 9) 73#define MTSP_SYSCALL_GETTOD (MTSP_SYSCALL_BASE + 9)
74#define MTSP_SYSCALL_IOCTL (MTSP_SYSCALL_BASE + 10)
73 75
74#define MTSP_O_RDONLY 0x0000 76#define MTSP_O_RDONLY 0x0000
75#define MTSP_O_WRONLY 0x0001 77#define MTSP_O_WRONLY 0x0001
@@ -110,7 +112,8 @@ struct apsp_table syscall_command_table[] = {
110 { MTSP_SYSCALL_CLOSE, __NR_close }, 112 { MTSP_SYSCALL_CLOSE, __NR_close },
111 { MTSP_SYSCALL_READ, __NR_read }, 113 { MTSP_SYSCALL_READ, __NR_read },
112 { MTSP_SYSCALL_WRITE, __NR_write }, 114 { MTSP_SYSCALL_WRITE, __NR_write },
113 { MTSP_SYSCALL_LSEEK32, __NR_lseek } 115 { MTSP_SYSCALL_LSEEK32, __NR_lseek },
116 { MTSP_SYSCALL_IOCTL, __NR_ioctl }
114}; 117};
115 118
116static int sp_syscall(int num, int arg0, int arg1, int arg2, int arg3) 119static int sp_syscall(int num, int arg0, int arg1, int arg2, int arg3)
@@ -189,17 +192,22 @@ void sp_work_handle_request(void)
189 struct mtsp_syscall_generic generic; 192 struct mtsp_syscall_generic generic;
190 struct mtsp_syscall_ret ret; 193 struct mtsp_syscall_ret ret;
191 struct kspd_notifications *n; 194 struct kspd_notifications *n;
195 unsigned long written;
196 mm_segment_t old_fs;
192 struct timeval tv; 197 struct timeval tv;
193 struct timezone tz; 198 struct timezone tz;
194 int cmd; 199 int cmd;
195 200
196 char *vcwd; 201 char *vcwd;
197 mm_segment_t old_fs;
198 int size; 202 int size;
199 203
200 ret.retval = -1; 204 ret.retval = -1;
201 205
202 if (!rtlx_read(RTLX_CHANNEL_SYSIO, &sc, sizeof(struct mtsp_syscall), 0)) { 206 old_fs = get_fs();
207 set_fs(KERNEL_DS);
208
209 if (!rtlx_read(RTLX_CHANNEL_SYSIO, &sc, sizeof(struct mtsp_syscall))) {
210 set_fs(old_fs);
203 printk(KERN_ERR "Expected request but nothing to read\n"); 211 printk(KERN_ERR "Expected request but nothing to read\n");
204 return; 212 return;
205 } 213 }
@@ -207,7 +215,8 @@ void sp_work_handle_request(void)
207 size = sc.size; 215 size = sc.size;
208 216
209 if (size) { 217 if (size) {
210 if (!rtlx_read(RTLX_CHANNEL_SYSIO, &generic, size, 0)) { 218 if (!rtlx_read(RTLX_CHANNEL_SYSIO, &generic, size)) {
219 set_fs(old_fs);
211 printk(KERN_ERR "Expected request but nothing to read\n"); 220 printk(KERN_ERR "Expected request but nothing to read\n");
212 return; 221 return;
213 } 222 }
@@ -232,8 +241,6 @@ void sp_work_handle_request(void)
232 if ((ret.retval = sp_syscall(__NR_gettimeofday, (int)&tv, 241 if ((ret.retval = sp_syscall(__NR_gettimeofday, (int)&tv,
233 (int)&tz, 0,0)) == 0) 242 (int)&tz, 0,0)) == 0)
234 ret.retval = tv.tv_sec; 243 ret.retval = tv.tv_sec;
235
236 ret.errno = errno;
237 break; 244 break;
238 245
239 case MTSP_SYSCALL_EXIT: 246 case MTSP_SYSCALL_EXIT:
@@ -270,7 +277,6 @@ void sp_work_handle_request(void)
270 if (cmd >= 0) { 277 if (cmd >= 0) {
271 ret.retval = sp_syscall(cmd, generic.arg0, generic.arg1, 278 ret.retval = sp_syscall(cmd, generic.arg0, generic.arg1,
272 generic.arg2, generic.arg3); 279 generic.arg2, generic.arg3);
273 ret.errno = errno;
274 } else 280 } else
275 printk(KERN_WARNING 281 printk(KERN_WARNING
276 "KSPD: Unknown SP syscall number %d\n", sc.cmd); 282 "KSPD: Unknown SP syscall number %d\n", sc.cmd);
@@ -280,8 +286,11 @@ void sp_work_handle_request(void)
280 if (vpe_getuid(SP_VPE)) 286 if (vpe_getuid(SP_VPE))
281 sp_setfsuidgid( 0, 0); 287 sp_setfsuidgid( 0, 0);
282 288
283 if ((rtlx_write(RTLX_CHANNEL_SYSIO, &ret, sizeof(struct mtsp_syscall_ret), 0)) 289 old_fs = get_fs();
284 < sizeof(struct mtsp_syscall_ret)) 290 set_fs(KERNEL_DS);
291 written = rtlx_write(RTLX_CHANNEL_SYSIO, &ret, sizeof(ret));
292 set_fs(old_fs);
293 if (written < sizeof(ret))
285 printk("KSPD: sp_work_handle_request failed to send to SP\n"); 294 printk("KSPD: sp_work_handle_request failed to send to SP\n");
286} 295}
287 296
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c
index fc4dd6c9dd80..37849edd0645 100644
--- a/arch/mips/kernel/linux32.c
+++ b/arch/mips/kernel/linux32.c
@@ -166,34 +166,6 @@ out:
166 return error; 166 return error;
167} 167}
168 168
169asmlinkage long
170sysn32_waitid(int which, compat_pid_t pid,
171 siginfo_t __user *uinfo, int options,
172 struct compat_rusage __user *uru)
173{
174 struct rusage ru;
175 long ret;
176 mm_segment_t old_fs = get_fs();
177 int si_signo;
178
179 if (!access_ok(VERIFY_WRITE, uinfo, sizeof(*uinfo)))
180 return -EFAULT;
181
182 set_fs (KERNEL_DS);
183 ret = sys_waitid(which, pid, uinfo, options,
184 uru ? (struct rusage __user *) &ru : NULL);
185 set_fs (old_fs);
186
187 if (__get_user(si_signo, &uinfo->si_signo))
188 return -EFAULT;
189 if (ret < 0 || si_signo == 0)
190 return ret;
191
192 if (uru)
193 ret = put_compat_rusage(&ru, uru);
194 return ret;
195}
196
197#define RLIM_INFINITY32 0x7fffffff 169#define RLIM_INFINITY32 0x7fffffff
198#define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x) 170#define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
199 171
@@ -339,6 +311,8 @@ asmlinkage int sys32_sched_rr_get_interval(compat_pid_t pid,
339 return ret; 311 return ret;
340} 312}
341 313
314#ifdef CONFIG_SYSVIPC
315
342asmlinkage long 316asmlinkage long
343sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth) 317sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
344{ 318{
@@ -396,6 +370,16 @@ sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
396 return err; 370 return err;
397} 371}
398 372
373#else
374
375asmlinkage long
376sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
377{
378 return -ENOSYS;
379}
380
381#endif /* CONFIG_SYSVIPC */
382
399#ifdef CONFIG_MIPS32_N32 383#ifdef CONFIG_MIPS32_N32
400asmlinkage long sysn32_semctl(int semid, int semnum, int cmd, u32 arg) 384asmlinkage long sysn32_semctl(int semid, int semnum, int cmd, u32 arg)
401{ 385{
@@ -572,151 +556,6 @@ asmlinkage long sys32_sync_file_range(int fd, int __pad,
572 flags); 556 flags);
573} 557}
574 558
575/* Argument list sizes for sys_socketcall */
576#define AL(x) ((x) * sizeof(unsigned int))
577static unsigned char socketcall_nargs[18]={AL(0),AL(3),AL(3),AL(3),AL(2),AL(3),
578 AL(3),AL(3),AL(4),AL(4),AL(4),AL(6),
579 AL(6),AL(2),AL(5),AL(5),AL(3),AL(3)};
580#undef AL
581
582/*
583 * System call vectors.
584 *
585 * Argument checking cleaned up. Saved 20% in size.
586 * This function doesn't need to set the kernel lock because
587 * it is set by the callees.
588 */
589
590asmlinkage long sys32_socketcall(int call, unsigned int __user *args32)
591{
592 unsigned int a[6];
593 unsigned int a0,a1;
594 int err;
595
596 extern asmlinkage long sys_socket(int family, int type, int protocol);
597 extern asmlinkage long sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen);
598 extern asmlinkage long sys_connect(int fd, struct sockaddr __user *uservaddr, int addrlen);
599 extern asmlinkage long sys_listen(int fd, int backlog);
600 extern asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, int __user *upeer_addrlen);
601 extern asmlinkage long sys_getsockname(int fd, struct sockaddr __user *usockaddr, int __user *usockaddr_len);
602 extern asmlinkage long sys_getpeername(int fd, struct sockaddr __user *usockaddr, int __user *usockaddr_len);
603 extern asmlinkage long sys_socketpair(int family, int type, int protocol, int __user *usockvec);
604 extern asmlinkage long sys_send(int fd, void __user * buff, size_t len, unsigned flags);
605 extern asmlinkage long sys_sendto(int fd, void __user * buff, size_t len, unsigned flags,
606 struct sockaddr __user *addr, int addr_len);
607 extern asmlinkage long sys_recv(int fd, void __user * ubuf, size_t size, unsigned flags);
608 extern asmlinkage long sys_recvfrom(int fd, void __user * ubuf, size_t size, unsigned flags,
609 struct sockaddr __user *addr, int __user *addr_len);
610 extern asmlinkage long sys_shutdown(int fd, int how);
611 extern asmlinkage long sys_setsockopt(int fd, int level, int optname, char __user *optval, int optlen);
612 extern asmlinkage long sys_getsockopt(int fd, int level, int optname, char __user *optval, int __user *optlen);
613 extern asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags);
614 extern asmlinkage long sys_recvmsg(int fd, struct msghdr __user *msg, unsigned int flags);
615
616
617 if(call<1||call>SYS_RECVMSG)
618 return -EINVAL;
619
620 /* copy_from_user should be SMP safe. */
621 if (copy_from_user(a, args32, socketcall_nargs[call]))
622 return -EFAULT;
623
624 a0=a[0];
625 a1=a[1];
626
627 switch(call)
628 {
629 case SYS_SOCKET:
630 err = sys_socket(a0,a1,a[2]);
631 break;
632 case SYS_BIND:
633 err = sys_bind(a0,(struct sockaddr __user *)A(a1), a[2]);
634 break;
635 case SYS_CONNECT:
636 err = sys_connect(a0, (struct sockaddr __user *)A(a1), a[2]);
637 break;
638 case SYS_LISTEN:
639 err = sys_listen(a0,a1);
640 break;
641 case SYS_ACCEPT:
642 err = sys_accept(a0,(struct sockaddr __user *)A(a1), (int __user *)A(a[2]));
643 break;
644 case SYS_GETSOCKNAME:
645 err = sys_getsockname(a0,(struct sockaddr __user *)A(a1), (int __user *)A(a[2]));
646 break;
647 case SYS_GETPEERNAME:
648 err = sys_getpeername(a0, (struct sockaddr __user *)A(a1), (int __user *)A(a[2]));
649 break;
650 case SYS_SOCKETPAIR:
651 err = sys_socketpair(a0,a1, a[2], (int __user *)A(a[3]));
652 break;
653 case SYS_SEND:
654 err = sys_send(a0, (void __user *)A(a1), a[2], a[3]);
655 break;
656 case SYS_SENDTO:
657 err = sys_sendto(a0,(void __user *)A(a1), a[2], a[3],
658 (struct sockaddr __user *)A(a[4]), a[5]);
659 break;
660 case SYS_RECV:
661 err = sys_recv(a0, (void __user *)A(a1), a[2], a[3]);
662 break;
663 case SYS_RECVFROM:
664 err = sys_recvfrom(a0, (void __user *)A(a1), a[2], a[3],
665 (struct sockaddr __user *)A(a[4]), (int __user *)A(a[5]));
666 break;
667 case SYS_SHUTDOWN:
668 err = sys_shutdown(a0,a1);
669 break;
670 case SYS_SETSOCKOPT:
671 err = sys_setsockopt(a0, a1, a[2], (char __user *)A(a[3]), a[4]);
672 break;
673 case SYS_GETSOCKOPT:
674 err = sys_getsockopt(a0, a1, a[2], (char __user *)A(a[3]), (int __user *)A(a[4]));
675 break;
676 case SYS_SENDMSG:
677 err = sys_sendmsg(a0, (struct msghdr __user *) A(a1), a[2]);
678 break;
679 case SYS_RECVMSG:
680 err = sys_recvmsg(a0, (struct msghdr __user *) A(a1), a[2]);
681 break;
682 default:
683 err = -EINVAL;
684 break;
685 }
686 return err;
687}
688
689struct sigevent32 {
690 u32 sigev_value;
691 u32 sigev_signo;
692 u32 sigev_notify;
693 u32 payload[(64 / 4) - 3];
694};
695
696extern asmlinkage long
697sys_timer_create(clockid_t which_clock,
698 struct sigevent __user *timer_event_spec,
699 timer_t __user * created_timer_id);
700
701long
702sys32_timer_create(u32 clock, struct sigevent32 __user *se32, timer_t __user *timer_id)
703{
704 struct sigevent __user *p = NULL;
705 if (se32) {
706 struct sigevent se;
707 p = compat_alloc_user_space(sizeof(struct sigevent));
708 memset(&se, 0, sizeof(struct sigevent));
709 if (get_user(se.sigev_value.sival_int, &se32->sigev_value) ||
710 __get_user(se.sigev_signo, &se32->sigev_signo) ||
711 __get_user(se.sigev_notify, &se32->sigev_notify) ||
712 __copy_from_user(&se._sigev_un._pad, &se32->payload,
713 sizeof(se32->payload)) ||
714 copy_to_user(p, &se, sizeof(se)))
715 return -EFAULT;
716 }
717 return sys_timer_create(clock, p, timer_id);
718}
719
720save_static_function(sys32_clone); 559save_static_function(sys32_clone);
721__attribute_used__ noinline static int 560__attribute_used__ noinline static int
722_sys32_clone(nabi_no_regargs struct pt_regs regs) 561_sys32_clone(nabi_no_regargs struct pt_regs regs)
@@ -737,49 +576,3 @@ _sys32_clone(nabi_no_regargs struct pt_regs regs)
737 return do_fork(clone_flags, newsp, &regs, 0, 576 return do_fork(clone_flags, newsp, &regs, 0,
738 parent_tidptr, child_tidptr); 577 parent_tidptr, child_tidptr);
739} 578}
740
741/*
742 * Implement the event wait interface for the eventpoll file. It is the kernel
743 * part of the user space epoll_pwait(2).
744 */
745asmlinkage long compat_sys_epoll_pwait(int epfd,
746 struct epoll_event __user *events, int maxevents, int timeout,
747 const compat_sigset_t __user *sigmask, size_t sigsetsize)
748{
749 int error;
750 sigset_t ksigmask, sigsaved;
751
752 /*
753 * If the caller wants a certain signal mask to be set during the wait,
754 * we apply it here.
755 */
756 if (sigmask) {
757 if (sigsetsize != sizeof(sigset_t))
758 return -EINVAL;
759 if (!access_ok(VERIFY_READ, sigmask, sizeof(ksigmask)))
760 return -EFAULT;
761 if (__copy_conv_sigset_from_user(&ksigmask, sigmask))
762 return -EFAULT;
763 sigdelsetmask(&ksigmask, sigmask(SIGKILL) | sigmask(SIGSTOP));
764 sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
765 }
766
767 error = sys_epoll_wait(epfd, events, maxevents, timeout);
768
769 /*
770 * If we changed the signal mask, we need to restore the original one.
771 * In case we've got a signal while waiting, we do not restore the
772 * signal mask yet, and we allow do_signal() to deliver the signal on
773 * the way back to userspace, before the signal mask is restored.
774 */
775 if (sigmask) {
776 if (error == -EINTR) {
777 memcpy(&current->saved_sigmask, &sigsaved,
778 sizeof(sigsaved));
779 set_thread_flag(TIF_RESTORE_SIGMASK);
780 } else
781 sigprocmask(SIG_SETMASK, &sigsaved, NULL);
782 }
783
784 return error;
785}
diff --git a/arch/mips/kernel/machine_kexec.c b/arch/mips/kernel/machine_kexec.c
index e0ad754c7edd..8f42fa85ac9e 100644
--- a/arch/mips/kernel/machine_kexec.c
+++ b/arch/mips/kernel/machine_kexec.c
@@ -13,8 +13,8 @@
13#include <asm/cacheflush.h> 13#include <asm/cacheflush.h>
14#include <asm/page.h> 14#include <asm/page.h>
15 15
16const extern unsigned char relocate_new_kernel[]; 16extern const unsigned char relocate_new_kernel[];
17const extern unsigned int relocate_new_kernel_size; 17extern const unsigned int relocate_new_kernel_size;
18 18
19extern unsigned long kexec_start_address; 19extern unsigned long kexec_start_address;
20extern unsigned long kexec_indirection_page; 20extern unsigned long kexec_indirection_page;
diff --git a/arch/mips/kernel/mips_ksyms.c b/arch/mips/kernel/mips_ksyms.c
index 2ef857c3ee53..225755d0c1f6 100644
--- a/arch/mips/kernel/mips_ksyms.c
+++ b/arch/mips/kernel/mips_ksyms.c
@@ -37,6 +37,7 @@ EXPORT_SYMBOL(kernel_thread);
37 * Userspace access stuff. 37 * Userspace access stuff.
38 */ 38 */
39EXPORT_SYMBOL(__copy_user); 39EXPORT_SYMBOL(__copy_user);
40EXPORT_SYMBOL(__copy_user_inatomic);
40EXPORT_SYMBOL(__bzero); 41EXPORT_SYMBOL(__bzero);
41EXPORT_SYMBOL(__strncpy_from_user_nocheck_asm); 42EXPORT_SYMBOL(__strncpy_from_user_nocheck_asm);
42EXPORT_SYMBOL(__strncpy_from_user_asm); 43EXPORT_SYMBOL(__strncpy_from_user_asm);
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 04e5b38d327d..6bdfb5a9fa1a 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -26,7 +26,6 @@
26#include <linux/completion.h> 26#include <linux/completion.h>
27#include <linux/kallsyms.h> 27#include <linux/kallsyms.h>
28 28
29#include <asm/abi.h>
30#include <asm/bootinfo.h> 29#include <asm/bootinfo.h>
31#include <asm/cpu.h> 30#include <asm/cpu.h>
32#include <asm/dsp.h> 31#include <asm/dsp.h>
@@ -52,11 +51,11 @@ ATTRIB_NORET void cpu_idle(void)
52 /* endless idle loop with no priority at all */ 51 /* endless idle loop with no priority at all */
53 while (1) { 52 while (1) {
54 while (!need_resched()) { 53 while (!need_resched()) {
55#ifdef CONFIG_MIPS_MT_SMTC 54#ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG
56 extern void smtc_idle_loop_hook(void); 55 extern void smtc_idle_loop_hook(void);
57 56
58 smtc_idle_loop_hook(); 57 smtc_idle_loop_hook();
59#endif /* CONFIG_MIPS_MT_SMTC */ 58#endif
60 if (cpu_wait) 59 if (cpu_wait)
61 (*cpu_wait)(); 60 (*cpu_wait)();
62 } 61 }
@@ -66,38 +65,6 @@ ATTRIB_NORET void cpu_idle(void)
66 } 65 }
67} 66}
68 67
69/*
70 * Native o32 and N64 ABI without DSP ASE
71 */
72struct mips_abi mips_abi = {
73 .do_signal = do_signal,
74#ifdef CONFIG_TRAD_SIGNALS
75 .setup_frame = setup_frame,
76#endif
77 .setup_rt_frame = setup_rt_frame
78};
79
80#ifdef CONFIG_MIPS32_O32
81/*
82 * o32 compatibility on 64-bit kernels, without DSP ASE
83 */
84struct mips_abi mips_abi_32 = {
85 .do_signal = do_signal32,
86 .setup_frame = setup_frame_32,
87 .setup_rt_frame = setup_rt_frame_32
88};
89#endif /* CONFIG_MIPS32_O32 */
90
91#ifdef CONFIG_MIPS32_N32
92/*
93 * N32 on 64-bit kernels, without DSP ASE
94 */
95struct mips_abi mips_abi_n32 = {
96 .do_signal = do_signal,
97 .setup_rt_frame = setup_rt_frame_n32
98};
99#endif /* CONFIG_MIPS32_N32 */
100
101asmlinkage void ret_from_fork(void); 68asmlinkage void ret_from_fork(void);
102 69
103void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) 70void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
@@ -246,7 +213,7 @@ int dump_task_fpu (struct task_struct *t, elf_fpregset_t *fpr)
246/* 213/*
247 * Create a kernel thread 214 * Create a kernel thread
248 */ 215 */
249ATTRIB_NORET void kernel_thread_helper(void *arg, int (*fn)(void *)) 216static ATTRIB_NORET void kernel_thread_helper(void *arg, int (*fn)(void *))
250{ 217{
251 do_exit(fn(arg)); 218 do_exit(fn(arg));
252} 219}
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index 258d74fd0b63..201ae194d1b8 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -236,6 +236,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
236 case MMLO: 236 case MMLO:
237 tmp = regs->lo; 237 tmp = regs->lo;
238 break; 238 break;
239#ifdef CONFIG_CPU_HAS_SMARTMIPS
240 case ACX:
241 tmp = regs->acx;
242 break;
243#endif
239 case FPC_CSR: 244 case FPC_CSR:
240 tmp = child->thread.fpu.fcr31; 245 tmp = child->thread.fpu.fcr31;
241 break; 246 break;
@@ -362,6 +367,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
362 case MMLO: 367 case MMLO:
363 regs->lo = data; 368 regs->lo = data;
364 break; 369 break;
370#ifdef CONFIG_CPU_HAS_SMARTMIPS
371 case ACX:
372 regs->acx = data;
373 break;
374#endif
365 case FPC_CSR: 375 case FPC_CSR:
366 child->thread.fpu.fcr31 = data; 376 child->thread.fpu.fcr31 = data;
367 break; 377 break;
diff --git a/arch/mips/kernel/r4k_fpu.S b/arch/mips/kernel/r4k_fpu.S
index 59c1577ecbb3..dbd42adc52ed 100644
--- a/arch/mips/kernel/r4k_fpu.S
+++ b/arch/mips/kernel/r4k_fpu.S
@@ -114,14 +114,6 @@ LEAF(_save_fp_context32)
114 */ 114 */
115LEAF(_restore_fp_context) 115LEAF(_restore_fp_context)
116 EX lw t0, SC_FPC_CSR(a0) 116 EX lw t0, SC_FPC_CSR(a0)
117
118 /* Fail if the CSR has exceptions pending */
119 srl t1, t0, 5
120 and t1, t0
121 andi t1, 0x1f << 7
122 bnez t1, fault
123 nop
124
125#ifdef CONFIG_64BIT 117#ifdef CONFIG_64BIT
126 EX ldc1 $f1, SC_FPREGS+8(a0) 118 EX ldc1 $f1, SC_FPREGS+8(a0)
127 EX ldc1 $f3, SC_FPREGS+24(a0) 119 EX ldc1 $f3, SC_FPREGS+24(a0)
@@ -165,14 +157,6 @@ LEAF(_restore_fp_context)
165LEAF(_restore_fp_context32) 157LEAF(_restore_fp_context32)
166 /* Restore an o32 sigcontext. */ 158 /* Restore an o32 sigcontext. */
167 EX lw t0, SC32_FPC_CSR(a0) 159 EX lw t0, SC32_FPC_CSR(a0)
168
169 /* Fail if the CSR has exceptions pending */
170 srl t1, t0, 5
171 and t1, t0
172 andi t1, 0x1f << 7
173 bnez t1, fault
174 nop
175
176 EX ldc1 $f0, SC32_FPREGS+0(a0) 160 EX ldc1 $f0, SC32_FPREGS+0(a0)
177 EX ldc1 $f2, SC32_FPREGS+16(a0) 161 EX ldc1 $f2, SC32_FPREGS+16(a0)
178 EX ldc1 $f4, SC32_FPREGS+32(a0) 162 EX ldc1 $f4, SC32_FPREGS+32(a0)
diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c
index d92c48e0d7a6..bfc8ca168f83 100644
--- a/arch/mips/kernel/rtlx.c
+++ b/arch/mips/kernel/rtlx.c
@@ -53,7 +53,8 @@ static char module_name[] = "rtlx";
53static struct chan_waitqueues { 53static struct chan_waitqueues {
54 wait_queue_head_t rt_queue; 54 wait_queue_head_t rt_queue;
55 wait_queue_head_t lx_queue; 55 wait_queue_head_t lx_queue;
56 int in_open; 56 atomic_t in_open;
57 struct mutex mutex;
57} channel_wqs[RTLX_CHANNELS]; 58} channel_wqs[RTLX_CHANNELS];
58 59
59static struct irqaction irq; 60static struct irqaction irq;
@@ -146,110 +147,91 @@ static void stopping(int vpe)
146 147
147int rtlx_open(int index, int can_sleep) 148int rtlx_open(int index, int can_sleep)
148{ 149{
149 int ret; 150 struct rtlx_info **p;
150 struct rtlx_channel *chan; 151 struct rtlx_channel *chan;
151 volatile struct rtlx_info **p; 152 enum rtlx_state state;
153 int ret = 0;
152 154
153 if (index >= RTLX_CHANNELS) { 155 if (index >= RTLX_CHANNELS) {
154 printk(KERN_DEBUG "rtlx_open index out of range\n"); 156 printk(KERN_DEBUG "rtlx_open index out of range\n");
155 return -ENOSYS; 157 return -ENOSYS;
156 } 158 }
157 159
158 if (channel_wqs[index].in_open) { 160 if (atomic_inc_return(&channel_wqs[index].in_open) > 1) {
159 printk(KERN_DEBUG "rtlx_open channel %d already opened\n", index); 161 printk(KERN_DEBUG "rtlx_open channel %d already opened\n",
160 return -EBUSY; 162 index);
163 ret = -EBUSY;
164 goto out_fail;
161 } 165 }
162 166
163 channel_wqs[index].in_open++;
164
165 if (rtlx == NULL) { 167 if (rtlx == NULL) {
166 if( (p = vpe_get_shared(RTLX_TARG_VPE)) == NULL) { 168 if( (p = vpe_get_shared(RTLX_TARG_VPE)) == NULL) {
167 if (can_sleep) { 169 if (can_sleep) {
168 DECLARE_WAITQUEUE(wait, current); 170 __wait_event_interruptible(channel_wqs[index].lx_queue,
169 171 (p = vpe_get_shared(RTLX_TARG_VPE)),
170 /* go to sleep */ 172 ret);
171 add_wait_queue(&channel_wqs[index].lx_queue, &wait); 173 if (ret)
172 174 goto out_fail;
173 set_current_state(TASK_INTERRUPTIBLE);
174 while ((p = vpe_get_shared(RTLX_TARG_VPE)) == NULL) {
175 schedule();
176 set_current_state(TASK_INTERRUPTIBLE);
177 }
178
179 set_current_state(TASK_RUNNING);
180 remove_wait_queue(&channel_wqs[index].lx_queue, &wait);
181
182 /* back running */
183 } else { 175 } else {
184 printk( KERN_DEBUG "No SP program loaded, and device " 176 printk(KERN_DEBUG "No SP program loaded, and device "
185 "opened with O_NONBLOCK\n"); 177 "opened with O_NONBLOCK\n");
186 channel_wqs[index].in_open = 0; 178 ret = -ENOSYS;
187 return -ENOSYS; 179 goto out_fail;
188 } 180 }
189 } 181 }
190 182
183 smp_rmb();
191 if (*p == NULL) { 184 if (*p == NULL) {
192 if (can_sleep) { 185 if (can_sleep) {
193 DECLARE_WAITQUEUE(wait, current); 186 DEFINE_WAIT(wait);
194 187
195 /* go to sleep */ 188 for (;;) {
196 add_wait_queue(&channel_wqs[index].lx_queue, &wait); 189 prepare_to_wait(&channel_wqs[index].lx_queue, &wait, TASK_INTERRUPTIBLE);
197 190 smp_rmb();
198 set_current_state(TASK_INTERRUPTIBLE); 191 if (*p != NULL)
199 while (*p == NULL) { 192 break;
200 schedule(); 193 if (!signal_pending(current)) {
201 194 schedule();
202 /* reset task state to interruptable otherwise 195 continue;
203 we'll whizz round here like a very fast loopy 196 }
204 thing. schedule() appears to return with state 197 ret = -ERESTARTSYS;
205 set to TASK_RUNNING. 198 goto out_fail;
206
207 If the loaded SP program, for whatever reason,
208 doesn't set up the shared structure *p will never
209 become true. So whoever connected to either /dev/rt?
210 or if it was kspd, will then take up rather a lot of
211 processor cycles.
212 */
213
214 set_current_state(TASK_INTERRUPTIBLE);
215 } 199 }
216 200 finish_wait(&channel_wqs[index].lx_queue, &wait);
217 set_current_state(TASK_RUNNING); 201 } else {
218 remove_wait_queue(&channel_wqs[index].lx_queue, &wait);
219
220 /* back running */
221 }
222 else {
223 printk(" *vpe_get_shared is NULL. " 202 printk(" *vpe_get_shared is NULL. "
224 "Has an SP program been loaded?\n"); 203 "Has an SP program been loaded?\n");
225 channel_wqs[index].in_open = 0; 204 ret = -ENOSYS;
226 return -ENOSYS; 205 goto out_fail;
227 } 206 }
228 } 207 }
229 208
230 if ((unsigned int)*p < KSEG0) { 209 if ((unsigned int)*p < KSEG0) {
231 printk(KERN_WARNING "vpe_get_shared returned an invalid pointer " 210 printk(KERN_WARNING "vpe_get_shared returned an invalid pointer "
232 "maybe an error code %d\n", (int)*p); 211 "maybe an error code %d\n", (int)*p);
233 channel_wqs[index].in_open = 0; 212 ret = -ENOSYS;
234 return -ENOSYS; 213 goto out_fail;
235 } 214 }
236 215
237 if ((ret = rtlx_init(*p)) < 0) { 216 if ((ret = rtlx_init(*p)) < 0)
238 channel_wqs[index].in_open = 0; 217 goto out_ret;
239 return ret;
240 }
241 } 218 }
242 219
243 chan = &rtlx->channel[index]; 220 chan = &rtlx->channel[index];
244 221
245 if (chan->lx_state == RTLX_STATE_OPENED) { 222 state = xchg(&chan->lx_state, RTLX_STATE_OPENED);
246 channel_wqs[index].in_open = 0; 223 if (state == RTLX_STATE_OPENED) {
247 return -EBUSY; 224 ret = -EBUSY;
248 } 225 goto out_fail;
226 }
249 227
250 chan->lx_state = RTLX_STATE_OPENED; 228out_fail:
251 channel_wqs[index].in_open = 0; 229 smp_mb();
252 return 0; 230 atomic_dec(&channel_wqs[index].in_open);
231 smp_mb();
232
233out_ret:
234 return ret;
253} 235}
254 236
255int rtlx_release(int index) 237int rtlx_release(int index)
@@ -270,30 +252,17 @@ unsigned int rtlx_read_poll(int index, int can_sleep)
270 /* data available to read? */ 252 /* data available to read? */
271 if (chan->lx_read == chan->lx_write) { 253 if (chan->lx_read == chan->lx_write) {
272 if (can_sleep) { 254 if (can_sleep) {
273 DECLARE_WAITQUEUE(wait, current); 255 int ret = 0;
274
275 /* go to sleep */
276 add_wait_queue(&channel_wqs[index].lx_queue, &wait);
277
278 set_current_state(TASK_INTERRUPTIBLE);
279 while (chan->lx_read == chan->lx_write) {
280 schedule();
281 256
282 set_current_state(TASK_INTERRUPTIBLE); 257 __wait_event_interruptible(channel_wqs[index].lx_queue,
258 chan->lx_read != chan->lx_write || sp_stopping,
259 ret);
260 if (ret)
261 return ret;
283 262
284 if (sp_stopping) { 263 if (sp_stopping)
285 set_current_state(TASK_RUNNING); 264 return 0;
286 remove_wait_queue(&channel_wqs[index].lx_queue, &wait); 265 } else
287 return 0;
288 }
289 }
290
291 set_current_state(TASK_RUNNING);
292 remove_wait_queue(&channel_wqs[index].lx_queue, &wait);
293
294 /* back running */
295 }
296 else
297 return 0; 266 return 0;
298 } 267 }
299 268
@@ -320,56 +289,53 @@ unsigned int rtlx_write_poll(int index)
320 return write_spacefree(chan->rt_read, chan->rt_write, chan->buffer_size); 289 return write_spacefree(chan->rt_read, chan->rt_write, chan->buffer_size);
321} 290}
322 291
323static inline void copy_to(void *dst, void *src, size_t count, int user) 292ssize_t rtlx_read(int index, void __user *buff, size_t count)
324{ 293{
325 if (user) 294 size_t lx_write, fl = 0L;
326 copy_to_user(dst, src, count);
327 else
328 memcpy(dst, src, count);
329}
330
331static inline void copy_from(void *dst, void *src, size_t count, int user)
332{
333 if (user)
334 copy_from_user(dst, src, count);
335 else
336 memcpy(dst, src, count);
337}
338
339ssize_t rtlx_read(int index, void *buff, size_t count, int user)
340{
341 size_t fl = 0L;
342 struct rtlx_channel *lx; 295 struct rtlx_channel *lx;
296 unsigned long failed;
343 297
344 if (rtlx == NULL) 298 if (rtlx == NULL)
345 return -ENOSYS; 299 return -ENOSYS;
346 300
347 lx = &rtlx->channel[index]; 301 lx = &rtlx->channel[index];
348 302
303 mutex_lock(&channel_wqs[index].mutex);
304 smp_rmb();
305 lx_write = lx->lx_write;
306
349 /* find out how much in total */ 307 /* find out how much in total */
350 count = min(count, 308 count = min(count,
351 (size_t)(lx->lx_write + lx->buffer_size - lx->lx_read) 309 (size_t)(lx_write + lx->buffer_size - lx->lx_read)
352 % lx->buffer_size); 310 % lx->buffer_size);
353 311
354 /* then how much from the read pointer onwards */ 312 /* then how much from the read pointer onwards */
355 fl = min( count, (size_t)lx->buffer_size - lx->lx_read); 313 fl = min(count, (size_t)lx->buffer_size - lx->lx_read);
356 314
357 copy_to(buff, &lx->lx_buffer[lx->lx_read], fl, user); 315 failed = copy_to_user(buff, lx->lx_buffer + lx->lx_read, fl);
316 if (failed)
317 goto out;
358 318
359 /* and if there is anything left at the beginning of the buffer */ 319 /* and if there is anything left at the beginning of the buffer */
360 if ( count - fl ) 320 if (count - fl)
361 copy_to (buff + fl, lx->lx_buffer, count - fl, user); 321 failed = copy_to_user(buff + fl, lx->lx_buffer, count - fl);
322
323out:
324 count -= failed;
362 325
363 /* update the index */ 326 smp_wmb();
364 lx->lx_read += count; 327 lx->lx_read = (lx->lx_read + count) % lx->buffer_size;
365 lx->lx_read %= lx->buffer_size; 328 smp_wmb();
329 mutex_unlock(&channel_wqs[index].mutex);
366 330
367 return count; 331 return count;
368} 332}
369 333
370ssize_t rtlx_write(int index, void *buffer, size_t count, int user) 334ssize_t rtlx_write(int index, const void __user *buffer, size_t count)
371{ 335{
372 struct rtlx_channel *rt; 336 struct rtlx_channel *rt;
337 unsigned long failed;
338 size_t rt_read;
373 size_t fl; 339 size_t fl;
374 340
375 if (rtlx == NULL) 341 if (rtlx == NULL)
@@ -377,24 +343,35 @@ ssize_t rtlx_write(int index, void *buffer, size_t count, int user)
377 343
378 rt = &rtlx->channel[index]; 344 rt = &rtlx->channel[index];
379 345
346 mutex_lock(&channel_wqs[index].mutex);
347 smp_rmb();
348 rt_read = rt->rt_read;
349
380 /* total number of bytes to copy */ 350 /* total number of bytes to copy */
381 count = min(count, 351 count = min(count,
382 (size_t)write_spacefree(rt->rt_read, rt->rt_write, 352 (size_t)write_spacefree(rt_read, rt->rt_write, rt->buffer_size));
383 rt->buffer_size));
384 353
385 /* first bit from write pointer to the end of the buffer, or count */ 354 /* first bit from write pointer to the end of the buffer, or count */
386 fl = min(count, (size_t) rt->buffer_size - rt->rt_write); 355 fl = min(count, (size_t) rt->buffer_size - rt->rt_write);
387 356
388 copy_from (&rt->rt_buffer[rt->rt_write], buffer, fl, user); 357 failed = copy_from_user(rt->rt_buffer + rt->rt_write, buffer, fl);
358 if (failed)
359 goto out;
389 360
390 /* if there's any left copy to the beginning of the buffer */ 361 /* if there's any left copy to the beginning of the buffer */
391 if( count - fl ) 362 if (count - fl) {
392 copy_from (rt->rt_buffer, buffer + fl, count - fl, user); 363 failed = copy_from_user(rt->rt_buffer, buffer + fl, count - fl);
364 }
393 365
394 rt->rt_write += count; 366out:
395 rt->rt_write %= rt->buffer_size; 367 count -= failed;
396 368
397 return(count); 369 smp_wmb();
370 rt->rt_write = (rt->rt_write + count) % rt->buffer_size;
371 smp_wmb();
372 mutex_unlock(&channel_wqs[index].mutex);
373
374 return count;
398} 375}
399 376
400 377
@@ -446,7 +423,7 @@ static ssize_t file_read(struct file *file, char __user * buffer, size_t count,
446 return 0; // -EAGAIN makes cat whinge 423 return 0; // -EAGAIN makes cat whinge
447 } 424 }
448 425
449 return rtlx_read(minor, buffer, count, 1); 426 return rtlx_read(minor, buffer, count);
450} 427}
451 428
452static ssize_t file_write(struct file *file, const char __user * buffer, 429static ssize_t file_write(struct file *file, const char __user * buffer,
@@ -454,28 +431,25 @@ static ssize_t file_write(struct file *file, const char __user * buffer,
454{ 431{
455 int minor; 432 int minor;
456 struct rtlx_channel *rt; 433 struct rtlx_channel *rt;
457 DECLARE_WAITQUEUE(wait, current);
458 434
459 minor = iminor(file->f_path.dentry->d_inode); 435 minor = iminor(file->f_path.dentry->d_inode);
460 rt = &rtlx->channel[minor]; 436 rt = &rtlx->channel[minor];
461 437
462 /* any space left... */ 438 /* any space left... */
463 if (!rtlx_write_poll(minor)) { 439 if (!rtlx_write_poll(minor)) {
440 int ret = 0;
464 441
465 if (file->f_flags & O_NONBLOCK) 442 if (file->f_flags & O_NONBLOCK)
466 return -EAGAIN; 443 return -EAGAIN;
467 444
468 add_wait_queue(&channel_wqs[minor].rt_queue, &wait); 445 __wait_event_interruptible(channel_wqs[minor].rt_queue,
469 set_current_state(TASK_INTERRUPTIBLE); 446 rtlx_write_poll(minor),
470 447 ret);
471 while (!rtlx_write_poll(minor)) 448 if (ret)
472 schedule(); 449 return ret;
473
474 set_current_state(TASK_RUNNING);
475 remove_wait_queue(&channel_wqs[minor].rt_queue, &wait);
476 } 450 }
477 451
478 return rtlx_write(minor, (void *)buffer, count, 1); 452 return rtlx_write(minor, buffer, count);
479} 453}
480 454
481static const struct file_operations rtlx_fops = { 455static const struct file_operations rtlx_fops = {
@@ -513,7 +487,8 @@ static int rtlx_module_init(void)
513 for (i = 0; i < RTLX_CHANNELS; i++) { 487 for (i = 0; i < RTLX_CHANNELS; i++) {
514 init_waitqueue_head(&channel_wqs[i].rt_queue); 488 init_waitqueue_head(&channel_wqs[i].rt_queue);
515 init_waitqueue_head(&channel_wqs[i].lx_queue); 489 init_waitqueue_head(&channel_wqs[i].lx_queue);
516 channel_wqs[i].in_open = 0; 490 atomic_set(&channel_wqs[i].in_open, 0);
491 mutex_init(&channel_wqs[i].mutex);
517 492
518 dev = device_create(mt_class, NULL, MKDEV(major, i), 493 dev = device_create(mt_class, NULL, MKDEV(major, i),
519 "%s%d", module_name, i); 494 "%s%d", module_name, i);
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S
index 7c0b3936ba44..0c9a9ff8cd25 100644
--- a/arch/mips/kernel/scall32-o32.S
+++ b/arch/mips/kernel/scall32-o32.S
@@ -656,6 +656,8 @@ einval: li v0, -EINVAL
656 sys sys_kexec_load 4 656 sys sys_kexec_load 4
657 sys sys_getcpu 3 657 sys sys_getcpu 3
658 sys sys_epoll_pwait 6 658 sys sys_epoll_pwait 6
659 sys sys_ioprio_set 3
660 sys sys_ioprio_get 2
659 .endm 661 .endm
660 662
661 /* We pre-compute the number of _instruction_ bytes needed to 663 /* We pre-compute the number of _instruction_ bytes needed to
diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S
index 10e9a18630aa..23f3b118f718 100644
--- a/arch/mips/kernel/scall64-64.S
+++ b/arch/mips/kernel/scall64-64.S
@@ -470,4 +470,7 @@ sys_call_table:
470 PTR sys_get_robust_list 470 PTR sys_get_robust_list
471 PTR sys_kexec_load /* 5270 */ 471 PTR sys_kexec_load /* 5270 */
472 PTR sys_getcpu 472 PTR sys_getcpu
473 PTR compat_sys_epoll_pwait 473 PTR sys_epoll_pwait
474 PTR sys_ioprio_set
475 PTR sys_ioprio_get
476 .size sys_call_table,.-sys_call_table
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index 2ceda4644a4d..6eac28337423 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -340,7 +340,7 @@ EXPORT(sysn32_call_table)
340 PTR compat_sys_statfs64 340 PTR compat_sys_statfs64
341 PTR compat_sys_fstatfs64 341 PTR compat_sys_fstatfs64
342 PTR sys_sendfile64 342 PTR sys_sendfile64
343 PTR sys32_timer_create /* 6220 */ 343 PTR compat_sys_timer_create /* 6220 */
344 PTR compat_sys_timer_settime 344 PTR compat_sys_timer_settime
345 PTR compat_sys_timer_gettime 345 PTR compat_sys_timer_gettime
346 PTR sys_timer_getoverrun 346 PTR sys_timer_getoverrun
@@ -361,7 +361,7 @@ EXPORT(sysn32_call_table)
361 PTR compat_sys_mq_notify 361 PTR compat_sys_mq_notify
362 PTR compat_sys_mq_getsetattr 362 PTR compat_sys_mq_getsetattr
363 PTR sys_ni_syscall /* 6240, sys_vserver */ 363 PTR sys_ni_syscall /* 6240, sys_vserver */
364 PTR sysn32_waitid 364 PTR compat_sys_waitid
365 PTR sys_ni_syscall /* available, was setaltroot */ 365 PTR sys_ni_syscall /* available, was setaltroot */
366 PTR sys_add_key 366 PTR sys_add_key
367 PTR sys_request_key 367 PTR sys_request_key
@@ -395,5 +395,8 @@ EXPORT(sysn32_call_table)
395 PTR compat_sys_set_robust_list 395 PTR compat_sys_set_robust_list
396 PTR compat_sys_get_robust_list 396 PTR compat_sys_get_robust_list
397 PTR compat_sys_kexec_load 397 PTR compat_sys_kexec_load
398 PTR sys_getcpu 398 PTR sys_getcpu /* 6275 */
399 PTR compat_sys_epoll_pwait 399 PTR compat_sys_epoll_pwait
400 PTR sys_ioprio_set
401 PTR sys_ioprio_get
402 .size sysn32_call_table,.-sysn32_call_table
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
index c5f590ca99b0..7e74b412a782 100644
--- a/arch/mips/kernel/scall64-o32.S
+++ b/arch/mips/kernel/scall64-o32.S
@@ -307,7 +307,7 @@ sys_call_table:
307 PTR compat_sys_statfs 307 PTR compat_sys_statfs
308 PTR compat_sys_fstatfs /* 4100 */ 308 PTR compat_sys_fstatfs /* 4100 */
309 PTR sys_ni_syscall /* sys_ioperm */ 309 PTR sys_ni_syscall /* sys_ioperm */
310 PTR sys32_socketcall 310 PTR compat_sys_socketcall
311 PTR sys_syslog 311 PTR sys_syslog
312 PTR compat_sys_setitimer 312 PTR compat_sys_setitimer
313 PTR compat_sys_getitimer /* 4105 */ 313 PTR compat_sys_getitimer /* 4105 */
@@ -462,7 +462,7 @@ sys_call_table:
462 PTR sys_fadvise64_64 462 PTR sys_fadvise64_64
463 PTR compat_sys_statfs64 /* 4255 */ 463 PTR compat_sys_statfs64 /* 4255 */
464 PTR compat_sys_fstatfs64 464 PTR compat_sys_fstatfs64
465 PTR sys32_timer_create 465 PTR compat_sys_timer_create
466 PTR compat_sys_timer_settime 466 PTR compat_sys_timer_settime
467 PTR compat_sys_timer_gettime 467 PTR compat_sys_timer_gettime
468 PTR sys_timer_getoverrun /* 4260 */ 468 PTR sys_timer_getoverrun /* 4260 */
@@ -518,5 +518,7 @@ sys_call_table:
518 PTR compat_sys_get_robust_list /* 4310 */ 518 PTR compat_sys_get_robust_list /* 4310 */
519 PTR compat_sys_kexec_load 519 PTR compat_sys_kexec_load
520 PTR sys_getcpu 520 PTR sys_getcpu
521 PTR sys_epoll_pwait 521 PTR compat_sys_epoll_pwait
522 PTR sys_ioprio_set
523 PTR sys_ioprio_get /* 4315 */
522 .size sys_call_table,.-sys_call_table 524 .size sys_call_table,.-sys_call_table
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 394540fad769..4975da0bfb63 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -525,6 +525,14 @@ void __init setup_arch(char **cmdline_p)
525{ 525{
526 cpu_probe(); 526 cpu_probe();
527 prom_init(); 527 prom_init();
528
529#ifdef CONFIG_EARLY_PRINTK
530 {
531 extern void setup_early_printk(void);
532
533 setup_early_printk();
534 }
535#endif
528 cpu_report(); 536 cpu_report();
529 537
530#if defined(CONFIG_VT) 538#if defined(CONFIG_VT)
@@ -543,7 +551,7 @@ void __init setup_arch(char **cmdline_p)
543#endif 551#endif
544} 552}
545 553
546int __init fpu_disable(char *s) 554static int __init fpu_disable(char *s)
547{ 555{
548 int i; 556 int i;
549 557
@@ -555,7 +563,7 @@ int __init fpu_disable(char *s)
555 563
556__setup("nofpu", fpu_disable); 564__setup("nofpu", fpu_disable);
557 565
558int __init dsp_disable(char *s) 566static int __init dsp_disable(char *s)
559{ 567{
560 cpu_data[0].ases &= ~MIPS_ASE_DSP; 568 cpu_data[0].ases &= ~MIPS_ASE_DSP;
561 569
diff --git a/arch/mips/kernel/signal-common.h b/arch/mips/kernel/signal-common.h
index fdbdbdc65b54..c0faabd52010 100644
--- a/arch/mips/kernel/signal-common.h
+++ b/arch/mips/kernel/signal-common.h
@@ -31,4 +31,16 @@ extern void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
31 */ 31 */
32extern int install_sigtramp(unsigned int __user *tramp, unsigned int syscall); 32extern int install_sigtramp(unsigned int __user *tramp, unsigned int syscall);
33 33
34/* Check and clear pending FPU exceptions in saved CSR */
35extern int fpcsr_pending(unsigned int __user *fpcsr);
36
37/* Make sure we will not lose FPU ownership */
38#ifdef CONFIG_PREEMPT
39#define lock_fpu_owner() preempt_disable()
40#define unlock_fpu_owner() preempt_enable()
41#else
42#define lock_fpu_owner() pagefault_disable()
43#define unlock_fpu_owner() pagefault_enable()
44#endif
45
34#endif /* __SIGNAL_COMMON_H */ 46#endif /* __SIGNAL_COMMON_H */
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index b2e9ab1bb101..07d67309451a 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -20,6 +20,7 @@
20#include <linux/ptrace.h> 20#include <linux/ptrace.h>
21#include <linux/unistd.h> 21#include <linux/unistd.h>
22#include <linux/compiler.h> 22#include <linux/compiler.h>
23#include <linux/uaccess.h>
23 24
24#include <asm/abi.h> 25#include <asm/abi.h>
25#include <asm/asm.h> 26#include <asm/asm.h>
@@ -27,7 +28,6 @@
27#include <asm/cacheflush.h> 28#include <asm/cacheflush.h>
28#include <asm/fpu.h> 29#include <asm/fpu.h>
29#include <asm/sim.h> 30#include <asm/sim.h>
30#include <asm/uaccess.h>
31#include <asm/ucontext.h> 31#include <asm/ucontext.h>
32#include <asm/cpu-features.h> 32#include <asm/cpu-features.h>
33#include <asm/war.h> 33#include <asm/war.h>
@@ -78,10 +78,51 @@ struct rt_sigframe {
78/* 78/*
79 * Helper routines 79 * Helper routines
80 */ 80 */
81static int protected_save_fp_context(struct sigcontext __user *sc)
82{
83 int err;
84 while (1) {
85 lock_fpu_owner();
86 own_fpu_inatomic(1);
87 err = save_fp_context(sc); /* this might fail */
88 unlock_fpu_owner();
89 if (likely(!err))
90 break;
91 /* touch the sigcontext and try again */
92 err = __put_user(0, &sc->sc_fpregs[0]) |
93 __put_user(0, &sc->sc_fpregs[31]) |
94 __put_user(0, &sc->sc_fpc_csr);
95 if (err)
96 break; /* really bad sigcontext */
97 }
98 return err;
99}
100
101static int protected_restore_fp_context(struct sigcontext __user *sc)
102{
103 int err, tmp;
104 while (1) {
105 lock_fpu_owner();
106 own_fpu_inatomic(0);
107 err = restore_fp_context(sc); /* this might fail */
108 unlock_fpu_owner();
109 if (likely(!err))
110 break;
111 /* touch the sigcontext and try again */
112 err = __get_user(tmp, &sc->sc_fpregs[0]) |
113 __get_user(tmp, &sc->sc_fpregs[31]) |
114 __get_user(tmp, &sc->sc_fpc_csr);
115 if (err)
116 break; /* really bad sigcontext */
117 }
118 return err;
119}
120
81int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) 121int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
82{ 122{
83 int err = 0; 123 int err = 0;
84 int i; 124 int i;
125 unsigned int used_math;
85 126
86 err |= __put_user(regs->cp0_epc, &sc->sc_pc); 127 err |= __put_user(regs->cp0_epc, &sc->sc_pc);
87 128
@@ -89,6 +130,9 @@ int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
89 for (i = 1; i < 32; i++) 130 for (i = 1; i < 32; i++)
90 err |= __put_user(regs->regs[i], &sc->sc_regs[i]); 131 err |= __put_user(regs->regs[i], &sc->sc_regs[i]);
91 132
133#ifdef CONFIG_CPU_HAS_SMARTMIPS
134 err |= __put_user(regs->acx, &sc->sc_acx);
135#endif
92 err |= __put_user(regs->hi, &sc->sc_mdhi); 136 err |= __put_user(regs->hi, &sc->sc_mdhi);
93 err |= __put_user(regs->lo, &sc->sc_mdlo); 137 err |= __put_user(regs->lo, &sc->sc_mdlo);
94 if (cpu_has_dsp) { 138 if (cpu_has_dsp) {
@@ -101,24 +145,48 @@ int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
101 err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp); 145 err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
102 } 146 }
103 147
104 err |= __put_user(!!used_math(), &sc->sc_used_math); 148 used_math = !!used_math();
149 err |= __put_user(used_math, &sc->sc_used_math);
105 150
106 if (used_math()) { 151 if (used_math) {
107 /* 152 /*
108 * Save FPU state to signal context. Signal handler 153 * Save FPU state to signal context. Signal handler
109 * will "inherit" current FPU state. 154 * will "inherit" current FPU state.
110 */ 155 */
111 preempt_disable(); 156 err |= protected_save_fp_context(sc);
157 }
158 return err;
159}
112 160
113 if (!is_fpu_owner()) { 161int fpcsr_pending(unsigned int __user *fpcsr)
114 own_fpu(); 162{
115 restore_fp(current); 163 int err, sig = 0;
116 } 164 unsigned int csr, enabled;
117 err |= save_fp_context(sc);
118 165
119 preempt_enable(); 166 err = __get_user(csr, fpcsr);
167 enabled = FPU_CSR_UNI_X | ((csr & FPU_CSR_ALL_E) << 5);
168 /*
169 * If the signal handler set some FPU exceptions, clear it and
170 * send SIGFPE.
171 */
172 if (csr & enabled) {
173 csr &= ~enabled;
174 err |= __put_user(csr, fpcsr);
175 sig = SIGFPE;
120 } 176 }
121 return err; 177 return err ?: sig;
178}
179
180static int
181check_and_restore_fp_context(struct sigcontext __user *sc)
182{
183 int err, sig;
184
185 err = sig = fpcsr_pending(&sc->sc_fpc_csr);
186 if (err > 0)
187 err = 0;
188 err |= protected_restore_fp_context(sc);
189 return err ?: sig;
122} 190}
123 191
124int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) 192int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
@@ -132,6 +200,10 @@ int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
132 current_thread_info()->restart_block.fn = do_no_restart_syscall; 200 current_thread_info()->restart_block.fn = do_no_restart_syscall;
133 201
134 err |= __get_user(regs->cp0_epc, &sc->sc_pc); 202 err |= __get_user(regs->cp0_epc, &sc->sc_pc);
203
204#ifdef CONFIG_CPU_HAS_SMARTMIPS
205 err |= __get_user(regs->acx, &sc->sc_acx);
206#endif
135 err |= __get_user(regs->hi, &sc->sc_mdhi); 207 err |= __get_user(regs->hi, &sc->sc_mdhi);
136 err |= __get_user(regs->lo, &sc->sc_mdlo); 208 err |= __get_user(regs->lo, &sc->sc_mdlo);
137 if (cpu_has_dsp) { 209 if (cpu_has_dsp) {
@@ -150,19 +222,15 @@ int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
150 err |= __get_user(used_math, &sc->sc_used_math); 222 err |= __get_user(used_math, &sc->sc_used_math);
151 conditional_used_math(used_math); 223 conditional_used_math(used_math);
152 224
153 preempt_disable(); 225 if (used_math) {
154
155 if (used_math()) {
156 /* restore fpu context if we have used it before */ 226 /* restore fpu context if we have used it before */
157 own_fpu(); 227 if (!err)
158 err |= restore_fp_context(sc); 228 err = check_and_restore_fp_context(sc);
159 } else { 229 } else {
160 /* signal handler may have used FPU. Give it up. */ 230 /* signal handler may have used FPU. Give it up. */
161 lose_fpu(); 231 lose_fpu(0);
162 } 232 }
163 233
164 preempt_enable();
165
166 return err; 234 return err;
167} 235}
168 236
@@ -325,6 +393,7 @@ asmlinkage void sys_sigreturn(nabi_no_regargs struct pt_regs regs)
325{ 393{
326 struct sigframe __user *frame; 394 struct sigframe __user *frame;
327 sigset_t blocked; 395 sigset_t blocked;
396 int sig;
328 397
329 frame = (struct sigframe __user *) regs.regs[29]; 398 frame = (struct sigframe __user *) regs.regs[29];
330 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 399 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
@@ -338,8 +407,11 @@ asmlinkage void sys_sigreturn(nabi_no_regargs struct pt_regs regs)
338 recalc_sigpending(); 407 recalc_sigpending();
339 spin_unlock_irq(&current->sighand->siglock); 408 spin_unlock_irq(&current->sighand->siglock);
340 409
341 if (restore_sigcontext(&regs, &frame->sf_sc)) 410 sig = restore_sigcontext(&regs, &frame->sf_sc);
411 if (sig < 0)
342 goto badframe; 412 goto badframe;
413 else if (sig)
414 force_sig(sig, current);
343 415
344 /* 416 /*
345 * Don't let your children do this ... 417 * Don't let your children do this ...
@@ -361,6 +433,7 @@ asmlinkage void sys_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
361 struct rt_sigframe __user *frame; 433 struct rt_sigframe __user *frame;
362 sigset_t set; 434 sigset_t set;
363 stack_t st; 435 stack_t st;
436 int sig;
364 437
365 frame = (struct rt_sigframe __user *) regs.regs[29]; 438 frame = (struct rt_sigframe __user *) regs.regs[29];
366 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 439 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
@@ -374,8 +447,11 @@ asmlinkage void sys_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
374 recalc_sigpending(); 447 recalc_sigpending();
375 spin_unlock_irq(&current->sighand->siglock); 448 spin_unlock_irq(&current->sighand->siglock);
376 449
377 if (restore_sigcontext(&regs, &frame->rs_uc.uc_mcontext)) 450 sig = restore_sigcontext(&regs, &frame->rs_uc.uc_mcontext);
451 if (sig < 0)
378 goto badframe; 452 goto badframe;
453 else if (sig)
454 force_sig(sig, current);
379 455
380 if (__copy_from_user(&st, &frame->rs_uc.uc_stack, sizeof(st))) 456 if (__copy_from_user(&st, &frame->rs_uc.uc_stack, sizeof(st)))
381 goto badframe; 457 goto badframe;
@@ -398,7 +474,7 @@ badframe:
398} 474}
399 475
400#ifdef CONFIG_TRAD_SIGNALS 476#ifdef CONFIG_TRAD_SIGNALS
401int setup_frame(struct k_sigaction * ka, struct pt_regs *regs, 477static int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
402 int signr, sigset_t *set) 478 int signr, sigset_t *set)
403{ 479{
404 struct sigframe __user *frame; 480 struct sigframe __user *frame;
@@ -443,7 +519,7 @@ give_sigsegv:
443} 519}
444#endif 520#endif
445 521
446int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs, 522static int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
447 int signr, sigset_t *set, siginfo_t *info) 523 int signr, sigset_t *set, siginfo_t *info)
448{ 524{
449 struct rt_sigframe __user *frame; 525 struct rt_sigframe __user *frame;
@@ -501,6 +577,14 @@ give_sigsegv:
501 return -EFAULT; 577 return -EFAULT;
502} 578}
503 579
580struct mips_abi mips_abi = {
581#ifdef CONFIG_TRAD_SIGNALS
582 .setup_frame = setup_frame,
583#endif
584 .setup_rt_frame = setup_rt_frame,
585 .restart = __NR_restart_syscall
586};
587
504static int handle_signal(unsigned long sig, siginfo_t *info, 588static int handle_signal(unsigned long sig, siginfo_t *info,
505 struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs) 589 struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs)
506{ 590{
@@ -539,7 +623,7 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
539 return ret; 623 return ret;
540} 624}
541 625
542void do_signal(struct pt_regs *regs) 626static void do_signal(struct pt_regs *regs)
543{ 627{
544 struct k_sigaction ka; 628 struct k_sigaction ka;
545 sigset_t *oldset; 629 sigset_t *oldset;
@@ -589,7 +673,7 @@ void do_signal(struct pt_regs *regs)
589 regs->cp0_epc -= 8; 673 regs->cp0_epc -= 8;
590 } 674 }
591 if (regs->regs[2] == ERESTART_RESTARTBLOCK) { 675 if (regs->regs[2] == ERESTART_RESTARTBLOCK) {
592 regs->regs[2] = __NR_restart_syscall; 676 regs->regs[2] = current->thread.abi->restart;
593 regs->regs[7] = regs->regs[26]; 677 regs->regs[7] = regs->regs[26];
594 regs->cp0_epc -= 4; 678 regs->cp0_epc -= 4;
595 } 679 }
@@ -615,5 +699,5 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused,
615{ 699{
616 /* deal with pending signal delivery */ 700 /* deal with pending signal delivery */
617 if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) 701 if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
618 current->thread.abi->do_signal(regs); 702 do_signal(regs);
619} 703}
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
index c28cb21514c8..b9a014411f83 100644
--- a/arch/mips/kernel/signal32.c
+++ b/arch/mips/kernel/signal32.c
@@ -22,6 +22,7 @@
22#include <linux/compat.h> 22#include <linux/compat.h>
23#include <linux/suspend.h> 23#include <linux/suspend.h>
24#include <linux/compiler.h> 24#include <linux/compiler.h>
25#include <linux/uaccess.h>
25 26
26#include <asm/abi.h> 27#include <asm/abi.h>
27#include <asm/asm.h> 28#include <asm/asm.h>
@@ -29,7 +30,6 @@
29#include <linux/bitops.h> 30#include <linux/bitops.h>
30#include <asm/cacheflush.h> 31#include <asm/cacheflush.h>
31#include <asm/sim.h> 32#include <asm/sim.h>
32#include <asm/uaccess.h>
33#include <asm/ucontext.h> 33#include <asm/ucontext.h>
34#include <asm/system.h> 34#include <asm/system.h>
35#include <asm/fpu.h> 35#include <asm/fpu.h>
@@ -104,17 +104,10 @@ typedef struct compat_siginfo {
104 */ 104 */
105#define __NR_O32_sigreturn 4119 105#define __NR_O32_sigreturn 4119
106#define __NR_O32_rt_sigreturn 4193 106#define __NR_O32_rt_sigreturn 4193
107#define __NR_O32_restart_syscall 4253 107#define __NR_O32_restart_syscall 4253
108 108
109/* 32-bit compatibility types */ 109/* 32-bit compatibility types */
110 110
111#define _NSIG_BPW32 32
112#define _NSIG_WORDS32 (_NSIG / _NSIG_BPW32)
113
114typedef struct {
115 unsigned int sig[_NSIG_WORDS32];
116} sigset_t32;
117
118typedef unsigned int __sighandler32_t; 111typedef unsigned int __sighandler32_t;
119typedef void (*vfptr_t)(void); 112typedef void (*vfptr_t)(void);
120 113
@@ -136,7 +129,7 @@ struct ucontext32 {
136 s32 uc_link; 129 s32 uc_link;
137 stack32_t uc_stack; 130 stack32_t uc_stack;
138 struct sigcontext32 uc_mcontext; 131 struct sigcontext32 uc_mcontext;
139 sigset_t32 uc_sigmask; /* mask last for extensibility */ 132 compat_sigset_t uc_sigmask; /* mask last for extensibility */
140}; 133};
141 134
142/* 135/*
@@ -150,7 +143,7 @@ struct sigframe32 {
150 u32 sf_ass[4]; /* argument save space for o32 */ 143 u32 sf_ass[4]; /* argument save space for o32 */
151 u32 sf_code[2]; /* signal trampoline */ 144 u32 sf_code[2]; /* signal trampoline */
152 struct sigcontext32 sf_sc; 145 struct sigcontext32 sf_sc;
153 sigset_t sf_mask; 146 compat_sigset_t sf_mask;
154}; 147};
155 148
156struct rt_sigframe32 { 149struct rt_sigframe32 {
@@ -166,7 +159,7 @@ struct sigframe32 {
166 u32 sf_ass[4]; /* argument save space for o32 */ 159 u32 sf_ass[4]; /* argument save space for o32 */
167 u32 sf_pad[2]; 160 u32 sf_pad[2];
168 struct sigcontext32 sf_sc; /* hw context */ 161 struct sigcontext32 sf_sc; /* hw context */
169 sigset_t sf_mask; 162 compat_sigset_t sf_mask;
170 u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */ 163 u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */
171}; 164};
172 165
@@ -183,11 +176,52 @@ struct rt_sigframe32 {
183/* 176/*
184 * sigcontext handlers 177 * sigcontext handlers
185 */ 178 */
179static int protected_save_fp_context32(struct sigcontext32 __user *sc)
180{
181 int err;
182 while (1) {
183 lock_fpu_owner();
184 own_fpu_inatomic(1);
185 err = save_fp_context32(sc); /* this might fail */
186 unlock_fpu_owner();
187 if (likely(!err))
188 break;
189 /* touch the sigcontext and try again */
190 err = __put_user(0, &sc->sc_fpregs[0]) |
191 __put_user(0, &sc->sc_fpregs[31]) |
192 __put_user(0, &sc->sc_fpc_csr);
193 if (err)
194 break; /* really bad sigcontext */
195 }
196 return err;
197}
198
199static int protected_restore_fp_context32(struct sigcontext32 __user *sc)
200{
201 int err, tmp;
202 while (1) {
203 lock_fpu_owner();
204 own_fpu_inatomic(0);
205 err = restore_fp_context32(sc); /* this might fail */
206 unlock_fpu_owner();
207 if (likely(!err))
208 break;
209 /* touch the sigcontext and try again */
210 err = __get_user(tmp, &sc->sc_fpregs[0]) |
211 __get_user(tmp, &sc->sc_fpregs[31]) |
212 __get_user(tmp, &sc->sc_fpc_csr);
213 if (err)
214 break; /* really bad sigcontext */
215 }
216 return err;
217}
218
186static int setup_sigcontext32(struct pt_regs *regs, 219static int setup_sigcontext32(struct pt_regs *regs,
187 struct sigcontext32 __user *sc) 220 struct sigcontext32 __user *sc)
188{ 221{
189 int err = 0; 222 int err = 0;
190 int i; 223 int i;
224 u32 used_math;
191 225
192 err |= __put_user(regs->cp0_epc, &sc->sc_pc); 226 err |= __put_user(regs->cp0_epc, &sc->sc_pc);
193 227
@@ -207,26 +241,31 @@ static int setup_sigcontext32(struct pt_regs *regs,
207 err |= __put_user(mflo3(), &sc->sc_lo3); 241 err |= __put_user(mflo3(), &sc->sc_lo3);
208 } 242 }
209 243
210 err |= __put_user(!!used_math(), &sc->sc_used_math); 244 used_math = !!used_math();
245 err |= __put_user(used_math, &sc->sc_used_math);
211 246
212 if (used_math()) { 247 if (used_math) {
213 /* 248 /*
214 * Save FPU state to signal context. Signal handler 249 * Save FPU state to signal context. Signal handler
215 * will "inherit" current FPU state. 250 * will "inherit" current FPU state.
216 */ 251 */
217 preempt_disable(); 252 err |= protected_save_fp_context32(sc);
218
219 if (!is_fpu_owner()) {
220 own_fpu();
221 restore_fp(current);
222 }
223 err |= save_fp_context32(sc);
224
225 preempt_enable();
226 } 253 }
227 return err; 254 return err;
228} 255}
229 256
257static int
258check_and_restore_fp_context32(struct sigcontext32 __user *sc)
259{
260 int err, sig;
261
262 err = sig = fpcsr_pending(&sc->sc_fpc_csr);
263 if (err > 0)
264 err = 0;
265 err |= protected_restore_fp_context32(sc);
266 return err ?: sig;
267}
268
230static int restore_sigcontext32(struct pt_regs *regs, 269static int restore_sigcontext32(struct pt_regs *regs,
231 struct sigcontext32 __user *sc) 270 struct sigcontext32 __user *sc)
232{ 271{
@@ -257,19 +296,15 @@ static int restore_sigcontext32(struct pt_regs *regs,
257 err |= __get_user(used_math, &sc->sc_used_math); 296 err |= __get_user(used_math, &sc->sc_used_math);
258 conditional_used_math(used_math); 297 conditional_used_math(used_math);
259 298
260 preempt_disable(); 299 if (used_math) {
261
262 if (used_math()) {
263 /* restore fpu context if we have used it before */ 300 /* restore fpu context if we have used it before */
264 own_fpu(); 301 if (!err)
265 err |= restore_fp_context32(sc); 302 err = check_and_restore_fp_context32(sc);
266 } else { 303 } else {
267 /* signal handler may have used FPU. Give it up. */ 304 /* signal handler may have used FPU. Give it up. */
268 lose_fpu(); 305 lose_fpu(0);
269 } 306 }
270 307
271 preempt_enable();
272
273 return err; 308 return err;
274} 309}
275 310
@@ -515,6 +550,7 @@ asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
515{ 550{
516 struct sigframe32 __user *frame; 551 struct sigframe32 __user *frame;
517 sigset_t blocked; 552 sigset_t blocked;
553 int sig;
518 554
519 frame = (struct sigframe32 __user *) regs.regs[29]; 555 frame = (struct sigframe32 __user *) regs.regs[29];
520 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 556 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
@@ -528,8 +564,11 @@ asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
528 recalc_sigpending(); 564 recalc_sigpending();
529 spin_unlock_irq(&current->sighand->siglock); 565 spin_unlock_irq(&current->sighand->siglock);
530 566
531 if (restore_sigcontext32(&regs, &frame->sf_sc)) 567 sig = restore_sigcontext32(&regs, &frame->sf_sc);
568 if (sig < 0)
532 goto badframe; 569 goto badframe;
570 else if (sig)
571 force_sig(sig, current);
533 572
534 /* 573 /*
535 * Don't let your children do this ... 574 * Don't let your children do this ...
@@ -552,6 +591,7 @@ asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
552 sigset_t set; 591 sigset_t set;
553 stack_t st; 592 stack_t st;
554 s32 sp; 593 s32 sp;
594 int sig;
555 595
556 frame = (struct rt_sigframe32 __user *) regs.regs[29]; 596 frame = (struct rt_sigframe32 __user *) regs.regs[29];
557 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 597 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
@@ -565,8 +605,11 @@ asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
565 recalc_sigpending(); 605 recalc_sigpending();
566 spin_unlock_irq(&current->sighand->siglock); 606 spin_unlock_irq(&current->sighand->siglock);
567 607
568 if (restore_sigcontext32(&regs, &frame->rs_uc.uc_mcontext)) 608 sig = restore_sigcontext32(&regs, &frame->rs_uc.uc_mcontext);
609 if (sig < 0)
569 goto badframe; 610 goto badframe;
611 else if (sig)
612 force_sig(sig, current);
570 613
571 /* The ucontext contains a stack32_t, so we must convert! */ 614 /* The ucontext contains a stack32_t, so we must convert! */
572 if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp)) 615 if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp))
@@ -598,7 +641,7 @@ badframe:
598 force_sig(SIGSEGV, current); 641 force_sig(SIGSEGV, current);
599} 642}
600 643
601int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs, 644static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
602 int signr, sigset_t *set) 645 int signr, sigset_t *set)
603{ 646{
604 struct sigframe32 __user *frame; 647 struct sigframe32 __user *frame;
@@ -644,7 +687,7 @@ give_sigsegv:
644 return -EFAULT; 687 return -EFAULT;
645} 688}
646 689
647int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs, 690static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
648 int signr, sigset_t *set, siginfo_t *info) 691 int signr, sigset_t *set, siginfo_t *info)
649{ 692{
650 struct rt_sigframe32 __user *frame; 693 struct rt_sigframe32 __user *frame;
@@ -704,110 +747,14 @@ give_sigsegv:
704 return -EFAULT; 747 return -EFAULT;
705} 748}
706 749
707static inline int handle_signal(unsigned long sig, siginfo_t *info, 750/*
708 struct k_sigaction *ka, sigset_t *oldset, struct pt_regs * regs) 751 * o32 compatibility on 64-bit kernels, without DSP ASE
709{ 752 */
710 int ret; 753struct mips_abi mips_abi_32 = {
711 754 .setup_frame = setup_frame_32,
712 switch (regs->regs[0]) { 755 .setup_rt_frame = setup_rt_frame_32,
713 case ERESTART_RESTARTBLOCK: 756 .restart = __NR_O32_restart_syscall
714 case ERESTARTNOHAND: 757};
715 regs->regs[2] = EINTR;
716 break;
717 case ERESTARTSYS:
718 if (!(ka->sa.sa_flags & SA_RESTART)) {
719 regs->regs[2] = EINTR;
720 break;
721 }
722 /* fallthrough */
723 case ERESTARTNOINTR: /* Userland will reload $v0. */
724 regs->regs[7] = regs->regs[26];
725 regs->cp0_epc -= 8;
726 }
727
728 regs->regs[0] = 0; /* Don't deal with this again. */
729
730 if (ka->sa.sa_flags & SA_SIGINFO)
731 ret = current->thread.abi->setup_rt_frame(ka, regs, sig, oldset, info);
732 else
733 ret = current->thread.abi->setup_frame(ka, regs, sig, oldset);
734
735 spin_lock_irq(&current->sighand->siglock);
736 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
737 if (!(ka->sa.sa_flags & SA_NODEFER))
738 sigaddset(&current->blocked,sig);
739 recalc_sigpending();
740 spin_unlock_irq(&current->sighand->siglock);
741
742 return ret;
743}
744
745void do_signal32(struct pt_regs *regs)
746{
747 struct k_sigaction ka;
748 sigset_t *oldset;
749 siginfo_t info;
750 int signr;
751
752 /*
753 * We want the common case to go fast, which is why we may in certain
754 * cases get here from kernel mode. Just return without doing anything
755 * if so.
756 */
757 if (!user_mode(regs))
758 return;
759
760 if (test_thread_flag(TIF_RESTORE_SIGMASK))
761 oldset = &current->saved_sigmask;
762 else
763 oldset = &current->blocked;
764
765 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
766 if (signr > 0) {
767 /* Whee! Actually deliver the signal. */
768 if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
769 /*
770 * A signal was successfully delivered; the saved
771 * sigmask will have been stored in the signal frame,
772 * and will be restored by sigreturn, so we can simply
773 * clear the TIF_RESTORE_SIGMASK flag.
774 */
775 if (test_thread_flag(TIF_RESTORE_SIGMASK))
776 clear_thread_flag(TIF_RESTORE_SIGMASK);
777 }
778
779 return;
780 }
781
782 /*
783 * Who's code doesn't conform to the restartable syscall convention
784 * dies here!!! The li instruction, a single machine instruction,
785 * must directly be followed by the syscall instruction.
786 */
787 if (regs->regs[0]) {
788 if (regs->regs[2] == ERESTARTNOHAND ||
789 regs->regs[2] == ERESTARTSYS ||
790 regs->regs[2] == ERESTARTNOINTR) {
791 regs->regs[7] = regs->regs[26];
792 regs->cp0_epc -= 8;
793 }
794 if (regs->regs[2] == ERESTART_RESTARTBLOCK) {
795 regs->regs[2] = __NR_O32_restart_syscall;
796 regs->regs[7] = regs->regs[26];
797 regs->cp0_epc -= 4;
798 }
799 regs->regs[0] = 0; /* Don't deal with this again. */
800 }
801
802 /*
803 * If there's no signal to deliver, we just put the saved sigmask
804 * back
805 */
806 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
807 clear_thread_flag(TIF_RESTORE_SIGMASK);
808 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
809 }
810}
811 758
812asmlinkage int sys32_rt_sigaction(int sig, const struct sigaction32 __user *act, 759asmlinkage int sys32_rt_sigaction(int sig, const struct sigaction32 __user *act,
813 struct sigaction32 __user *oact, 760 struct sigaction32 __user *oact,
diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c
index 7ca2a078841f..a9202fa95987 100644
--- a/arch/mips/kernel/signal_n32.c
+++ b/arch/mips/kernel/signal_n32.c
@@ -29,6 +29,7 @@
29#include <linux/compat.h> 29#include <linux/compat.h>
30#include <linux/bitops.h> 30#include <linux/bitops.h>
31 31
32#include <asm/abi.h>
32#include <asm/asm.h> 33#include <asm/asm.h>
33#include <asm/cacheflush.h> 34#include <asm/cacheflush.h>
34#include <asm/compat-signal.h> 35#include <asm/compat-signal.h>
@@ -126,6 +127,7 @@ asmlinkage void sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
126 sigset_t set; 127 sigset_t set;
127 stack_t st; 128 stack_t st;
128 s32 sp; 129 s32 sp;
130 int sig;
129 131
130 frame = (struct rt_sigframe_n32 __user *) regs.regs[29]; 132 frame = (struct rt_sigframe_n32 __user *) regs.regs[29];
131 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 133 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
@@ -139,8 +141,11 @@ asmlinkage void sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
139 recalc_sigpending(); 141 recalc_sigpending();
140 spin_unlock_irq(&current->sighand->siglock); 142 spin_unlock_irq(&current->sighand->siglock);
141 143
142 if (restore_sigcontext(&regs, &frame->rs_uc.uc_mcontext)) 144 sig = restore_sigcontext(&regs, &frame->rs_uc.uc_mcontext);
145 if (sig < 0)
143 goto badframe; 146 goto badframe;
147 else if (sig)
148 force_sig(sig, current);
144 149
145 /* The ucontext contains a stack32_t, so we must convert! */ 150 /* The ucontext contains a stack32_t, so we must convert! */
146 if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp)) 151 if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp))
@@ -169,7 +174,7 @@ badframe:
169 force_sig(SIGSEGV, current); 174 force_sig(SIGSEGV, current);
170} 175}
171 176
172int setup_rt_frame_n32(struct k_sigaction * ka, 177static int setup_rt_frame_n32(struct k_sigaction * ka,
173 struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info) 178 struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info)
174{ 179{
175 struct rt_sigframe_n32 __user *frame; 180 struct rt_sigframe_n32 __user *frame;
@@ -228,3 +233,8 @@ give_sigsegv:
228 force_sigsegv(signr, current); 233 force_sigsegv(signr, current);
229 return -EFAULT; 234 return -EFAULT;
230} 235}
236
237struct mips_abi mips_abi_n32 = {
238 .setup_rt_frame = setup_rt_frame_n32,
239 .restart = __NR_N32_restart_syscall
240};
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index 0555fc554f65..c46e479c992b 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -51,31 +51,14 @@ int __cpu_logical_map[NR_CPUS]; /* Map logical to physical */
51EXPORT_SYMBOL(phys_cpu_present_map); 51EXPORT_SYMBOL(phys_cpu_present_map);
52EXPORT_SYMBOL(cpu_online_map); 52EXPORT_SYMBOL(cpu_online_map);
53 53
54/* This happens early in bootup, can't really do it better */
54static void smp_tune_scheduling (void) 55static void smp_tune_scheduling (void)
55{ 56{
56 struct cache_desc *cd = &current_cpu_data.scache; 57 struct cache_desc *cd = &current_cpu_data.scache;
57 unsigned long cachesize; /* kB */ 58 unsigned long cachesize = cd->linesz * cd->sets * cd->ways;
58 unsigned long cpu_khz;
59 59
60 /* 60 if (cachesize > max_cache_size)
61 * Crude estimate until we actually meassure ... 61 max_cache_size = cachesize;
62 */
63 cpu_khz = loops_per_jiffy * 2 * HZ / 1000;
64
65 /*
66 * Rough estimation for SMP scheduling, this is the number of
67 * cycles it takes for a fully memory-limited process to flush
68 * the SMP-local cache.
69 *
70 * (For a P5 this pretty much means we will choose another idle
71 * CPU almost always at wakeup time (this is due to the small
72 * L1 cache), on PIIs it's around 50-100 usecs, depending on
73 * the cache size)
74 */
75 if (!cpu_khz)
76 return;
77
78 cachesize = cd->linesz * cd->sets * cd->ways;
79} 62}
80 63
81extern void __init calibrate_delay(void); 64extern void __init calibrate_delay(void);
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c
index 9251ea824937..5dcfab6b288e 100644
--- a/arch/mips/kernel/smtc.c
+++ b/arch/mips/kernel/smtc.c
@@ -4,6 +4,7 @@
4#include <linux/sched.h> 4#include <linux/sched.h>
5#include <linux/cpumask.h> 5#include <linux/cpumask.h>
6#include <linux/interrupt.h> 6#include <linux/interrupt.h>
7#include <linux/kernel_stat.h>
7#include <linux/module.h> 8#include <linux/module.h>
8 9
9#include <asm/cpu.h> 10#include <asm/cpu.h>
@@ -14,6 +15,7 @@
14#include <asm/hazards.h> 15#include <asm/hazards.h>
15#include <asm/mmu_context.h> 16#include <asm/mmu_context.h>
16#include <asm/smp.h> 17#include <asm/smp.h>
18#include <asm/mips-boards/maltaint.h>
17#include <asm/mipsregs.h> 19#include <asm/mipsregs.h>
18#include <asm/cacheflush.h> 20#include <asm/cacheflush.h>
19#include <asm/time.h> 21#include <asm/time.h>
@@ -75,7 +77,7 @@ static struct smtc_ipi_q freeIPIq;
75 77
76void ipi_decode(struct smtc_ipi *); 78void ipi_decode(struct smtc_ipi *);
77static void post_direct_ipi(int cpu, struct smtc_ipi *pipi); 79static void post_direct_ipi(int cpu, struct smtc_ipi *pipi);
78static void setup_cross_vpe_interrupts(void); 80static void setup_cross_vpe_interrupts(unsigned int nvpe);
79void init_smtc_stats(void); 81void init_smtc_stats(void);
80 82
81/* Global SMTC Status */ 83/* Global SMTC Status */
@@ -141,10 +143,7 @@ __setup("ipibufs=", ipibufs);
141__setup("nostlb", stlb_disable); 143__setup("nostlb", stlb_disable);
142__setup("asidmask=", asidmask_set); 144__setup("asidmask=", asidmask_set);
143 145
144/* Enable additional debug checks before going into CPU idle loop */ 146#ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG
145#define SMTC_IDLE_HOOK_DEBUG
146
147#ifdef SMTC_IDLE_HOOK_DEBUG
148 147
149static int hang_trig = 0; 148static int hang_trig = 0;
150 149
@@ -171,12 +170,15 @@ __setup("tintq=", tintq);
171 170
172int imstuckcount[2][8]; 171int imstuckcount[2][8];
173/* vpemask represents IM/IE bits of per-VPE Status registers, low-to-high */ 172/* vpemask represents IM/IE bits of per-VPE Status registers, low-to-high */
174int vpemask[2][8] = {{0,1,1,0,0,0,0,1},{0,1,0,0,0,0,0,1}}; 173int vpemask[2][8] = {
174 {0, 0, 1, 0, 0, 0, 0, 1},
175 {0, 0, 0, 0, 0, 0, 0, 1}
176};
175int tcnoprog[NR_CPUS]; 177int tcnoprog[NR_CPUS];
176static atomic_t idle_hook_initialized = {0}; 178static atomic_t idle_hook_initialized = {0};
177static int clock_hang_reported[NR_CPUS]; 179static int clock_hang_reported[NR_CPUS];
178 180
179#endif /* SMTC_IDLE_HOOK_DEBUG */ 181#endif /* CONFIG_SMTC_IDLE_HOOK_DEBUG */
180 182
181/* Initialize shared TLB - the should probably migrate to smtc_setup_cpus() */ 183/* Initialize shared TLB - the should probably migrate to smtc_setup_cpus() */
182 184
@@ -394,10 +396,10 @@ void mipsmt_prepare_cpus(void)
394 printk("ASID mask value override to 0x%x\n", asidmask); 396 printk("ASID mask value override to 0x%x\n", asidmask);
395 397
396 /* Temporary */ 398 /* Temporary */
397#ifdef SMTC_IDLE_HOOK_DEBUG 399#ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG
398 if (hang_trig) 400 if (hang_trig)
399 printk("Logic Analyser Trigger on suspected TC hang\n"); 401 printk("Logic Analyser Trigger on suspected TC hang\n");
400#endif /* SMTC_IDLE_HOOK_DEBUG */ 402#endif /* CONFIG_SMTC_IDLE_HOOK_DEBUG */
401 403
402 /* Put MVPE's into 'configuration state' */ 404 /* Put MVPE's into 'configuration state' */
403 write_c0_mvpcontrol( read_c0_mvpcontrol() | MVPCONTROL_VPC ); 405 write_c0_mvpcontrol( read_c0_mvpcontrol() | MVPCONTROL_VPC );
@@ -504,8 +506,7 @@ void mipsmt_prepare_cpus(void)
504 506
505 /* If we have multiple VPEs running, set up the cross-VPE interrupt */ 507 /* If we have multiple VPEs running, set up the cross-VPE interrupt */
506 508
507 if (nvpe > 1) 509 setup_cross_vpe_interrupts(nvpe);
508 setup_cross_vpe_interrupts();
509 510
510 /* Set up queue of free IPI "messages". */ 511 /* Set up queue of free IPI "messages". */
511 nipi = NR_CPUS * IPIBUF_PER_CPU; 512 nipi = NR_CPUS * IPIBUF_PER_CPU;
@@ -610,7 +611,12 @@ void smtc_cpus_done(void)
610int setup_irq_smtc(unsigned int irq, struct irqaction * new, 611int setup_irq_smtc(unsigned int irq, struct irqaction * new,
611 unsigned long hwmask) 612 unsigned long hwmask)
612{ 613{
614 unsigned int vpe = current_cpu_data.vpe_id;
615
613 irq_hwmask[irq] = hwmask; 616 irq_hwmask[irq] = hwmask;
617#ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG
618 vpemask[vpe][irq - MIPSCPU_INT_BASE] = 1;
619#endif
614 620
615 return setup_irq(irq, new); 621 return setup_irq(irq, new);
616} 622}
@@ -815,12 +821,15 @@ void ipi_decode(struct smtc_ipi *pipi)
815 smtc_ipi_nq(&freeIPIq, pipi); 821 smtc_ipi_nq(&freeIPIq, pipi);
816 switch (type_copy) { 822 switch (type_copy) {
817 case SMTC_CLOCK_TICK: 823 case SMTC_CLOCK_TICK:
824 irq_enter();
825 kstat_this_cpu.irqs[MIPSCPU_INT_BASE + MIPSCPU_INT_CPUCTR]++;
818 /* Invoke Clock "Interrupt" */ 826 /* Invoke Clock "Interrupt" */
819 ipi_timer_latch[dest_copy] = 0; 827 ipi_timer_latch[dest_copy] = 0;
820#ifdef SMTC_IDLE_HOOK_DEBUG 828#ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG
821 clock_hang_reported[dest_copy] = 0; 829 clock_hang_reported[dest_copy] = 0;
822#endif /* SMTC_IDLE_HOOK_DEBUG */ 830#endif /* CONFIG_SMTC_IDLE_HOOK_DEBUG */
823 local_timer_interrupt(0, NULL); 831 local_timer_interrupt(0, NULL);
832 irq_exit();
824 break; 833 break;
825 case LINUX_SMP_IPI: 834 case LINUX_SMP_IPI:
826 switch ((int)arg_copy) { 835 switch ((int)arg_copy) {
@@ -968,8 +977,11 @@ static void ipi_irq_dispatch(void)
968 977
969static struct irqaction irq_ipi; 978static struct irqaction irq_ipi;
970 979
971static void setup_cross_vpe_interrupts(void) 980static void setup_cross_vpe_interrupts(unsigned int nvpe)
972{ 981{
982 if (nvpe < 1)
983 return;
984
973 if (!cpu_has_vint) 985 if (!cpu_has_vint)
974 panic("SMTC Kernel requires Vectored Interupt support"); 986 panic("SMTC Kernel requires Vectored Interupt support");
975 987
@@ -987,10 +999,17 @@ static void setup_cross_vpe_interrupts(void)
987 999
988/* 1000/*
989 * SMTC-specific hacks invoked from elsewhere in the kernel. 1001 * SMTC-specific hacks invoked from elsewhere in the kernel.
1002 *
1003 * smtc_ipi_replay is called from raw_local_irq_restore which is only ever
1004 * called with interrupts disabled. We do rely on interrupts being disabled
1005 * here because using spin_lock_irqsave()/spin_unlock_irqrestore() would
1006 * result in a recursive call to raw_local_irq_restore().
990 */ 1007 */
991 1008
992void smtc_ipi_replay(void) 1009static void __smtc_ipi_replay(void)
993{ 1010{
1011 unsigned int cpu = smp_processor_id();
1012
994 /* 1013 /*
995 * To the extent that we've ever turned interrupts off, 1014 * To the extent that we've ever turned interrupts off,
996 * we may have accumulated deferred IPIs. This is subtle. 1015 * we may have accumulated deferred IPIs. This is subtle.
@@ -1005,22 +1024,35 @@ void smtc_ipi_replay(void)
1005 * is clear, and we'll handle it as a real pseudo-interrupt 1024 * is clear, and we'll handle it as a real pseudo-interrupt
1006 * and not a pseudo-pseudo interrupt. 1025 * and not a pseudo-pseudo interrupt.
1007 */ 1026 */
1008 if (IPIQ[smp_processor_id()].depth > 0) { 1027 if (IPIQ[cpu].depth > 0) {
1009 struct smtc_ipi *pipi; 1028 while (1) {
1010 extern void self_ipi(struct smtc_ipi *); 1029 struct smtc_ipi_q *q = &IPIQ[cpu];
1030 struct smtc_ipi *pipi;
1031 extern void self_ipi(struct smtc_ipi *);
1032
1033 spin_lock(&q->lock);
1034 pipi = __smtc_ipi_dq(q);
1035 spin_unlock(&q->lock);
1036 if (!pipi)
1037 break;
1011 1038
1012 while ((pipi = smtc_ipi_dq(&IPIQ[smp_processor_id()]))) {
1013 self_ipi(pipi); 1039 self_ipi(pipi);
1014 smtc_cpu_stats[smp_processor_id()].selfipis++; 1040 smtc_cpu_stats[cpu].selfipis++;
1015 } 1041 }
1016 } 1042 }
1017} 1043}
1018 1044
1045void smtc_ipi_replay(void)
1046{
1047 raw_local_irq_disable();
1048 __smtc_ipi_replay();
1049}
1050
1019EXPORT_SYMBOL(smtc_ipi_replay); 1051EXPORT_SYMBOL(smtc_ipi_replay);
1020 1052
1021void smtc_idle_loop_hook(void) 1053void smtc_idle_loop_hook(void)
1022{ 1054{
1023#ifdef SMTC_IDLE_HOOK_DEBUG 1055#ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG
1024 int im; 1056 int im;
1025 int flags; 1057 int flags;
1026 int mtflags; 1058 int mtflags;
@@ -1113,14 +1145,20 @@ void smtc_idle_loop_hook(void)
1113 local_irq_restore(flags); 1145 local_irq_restore(flags);
1114 if (pdb_msg != &id_ho_db_msg[0]) 1146 if (pdb_msg != &id_ho_db_msg[0])
1115 printk("CPU%d: %s", smp_processor_id(), id_ho_db_msg); 1147 printk("CPU%d: %s", smp_processor_id(), id_ho_db_msg);
1116#endif /* SMTC_IDLE_HOOK_DEBUG */ 1148#endif /* CONFIG_SMTC_IDLE_HOOK_DEBUG */
1117 1149
1118 /* 1150 /*
1119 * Replay any accumulated deferred IPIs. If "Instant Replay" 1151 * Replay any accumulated deferred IPIs. If "Instant Replay"
1120 * is in use, there should never be any. 1152 * is in use, there should never be any.
1121 */ 1153 */
1122#ifndef CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY 1154#ifndef CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY
1123 smtc_ipi_replay(); 1155 {
1156 unsigned long flags;
1157
1158 local_irq_save(flags);
1159 __smtc_ipi_replay();
1160 local_irq_restore(flags);
1161 }
1124#endif /* CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY */ 1162#endif /* CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY */
1125} 1163}
1126 1164
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 2a932cada244..493cb29b8a42 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -229,6 +229,9 @@ void show_regs(struct pt_regs *regs)
229 printk("\n"); 229 printk("\n");
230 } 230 }
231 231
232#ifdef CONFIG_CPU_HAS_SMARTMIPS
233 printk("Acx : %0*lx\n", field, regs->acx);
234#endif
232 printk("Hi : %0*lx\n", field, regs->hi); 235 printk("Hi : %0*lx\n", field, regs->hi);
233 printk("Lo : %0*lx\n", field, regs->lo); 236 printk("Lo : %0*lx\n", field, regs->lo);
234 237
@@ -340,13 +343,9 @@ NORET_TYPE void ATTRIB_NORET die(const char * str, struct pt_regs * regs)
340extern const struct exception_table_entry __start___dbe_table[]; 343extern const struct exception_table_entry __start___dbe_table[];
341extern const struct exception_table_entry __stop___dbe_table[]; 344extern const struct exception_table_entry __stop___dbe_table[];
342 345
343void __declare_dbe_table(void) 346__asm__(
344{ 347" .section __dbe_table, \"a\"\n"
345 __asm__ __volatile__( 348" .previous \n");
346 ".section\t__dbe_table,\"a\"\n\t"
347 ".previous"
348 );
349}
350 349
351/* Given an address, look for it in the exception tables. */ 350/* Given an address, look for it in the exception tables. */
352static const struct exception_table_entry *search_dbe_tables(unsigned long addr) 351static const struct exception_table_entry *search_dbe_tables(unsigned long addr)
@@ -611,16 +610,6 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
611 if (fcr31 & FPU_CSR_UNI_X) { 610 if (fcr31 & FPU_CSR_UNI_X) {
612 int sig; 611 int sig;
613 612
614 preempt_disable();
615
616#ifdef CONFIG_PREEMPT
617 if (!is_fpu_owner()) {
618 /* We might lose fpu before disabling preempt... */
619 own_fpu();
620 BUG_ON(!used_math());
621 restore_fp(current);
622 }
623#endif
624 /* 613 /*
625 * Unimplemented operation exception. If we've got the full 614 * Unimplemented operation exception. If we've got the full
626 * software emulator on-board, let's use it... 615 * software emulator on-board, let's use it...
@@ -631,18 +620,12 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
631 * register operands before invoking the emulator, which seems 620 * register operands before invoking the emulator, which seems
632 * a bit extreme for what should be an infrequent event. 621 * a bit extreme for what should be an infrequent event.
633 */ 622 */
634 save_fp(current);
635 /* Ensure 'resume' not overwrite saved fp context again. */ 623 /* Ensure 'resume' not overwrite saved fp context again. */
636 lose_fpu(); 624 lose_fpu(1);
637
638 preempt_enable();
639 625
640 /* Run the emulator */ 626 /* Run the emulator */
641 sig = fpu_emulator_cop1Handler (regs, &current->thread.fpu, 1); 627 sig = fpu_emulator_cop1Handler (regs, &current->thread.fpu, 1);
642 628
643 preempt_disable();
644
645 own_fpu(); /* Using the FPU again. */
646 /* 629 /*
647 * We can't allow the emulated instruction to leave any of 630 * We can't allow the emulated instruction to leave any of
648 * the cause bit set in $fcr31. 631 * the cause bit set in $fcr31.
@@ -650,9 +633,7 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
650 current->thread.fpu.fcr31 &= ~FPU_CSR_ALL_X; 633 current->thread.fpu.fcr31 &= ~FPU_CSR_ALL_X;
651 634
652 /* Restore the hardware register state */ 635 /* Restore the hardware register state */
653 restore_fp(current); 636 own_fpu(1); /* Using the FPU again. */
654
655 preempt_enable();
656 637
657 /* If something went wrong, signal */ 638 /* If something went wrong, signal */
658 if (sig) 639 if (sig)
@@ -669,7 +650,7 @@ asmlinkage void do_bp(struct pt_regs *regs)
669 unsigned int opcode, bcode; 650 unsigned int opcode, bcode;
670 siginfo_t info; 651 siginfo_t info;
671 652
672 if (get_user(opcode, (unsigned int __user *) exception_epc(regs))) 653 if (__get_user(opcode, (unsigned int __user *) exception_epc(regs)))
673 goto out_sigsegv; 654 goto out_sigsegv;
674 655
675 /* 656 /*
@@ -708,6 +689,7 @@ asmlinkage void do_bp(struct pt_regs *regs)
708 die_if_kernel("Break instruction in kernel code", regs); 689 die_if_kernel("Break instruction in kernel code", regs);
709 force_sig(SIGTRAP, current); 690 force_sig(SIGTRAP, current);
710 } 691 }
692 return;
711 693
712out_sigsegv: 694out_sigsegv:
713 force_sig(SIGSEGV, current); 695 force_sig(SIGSEGV, current);
@@ -718,7 +700,7 @@ asmlinkage void do_tr(struct pt_regs *regs)
718 unsigned int opcode, tcode = 0; 700 unsigned int opcode, tcode = 0;
719 siginfo_t info; 701 siginfo_t info;
720 702
721 if (get_user(opcode, (unsigned int __user *) exception_epc(regs))) 703 if (__get_user(opcode, (unsigned int __user *) exception_epc(regs)))
722 goto out_sigsegv; 704 goto out_sigsegv;
723 705
724 /* Immediate versions don't provide a code. */ 706 /* Immediate versions don't provide a code. */
@@ -751,6 +733,7 @@ asmlinkage void do_tr(struct pt_regs *regs)
751 die_if_kernel("Trap instruction in kernel code", regs); 733 die_if_kernel("Trap instruction in kernel code", regs);
752 force_sig(SIGTRAP, current); 734 force_sig(SIGTRAP, current);
753 } 735 }
736 return;
754 737
755out_sigsegv: 738out_sigsegv:
756 force_sig(SIGSEGV, current); 739 force_sig(SIGSEGV, current);
@@ -790,21 +773,15 @@ asmlinkage void do_cpu(struct pt_regs *regs)
790 break; 773 break;
791 774
792 case 1: 775 case 1:
793 preempt_disable(); 776 if (used_math()) /* Using the FPU again. */
794 777 own_fpu(1);
795 own_fpu(); 778 else { /* First time FPU user. */
796 if (used_math()) { /* Using the FPU again. */
797 restore_fp(current);
798 } else { /* First time FPU user. */
799 init_fpu(); 779 init_fpu();
800 set_used_math(); 780 set_used_math();
801 } 781 }
802 782
803 if (cpu_has_fpu) { 783 if (!raw_cpu_has_fpu) {
804 preempt_enable();
805 } else {
806 int sig; 784 int sig;
807 preempt_enable();
808 sig = fpu_emulator_cop1Handler(regs, 785 sig = fpu_emulator_cop1Handler(regs,
809 &current->thread.fpu, 0); 786 &current->thread.fpu, 0);
810 if (sig) 787 if (sig)
@@ -845,7 +822,6 @@ asmlinkage void do_cpu(struct pt_regs *regs)
845 822
846 case 2: 823 case 2:
847 case 3: 824 case 3:
848 die_if_kernel("do_cpu invoked from kernel context!", regs);
849 break; 825 break;
850 } 826 }
851 827
@@ -1258,26 +1234,26 @@ static inline void mips_srs_init(void)
1258/* 1234/*
1259 * This is used by native signal handling 1235 * This is used by native signal handling
1260 */ 1236 */
1261asmlinkage int (*save_fp_context)(struct sigcontext *sc); 1237asmlinkage int (*save_fp_context)(struct sigcontext __user *sc);
1262asmlinkage int (*restore_fp_context)(struct sigcontext *sc); 1238asmlinkage int (*restore_fp_context)(struct sigcontext __user *sc);
1263 1239
1264extern asmlinkage int _save_fp_context(struct sigcontext *sc); 1240extern asmlinkage int _save_fp_context(struct sigcontext __user *sc);
1265extern asmlinkage int _restore_fp_context(struct sigcontext *sc); 1241extern asmlinkage int _restore_fp_context(struct sigcontext __user *sc);
1266 1242
1267extern asmlinkage int fpu_emulator_save_context(struct sigcontext *sc); 1243extern asmlinkage int fpu_emulator_save_context(struct sigcontext __user *sc);
1268extern asmlinkage int fpu_emulator_restore_context(struct sigcontext *sc); 1244extern asmlinkage int fpu_emulator_restore_context(struct sigcontext __user *sc);
1269 1245
1270#ifdef CONFIG_SMP 1246#ifdef CONFIG_SMP
1271static int smp_save_fp_context(struct sigcontext *sc) 1247static int smp_save_fp_context(struct sigcontext __user *sc)
1272{ 1248{
1273 return cpu_has_fpu 1249 return raw_cpu_has_fpu
1274 ? _save_fp_context(sc) 1250 ? _save_fp_context(sc)
1275 : fpu_emulator_save_context(sc); 1251 : fpu_emulator_save_context(sc);
1276} 1252}
1277 1253
1278static int smp_restore_fp_context(struct sigcontext *sc) 1254static int smp_restore_fp_context(struct sigcontext __user *sc)
1279{ 1255{
1280 return cpu_has_fpu 1256 return raw_cpu_has_fpu
1281 ? _restore_fp_context(sc) 1257 ? _restore_fp_context(sc)
1282 : fpu_emulator_restore_context(sc); 1258 : fpu_emulator_restore_context(sc);
1283} 1259}
@@ -1305,14 +1281,14 @@ static inline void signal_init(void)
1305/* 1281/*
1306 * This is used by 32-bit signal stuff on the 64-bit kernel 1282 * This is used by 32-bit signal stuff on the 64-bit kernel
1307 */ 1283 */
1308asmlinkage int (*save_fp_context32)(struct sigcontext32 *sc); 1284asmlinkage int (*save_fp_context32)(struct sigcontext32 __user *sc);
1309asmlinkage int (*restore_fp_context32)(struct sigcontext32 *sc); 1285asmlinkage int (*restore_fp_context32)(struct sigcontext32 __user *sc);
1310 1286
1311extern asmlinkage int _save_fp_context32(struct sigcontext32 *sc); 1287extern asmlinkage int _save_fp_context32(struct sigcontext32 __user *sc);
1312extern asmlinkage int _restore_fp_context32(struct sigcontext32 *sc); 1288extern asmlinkage int _restore_fp_context32(struct sigcontext32 __user *sc);
1313 1289
1314extern asmlinkage int fpu_emulator_save_context32(struct sigcontext32 *sc); 1290extern asmlinkage int fpu_emulator_save_context32(struct sigcontext32 __user *sc);
1315extern asmlinkage int fpu_emulator_restore_context32(struct sigcontext32 *sc); 1291extern asmlinkage int fpu_emulator_restore_context32(struct sigcontext32 __user *sc);
1316 1292
1317static inline void signal32_init(void) 1293static inline void signal32_init(void)
1318{ 1294{
diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c
index 7e7d54823486..24b7b053cfe9 100644
--- a/arch/mips/kernel/unaligned.c
+++ b/arch/mips/kernel/unaligned.c
@@ -515,7 +515,7 @@ asmlinkage void do_ade(struct pt_regs *regs)
515 goto sigbus; 515 goto sigbus;
516 516
517 pc = (unsigned int __user *) exception_epc(regs); 517 pc = (unsigned int __user *) exception_epc(regs);
518 if ((current->thread.mflags & MF_FIXADE) == 0) 518 if (user_mode(regs) && (current->thread.mflags & MF_FIXADE) == 0)
519 goto sigbus; 519 goto sigbus;
520 520
521 /* 521 /*
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c
index 9aca871a307f..c9ee9d2d5856 100644
--- a/arch/mips/kernel/vpe.c
+++ b/arch/mips/kernel/vpe.c
@@ -1079,6 +1079,7 @@ static int getcwd(char *buff, int size)
1079static int vpe_open(struct inode *inode, struct file *filp) 1079static int vpe_open(struct inode *inode, struct file *filp)
1080{ 1080{
1081 int minor, ret; 1081 int minor, ret;
1082 enum vpe_state state;
1082 struct vpe *v; 1083 struct vpe *v;
1083 struct vpe_notifications *not; 1084 struct vpe_notifications *not;
1084 1085
@@ -1093,7 +1094,8 @@ static int vpe_open(struct inode *inode, struct file *filp)
1093 return -ENODEV; 1094 return -ENODEV;
1094 } 1095 }
1095 1096
1096 if (v->state != VPE_STATE_UNUSED) { 1097 state = xchg(&v->state, VPE_STATE_INUSE);
1098 if (state != VPE_STATE_UNUSED) {
1097 dvpe(); 1099 dvpe();
1098 1100
1099 printk(KERN_DEBUG "VPE loader: tc in use dumping regs\n"); 1101 printk(KERN_DEBUG "VPE loader: tc in use dumping regs\n");
@@ -1108,9 +1110,6 @@ static int vpe_open(struct inode *inode, struct file *filp)
1108 cleanup_tc(get_tc(minor)); 1110 cleanup_tc(get_tc(minor));
1109 } 1111 }
1110 1112
1111 // allocate it so when we get write ops we know it's expected.
1112 v->state = VPE_STATE_INUSE;
1113
1114 /* this of-course trashes what was there before... */ 1113 /* this of-course trashes what was there before... */
1115 v->pbuffer = vmalloc(P_SIZE); 1114 v->pbuffer = vmalloc(P_SIZE);
1116 v->plen = P_SIZE; 1115 v->plen = P_SIZE;