summaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/kprobes-common.c
diff options
context:
space:
mode:
authorJon Medhurst <tixy@yxit.co.uk>2011-07-01 18:32:06 +0200
committerTixy <tixy@medhuaa1.miniserver.com>2011-07-13 19:32:48 +0200
commitdf4fa1f8dde23db25f50e49535d2c7db0005f9ad (patch)
treeafd56bec1275665bcd429e0dbe91352596436152 /arch/arm/kernel/kprobes-common.c
parentARM: kprobes: Migrate ARM space_1111 to decoding tables (diff)
downloadlinux-df4fa1f8dde23db25f50e49535d2c7db0005f9ad.tar.xz
linux-df4fa1f8dde23db25f50e49535d2c7db0005f9ad.zip
ARM: kprobes: Add alu_write_pc()
This writes a new value to PC which was obtained as the result of an ARM ALU instruction. For ARMv7 and later this performs interworking. On ARM kernels we shouldn't encounter any ALU instructions trying to switch to Thumb mode so support for this isn't strictly necessary. However, the approach taken in all other instruction decoding is for us to avoid unpredictable modification of the PC for security reasons. This is usually achieved by rejecting insertion of probes on problematic instruction, but for ALU instructions we can't do this as it depends on the contents of the CPU registers at the time the probe is hit. So, as we require some form of run-time checking to trap undesirable PC modification, we may as well simulate the instructions correctly, i.e. in the way they would behave in the absence of a probe. Signed-off-by: Jon Medhurst <tixy@yxit.co.uk> Acked-by: Nicolas Pitre <nicolas.pitre@linaro.org>
Diffstat (limited to 'arch/arm/kernel/kprobes-common.c')
-rw-r--r--arch/arm/kernel/kprobes-common.c15
1 files changed, 15 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)
#endif /* !test_load_write_pc_interworking */
+#ifndef test_alu_write_pc_interworking
+
+bool alu_write_pc_interworks;
+
+void __init test_alu_write_pc_interworking(void)
+{
+ int arch = cpu_architecture();
+ BUG_ON(arch == CPU_ARCH_UNKNOWN);
+ alu_write_pc_interworks = arch >= CPU_ARCH_ARMv7;
+}
+
+#endif /* !test_alu_write_pc_interworking */
+
+
void __init arm_kprobe_decode_init(void)
{
find_str_pc_offset();
test_load_write_pc_interworking();
+ test_alu_write_pc_interworking();
}