Commit fd615f69 authored by LiuHailong's avatar LiuHailong Committed by Scott Wood

powerpc/64e: Fix hang when debugging programs with relocated kernel

Debug interrupts can be taken during interrupt entry, since interrupt
entry does not automatically turn them off.  The kernel will check
whether the faulting instruction is between [interrupt_base_book3e,
__end_interrupts], and if so clear MSR[DE] and return.

However, when the kernel is built with CONFIG_RELOCATABLE, it can't use
LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e) and
LOAD_REG_IMMEDIATE(r15,__end_interrupts), as they ignore relocation.
Thus, if the kernel is actually running at a different address than it
was built at, the address comparison will fail, and the exception entry
code will hang at kernel_dbg_exc.

r2(toc) is also not usable here, as r2 still holds data from the
interrupted context, so LOAD_REG_ADDR() doesn't work either.  So we use
the *name@got* to get the EV of two labels directly.

Test programs test.c shows as follows:
int main(int argc, char *argv[])
{
	if (access("/proc/sys/kernel/perf_event_paranoid", F_OK) == -1)
		printf("Kernel doesn't have perf_event support\n");
}

Steps to reproduce the bug, for example:
 1) ./gdb ./test
 2) (gdb) b access
 3) (gdb) r
 4) (gdb) s
Signed-off-by: default avatarLiu Hailong <liu.hailong6@zte.com.cn>
Signed-off-by: default avatarJiang Xuexin <jiang.xuexin@zte.com.cn>
Reviewed-by: default avatarJiang Biao <jiang.biao2@zte.com.cn>
Reviewed-by: default avatarLiu Song <liu.song11@zte.com.cn>
Reviewed-by: default avatarHuang Jian <huang.jian@zte.com.cn>
[scottwood: cleaned up commit message, and specified bad behavior
 as a hang rather than an oops to correspond to mainline kernel behavior]
Fixes: 1cb6e064 ("powerpc/book3e: support CONFIG_RELOCATABLE")
Cc: <stable@vger.kernel.org> # 4.4.x-
Signed-off-by: default avatarScott Wood <oss@buserror.net>
parent 096ff2dd
...@@ -735,8 +735,14 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) ...@@ -735,8 +735,14 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
andis. r15,r14,(DBSR_IC|DBSR_BT)@h andis. r15,r14,(DBSR_IC|DBSR_BT)@h
beq+ 1f beq+ 1f
#ifdef CONFIG_RELOCATABLE
ld r15,PACATOC(r13)
ld r14,interrupt_base_book3e@got(r15)
ld r15,__end_interrupts@got(r15)
#else
LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e) LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e)
LOAD_REG_IMMEDIATE(r15,__end_interrupts) LOAD_REG_IMMEDIATE(r15,__end_interrupts)
#endif
cmpld cr0,r10,r14 cmpld cr0,r10,r14
cmpld cr1,r10,r15 cmpld cr1,r10,r15
blt+ cr0,1f blt+ cr0,1f
...@@ -799,8 +805,14 @@ kernel_dbg_exc: ...@@ -799,8 +805,14 @@ kernel_dbg_exc:
andis. r15,r14,(DBSR_IC|DBSR_BT)@h andis. r15,r14,(DBSR_IC|DBSR_BT)@h
beq+ 1f beq+ 1f
#ifdef CONFIG_RELOCATABLE
ld r15,PACATOC(r13)
ld r14,interrupt_base_book3e@got(r15)
ld r15,__end_interrupts@got(r15)
#else
LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e) LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e)
LOAD_REG_IMMEDIATE(r15,__end_interrupts) LOAD_REG_IMMEDIATE(r15,__end_interrupts)
#endif
cmpld cr0,r10,r14 cmpld cr0,r10,r14
cmpld cr1,r10,r15 cmpld cr1,r10,r15
blt+ cr0,1f blt+ cr0,1f
......
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