aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/signal.c
diff options
context:
space:
mode:
authorFranck Bui-Huu <fbuihuu@gmail.com>2007-02-05 09:24:20 -0500
committerRalf Baechle <ralf@linux-mips.org>2007-02-10 17:38:45 -0500
commitc3fc4ab36d495f50ccc89986fe32eeabc2549fa1 (patch)
treec83a3a56c8a04bb06fc96932b6edba5b54143c89 /arch/mips/kernel/signal.c
parenta007b1f1c764c08896bc574fbd33e19ce898a188 (diff)
[MIPS] signal: do not inline functions in signal-common.h
These functions are quite big and there are no points to make them inlined. So this patch moves the functions implementation in signal.c and make them available for others source files which need them. Signed-off-by: Franck Bui-Huu <fbuihuu@gmail.com> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/kernel/signal.c')
-rw-r--r--arch/mips/kernel/signal.c139
1 files changed, 139 insertions, 0 deletions
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index 9a44053cd9f1..7d5a631d6cab 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -39,6 +39,145 @@
39#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 39#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
40 40
41/* 41/*
42 * Helper routines
43 */
44int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
45{
46 int err = 0;
47 int i;
48
49 err |= __put_user(regs->cp0_epc, &sc->sc_pc);
50
51 err |= __put_user(0, &sc->sc_regs[0]);
52 for (i = 1; i < 32; i++)
53 err |= __put_user(regs->regs[i], &sc->sc_regs[i]);
54
55 err |= __put_user(regs->hi, &sc->sc_mdhi);
56 err |= __put_user(regs->lo, &sc->sc_mdlo);
57 if (cpu_has_dsp) {
58 err |= __put_user(mfhi1(), &sc->sc_hi1);
59 err |= __put_user(mflo1(), &sc->sc_lo1);
60 err |= __put_user(mfhi2(), &sc->sc_hi2);
61 err |= __put_user(mflo2(), &sc->sc_lo2);
62 err |= __put_user(mfhi3(), &sc->sc_hi3);
63 err |= __put_user(mflo3(), &sc->sc_lo3);
64 err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
65 }
66
67 err |= __put_user(!!used_math(), &sc->sc_used_math);
68
69 if (used_math()) {
70 /*
71 * Save FPU state to signal context. Signal handler
72 * will "inherit" current FPU state.
73 */
74 preempt_disable();
75
76 if (!is_fpu_owner()) {
77 own_fpu();
78 restore_fp(current);
79 }
80 err |= save_fp_context(sc);
81
82 preempt_enable();
83 }
84 return err;
85}
86
87int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
88{
89 unsigned int used_math;
90 unsigned long treg;
91 int err = 0;
92 int i;
93
94 /* Always make any pending restarted system calls return -EINTR */
95 current_thread_info()->restart_block.fn = do_no_restart_syscall;
96
97 err |= __get_user(regs->cp0_epc, &sc->sc_pc);
98 err |= __get_user(regs->hi, &sc->sc_mdhi);
99 err |= __get_user(regs->lo, &sc->sc_mdlo);
100 if (cpu_has_dsp) {
101 err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
102 err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
103 err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
104 err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
105 err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
106 err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
107 err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
108 }
109
110 for (i = 1; i < 32; i++)
111 err |= __get_user(regs->regs[i], &sc->sc_regs[i]);
112
113 err |= __get_user(used_math, &sc->sc_used_math);
114 conditional_used_math(used_math);
115
116 preempt_disable();
117
118 if (used_math()) {
119 /* restore fpu context if we have used it before */
120 own_fpu();
121 err |= restore_fp_context(sc);
122 } else {
123 /* signal handler may have used FPU. Give it up. */
124 lose_fpu();
125 }
126
127 preempt_enable();
128
129 return err;
130}
131
132void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
133 size_t frame_size)
134{
135 unsigned long sp;
136
137 /* Default to using normal stack */
138 sp = regs->regs[29];
139
140 /*
141 * FPU emulator may have it's own trampoline active just
142 * above the user stack, 16-bytes before the next lowest
143 * 16 byte boundary. Try to avoid trashing it.
144 */
145 sp -= 32;
146
147 /* This is the X/Open sanctioned signal stack switching. */
148 if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
149 sp = current->sas_ss_sp + current->sas_ss_size;
150
151 return (void __user *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? ~(cpu_icache_line_size()-1) : ALMASK));
152}
153
154int install_sigtramp(unsigned int __user *tramp, unsigned int syscall)
155{
156 int err;
157
158 /*
159 * Set up the return code ...
160 *
161 * li v0, __NR__foo_sigreturn
162 * syscall
163 */
164
165 err = __put_user(0x24020000 + syscall, tramp + 0);
166 err |= __put_user(0x0000000c , tramp + 1);
167 if (ICACHE_REFILLS_WORKAROUND_WAR) {
168 err |= __put_user(0, tramp + 2);
169 err |= __put_user(0, tramp + 3);
170 err |= __put_user(0, tramp + 4);
171 err |= __put_user(0, tramp + 5);
172 err |= __put_user(0, tramp + 6);
173 err |= __put_user(0, tramp + 7);
174 }
175 flush_cache_sigtramp((unsigned long) tramp);
176
177 return err;
178}
179
180/*
42 * Atomically swap in the new signal mask, and wait for a signal. 181 * Atomically swap in the new signal mask, and wait for a signal.
43 */ 182 */
44 183