diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2005-06-15 09:00:12 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2005-10-29 14:31:23 -0400 |
commit | 02416dcf5a94af34bcd28b4baf25bbbf399d8136 (patch) | |
tree | 1906c4266d4e28ef0b13d0579a145603dcbcff1b /arch/mips/kernel/signal.c | |
parent | aac8aa7717a23a9bf8740dbfb59755b1d62f04bf (diff) |
Redo RM9000 workaround which along with other DSP ASE changes was
causing some headache for debuggers knowing about signal frames.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/kernel/signal.c')
-rw-r--r-- | arch/mips/kernel/signal.c | 59 |
1 files changed, 27 insertions, 32 deletions
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index 8504febf8b22..8679ccff870e 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c | |||
@@ -8,6 +8,7 @@ | |||
8 | * Copyright (C) 1999, 2000 Silicon Graphics, Inc. | 8 | * Copyright (C) 1999, 2000 Silicon Graphics, Inc. |
9 | */ | 9 | */ |
10 | #include <linux/config.h> | 10 | #include <linux/config.h> |
11 | #include <linux/cache.h> | ||
11 | #include <linux/sched.h> | 12 | #include <linux/sched.h> |
12 | #include <linux/mm.h> | 13 | #include <linux/mm.h> |
13 | #include <linux/personality.h> | 14 | #include <linux/personality.h> |
@@ -30,6 +31,7 @@ | |||
30 | #include <asm/uaccess.h> | 31 | #include <asm/uaccess.h> |
31 | #include <asm/ucontext.h> | 32 | #include <asm/ucontext.h> |
32 | #include <asm/cpu-features.h> | 33 | #include <asm/cpu-features.h> |
34 | #include <asm/war.h> | ||
33 | 35 | ||
34 | #include "signal-common.h" | 36 | #include "signal-common.h" |
35 | 37 | ||
@@ -157,26 +159,39 @@ asmlinkage int sys_sigaltstack(nabi_no_regargs struct pt_regs regs) | |||
157 | return do_sigaltstack(uss, uoss, usp); | 159 | return do_sigaltstack(uss, uoss, usp); |
158 | } | 160 | } |
159 | 161 | ||
160 | #if PLAT_TRAMPOLINE_STUFF_LINE | 162 | /* |
161 | #define __tramp __attribute__((aligned(PLAT_TRAMPOLINE_STUFF_LINE))) | 163 | * Horribly complicated - with the bloody RM9000 workarounds enabled |
162 | #else | 164 | * the signal trampolines is moving to the end of the structure so we can |
163 | #define __tramp | 165 | * increase the alignment without breaking software compatibility. |
164 | #endif | 166 | */ |
165 | |||
166 | #ifdef CONFIG_TRAD_SIGNALS | 167 | #ifdef CONFIG_TRAD_SIGNALS |
167 | struct sigframe { | 168 | struct sigframe { |
168 | u32 sf_ass[4]; /* argument save space for o32 */ | 169 | u32 sf_ass[4]; /* argument save space for o32 */ |
169 | u32 sf_code[2] __tramp; /* signal trampoline */ | 170 | #if ICACHE_REFILLS_WORKAROUND_WAR |
170 | struct sigcontext sf_sc __tramp; | 171 | u32 sf_pad[2]; |
172 | #else | ||
173 | u32 sf_code[2]; /* signal trampoline */ | ||
174 | #endif | ||
175 | struct sigcontext sf_sc; | ||
171 | sigset_t sf_mask; | 176 | sigset_t sf_mask; |
177 | #if ICACHE_REFILLS_WORKAROUND_WAR | ||
178 | u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */ | ||
179 | #endif | ||
172 | }; | 180 | }; |
173 | #endif | 181 | #endif |
174 | 182 | ||
175 | struct rt_sigframe { | 183 | struct rt_sigframe { |
176 | u32 rs_ass[4]; /* argument save space for o32 */ | 184 | u32 rs_ass[4]; /* argument save space for o32 */ |
177 | u32 rs_code[2] __tramp; /* signal trampoline */ | 185 | #if ICACHE_REFILLS_WORKAROUND_WAR |
178 | struct siginfo rs_info __tramp; | 186 | u32 rs_pad[2]; |
187 | #else | ||
188 | u32 rs_code[2]; /* signal trampoline */ | ||
189 | #endif | ||
190 | struct siginfo rs_info; | ||
179 | struct ucontext rs_uc; | 191 | struct ucontext rs_uc; |
192 | #if ICACHE_REFILLS_WORKAROUND_WAR | ||
193 | u32 rs_code[8] ____cacheline_aligned; /* signal trampoline */ | ||
194 | #endif | ||
180 | }; | 195 | }; |
181 | 196 | ||
182 | #ifdef CONFIG_TRAD_SIGNALS | 197 | #ifdef CONFIG_TRAD_SIGNALS |
@@ -273,17 +288,7 @@ void setup_frame(struct k_sigaction * ka, struct pt_regs *regs, | |||
273 | if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) | 288 | if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) |
274 | goto give_sigsegv; | 289 | goto give_sigsegv; |
275 | 290 | ||
276 | /* | 291 | install_sigtramp(frame->sf_code, __NR_sigreturn); |
277 | * Set up the return code ... | ||
278 | * | ||
279 | * li v0, __NR_sigreturn | ||
280 | * syscall | ||
281 | */ | ||
282 | if (PLAT_TRAMPOLINE_STUFF_LINE) | ||
283 | __clear_user(frame->sf_code, PLAT_TRAMPOLINE_STUFF_LINE); | ||
284 | err |= __put_user(0x24020000 + __NR_sigreturn, frame->sf_code + 0); | ||
285 | err |= __put_user(0x0000000c , frame->sf_code + 1); | ||
286 | flush_cache_sigtramp((unsigned long) frame->sf_code); | ||
287 | 292 | ||
288 | err |= setup_sigcontext(regs, &frame->sf_sc); | 293 | err |= setup_sigcontext(regs, &frame->sf_sc); |
289 | err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set)); | 294 | err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set)); |
@@ -329,17 +334,7 @@ void setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs, | |||
329 | if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) | 334 | if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) |
330 | goto give_sigsegv; | 335 | goto give_sigsegv; |
331 | 336 | ||
332 | /* | 337 | install_sigtramp(frame->rs_code, __NR_rt_sigreturn); |
333 | * Set up the return code ... | ||
334 | * | ||
335 | * li v0, __NR_rt_sigreturn | ||
336 | * syscall | ||
337 | */ | ||
338 | if (PLAT_TRAMPOLINE_STUFF_LINE) | ||
339 | __clear_user(frame->rs_code, PLAT_TRAMPOLINE_STUFF_LINE); | ||
340 | err |= __put_user(0x24020000 + __NR_rt_sigreturn, frame->rs_code + 0); | ||
341 | err |= __put_user(0x0000000c , frame->rs_code + 1); | ||
342 | flush_cache_sigtramp((unsigned long) frame->rs_code); | ||
343 | 338 | ||
344 | /* Create siginfo. */ | 339 | /* Create siginfo. */ |
345 | err |= copy_siginfo_to_user(&frame->rs_info, info); | 340 | err |= copy_siginfo_to_user(&frame->rs_info, info); |