aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/signal.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2005-06-15 09:00:12 -0400
committerRalf Baechle <ralf@linux-mips.org>2005-10-29 14:31:23 -0400
commit02416dcf5a94af34bcd28b4baf25bbbf399d8136 (patch)
tree1906c4266d4e28ef0b13d0579a145603dcbcff1b /arch/mips/kernel/signal.c
parentaac8aa7717a23a9bf8740dbfb59755b1d62f04bf (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.c59
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
167struct sigframe { 168struct 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
175struct rt_sigframe { 183struct 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);