aboutsummaryrefslogtreecommitdiffstats
path: root/arch/tile/kernel/traps.c
diff options
context:
space:
mode:
authorChris Metcalf <cmetcalf@tilera.com>2012-03-29 14:52:00 -0400
committerChris Metcalf <cmetcalf@tilera.com>2012-04-02 12:12:48 -0400
commite17235382dbb05f70146e141e4b780fd069050dc (patch)
treed4da45df23c48ac7e0e4f61821125174a39e436a /arch/tile/kernel/traps.c
parent5f639fdcd8c186c8128c616e94a7e7b159c968ae (diff)
arch/tile: work around a hardware issue with the return-address stack
In certain circumstances we need to do a bunch of jump-and-link instructions to fill the hardware return-address stack with nonzero values. Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
Diffstat (limited to 'arch/tile/kernel/traps.c')
-rw-r--r--arch/tile/kernel/traps.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/arch/tile/kernel/traps.c b/arch/tile/kernel/traps.c
index 2bb6602a1ee7..32acfd9e23d0 100644
--- a/arch/tile/kernel/traps.c
+++ b/arch/tile/kernel/traps.c
@@ -289,7 +289,10 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num,
289 address = regs->pc; 289 address = regs->pc;
290 break; 290 break;
291#ifdef __tilegx__ 291#ifdef __tilegx__
292 case INT_ILL_TRANS: 292 case INT_ILL_TRANS: {
293 /* Avoid a hardware erratum with the return address stack. */
294 fill_ra_stack();
295
293 signo = SIGSEGV; 296 signo = SIGSEGV;
294 code = SEGV_MAPERR; 297 code = SEGV_MAPERR;
295 if (reason & SPR_ILL_TRANS_REASON__I_STREAM_VA_RMASK) 298 if (reason & SPR_ILL_TRANS_REASON__I_STREAM_VA_RMASK)
@@ -297,6 +300,7 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num,
297 else 300 else
298 address = 0; /* FIXME: GX: single-step for address */ 301 address = 0; /* FIXME: GX: single-step for address */
299 break; 302 break;
303 }
300#endif 304#endif
301 default: 305 default:
302 panic("Unexpected do_trap interrupt number %d", fault_num); 306 panic("Unexpected do_trap interrupt number %d", fault_num);