1 From fd615f69a18a9d4aa5ef02a1dc83f319f75da8e7 Mon Sep 17 00:00:00 2001
2 From: LiuHailong <liu.hailong6@zte.com.cn>
3 Date: Tue, 7 Feb 2017 10:35:52 +0800
4 Subject: powerpc/64e: Fix hang when debugging programs with relocated kernel
6 From: LiuHailong <liu.hailong6@zte.com.cn>
8 commit fd615f69a18a9d4aa5ef02a1dc83f319f75da8e7 upstream.
10 Debug interrupts can be taken during interrupt entry, since interrupt
11 entry does not automatically turn them off. The kernel will check
12 whether the faulting instruction is between [interrupt_base_book3e,
13 __end_interrupts], and if so clear MSR[DE] and return.
15 However, when the kernel is built with CONFIG_RELOCATABLE, it can't use
16 LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e) and
17 LOAD_REG_IMMEDIATE(r15,__end_interrupts), as they ignore relocation.
18 Thus, if the kernel is actually running at a different address than it
19 was built at, the address comparison will fail, and the exception entry
20 code will hang at kernel_dbg_exc.
22 r2(toc) is also not usable here, as r2 still holds data from the
23 interrupted context, so LOAD_REG_ADDR() doesn't work either. So we use
24 the *name@got* to get the EV of two labels directly.
26 Test programs test.c shows as follows:
27 int main(int argc, char *argv[])
29 if (access("/proc/sys/kernel/perf_event_paranoid", F_OK) == -1)
30 printf("Kernel doesn't have perf_event support\n");
33 Steps to reproduce the bug, for example:
39 Signed-off-by: Liu Hailong <liu.hailong6@zte.com.cn>
40 Signed-off-by: Jiang Xuexin <jiang.xuexin@zte.com.cn>
41 Reviewed-by: Jiang Biao <jiang.biao2@zte.com.cn>
42 Reviewed-by: Liu Song <liu.song11@zte.com.cn>
43 Reviewed-by: Huang Jian <huang.jian@zte.com.cn>
44 [scottwood: cleaned up commit message, and specified bad behavior
45 as a hang rather than an oops to correspond to mainline kernel behavior]
46 Fixes: 1cb6e0649248 ("powerpc/book3e: support CONFIG_RELOCATABLE")
47 Signed-off-by: Scott Wood <oss@buserror.net>
48 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
51 arch/powerpc/kernel/exceptions-64e.S | 12 ++++++++++++
52 1 file changed, 12 insertions(+)
54 --- a/arch/powerpc/kernel/exceptions-64e.S
55 +++ b/arch/powerpc/kernel/exceptions-64e.S
56 @@ -735,8 +735,14 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
57 andis. r15,r14,(DBSR_IC|DBSR_BT)@h
60 +#ifdef CONFIG_RELOCATABLE
62 + ld r14,interrupt_base_book3e@got(r15)
63 + ld r15,__end_interrupts@got(r15)
65 LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e)
66 LOAD_REG_IMMEDIATE(r15,__end_interrupts)
71 @@ -799,8 +805,14 @@ kernel_dbg_exc:
72 andis. r15,r14,(DBSR_IC|DBSR_BT)@h
75 +#ifdef CONFIG_RELOCATABLE
77 + ld r14,interrupt_base_book3e@got(r15)
78 + ld r15,__end_interrupts@got(r15)
80 LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e)
81 LOAD_REG_IMMEDIATE(r15,__end_interrupts)