]>
Commit | Line | Data |
---|---|---|
79adb0ff GKH |
1 | From ddc37832a1349f474c4532de381498020ed71d31 Mon Sep 17 00:00:00 2001 |
2 | From: Mark Rutland <mark.rutland@arm.com> | |
3 | Date: Fri, 6 Jan 2017 13:12:47 +0100 | |
4 | Subject: ARM: 8634/1: hw_breakpoint: blacklist Scorpion CPUs | |
5 | ||
6 | From: Mark Rutland <mark.rutland@arm.com> | |
7 | ||
8 | commit ddc37832a1349f474c4532de381498020ed71d31 upstream. | |
9 | ||
10 | On APQ8060, the kernel crashes in arch_hw_breakpoint_init, taking an | |
11 | undefined instruction trap within write_wb_reg. This is because Scorpion | |
12 | CPUs erroneously appear to set DBGPRSR.SPD when WFI is issued, even if | |
13 | the core is not powered down. When DBGPRSR.SPD is set, breakpoint and | |
14 | watchpoint registers are treated as undefined. | |
15 | ||
16 | It's possible to trigger similar crashes later on from userspace, by | |
17 | requesting the kernel to install a breakpoint or watchpoint, as we can | |
18 | go idle at any point between the reset of the debug registers and their | |
19 | later use. This has always been the case. | |
20 | ||
21 | Given that this has always been broken, no-one has complained until now, | |
22 | and there is no clear workaround, disable hardware breakpoints and | |
23 | watchpoints on Scorpion to avoid these issues. | |
24 | ||
25 | Signed-off-by: Mark Rutland <mark.rutland@arm.com> | |
26 | Reported-by: Linus Walleij <linus.walleij@linaro.org> | |
27 | Reviewed-by: Stephen Boyd <sboyd@codeaurora.org> | |
28 | Acked-by: Will Deacon <will.deacon@arm.com> | |
29 | Cc: Russell King <linux@armlinux.org.uk> | |
30 | Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> | |
31 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
32 | ||
33 | --- | |
34 | arch/arm/include/asm/cputype.h | 3 +++ | |
35 | arch/arm/kernel/hw_breakpoint.c | 16 ++++++++++++++++ | |
36 | 2 files changed, 19 insertions(+) | |
37 | ||
38 | --- a/arch/arm/include/asm/cputype.h | |
39 | +++ b/arch/arm/include/asm/cputype.h | |
40 | @@ -81,6 +81,9 @@ | |
41 | #define ARM_CPU_XSCALE_ARCH_V2 0x4000 | |
42 | #define ARM_CPU_XSCALE_ARCH_V3 0x6000 | |
43 | ||
44 | +/* Qualcomm implemented cores */ | |
45 | +#define ARM_CPU_PART_SCORPION 0x510002d0 | |
46 | + | |
47 | extern unsigned int processor_id; | |
48 | ||
49 | #ifdef CONFIG_CPU_CP15 | |
50 | --- a/arch/arm/kernel/hw_breakpoint.c | |
51 | +++ b/arch/arm/kernel/hw_breakpoint.c | |
52 | @@ -1066,6 +1066,22 @@ static int __init arch_hw_breakpoint_ini | |
53 | return 0; | |
54 | } | |
55 | ||
56 | + /* | |
57 | + * Scorpion CPUs (at least those in APQ8060) seem to set DBGPRSR.SPD | |
58 | + * whenever a WFI is issued, even if the core is not powered down, in | |
59 | + * violation of the architecture. When DBGPRSR.SPD is set, accesses to | |
60 | + * breakpoint and watchpoint registers are treated as undefined, so | |
61 | + * this results in boot time and runtime failures when these are | |
62 | + * accessed and we unexpectedly take a trap. | |
63 | + * | |
64 | + * It's not clear if/how this can be worked around, so we blacklist | |
65 | + * Scorpion CPUs to avoid these issues. | |
66 | + */ | |
67 | + if (read_cpuid_part() == ARM_CPU_PART_SCORPION) { | |
68 | + pr_info("Scorpion CPU detected. Hardware breakpoints and watchpoints disabled\n"); | |
69 | + return 0; | |
70 | + } | |
71 | + | |
72 | has_ossr = core_has_os_save_restore(); | |
73 | ||
74 | /* Determine how many BRPs/WRPs are available. */ |