aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel
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
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')
-rw-r--r--arch/mips/kernel/signal-common.h150
-rw-r--r--arch/mips/kernel/signal.c139
2 files changed, 153 insertions, 136 deletions
diff --git a/arch/mips/kernel/signal-common.h b/arch/mips/kernel/signal-common.h
index bb3c631b808e..03d2b603fb84 100644
--- a/arch/mips/kernel/signal-common.h
+++ b/arch/mips/kernel/signal-common.h
@@ -8,145 +8,23 @@
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/*
13setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) 15 * handle hardware context
14{ 16 */
15 int err = 0; 17extern int setup_sigcontext(struct pt_regs *, struct sigcontext __user *);
16 int i; 18extern int restore_sigcontext(struct pt_regs *, struct sigcontext __user *);
17
18 err |= __put_user(regs->cp0_epc, &sc->sc_pc);
19
20 err |= __put_user(0, &sc->sc_regs[0]);
21 for (i = 1; i < 32; i++)
22 err |= __put_user(regs->regs[i], &sc->sc_regs[i]);
23
24 err |= __put_user(regs->hi, &sc->sc_mdhi);
25 err |= __put_user(regs->lo, &sc->sc_mdlo);
26 if (cpu_has_dsp) {
27 err |= __put_user(mfhi1(), &sc->sc_hi1);
28 err |= __put_user(mflo1(), &sc->sc_lo1);
29 err |= __put_user(mfhi2(), &sc->sc_hi2);
30 err |= __put_user(mflo2(), &sc->sc_lo2);
31 err |= __put_user(mfhi3(), &sc->sc_hi3);
32 err |= __put_user(mflo3(), &sc->sc_lo3);
33 err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
34 }
35
36 err |= __put_user(!!used_math(), &sc->sc_used_math);
37
38 if (used_math()) {
39 /*
40 * Save FPU state to signal context. Signal handler
41 * will "inherit" current FPU state.
42 */
43 preempt_disable();
44
45 if (!is_fpu_owner()) {
46 own_fpu();
47 restore_fp(current);
48 }
49 err |= save_fp_context(sc);
50
51 preempt_enable();
52 }
53 return err;
54}
55
56static inline int
57restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
58{
59 unsigned int used_math;
60 unsigned long treg;
61 int err = 0;
62 int i;
63
64 /* Always make any pending restarted system calls return -EINTR */
65 current_thread_info()->restart_block.fn = do_no_restart_syscall;
66
67 err |= __get_user(regs->cp0_epc, &sc->sc_pc);
68 err |= __get_user(regs->hi, &sc->sc_mdhi);
69 err |= __get_user(regs->lo, &sc->sc_mdlo);
70 if (cpu_has_dsp) {
71 err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
72 err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
73 err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
74 err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
75 err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
76 err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
77 err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
78 }
79
80 for (i = 1; i < 32; i++)
81 err |= __get_user(regs->regs[i], &sc->sc_regs[i]);
82
83 err |= __get_user(used_math, &sc->sc_used_math);
84 conditional_used_math(used_math);
85
86 preempt_disable();
87
88 if (used_math()) {
89 /* restore fpu context if we have used it before */
90 own_fpu();
91 err |= restore_fp_context(sc);
92 } else {
93 /* signal handler may have used FPU. Give it up. */
94 lose_fpu();
95 }
96
97 preempt_enable();
98
99 return err;
100}
101 19
102/* 20/*
103 * Determine which stack to use.. 21 * Determine which stack to use..
104 */ 22 */
105static inline void __user * 23extern void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
106get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) 24 size_t frame_size);
107{ 25/*
108 unsigned long sp; 26 * install trampoline code to get back from the sig handler
109 27 */
110 /* Default to using normal stack */ 28extern int install_sigtramp(unsigned int __user *tramp, unsigned int syscall);
111 sp = regs->regs[29];
112
113 /*
114 * FPU emulator may have it's own trampoline active just
115 * above the user stack, 16-bytes before the next lowest
116 * 16 byte boundary. Try to avoid trashing it.
117 */
118 sp -= 32;
119
120 /* This is the X/Open sanctioned signal stack switching. */
121 if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
122 sp = current->sas_ss_sp + current->sas_ss_size;
123
124 return (void __user *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? ~(cpu_icache_line_size()-1) : ALMASK));
125}
126
127static inline int install_sigtramp(unsigned int __user *tramp,
128 unsigned int syscall)
129{
130 int err;
131
132 /*
133 * Set up the return code ...
134 *
135 * li v0, __NR__foo_sigreturn
136 * syscall
137 */
138
139 err = __put_user(0x24020000 + syscall, tramp + 0);
140 err |= __put_user(0x0000000c , tramp + 1);
141 if (ICACHE_REFILLS_WORKAROUND_WAR) {
142 err |= __put_user(0, tramp + 2);
143 err |= __put_user(0, tramp + 3);
144 err |= __put_user(0, tramp + 4);
145 err |= __put_user(0, tramp + 5);
146 err |= __put_user(0, tramp + 6);
147 err |= __put_user(0, tramp + 7);
148 }
149 flush_cache_sigtramp((unsigned long) tramp);
150 29
151 return err; 30#endif /* __SIGNAL_COMMON_H */
152}
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