diff options
Diffstat (limited to 'arch/mips/kernel/signal-common.h')
-rw-r--r-- | arch/mips/kernel/signal-common.h | 90 |
1 files changed, 80 insertions, 10 deletions
diff --git a/arch/mips/kernel/signal-common.h b/arch/mips/kernel/signal-common.h index f9234df53253..0f66ae5838b9 100644 --- a/arch/mips/kernel/signal-common.h +++ b/arch/mips/kernel/signal-common.h | |||
@@ -8,13 +8,14 @@ | |||
8 | * Copyright (C) 1999, 2000 Silicon Graphics, Inc. | 8 | * Copyright (C) 1999, 2000 Silicon Graphics, Inc. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/config.h> | ||
12 | |||
11 | static inline int | 13 | static inline int |
12 | setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc) | 14 | setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc) |
13 | { | 15 | { |
14 | int err = 0; | 16 | int err = 0; |
15 | 17 | ||
16 | err |= __put_user(regs->cp0_epc, &sc->sc_pc); | 18 | err |= __put_user(regs->cp0_epc, &sc->sc_pc); |
17 | err |= __put_user(regs->cp0_status, &sc->sc_status); | ||
18 | 19 | ||
19 | #define save_gp_reg(i) do { \ | 20 | #define save_gp_reg(i) do { \ |
20 | err |= __put_user(regs->regs[i], &sc->sc_regs[i]); \ | 21 | err |= __put_user(regs->regs[i], &sc->sc_regs[i]); \ |
@@ -30,10 +31,32 @@ setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc) | |||
30 | save_gp_reg(31); | 31 | save_gp_reg(31); |
31 | #undef save_gp_reg | 32 | #undef save_gp_reg |
32 | 33 | ||
34 | #ifdef CONFIG_32BIT | ||
33 | err |= __put_user(regs->hi, &sc->sc_mdhi); | 35 | err |= __put_user(regs->hi, &sc->sc_mdhi); |
34 | err |= __put_user(regs->lo, &sc->sc_mdlo); | 36 | err |= __put_user(regs->lo, &sc->sc_mdlo); |
35 | err |= __put_user(regs->cp0_cause, &sc->sc_cause); | 37 | if (cpu_has_dsp) { |
36 | err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr); | 38 | err |= __put_user(mfhi1(), &sc->sc_hi1); |
39 | err |= __put_user(mflo1(), &sc->sc_lo1); | ||
40 | err |= __put_user(mfhi2(), &sc->sc_hi2); | ||
41 | err |= __put_user(mflo2(), &sc->sc_lo2); | ||
42 | err |= __put_user(mfhi3(), &sc->sc_hi3); | ||
43 | err |= __put_user(mflo3(), &sc->sc_lo3); | ||
44 | err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp); | ||
45 | } | ||
46 | #endif | ||
47 | #ifdef CONFIG_64BIT | ||
48 | err |= __put_user(regs->hi, &sc->sc_hi[0]); | ||
49 | err |= __put_user(regs->lo, &sc->sc_lo[0]); | ||
50 | if (cpu_has_dsp) { | ||
51 | err |= __put_user(mfhi1(), &sc->sc_hi[1]); | ||
52 | err |= __put_user(mflo1(), &sc->sc_lo[1]); | ||
53 | err |= __put_user(mfhi2(), &sc->sc_hi[2]); | ||
54 | err |= __put_user(mflo2(), &sc->sc_lo[2]); | ||
55 | err |= __put_user(mfhi3(), &sc->sc_hi[3]); | ||
56 | err |= __put_user(mflo3(), &sc->sc_lo[3]); | ||
57 | err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp); | ||
58 | } | ||
59 | #endif | ||
37 | 60 | ||
38 | err |= __put_user(!!used_math(), &sc->sc_used_math); | 61 | err |= __put_user(!!used_math(), &sc->sc_used_math); |
39 | 62 | ||
@@ -61,15 +84,40 @@ out: | |||
61 | static inline int | 84 | static inline int |
62 | restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) | 85 | restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) |
63 | { | 86 | { |
64 | int err = 0; | ||
65 | unsigned int used_math; | 87 | unsigned int used_math; |
88 | unsigned long treg; | ||
89 | int err = 0; | ||
66 | 90 | ||
67 | /* Always make any pending restarted system calls return -EINTR */ | 91 | /* Always make any pending restarted system calls return -EINTR */ |
68 | current_thread_info()->restart_block.fn = do_no_restart_syscall; | 92 | current_thread_info()->restart_block.fn = do_no_restart_syscall; |
69 | 93 | ||
70 | err |= __get_user(regs->cp0_epc, &sc->sc_pc); | 94 | err |= __get_user(regs->cp0_epc, &sc->sc_pc); |
95 | #ifdef CONFIG_32BIT | ||
71 | err |= __get_user(regs->hi, &sc->sc_mdhi); | 96 | err |= __get_user(regs->hi, &sc->sc_mdhi); |
72 | err |= __get_user(regs->lo, &sc->sc_mdlo); | 97 | err |= __get_user(regs->lo, &sc->sc_mdlo); |
98 | if (cpu_has_dsp) { | ||
99 | err |= __get_user(treg, &sc->sc_hi1); mthi1(treg); | ||
100 | err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg); | ||
101 | err |= __get_user(treg, &sc->sc_hi2); mthi2(treg); | ||
102 | err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg); | ||
103 | err |= __get_user(treg, &sc->sc_hi3); mthi3(treg); | ||
104 | err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg); | ||
105 | err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK); | ||
106 | } | ||
107 | #endif | ||
108 | #ifdef CONFIG_64BIT | ||
109 | err |= __get_user(regs->hi, &sc->sc_hi[0]); | ||
110 | err |= __get_user(regs->lo, &sc->sc_lo[0]); | ||
111 | if (cpu_has_dsp) { | ||
112 | err |= __get_user(treg, &sc->sc_hi[1]); mthi1(treg); | ||
113 | err |= __get_user(treg, &sc->sc_lo[1]); mthi1(treg); | ||
114 | err |= __get_user(treg, &sc->sc_hi[2]); mthi2(treg); | ||
115 | err |= __get_user(treg, &sc->sc_lo[2]); mthi2(treg); | ||
116 | err |= __get_user(treg, &sc->sc_hi[3]); mthi3(treg); | ||
117 | err |= __get_user(treg, &sc->sc_lo[3]); mthi3(treg); | ||
118 | err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK); | ||
119 | } | ||
120 | #endif | ||
73 | 121 | ||
74 | #define restore_gp_reg(i) do { \ | 122 | #define restore_gp_reg(i) do { \ |
75 | err |= __get_user(regs->regs[i], &sc->sc_regs[i]); \ | 123 | err |= __get_user(regs->regs[i], &sc->sc_regs[i]); \ |
@@ -112,7 +160,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) | |||
112 | static inline void * | 160 | static inline void * |
113 | get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) | 161 | get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) |
114 | { | 162 | { |
115 | unsigned long sp, almask; | 163 | unsigned long sp; |
116 | 164 | ||
117 | /* Default to using normal stack */ | 165 | /* Default to using normal stack */ |
118 | sp = regs->regs[29]; | 166 | sp = regs->regs[29]; |
@@ -128,10 +176,32 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) | |||
128 | if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0)) | 176 | if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0)) |
129 | sp = current->sas_ss_sp + current->sas_ss_size; | 177 | sp = current->sas_ss_sp + current->sas_ss_size; |
130 | 178 | ||
131 | if (PLAT_TRAMPOLINE_STUFF_LINE) | 179 | return (void *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? 32 : ALMASK)); |
132 | almask = ~(PLAT_TRAMPOLINE_STUFF_LINE - 1); | 180 | } |
133 | else | 181 | |
134 | almask = ALMASK; | 182 | static inline int install_sigtramp(unsigned int __user *tramp, |
183 | unsigned int syscall) | ||
184 | { | ||
185 | int err; | ||
186 | |||
187 | /* | ||
188 | * Set up the return code ... | ||
189 | * | ||
190 | * li v0, __NR__foo_sigreturn | ||
191 | * syscall | ||
192 | */ | ||
193 | |||
194 | err = __put_user(0x24020000 + syscall, tramp + 0); | ||
195 | err |= __put_user(0x0000000c , tramp + 1); | ||
196 | if (ICACHE_REFILLS_WORKAROUND_WAR) { | ||
197 | err |= __put_user(0, tramp + 2); | ||
198 | err |= __put_user(0, tramp + 3); | ||
199 | err |= __put_user(0, tramp + 4); | ||
200 | err |= __put_user(0, tramp + 5); | ||
201 | err |= __put_user(0, tramp + 6); | ||
202 | err |= __put_user(0, tramp + 7); | ||
203 | } | ||
204 | flush_cache_sigtramp((unsigned long) tramp); | ||
135 | 205 | ||
136 | return (void *)((sp - frame_size) & almask); | 206 | return err; |
137 | } | 207 | } |