diff options
Diffstat (limited to 'arch/arm64/kernel/stacktrace.c')
| -rw-r--r-- | arch/arm64/kernel/stacktrace.c | 10 | 
1 files changed, 7 insertions, 3 deletions
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c index d25459ff57f..55437ba1f5a 100644 --- a/arch/arm64/kernel/stacktrace.c +++ b/arch/arm64/kernel/stacktrace.c @@ -35,7 +35,7 @@   *	ldp	x29, x30, [sp]   *	add	sp, sp, #0x10   */ -int unwind_frame(struct stackframe *frame) +int notrace unwind_frame(struct stackframe *frame)  {  	unsigned long high, low;  	unsigned long fp = frame->fp; @@ -43,12 +43,16 @@ int unwind_frame(struct stackframe *frame)  	low  = frame->sp;  	high = ALIGN(low, THREAD_SIZE); -	if (fp < low || fp > high || fp & 0xf) +	if (fp < low || fp > high - 0x18 || fp & 0xf)  		return -EINVAL;  	frame->sp = fp + 0x10;  	frame->fp = *(unsigned long *)(fp); -	frame->pc = *(unsigned long *)(fp + 8); +	/* +	 * -4 here because we care about the PC at time of bl, +	 * not where the return will go. +	 */ +	frame->pc = *(unsigned long *)(fp + 8) - 4;  	return 0;  }  | 
