Commit e1723538 authored by Chris Metcalf's avatar Chris Metcalf

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: default avatarChris Metcalf <cmetcalf@tilera.com>
parent 5f639fdc
...@@ -64,7 +64,11 @@ void do_breakpoint(struct pt_regs *, int fault_num); ...@@ -64,7 +64,11 @@ void do_breakpoint(struct pt_regs *, int fault_num);
#ifdef __tilegx__ #ifdef __tilegx__
/* kernel/single_step.c */
void gx_singlestep_handle(struct pt_regs *, int fault_num); void gx_singlestep_handle(struct pt_regs *, int fault_num);
/* kernel/intvec_64.S */
void fill_ra_stack(void);
#endif #endif
#endif /* _ASM_TILE_SYSCALLS_H */ #endif /* _ASM_TILE_TRAPS_H */
...@@ -1156,6 +1156,18 @@ int_unalign: ...@@ -1156,6 +1156,18 @@ int_unalign:
push_extra_callee_saves r0 push_extra_callee_saves r0
j do_trap j do_trap
/* Fill the return address stack with nonzero entries. */
STD_ENTRY(fill_ra_stack)
{
move r0, lr
jal 1f
}
1: jal 2f
2: jal 3f
3: jal 4f
4: jrp r0
STD_ENDPROC(fill_ra_stack)
/* Include .intrpt1 array of interrupt vectors */ /* Include .intrpt1 array of interrupt vectors */
.section ".intrpt1", "ax" .section ".intrpt1", "ax"
......
...@@ -289,7 +289,10 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num, ...@@ -289,7 +289,10 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num,
address = regs->pc; address = regs->pc;
break; break;
#ifdef __tilegx__ #ifdef __tilegx__
case INT_ILL_TRANS: case INT_ILL_TRANS: {
/* Avoid a hardware erratum with the return address stack. */
fill_ra_stack();
signo = SIGSEGV; signo = SIGSEGV;
code = SEGV_MAPERR; code = SEGV_MAPERR;
if (reason & SPR_ILL_TRANS_REASON__I_STREAM_VA_RMASK) 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,6 +300,7 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num,
else else
address = 0; /* FIXME: GX: single-step for address */ address = 0; /* FIXME: GX: single-step for address */
break; break;
}
#endif #endif
default: default:
panic("Unexpected do_trap interrupt number %d", fault_num); panic("Unexpected do_trap interrupt number %d", fault_num);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment