aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/kernel/kprobes-common.c15
-rw-r--r--arch/arm/kernel/kprobes.h28
2 files changed, 43 insertions, 0 deletions
diff --git a/arch/arm/kernel/kprobes-common.c b/arch/arm/kernel/kprobes-common.c
index 32bb0f236684..a5394fb4e4e0 100644
--- a/arch/arm/kernel/kprobes-common.c
+++ b/arch/arm/kernel/kprobes-common.c
@@ -59,10 +59,25 @@ void __init test_load_write_pc_interworking(void)
59#endif /* !test_load_write_pc_interworking */ 59#endif /* !test_load_write_pc_interworking */
60 60
61 61
62#ifndef test_alu_write_pc_interworking
63
64bool alu_write_pc_interworks;
65
66void __init test_alu_write_pc_interworking(void)
67{
68 int arch = cpu_architecture();
69 BUG_ON(arch == CPU_ARCH_UNKNOWN);
70 alu_write_pc_interworks = arch >= CPU_ARCH_ARMv7;
71}
72
73#endif /* !test_alu_write_pc_interworking */
74
75
62void __init arm_kprobe_decode_init(void) 76void __init arm_kprobe_decode_init(void)
63{ 77{
64 find_str_pc_offset(); 78 find_str_pc_offset();
65 test_load_write_pc_interworking(); 79 test_load_write_pc_interworking();
80 test_alu_write_pc_interworking();
66} 81}
67 82
68 83
diff --git a/arch/arm/kernel/kprobes.h b/arch/arm/kernel/kprobes.h
index c442852e65e4..a6aeda0a6c7f 100644
--- a/arch/arm/kernel/kprobes.h
+++ b/arch/arm/kernel/kprobes.h
@@ -133,6 +133,34 @@ static inline void __kprobes load_write_pc(long pcv, struct pt_regs *regs)
133} 133}
134 134
135 135
136#if __LINUX_ARM_ARCH__ >= 7
137
138#define alu_write_pc_interworks true
139#define test_alu_write_pc_interworking()
140
141#elif __LINUX_ARM_ARCH__ <= 5
142
143/* Kernels built for <= ARMv5 should never run on >= ARMv6 hardware, so... */
144#define alu_write_pc_interworks false
145#define test_alu_write_pc_interworking()
146
147#else /* __LINUX_ARM_ARCH__ == 6 */
148
149/* We could be an ARMv6 binary on ARMv7 hardware so we need a run-time check. */
150extern bool alu_write_pc_interworks;
151void __init test_alu_write_pc_interworking(void);
152
153#endif /* __LINUX_ARM_ARCH__ == 6 */
154
155static inline void __kprobes alu_write_pc(long pcv, struct pt_regs *regs)
156{
157 if (alu_write_pc_interworks)
158 bx_write_pc(pcv, regs);
159 else
160 regs->ARM_pc = pcv;
161}
162
163
136void __kprobes kprobe_simulate_nop(struct kprobe *p, struct pt_regs *regs); 164void __kprobes kprobe_simulate_nop(struct kprobe *p, struct pt_regs *regs);
137void __kprobes kprobe_emulate_none(struct kprobe *p, struct pt_regs *regs); 165void __kprobes kprobe_emulate_none(struct kprobe *p, struct pt_regs *regs);
138 166