Skip to content

Commit 1ab43a5

Browse files
LiuHailonggregkh
authored andcommitted
powerpc/64e: Fix hang when debugging programs with relocated kernel
commit fd615f69a18a9d4aa5ef02a1dc83f319f75da8e7 upstream. 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: Liu Hailong <liu.hailong6@zte.com.cn> Signed-off-by: Jiang Xuexin <jiang.xuexin@zte.com.cn> Reviewed-by: Jiang Biao <jiang.biao2@zte.com.cn> Reviewed-by: Liu Song <liu.song11@zte.com.cn> Reviewed-by: Huang 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: 1cb6e06 ("powerpc/book3e: support CONFIG_RELOCATABLE") Signed-off-by: Scott Wood <oss@buserror.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 33c0c0f commit 1ab43a5

1 file changed

Lines changed: 12 additions & 0 deletions

File tree

arch/powerpc/kernel/exceptions-64e.S

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -735,8 +735,14 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
735735
andis. r15,r14,(DBSR_IC|DBSR_BT)@h
736736
beq+ 1f
737737

738+
#ifdef CONFIG_RELOCATABLE
739+
ld r15,PACATOC(r13)
740+
ld r14,interrupt_base_book3e@got(r15)
741+
ld r15,__end_interrupts@got(r15)
742+
#else
738743
LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e)
739744
LOAD_REG_IMMEDIATE(r15,__end_interrupts)
745+
#endif
740746
cmpld cr0,r10,r14
741747
cmpld cr1,r10,r15
742748
blt+ cr0,1f
@@ -799,8 +805,14 @@ kernel_dbg_exc:
799805
andis. r15,r14,(DBSR_IC|DBSR_BT)@h
800806
beq+ 1f
801807

808+
#ifdef CONFIG_RELOCATABLE
809+
ld r15,PACATOC(r13)
810+
ld r14,interrupt_base_book3e@got(r15)
811+
ld r15,__end_interrupts@got(r15)
812+
#else
802813
LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e)
803814
LOAD_REG_IMMEDIATE(r15,__end_interrupts)
815+
#endif
804816
cmpld cr0,r10,r14
805817
cmpld cr1,r10,r15
806818
blt+ cr0,1f

0 commit comments

Comments
 (0)