Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e1723538 authored by Chris Metcalf's avatar Chris Metcalf
Browse files

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
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -64,7 +64,11 @@ void do_breakpoint(struct pt_regs *, int fault_num);


#ifdef __tilegx__
/* kernel/single_step.c */
void gx_singlestep_handle(struct pt_regs *, int fault_num);

/* kernel/intvec_64.S */
void fill_ra_stack(void);
#endif

#endif /* _ASM_TILE_SYSCALLS_H */
#endif /* _ASM_TILE_TRAPS_H */
+12 −0
Original line number Diff line number Diff line
@@ -1156,6 +1156,18 @@ int_unalign:
	push_extra_callee_saves r0
	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 */
	.section ".intrpt1", "ax"

+5 −1
Original line number Diff line number Diff line
@@ -289,7 +289,10 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num,
		address = regs->pc;
		break;
#ifdef __tilegx__
	case INT_ILL_TRANS:
	case INT_ILL_TRANS: {
		/* Avoid a hardware erratum with the return address stack. */
		fill_ra_stack();

		signo = SIGSEGV;
		code = SEGV_MAPERR;
		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,
		else
			address = 0;  /* FIXME: GX: single-step for address */
		break;
	}
#endif
	default:
		panic("Unexpected do_trap interrupt number %d", fault_num);