aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-11 14:40:04 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-11 14:40:04 -0500
commit574009c1a895aeeb85eaab29c235d75852b09eb8 (patch)
tree350208723aea3fa62927e5fed6c07567cee9f930
parenta727fea99bf4b2addcd64c596735148117a7b37f (diff)
parente692eb30ffc2b99e62f766f9958f46dfdc1013cc (diff)
Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus
* 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus: [MIPS] signal: do not inline handle_signal() [MIPS] signal: do not use save_static_function() anymore [MIPS] signal32: no need to save c0_status register in setup_sigcontext32() [MIPS] signal32: reduce {setup,restore}_sigcontext32 sizes [MIPS] signal: factorize debug code [MIPS] signal: test return value of install_sigtramp() [MIPS] signal32: remove duplicate code [MIPS] signal: clean up sigframe structure [MIPS] signal: do not inline functions in signal-common.h [MIPS] signals: reduce {setup,restore}_sigcontext sizes [MIPS] Fix warning in get_user when fetching pointer object from userspace. [MIPS] Fix eth2 platform device id for jaguar_atx and ocelot_3 platforms [MIPS] JMR3927 and RBTX49x7 support little endian [MIPS] RBTX49x7: declare prom_getcmdline() [MIPS] RTLX: Sprinkle device model code into code to make udev happier. [MIPS] VPE: Sprinkle device model code into code to make udev happier.
-rw-r--r--arch/mips/Kconfig2
-rw-r--r--arch/mips/kernel/asm-offsets.c1
-rw-r--r--arch/mips/kernel/mips-mt.c19
-rw-r--r--arch/mips/kernel/rtlx.c23
-rw-r--r--arch/mips/kernel/signal-common.h194
-rw-r--r--arch/mips/kernel/signal.c230
-rw-r--r--arch/mips/kernel/signal32.c341
-rw-r--r--arch/mips/kernel/signal_n32.c34
-rw-r--r--arch/mips/kernel/vpe.c22
-rw-r--r--arch/mips/momentum/jaguar_atx/platform.c2
-rw-r--r--arch/mips/momentum/ocelot_3/platform.c2
-rw-r--r--arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c2
-rw-r--r--include/asm-mips/mips_mt.h3
-rw-r--r--include/asm-mips/sigcontext.h4
-rw-r--r--include/asm-mips/uaccess.h5
15 files changed, 434 insertions, 450 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 1bc6d249be44..5fe195a41a80 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -757,6 +757,7 @@ config TOSHIBA_JMR3927
757 select SWAP_IO_SPACE 757 select SWAP_IO_SPACE
758 select SYS_HAS_CPU_TX39XX 758 select SYS_HAS_CPU_TX39XX
759 select SYS_SUPPORTS_32BIT_KERNEL 759 select SYS_SUPPORTS_32BIT_KERNEL
760 select SYS_SUPPORTS_LITTLE_ENDIAN
760 select SYS_SUPPORTS_BIG_ENDIAN 761 select SYS_SUPPORTS_BIG_ENDIAN
761 select TOSHIBA_BOARDS 762 select TOSHIBA_BOARDS
762 763
@@ -771,6 +772,7 @@ config TOSHIBA_RBTX4927
771 select SYS_HAS_CPU_TX49XX 772 select SYS_HAS_CPU_TX49XX
772 select SYS_SUPPORTS_32BIT_KERNEL 773 select SYS_SUPPORTS_32BIT_KERNEL
773 select SYS_SUPPORTS_64BIT_KERNEL 774 select SYS_SUPPORTS_64BIT_KERNEL
775 select SYS_SUPPORTS_LITTLE_ENDIAN
774 select SYS_SUPPORTS_BIG_ENDIAN 776 select SYS_SUPPORTS_BIG_ENDIAN
775 select TOSHIBA_BOARDS 777 select TOSHIBA_BOARDS
776 select GENERIC_HARDIRQS_NO__DO_IRQ 778 select GENERIC_HARDIRQS_NO__DO_IRQ
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c
index ea7df4b8da33..c0b089d47181 100644
--- a/arch/mips/kernel/asm-offsets.c
+++ b/arch/mips/kernel/asm-offsets.c
@@ -249,7 +249,6 @@ void output_sc_defines(void)
249 offset("#define SC_MDHI ", struct sigcontext, sc_mdhi); 249 offset("#define SC_MDHI ", struct sigcontext, sc_mdhi);
250 offset("#define SC_MDLO ", struct sigcontext, sc_mdlo); 250 offset("#define SC_MDLO ", struct sigcontext, sc_mdlo);
251 offset("#define SC_PC ", struct sigcontext, sc_pc); 251 offset("#define SC_PC ", struct sigcontext, sc_pc);
252 offset("#define SC_STATUS ", struct sigcontext, sc_status);
253 offset("#define SC_FPC_CSR ", struct sigcontext, sc_fpc_csr); 252 offset("#define SC_FPC_CSR ", struct sigcontext, sc_fpc_csr);
254 offset("#define SC_FPC_EIR ", struct sigcontext, sc_fpc_eir); 253 offset("#define SC_FPC_EIR ", struct sigcontext, sc_fpc_eir);
255 offset("#define SC_HI1 ", struct sigcontext, sc_hi1); 254 offset("#define SC_HI1 ", struct sigcontext, sc_hi1);
diff --git a/arch/mips/kernel/mips-mt.c b/arch/mips/kernel/mips-mt.c
index a32f6797353a..ba01800b6018 100644
--- a/arch/mips/kernel/mips-mt.c
+++ b/arch/mips/kernel/mips-mt.c
@@ -3,9 +3,11 @@
3 * Copyright (C) 2005 Mips Technologies, Inc 3 * Copyright (C) 2005 Mips Technologies, Inc
4 */ 4 */
5 5
6#include <linux/device.h>
6#include <linux/kernel.h> 7#include <linux/kernel.h>
7#include <linux/sched.h> 8#include <linux/sched.h>
8#include <linux/cpumask.h> 9#include <linux/cpumask.h>
10#include <linux/module.h>
9#include <linux/interrupt.h> 11#include <linux/interrupt.h>
10#include <linux/security.h> 12#include <linux/security.h>
11 13
@@ -453,3 +455,20 @@ void mt_cflush_release(void)
453#endif /* CONFIG_MIPS_MT_SMTC */ 455#endif /* CONFIG_MIPS_MT_SMTC */
454 /* FILL IN VSMP and AP/SP VERSIONS HERE */ 456 /* FILL IN VSMP and AP/SP VERSIONS HERE */
455} 457}
458
459struct class *mt_class;
460
461static int __init mt_init(void)
462{
463 struct class *mtc;
464
465 mtc = class_create(THIS_MODULE, "mt");
466 if (IS_ERR(mtc))
467 return PTR_ERR(mtc);
468
469 mt_class = mtc;
470
471 return 0;
472}
473
474subsys_initcall(mt_init);
diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c
index 8610f4a925e9..f29e93c6ccfc 100644
--- a/arch/mips/kernel/rtlx.c
+++ b/arch/mips/kernel/rtlx.c
@@ -17,6 +17,7 @@
17 * 17 *
18 */ 18 */
19 19
20#include <linux/device.h>
20#include <linux/kernel.h> 21#include <linux/kernel.h>
21#include <linux/module.h> 22#include <linux/module.h>
22#include <linux/fs.h> 23#include <linux/fs.h>
@@ -34,6 +35,7 @@
34#include <linux/sched.h> 35#include <linux/sched.h>
35#include <linux/wait.h> 36#include <linux/wait.h>
36#include <asm/mipsmtregs.h> 37#include <asm/mipsmtregs.h>
38#include <asm/mips_mt.h>
37#include <asm/cacheflush.h> 39#include <asm/cacheflush.h>
38#include <asm/atomic.h> 40#include <asm/atomic.h>
39#include <asm/cpu.h> 41#include <asm/cpu.h>
@@ -498,7 +500,8 @@ static char register_chrdev_failed[] __initdata =
498 500
499static int rtlx_module_init(void) 501static int rtlx_module_init(void)
500{ 502{
501 int i; 503 struct device *dev;
504 int i, err;
502 505
503 major = register_chrdev(0, module_name, &rtlx_fops); 506 major = register_chrdev(0, module_name, &rtlx_fops);
504 if (major < 0) { 507 if (major < 0) {
@@ -511,6 +514,13 @@ static int rtlx_module_init(void)
511 init_waitqueue_head(&channel_wqs[i].rt_queue); 514 init_waitqueue_head(&channel_wqs[i].rt_queue);
512 init_waitqueue_head(&channel_wqs[i].lx_queue); 515 init_waitqueue_head(&channel_wqs[i].lx_queue);
513 channel_wqs[i].in_open = 0; 516 channel_wqs[i].in_open = 0;
517
518 dev = device_create(mt_class, NULL, MKDEV(major, i),
519 "%s%d", module_name, i);
520 if (IS_ERR(dev)) {
521 err = PTR_ERR(dev);
522 goto out_chrdev;
523 }
514 } 524 }
515 525
516 /* set up notifiers */ 526 /* set up notifiers */
@@ -525,10 +535,21 @@ static int rtlx_module_init(void)
525 setup_irq(rtlx_irq_num, &rtlx_irq); 535 setup_irq(rtlx_irq_num, &rtlx_irq);
526 536
527 return 0; 537 return 0;
538
539out_chrdev:
540 for (i = 0; i < RTLX_CHANNELS; i++)
541 device_destroy(mt_class, MKDEV(major, i));
542
543 return err;
528} 544}
529 545
530static void __exit rtlx_module_exit(void) 546static void __exit rtlx_module_exit(void)
531{ 547{
548 int i;
549
550 for (i = 0; i < RTLX_CHANNELS; i++)
551 device_destroy(mt_class, MKDEV(major, i));
552
532 unregister_chrdev(major, module_name); 553 unregister_chrdev(major, module_name);
533} 554}
534 555
diff --git a/arch/mips/kernel/signal-common.h b/arch/mips/kernel/signal-common.h
index b1f09d54ebe6..9a8abd67ec5c 100644
--- a/arch/mips/kernel/signal-common.h
+++ b/arch/mips/kernel/signal-common.h
@@ -8,169 +8,57 @@
8 * Copyright (C) 1999, 2000 Silicon Graphics, Inc. 8 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
9 */ 9 */
10 10
11#ifndef __SIGNAL_COMMON_H
12#define __SIGNAL_COMMON_H
11 13
12static inline int 14/* #define DEBUG_SIG */
13setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
14{
15 int err = 0;
16 15
17 err |= __put_user(regs->cp0_epc, &sc->sc_pc); 16#ifdef DEBUG_SIG
17# define DEBUGP(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ##args)
18#else
19# define DEBUGP(fmt, args...)
20#endif
18 21
19#define save_gp_reg(i) do { \ 22/*
20 err |= __put_user(regs->regs[i], &sc->sc_regs[i]); \ 23 * Horribly complicated - with the bloody RM9000 workarounds enabled
21} while(0) 24 * the signal trampolines is moving to the end of the structure so we can
22 __put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2); 25 * increase the alignment without breaking software compatibility.
23 save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6); 26 */
24 save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10); 27#if ICACHE_REFILLS_WORKAROUND_WAR == 0
25 save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
26 save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
27 save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
28 save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
29 save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
30 save_gp_reg(31);
31#undef save_gp_reg
32
33 err |= __put_user(regs->hi, &sc->sc_mdhi);
34 err |= __put_user(regs->lo, &sc->sc_mdlo);
35 if (cpu_has_dsp) {
36 err |= __put_user(mfhi1(), &sc->sc_hi1);
37 err |= __put_user(mflo1(), &sc->sc_lo1);
38 err |= __put_user(mfhi2(), &sc->sc_hi2);
39 err |= __put_user(mflo2(), &sc->sc_lo2);
40 err |= __put_user(mfhi3(), &sc->sc_hi3);
41 err |= __put_user(mflo3(), &sc->sc_lo3);
42 err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
43 }
44
45 err |= __put_user(!!used_math(), &sc->sc_used_math);
46
47 if (!used_math())
48 goto out;
49
50 /*
51 * Save FPU state to signal context. Signal handler will "inherit"
52 * current FPU state.
53 */
54 preempt_disable();
55
56 if (!is_fpu_owner()) {
57 own_fpu();
58 restore_fp(current);
59 }
60 err |= save_fp_context(sc);
61
62 preempt_enable();
63
64out:
65 return err;
66}
67
68static inline int
69restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
70{
71 unsigned int used_math;
72 unsigned long treg;
73 int err = 0;
74
75 /* Always make any pending restarted system calls return -EINTR */
76 current_thread_info()->restart_block.fn = do_no_restart_syscall;
77
78 err |= __get_user(regs->cp0_epc, &sc->sc_pc);
79 err |= __get_user(regs->hi, &sc->sc_mdhi);
80 err |= __get_user(regs->lo, &sc->sc_mdlo);
81 if (cpu_has_dsp) {
82 err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
83 err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
84 err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
85 err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
86 err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
87 err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
88 err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
89 }
90
91#define restore_gp_reg(i) do { \
92 err |= __get_user(regs->regs[i], &sc->sc_regs[i]); \
93} while(0)
94 restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
95 restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
96 restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
97 restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
98 restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
99 restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
100 restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
101 restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
102 restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
103 restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
104 restore_gp_reg(31);
105#undef restore_gp_reg
106 28
107 err |= __get_user(used_math, &sc->sc_used_math); 29struct sigframe {
108 conditional_used_math(used_math); 30 u32 sf_ass[4]; /* argument save space for o32 */
31 u32 sf_code[2]; /* signal trampoline */
32 struct sigcontext sf_sc;
33 sigset_t sf_mask;
34};
109 35
110 preempt_disable(); 36#else /* ICACHE_REFILLS_WORKAROUND_WAR */
111 37
112 if (used_math()) { 38struct sigframe {
113 /* restore fpu context if we have used it before */ 39 u32 sf_ass[4]; /* argument save space for o32 */
114 own_fpu(); 40 u32 sf_pad[2];
115 err |= restore_fp_context(sc); 41 struct sigcontext sf_sc; /* hw context */
116 } else { 42 sigset_t sf_mask;
117 /* signal handler may have used FPU. Give it up. */ 43 u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */
118 lose_fpu(); 44};
119 }
120 45
121 preempt_enable(); 46#endif /* !ICACHE_REFILLS_WORKAROUND_WAR */
122 47
123 return err; 48/*
124} 49 * handle hardware context
50 */
51extern int setup_sigcontext(struct pt_regs *, struct sigcontext __user *);
52extern int restore_sigcontext(struct pt_regs *, struct sigcontext __user *);
125 53
126/* 54/*
127 * Determine which stack to use.. 55 * Determine which stack to use..
128 */ 56 */
129static inline void __user * 57extern void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
130get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) 58 size_t frame_size);
131{ 59/*
132 unsigned long sp; 60 * install trampoline code to get back from the sig handler
133 61 */
134 /* Default to using normal stack */ 62extern int install_sigtramp(unsigned int __user *tramp, unsigned int syscall);
135 sp = regs->regs[29];
136
137 /*
138 * FPU emulator may have it's own trampoline active just
139 * above the user stack, 16-bytes before the next lowest
140 * 16 byte boundary. Try to avoid trashing it.
141 */
142 sp -= 32;
143
144 /* This is the X/Open sanctioned signal stack switching. */
145 if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
146 sp = current->sas_ss_sp + current->sas_ss_size;
147
148 return (void __user *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? ~(cpu_icache_line_size()-1) : ALMASK));
149}
150
151static inline int install_sigtramp(unsigned int __user *tramp,
152 unsigned int syscall)
153{
154 int err;
155
156 /*
157 * Set up the return code ...
158 *
159 * li v0, __NR__foo_sigreturn
160 * syscall
161 */
162
163 err = __put_user(0x24020000 + syscall, tramp + 0);
164 err |= __put_user(0x0000000c , tramp + 1);
165 if (ICACHE_REFILLS_WORKAROUND_WAR) {
166 err |= __put_user(0, tramp + 2);
167 err |= __put_user(0, tramp + 3);
168 err |= __put_user(0, tramp + 4);
169 err |= __put_user(0, tramp + 5);
170 err |= __put_user(0, tramp + 6);
171 err |= __put_user(0, tramp + 7);
172 }
173 flush_cache_sigtramp((unsigned long) tramp);
174 63
175 return err; 64#endif /* __SIGNAL_COMMON_H */
176}
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index 9a44053cd9f1..54398af2371f 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -34,18 +34,174 @@
34 34
35#include "signal-common.h" 35#include "signal-common.h"
36 36
37#define DEBUG_SIG 0
38
39#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 37#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
40 38
39#if ICACHE_REFILLS_WORKAROUND_WAR == 0
40
41struct rt_sigframe {
42 u32 rs_ass[4]; /* argument save space for o32 */
43 u32 rs_code[2]; /* signal trampoline */
44 struct siginfo rs_info;
45 struct ucontext rs_uc;
46};
47
48#else
49
50struct rt_sigframe {
51 u32 rs_ass[4]; /* argument save space for o32 */
52 u32 rs_pad[2];
53 struct siginfo rs_info;
54 struct ucontext rs_uc;
55 u32 rs_code[8] ____cacheline_aligned; /* signal trampoline */
56};
57
58#endif
59
60/*
61 * Helper routines
62 */
63int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
64{
65 int err = 0;
66 int i;
67
68 err |= __put_user(regs->cp0_epc, &sc->sc_pc);
69
70 err |= __put_user(0, &sc->sc_regs[0]);
71 for (i = 1; i < 32; i++)
72 err |= __put_user(regs->regs[i], &sc->sc_regs[i]);
73
74 err |= __put_user(regs->hi, &sc->sc_mdhi);
75 err |= __put_user(regs->lo, &sc->sc_mdlo);
76 if (cpu_has_dsp) {
77 err |= __put_user(mfhi1(), &sc->sc_hi1);
78 err |= __put_user(mflo1(), &sc->sc_lo1);
79 err |= __put_user(mfhi2(), &sc->sc_hi2);
80 err |= __put_user(mflo2(), &sc->sc_lo2);
81 err |= __put_user(mfhi3(), &sc->sc_hi3);
82 err |= __put_user(mflo3(), &sc->sc_lo3);
83 err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
84 }
85
86 err |= __put_user(!!used_math(), &sc->sc_used_math);
87
88 if (used_math()) {
89 /*
90 * Save FPU state to signal context. Signal handler
91 * will "inherit" current FPU state.
92 */
93 preempt_disable();
94
95 if (!is_fpu_owner()) {
96 own_fpu();
97 restore_fp(current);
98 }
99 err |= save_fp_context(sc);
100
101 preempt_enable();
102 }
103 return err;
104}
105
106int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
107{
108 unsigned int used_math;
109 unsigned long treg;
110 int err = 0;
111 int i;
112
113 /* Always make any pending restarted system calls return -EINTR */
114 current_thread_info()->restart_block.fn = do_no_restart_syscall;
115
116 err |= __get_user(regs->cp0_epc, &sc->sc_pc);
117 err |= __get_user(regs->hi, &sc->sc_mdhi);
118 err |= __get_user(regs->lo, &sc->sc_mdlo);
119 if (cpu_has_dsp) {
120 err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
121 err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
122 err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
123 err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
124 err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
125 err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
126 err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
127 }
128
129 for (i = 1; i < 32; i++)
130 err |= __get_user(regs->regs[i], &sc->sc_regs[i]);
131
132 err |= __get_user(used_math, &sc->sc_used_math);
133 conditional_used_math(used_math);
134
135 preempt_disable();
136
137 if (used_math()) {
138 /* restore fpu context if we have used it before */
139 own_fpu();
140 err |= restore_fp_context(sc);
141 } else {
142 /* signal handler may have used FPU. Give it up. */
143 lose_fpu();
144 }
145
146 preempt_enable();
147
148 return err;
149}
150
151void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
152 size_t frame_size)
153{
154 unsigned long sp;
155
156 /* Default to using normal stack */
157 sp = regs->regs[29];
158
159 /*
160 * FPU emulator may have it's own trampoline active just
161 * above the user stack, 16-bytes before the next lowest
162 * 16 byte boundary. Try to avoid trashing it.
163 */
164 sp -= 32;
165
166 /* This is the X/Open sanctioned signal stack switching. */
167 if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
168 sp = current->sas_ss_sp + current->sas_ss_size;
169
170 return (void __user *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? ~(cpu_icache_line_size()-1) : ALMASK));
171}
172
173int install_sigtramp(unsigned int __user *tramp, unsigned int syscall)
174{
175 int err;
176
177 /*
178 * Set up the return code ...
179 *
180 * li v0, __NR__foo_sigreturn
181 * syscall
182 */
183
184 err = __put_user(0x24020000 + syscall, tramp + 0);
185 err |= __put_user(0x0000000c , tramp + 1);
186 if (ICACHE_REFILLS_WORKAROUND_WAR) {
187 err |= __put_user(0, tramp + 2);
188 err |= __put_user(0, tramp + 3);
189 err |= __put_user(0, tramp + 4);
190 err |= __put_user(0, tramp + 5);
191 err |= __put_user(0, tramp + 6);
192 err |= __put_user(0, tramp + 7);
193 }
194 flush_cache_sigtramp((unsigned long) tramp);
195
196 return err;
197}
198
41/* 199/*
42 * Atomically swap in the new signal mask, and wait for a signal. 200 * Atomically swap in the new signal mask, and wait for a signal.
43 */ 201 */
44 202
45#ifdef CONFIG_TRAD_SIGNALS 203#ifdef CONFIG_TRAD_SIGNALS
46save_static_function(sys_sigsuspend); 204asmlinkage int sys_sigsuspend(nabi_no_regargs struct pt_regs regs)
47__attribute_used__ noinline static int
48_sys_sigsuspend(nabi_no_regargs struct pt_regs regs)
49{ 205{
50 sigset_t newset; 206 sigset_t newset;
51 sigset_t __user *uset; 207 sigset_t __user *uset;
@@ -68,9 +224,7 @@ _sys_sigsuspend(nabi_no_regargs struct pt_regs regs)
68} 224}
69#endif 225#endif
70 226
71save_static_function(sys_rt_sigsuspend); 227asmlinkage int sys_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
72__attribute_used__ noinline static int
73_sys_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
74{ 228{
75 sigset_t newset; 229 sigset_t newset;
76 sigset_t __user *unewset; 230 sigset_t __user *unewset;
@@ -148,45 +302,8 @@ asmlinkage int sys_sigaltstack(nabi_no_regargs struct pt_regs regs)
148 return do_sigaltstack(uss, uoss, usp); 302 return do_sigaltstack(uss, uoss, usp);
149} 303}
150 304
151/*
152 * Horribly complicated - with the bloody RM9000 workarounds enabled
153 * the signal trampolines is moving to the end of the structure so we can
154 * increase the alignment without breaking software compatibility.
155 */
156#ifdef CONFIG_TRAD_SIGNALS 305#ifdef CONFIG_TRAD_SIGNALS
157struct sigframe { 306asmlinkage void sys_sigreturn(nabi_no_regargs struct pt_regs regs)
158 u32 sf_ass[4]; /* argument save space for o32 */
159#if ICACHE_REFILLS_WORKAROUND_WAR
160 u32 sf_pad[2];
161#else
162 u32 sf_code[2]; /* signal trampoline */
163#endif
164 struct sigcontext sf_sc;
165 sigset_t sf_mask;
166#if ICACHE_REFILLS_WORKAROUND_WAR
167 u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */
168#endif
169};
170#endif
171
172struct rt_sigframe {
173 u32 rs_ass[4]; /* argument save space for o32 */
174#if ICACHE_REFILLS_WORKAROUND_WAR
175 u32 rs_pad[2];
176#else
177 u32 rs_code[2]; /* signal trampoline */
178#endif
179 struct siginfo rs_info;
180 struct ucontext rs_uc;
181#if ICACHE_REFILLS_WORKAROUND_WAR
182 u32 rs_code[8] ____cacheline_aligned; /* signal trampoline */
183#endif
184};
185
186#ifdef CONFIG_TRAD_SIGNALS
187save_static_function(sys_sigreturn);
188__attribute_used__ noinline static void
189_sys_sigreturn(nabi_no_regargs struct pt_regs regs)
190{ 307{
191 struct sigframe __user *frame; 308 struct sigframe __user *frame;
192 sigset_t blocked; 309 sigset_t blocked;
@@ -221,9 +338,7 @@ badframe:
221} 338}
222#endif /* CONFIG_TRAD_SIGNALS */ 339#endif /* CONFIG_TRAD_SIGNALS */
223 340
224save_static_function(sys_rt_sigreturn); 341asmlinkage void sys_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
225__attribute_used__ noinline static void
226_sys_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
227{ 342{
228 struct rt_sigframe __user *frame; 343 struct rt_sigframe __user *frame;
229 sigset_t set; 344 sigset_t set;
@@ -275,7 +390,7 @@ int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
275 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) 390 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
276 goto give_sigsegv; 391 goto give_sigsegv;
277 392
278 install_sigtramp(frame->sf_code, __NR_sigreturn); 393 err |= install_sigtramp(frame->sf_code, __NR_sigreturn);
279 394
280 err |= setup_sigcontext(regs, &frame->sf_sc); 395 err |= setup_sigcontext(regs, &frame->sf_sc);
281 err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set)); 396 err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));
@@ -299,11 +414,9 @@ int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
299 regs->regs[31] = (unsigned long) frame->sf_code; 414 regs->regs[31] = (unsigned long) frame->sf_code;
300 regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; 415 regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
301 416
302#if DEBUG_SIG 417 DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
303 printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n",
304 current->comm, current->pid, 418 current->comm, current->pid,
305 frame, regs->cp0_epc, frame->regs[31]); 419 frame, regs->cp0_epc, regs->regs[31]);
306#endif
307 return 0; 420 return 0;
308 421
309give_sigsegv: 422give_sigsegv:
@@ -322,7 +435,7 @@ int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
322 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) 435 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
323 goto give_sigsegv; 436 goto give_sigsegv;
324 437
325 install_sigtramp(frame->rs_code, __NR_rt_sigreturn); 438 err |= install_sigtramp(frame->rs_code, __NR_rt_sigreturn);
326 439
327 /* Create siginfo. */ 440 /* Create siginfo. */
328 err |= copy_siginfo_to_user(&frame->rs_info, info); 441 err |= copy_siginfo_to_user(&frame->rs_info, info);
@@ -359,11 +472,10 @@ int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
359 regs->regs[31] = (unsigned long) frame->rs_code; 472 regs->regs[31] = (unsigned long) frame->rs_code;
360 regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; 473 regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
361 474
362#if DEBUG_SIG 475 DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
363 printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n",
364 current->comm, current->pid, 476 current->comm, current->pid,
365 frame, regs->cp0_epc, regs->regs[31]); 477 frame, regs->cp0_epc, regs->regs[31]);
366#endif 478
367 return 0; 479 return 0;
368 480
369give_sigsegv: 481give_sigsegv:
@@ -371,7 +483,7 @@ give_sigsegv:
371 return -EFAULT; 483 return -EFAULT;
372} 484}
373 485
374static inline int handle_signal(unsigned long sig, siginfo_t *info, 486static int handle_signal(unsigned long sig, siginfo_t *info,
375 struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs) 487 struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs)
376{ 488{
377 int ret; 489 int ret;
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
index c86a5ddff050..183fc7e55f34 100644
--- a/arch/mips/kernel/signal32.c
+++ b/arch/mips/kernel/signal32.c
@@ -33,6 +33,8 @@
33#include <asm/fpu.h> 33#include <asm/fpu.h>
34#include <asm/war.h> 34#include <asm/war.h>
35 35
36#include "signal-common.h"
37
36#define SI_PAD_SIZE32 ((SI_MAX_SIZE/sizeof(int)) - 3) 38#define SI_PAD_SIZE32 ((SI_MAX_SIZE/sizeof(int)) - 3)
37 39
38typedef struct compat_siginfo { 40typedef struct compat_siginfo {
@@ -102,8 +104,6 @@ typedef struct compat_siginfo {
102#define __NR_O32_rt_sigreturn 4193 104#define __NR_O32_rt_sigreturn 4193
103#define __NR_O32_restart_syscall 4253 105#define __NR_O32_restart_syscall 4253
104 106
105#define DEBUG_SIG 0
106
107#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 107#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
108 108
109/* 32-bit compatibility types */ 109/* 32-bit compatibility types */
@@ -139,6 +139,123 @@ struct ucontext32 {
139 sigset_t32 uc_sigmask; /* mask last for extensibility */ 139 sigset_t32 uc_sigmask; /* mask last for extensibility */
140}; 140};
141 141
142#if ICACHE_REFILLS_WORKAROUND_WAR == 0
143
144struct rt_sigframe32 {
145 u32 rs_ass[4]; /* argument save space for o32 */
146 u32 rs_code[2]; /* signal trampoline */
147 compat_siginfo_t rs_info;
148 struct ucontext32 rs_uc;
149};
150
151#else /* ICACHE_REFILLS_WORKAROUND_WAR */
152
153struct rt_sigframe32 {
154 u32 rs_ass[4]; /* argument save space for o32 */
155 u32 rs_pad[2];
156 compat_siginfo_t rs_info;
157 struct ucontext32 rs_uc;
158 u32 rs_code[8] __attribute__((aligned(32))); /* signal trampoline */
159};
160
161#endif /* !ICACHE_REFILLS_WORKAROUND_WAR */
162
163/*
164 * sigcontext handlers
165 */
166static int setup_sigcontext32(struct pt_regs *regs,
167 struct sigcontext32 __user *sc)
168{
169 int err = 0;
170 int i;
171
172 err |= __put_user(regs->cp0_epc, &sc->sc_pc);
173
174 err |= __put_user(0, &sc->sc_regs[0]);
175 for (i = 1; i < 32; i++)
176 err |= __put_user(regs->regs[i], &sc->sc_regs[i]);
177
178 err |= __put_user(regs->hi, &sc->sc_mdhi);
179 err |= __put_user(regs->lo, &sc->sc_mdlo);
180 if (cpu_has_dsp) {
181 err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
182 err |= __put_user(mfhi1(), &sc->sc_hi1);
183 err |= __put_user(mflo1(), &sc->sc_lo1);
184 err |= __put_user(mfhi2(), &sc->sc_hi2);
185 err |= __put_user(mflo2(), &sc->sc_lo2);
186 err |= __put_user(mfhi3(), &sc->sc_hi3);
187 err |= __put_user(mflo3(), &sc->sc_lo3);
188 }
189
190 err |= __put_user(!!used_math(), &sc->sc_used_math);
191
192 if (used_math()) {
193 /*
194 * Save FPU state to signal context. Signal handler
195 * will "inherit" current FPU state.
196 */
197 preempt_disable();
198
199 if (!is_fpu_owner()) {
200 own_fpu();
201 restore_fp(current);
202 }
203 err |= save_fp_context32(sc);
204
205 preempt_enable();
206 }
207 return err;
208}
209
210static int restore_sigcontext32(struct pt_regs *regs,
211 struct sigcontext32 __user *sc)
212{
213 u32 used_math;
214 int err = 0;
215 s32 treg;
216 int i;
217
218 /* Always make any pending restarted system calls return -EINTR */
219 current_thread_info()->restart_block.fn = do_no_restart_syscall;
220
221 err |= __get_user(regs->cp0_epc, &sc->sc_pc);
222 err |= __get_user(regs->hi, &sc->sc_mdhi);
223 err |= __get_user(regs->lo, &sc->sc_mdlo);
224 if (cpu_has_dsp) {
225 err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
226 err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
227 err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
228 err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
229 err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
230 err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
231 err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
232 }
233
234 for (i = 1; i < 32; i++)
235 err |= __get_user(regs->regs[i], &sc->sc_regs[i]);
236
237 err |= __get_user(used_math, &sc->sc_used_math);
238 conditional_used_math(used_math);
239
240 preempt_disable();
241
242 if (used_math()) {
243 /* restore fpu context if we have used it before */
244 own_fpu();
245 err |= restore_fp_context32(sc);
246 } else {
247 /* signal handler may have used FPU. Give it up. */
248 lose_fpu();
249 }
250
251 preempt_enable();
252
253 return err;
254}
255
256/*
257 *
258 */
142extern void __put_sigset_unknown_nsig(void); 259extern void __put_sigset_unknown_nsig(void);
143extern void __get_sigset_unknown_nsig(void); 260extern void __get_sigset_unknown_nsig(void);
144 261
@@ -191,9 +308,7 @@ static inline int get_sigset(sigset_t *kbuf, const compat_sigset_t __user *ubuf)
191 * Atomically swap in the new signal mask, and wait for a signal. 308 * Atomically swap in the new signal mask, and wait for a signal.
192 */ 309 */
193 310
194save_static_function(sys32_sigsuspend); 311asmlinkage int sys32_sigsuspend(nabi_no_regargs struct pt_regs regs)
195__attribute_used__ noinline static int
196_sys32_sigsuspend(nabi_no_regargs struct pt_regs regs)
197{ 312{
198 compat_sigset_t __user *uset; 313 compat_sigset_t __user *uset;
199 sigset_t newset; 314 sigset_t newset;
@@ -215,9 +330,7 @@ _sys32_sigsuspend(nabi_no_regargs struct pt_regs regs)
215 return -ERESTARTNOHAND; 330 return -ERESTARTNOHAND;
216} 331}
217 332
218save_static_function(sys32_rt_sigsuspend); 333asmlinkage int sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
219__attribute_used__ noinline static int
220_sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
221{ 334{
222 compat_sigset_t __user *uset; 335 compat_sigset_t __user *uset;
223 sigset_t newset; 336 sigset_t newset;
@@ -326,91 +439,6 @@ asmlinkage int sys32_sigaltstack(nabi_no_regargs struct pt_regs regs)
326 return ret; 439 return ret;
327} 440}
328 441
329static int restore_sigcontext32(struct pt_regs *regs, struct sigcontext32 __user *sc)
330{
331 u32 used_math;
332 int err = 0;
333 s32 treg;
334
335 /* Always make any pending restarted system calls return -EINTR */
336 current_thread_info()->restart_block.fn = do_no_restart_syscall;
337
338 err |= __get_user(regs->cp0_epc, &sc->sc_pc);
339 err |= __get_user(regs->hi, &sc->sc_mdhi);
340 err |= __get_user(regs->lo, &sc->sc_mdlo);
341 if (cpu_has_dsp) {
342 err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
343 err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
344 err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
345 err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
346 err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
347 err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
348 err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
349 }
350
351#define restore_gp_reg(i) do { \
352 err |= __get_user(regs->regs[i], &sc->sc_regs[i]); \
353} while(0)
354 restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
355 restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
356 restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
357 restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
358 restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
359 restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
360 restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
361 restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
362 restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
363 restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
364 restore_gp_reg(31);
365#undef restore_gp_reg
366
367 err |= __get_user(used_math, &sc->sc_used_math);
368 conditional_used_math(used_math);
369
370 preempt_disable();
371
372 if (used_math()) {
373 /* restore fpu context if we have used it before */
374 own_fpu();
375 err |= restore_fp_context32(sc);
376 } else {
377 /* signal handler may have used FPU. Give it up. */
378 lose_fpu();
379 }
380
381 preempt_enable();
382
383 return err;
384}
385
386struct sigframe {
387 u32 sf_ass[4]; /* argument save space for o32 */
388#if ICACHE_REFILLS_WORKAROUND_WAR
389 u32 sf_pad[2];
390#else
391 u32 sf_code[2]; /* signal trampoline */
392#endif
393 struct sigcontext32 sf_sc;
394 sigset_t sf_mask;
395#if ICACHE_REFILLS_WORKAROUND_WAR
396 u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */
397#endif
398};
399
400struct rt_sigframe32 {
401 u32 rs_ass[4]; /* argument save space for o32 */
402#if ICACHE_REFILLS_WORKAROUND_WAR
403 u32 rs_pad[2];
404#else
405 u32 rs_code[2]; /* signal trampoline */
406#endif
407 compat_siginfo_t rs_info;
408 struct ucontext32 rs_uc;
409#if ICACHE_REFILLS_WORKAROUND_WAR
410 u32 rs_code[8] __attribute__((aligned(32))); /* signal trampoline */
411#endif
412};
413
414int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from) 442int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
415{ 443{
416 int err; 444 int err;
@@ -463,9 +491,7 @@ int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
463 return err; 491 return err;
464} 492}
465 493
466save_static_function(sys32_sigreturn); 494asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
467__attribute_used__ noinline static void
468_sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
469{ 495{
470 struct sigframe __user *frame; 496 struct sigframe __user *frame;
471 sigset_t blocked; 497 sigset_t blocked;
@@ -499,9 +525,7 @@ badframe:
499 force_sig(SIGSEGV, current); 525 force_sig(SIGSEGV, current);
500} 526}
501 527
502save_static_function(sys32_rt_sigreturn); 528asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
503__attribute_used__ noinline static void
504_sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
505{ 529{
506 struct rt_sigframe32 __user *frame; 530 struct rt_sigframe32 __user *frame;
507 mm_segment_t old_fs; 531 mm_segment_t old_fs;
@@ -554,89 +578,6 @@ badframe:
554 force_sig(SIGSEGV, current); 578 force_sig(SIGSEGV, current);
555} 579}
556 580
557static inline int setup_sigcontext32(struct pt_regs *regs,
558 struct sigcontext32 __user *sc)
559{
560 int err = 0;
561
562 err |= __put_user(regs->cp0_epc, &sc->sc_pc);
563 err |= __put_user(regs->cp0_status, &sc->sc_status);
564
565#define save_gp_reg(i) { \
566 err |= __put_user(regs->regs[i], &sc->sc_regs[i]); \
567} while(0)
568 __put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
569 save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
570 save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
571 save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
572 save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
573 save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
574 save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
575 save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
576 save_gp_reg(31);
577#undef save_gp_reg
578
579 err |= __put_user(regs->hi, &sc->sc_mdhi);
580 err |= __put_user(regs->lo, &sc->sc_mdlo);
581 if (cpu_has_dsp) {
582 err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
583 err |= __put_user(mfhi1(), &sc->sc_hi1);
584 err |= __put_user(mflo1(), &sc->sc_lo1);
585 err |= __put_user(mfhi2(), &sc->sc_hi2);
586 err |= __put_user(mflo2(), &sc->sc_lo2);
587 err |= __put_user(mfhi3(), &sc->sc_hi3);
588 err |= __put_user(mflo3(), &sc->sc_lo3);
589 }
590
591 err |= __put_user(!!used_math(), &sc->sc_used_math);
592
593 if (!used_math())
594 goto out;
595
596 /*
597 * Save FPU state to signal context. Signal handler will "inherit"
598 * current FPU state.
599 */
600 preempt_disable();
601
602 if (!is_fpu_owner()) {
603 own_fpu();
604 restore_fp(current);
605 }
606 err |= save_fp_context32(sc);
607
608 preempt_enable();
609
610out:
611 return err;
612}
613
614/*
615 * Determine which stack to use..
616 */
617static inline void __user *get_sigframe(struct k_sigaction *ka,
618 struct pt_regs *regs,
619 size_t frame_size)
620{
621 unsigned long sp;
622
623 /* Default to using normal stack */
624 sp = regs->regs[29];
625
626 /*
627 * FPU emulator may have it's own trampoline active just
628 * above the user stack, 16-bytes before the next lowest
629 * 16 byte boundary. Try to avoid trashing it.
630 */
631 sp -= 32;
632
633 /* This is the X/Open sanctioned signal stack switching. */
634 if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
635 sp = current->sas_ss_sp + current->sas_ss_size;
636
637 return (void __user *)((sp - frame_size) & ALMASK);
638}
639
640int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs, 581int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
641 int signr, sigset_t *set) 582 int signr, sigset_t *set)
642{ 583{
@@ -647,15 +588,7 @@ int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
647 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) 588 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
648 goto give_sigsegv; 589 goto give_sigsegv;
649 590
650 /* 591 err |= install_sigtramp(frame->sf_code, __NR_O32_sigreturn);
651 * Set up the return code ...
652 *
653 * li v0, __NR_O32_sigreturn
654 * syscall
655 */
656 err |= __put_user(0x24020000 + __NR_O32_sigreturn, frame->sf_code + 0);
657 err |= __put_user(0x0000000c , frame->sf_code + 1);
658 flush_cache_sigtramp((unsigned long) frame->sf_code);
659 592
660 err |= setup_sigcontext32(regs, &frame->sf_sc); 593 err |= setup_sigcontext32(regs, &frame->sf_sc);
661 err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set)); 594 err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));
@@ -679,11 +612,10 @@ int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
679 regs->regs[31] = (unsigned long) frame->sf_code; 612 regs->regs[31] = (unsigned long) frame->sf_code;
680 regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; 613 regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
681 614
682#if DEBUG_SIG 615 DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
683 printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n",
684 current->comm, current->pid, 616 current->comm, current->pid,
685 frame, regs->cp0_epc, frame->sf_code); 617 frame, regs->cp0_epc, regs->regs[31]);
686#endif 618
687 return 0; 619 return 0;
688 620
689give_sigsegv: 621give_sigsegv:
@@ -702,17 +634,7 @@ int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
702 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) 634 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
703 goto give_sigsegv; 635 goto give_sigsegv;
704 636
705 /* Set up to return from userspace. If provided, use a stub already 637 err |= install_sigtramp(frame->rs_code, __NR_O32_rt_sigreturn);
706 in userspace. */
707 /*
708 * Set up the return code ...
709 *
710 * li v0, __NR_O32_rt_sigreturn
711 * syscall
712 */
713 err |= __put_user(0x24020000 + __NR_O32_rt_sigreturn, frame->rs_code + 0);
714 err |= __put_user(0x0000000c , frame->rs_code + 1);
715 flush_cache_sigtramp((unsigned long) frame->rs_code);
716 638
717 /* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */ 639 /* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
718 err |= copy_siginfo_to_user32(&frame->rs_info, info); 640 err |= copy_siginfo_to_user32(&frame->rs_info, info);
@@ -750,11 +672,10 @@ int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
750 regs->regs[31] = (unsigned long) frame->rs_code; 672 regs->regs[31] = (unsigned long) frame->rs_code;
751 regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; 673 regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
752 674
753#if DEBUG_SIG 675 DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
754 printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n",
755 current->comm, current->pid, 676 current->comm, current->pid,
756 frame, regs->cp0_epc, frame->rs_code); 677 frame, regs->cp0_epc, regs->regs[31]);
757#endif 678
758 return 0; 679 return 0;
759 680
760give_sigsegv: 681give_sigsegv:
diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c
index b28646b3ceae..57456e6a0c62 100644
--- a/arch/mips/kernel/signal_n32.c
+++ b/arch/mips/kernel/signal_n32.c
@@ -47,8 +47,6 @@
47#define __NR_N32_rt_sigreturn 6211 47#define __NR_N32_rt_sigreturn 6211
48#define __NR_N32_restart_syscall 6214 48#define __NR_N32_restart_syscall 6214
49 49
50#define DEBUG_SIG 0
51
52#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 50#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
53 51
54/* IRIX compatible stack_t */ 52/* IRIX compatible stack_t */
@@ -66,25 +64,30 @@ struct ucontextn32 {
66 sigset_t uc_sigmask; /* mask last for extensibility */ 64 sigset_t uc_sigmask; /* mask last for extensibility */
67}; 65};
68 66
67#if ICACHE_REFILLS_WORKAROUND_WAR == 0
68
69struct rt_sigframe_n32 { 69struct rt_sigframe_n32 {
70 u32 rs_ass[4]; /* argument save space for o32 */ 70 u32 rs_ass[4]; /* argument save space for o32 */
71#if ICACHE_REFILLS_WORKAROUND_WAR
72 u32 rs_pad[2];
73#else
74 u32 rs_code[2]; /* signal trampoline */ 71 u32 rs_code[2]; /* signal trampoline */
75#endif
76 struct siginfo rs_info; 72 struct siginfo rs_info;
77 struct ucontextn32 rs_uc; 73 struct ucontextn32 rs_uc;
78#if ICACHE_REFILLS_WORKAROUND_WAR 74};
75
76#else /* ICACHE_REFILLS_WORKAROUND_WAR */
77
78struct rt_sigframe_n32 {
79 u32 rs_ass[4]; /* argument save space for o32 */
80 u32 rs_pad[2];
81 struct siginfo rs_info;
82 struct ucontextn32 rs_uc;
79 u32 rs_code[8] ____cacheline_aligned; /* signal trampoline */ 83 u32 rs_code[8] ____cacheline_aligned; /* signal trampoline */
80#endif
81}; 84};
82 85
86#endif /* !ICACHE_REFILLS_WORKAROUND_WAR */
87
83extern void sigset_from_compat (sigset_t *set, compat_sigset_t *compat); 88extern void sigset_from_compat (sigset_t *set, compat_sigset_t *compat);
84 89
85save_static_function(sysn32_rt_sigsuspend); 90asmlinkage int sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
86__attribute_used__ noinline static int
87_sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
88{ 91{
89 compat_sigset_t __user *unewset; 92 compat_sigset_t __user *unewset;
90 compat_sigset_t uset; 93 compat_sigset_t uset;
@@ -114,9 +117,7 @@ _sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
114 return -ERESTARTNOHAND; 117 return -ERESTARTNOHAND;
115} 118}
116 119
117save_static_function(sysn32_rt_sigreturn); 120asmlinkage void sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
118__attribute_used__ noinline static void
119_sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
120{ 121{
121 struct rt_sigframe_n32 __user *frame; 122 struct rt_sigframe_n32 __user *frame;
122 sigset_t set; 123 sigset_t set;
@@ -214,11 +215,10 @@ int setup_rt_frame_n32(struct k_sigaction * ka,
214 regs->regs[31] = (unsigned long) frame->rs_code; 215 regs->regs[31] = (unsigned long) frame->rs_code;
215 regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; 216 regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
216 217
217#if DEBUG_SIG 218 DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
218 printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n",
219 current->comm, current->pid, 219 current->comm, current->pid,
220 frame, regs->cp0_epc, regs->regs[31]); 220 frame, regs->cp0_epc, regs->regs[31]);
221#endif 221
222 return 0; 222 return 0;
223 223
224give_sigsegv: 224give_sigsegv:
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c
index 459624969c99..4e832da48c69 100644
--- a/arch/mips/kernel/vpe.c
+++ b/arch/mips/kernel/vpe.c
@@ -29,6 +29,7 @@
29 */ 29 */
30 30
31#include <linux/kernel.h> 31#include <linux/kernel.h>
32#include <linux/device.h>
32#include <linux/module.h> 33#include <linux/module.h>
33#include <linux/fs.h> 34#include <linux/fs.h>
34#include <linux/init.h> 35#include <linux/init.h>
@@ -48,6 +49,7 @@
48#include <asm/cacheflush.h> 49#include <asm/cacheflush.h>
49#include <asm/atomic.h> 50#include <asm/atomic.h>
50#include <asm/cpu.h> 51#include <asm/cpu.h>
52#include <asm/mips_mt.h>
51#include <asm/processor.h> 53#include <asm/processor.h>
52#include <asm/system.h> 54#include <asm/system.h>
53#include <asm/vpe.h> 55#include <asm/vpe.h>
@@ -64,6 +66,7 @@ typedef void *vpe_handle;
64 66
65static char module_name[] = "vpe"; 67static char module_name[] = "vpe";
66static int major; 68static int major;
69static const int minor = 1; /* fixed for now */
67 70
68#ifdef CONFIG_MIPS_APSP_KSPD 71#ifdef CONFIG_MIPS_APSP_KSPD
69 static struct kspd_notifications kspd_events; 72 static struct kspd_notifications kspd_events;
@@ -1365,12 +1368,15 @@ static void kspd_sp_exit( int sp_id)
1365} 1368}
1366#endif 1369#endif
1367 1370
1371static struct device *vpe_dev;
1372
1368static int __init vpe_module_init(void) 1373static int __init vpe_module_init(void)
1369{ 1374{
1370 struct vpe *v = NULL; 1375 struct vpe *v = NULL;
1376 struct device *dev;
1371 struct tc *t; 1377 struct tc *t;
1372 unsigned long val; 1378 unsigned long val;
1373 int i; 1379 int i, err;
1374 1380
1375 if (!cpu_has_mipsmt) { 1381 if (!cpu_has_mipsmt) {
1376 printk("VPE loader: not a MIPS MT capable processor\n"); 1382 printk("VPE loader: not a MIPS MT capable processor\n");
@@ -1383,6 +1389,14 @@ static int __init vpe_module_init(void)
1383 return major; 1389 return major;
1384 } 1390 }
1385 1391
1392 dev = device_create(mt_class, NULL, MKDEV(major, minor),
1393 "tc%d", minor);
1394 if (IS_ERR(dev)) {
1395 err = PTR_ERR(dev);
1396 goto out_chrdev;
1397 }
1398 vpe_dev = dev;
1399
1386 dmt(); 1400 dmt();
1387 dvpe(); 1401 dvpe();
1388 1402
@@ -1478,6 +1492,11 @@ static int __init vpe_module_init(void)
1478 kspd_events.kspd_sp_exit = kspd_sp_exit; 1492 kspd_events.kspd_sp_exit = kspd_sp_exit;
1479#endif 1493#endif
1480 return 0; 1494 return 0;
1495
1496out_chrdev:
1497 unregister_chrdev(major, module_name);
1498
1499 return err;
1481} 1500}
1482 1501
1483static void __exit vpe_module_exit(void) 1502static void __exit vpe_module_exit(void)
@@ -1490,6 +1509,7 @@ static void __exit vpe_module_exit(void)
1490 } 1509 }
1491 } 1510 }
1492 1511
1512 device_destroy(mt_class, MKDEV(major, minor));
1493 unregister_chrdev(major, module_name); 1513 unregister_chrdev(major, module_name);
1494} 1514}
1495 1515
diff --git a/arch/mips/momentum/jaguar_atx/platform.c b/arch/mips/momentum/jaguar_atx/platform.c
index 035ea5137c71..81037709ba0d 100644
--- a/arch/mips/momentum/jaguar_atx/platform.c
+++ b/arch/mips/momentum/jaguar_atx/platform.c
@@ -129,7 +129,7 @@ static struct mv643xx_eth_platform_data eth2_pd = {
129 129
130static struct platform_device eth2_device = { 130static struct platform_device eth2_device = {
131 .name = MV643XX_ETH_NAME, 131 .name = MV643XX_ETH_NAME,
132 .id = 1, 132 .id = 2,
133 .num_resources = ARRAY_SIZE(mv64x60_eth2_resources), 133 .num_resources = ARRAY_SIZE(mv64x60_eth2_resources),
134 .resource = mv64x60_eth2_resources, 134 .resource = mv64x60_eth2_resources,
135 .dev = { 135 .dev = {
diff --git a/arch/mips/momentum/ocelot_3/platform.c b/arch/mips/momentum/ocelot_3/platform.c
index eefe5841fbb2..57cfe5c6e4a8 100644
--- a/arch/mips/momentum/ocelot_3/platform.c
+++ b/arch/mips/momentum/ocelot_3/platform.c
@@ -129,7 +129,7 @@ static struct mv643xx_eth_platform_data eth2_pd = {
129 129
130static struct platform_device eth2_device = { 130static struct platform_device eth2_device = {
131 .name = MV643XX_ETH_NAME, 131 .name = MV643XX_ETH_NAME,
132 .id = 1, 132 .id = 2,
133 .num_resources = ARRAY_SIZE(mv64x60_eth2_resources), 133 .num_resources = ARRAY_SIZE(mv64x60_eth2_resources),
134 .resource = mv64x60_eth2_resources, 134 .resource = mv64x60_eth2_resources,
135 .dev = { 135 .dev = {
diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
index 735cb8778f4c..7316a78fdd68 100644
--- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
+++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
@@ -137,6 +137,8 @@ int tx4927_using_backplane = 0;
137extern void gt64120_time_init(void); 137extern void gt64120_time_init(void);
138extern void toshiba_rbtx4927_irq_setup(void); 138extern void toshiba_rbtx4927_irq_setup(void);
139 139
140char *prom_getcmdline(void);
141
140#ifdef CONFIG_PCI 142#ifdef CONFIG_PCI
141#define CONFIG_TX4927BUG_WORKAROUND 143#define CONFIG_TX4927BUG_WORKAROUND
142#undef TX4927_SUPPORT_COMMAND_IO 144#undef TX4927_SUPPORT_COMMAND_IO
diff --git a/include/asm-mips/mips_mt.h b/include/asm-mips/mips_mt.h
index c31a312b9783..fdfff0b8ce42 100644
--- a/include/asm-mips/mips_mt.h
+++ b/include/asm-mips/mips_mt.h
@@ -12,4 +12,7 @@ extern unsigned long mt_fpemul_threshold;
12extern void mips_mt_regdump(unsigned long previous_mvpcontrol_value); 12extern void mips_mt_regdump(unsigned long previous_mvpcontrol_value);
13extern void mips_mt_set_cpuoptions(void); 13extern void mips_mt_set_cpuoptions(void);
14 14
15struct class;
16extern struct class *mt_class;
17
15#endif /* __ASM_MIPS_MT_H */ 18#endif /* __ASM_MIPS_MT_H */
diff --git a/include/asm-mips/sigcontext.h b/include/asm-mips/sigcontext.h
index cefa657dd04a..3c175a7e4345 100644
--- a/include/asm-mips/sigcontext.h
+++ b/include/asm-mips/sigcontext.h
@@ -19,7 +19,7 @@
19 */ 19 */
20struct sigcontext { 20struct sigcontext {
21 unsigned int sc_regmask; /* Unused */ 21 unsigned int sc_regmask; /* Unused */
22 unsigned int sc_status; 22 unsigned int sc_status; /* Unused */
23 unsigned long long sc_pc; 23 unsigned long long sc_pc;
24 unsigned long long sc_regs[32]; 24 unsigned long long sc_regs[32];
25 unsigned long long sc_fpregs[32]; 25 unsigned long long sc_fpregs[32];
@@ -76,7 +76,7 @@ struct sigcontext {
76 76
77struct sigcontext32 { 77struct sigcontext32 {
78 __u32 sc_regmask; /* Unused */ 78 __u32 sc_regmask; /* Unused */
79 __u32 sc_status; 79 __u32 sc_status; /* Unused */
80 __u64 sc_pc; 80 __u64 sc_pc;
81 __u64 sc_regs[32]; 81 __u64 sc_regs[32];
82 __u64 sc_fpregs[32]; 82 __u64 sc_fpregs[32];
diff --git a/include/asm-mips/uaccess.h b/include/asm-mips/uaccess.h
index c12ebc53ef31..825fcbd9eabd 100644
--- a/include/asm-mips/uaccess.h
+++ b/include/asm-mips/uaccess.h
@@ -265,8 +265,6 @@ do { \
265 */ 265 */
266#define __get_user_asm_ll32(val, addr) \ 266#define __get_user_asm_ll32(val, addr) \
267{ \ 267{ \
268 unsigned long long __gu_tmp; \
269 \
270 __asm__ __volatile__( \ 268 __asm__ __volatile__( \
271 "1: lw %1, (%3) \n" \ 269 "1: lw %1, (%3) \n" \
272 "2: lw %D1, 4(%3) \n" \ 270 "2: lw %D1, 4(%3) \n" \
@@ -281,9 +279,8 @@ do { \
281 " " __UA_ADDR " 1b, 4b \n" \ 279 " " __UA_ADDR " 1b, 4b \n" \
282 " " __UA_ADDR " 2b, 4b \n" \ 280 " " __UA_ADDR " 2b, 4b \n" \
283 " .previous \n" \ 281 " .previous \n" \
284 : "=r" (__gu_err), "=&r" (__gu_tmp) \ 282 : "=r" (__gu_err), "=&r" (val) \
285 : "0" (0), "r" (addr), "i" (-EFAULT)); \ 283 : "0" (0), "r" (addr), "i" (-EFAULT)); \
286 (val) = (__typeof__(*(addr))) __gu_tmp; \
287} 284}
288 285
289/* 286/*