ARM: kprobes: OPTPROBES and other improvements.
Subsystems (6)
v19 cover ARM: kprobes: OPTPROBES and other improvements.
According to Masami Hiramatsu's suggestion, there are some small code adjustments in this series of patch.
Jon Medhurst (Tixy) (2):
ARM: kprobes: Add test cases for stack consuming instructions
ARM: kprobes: Fix unreliable MRS instruction tests
Masami Hiramatsu (1):
kprobes: Pass the original kprobe for preparing optimized kprobe
Wang Nan (8):
ARM: probes: move all probe code to dedicate directory
ARM: kprobes: remove unused ARM decoder actions.
ARM: kprobes: introduces checker
ARM: kprobes: collects stack consumption for store instructions
ARM: kprobes: disallow probing stack consuming instructions
ARM: kprobes: enable OPTPROBES for ARM 32
ARM: kprobes: check register usage for probed instruction.
ARM: optprobes: execute instruction during restoring if possible.
arch/arm/Kconfig | 1 +
arch/arm/Makefile | 1 +
arch/arm/{kernel => include/asm}/insn.h | 0
arch/arm/include/asm/kprobes.h | 30 +-
arch/arm/{kernel => include/asm}/patch.h | 0
arch/arm/include/asm/probes.h | 23 ++
arch/arm/kernel/Makefile | 16 +-
arch/arm/kernel/entry-armv.S | 3 +-
arch/arm/kernel/ftrace.c | 3 +-
arch/arm/kernel/jump_label.c | 5 +-
arch/arm/kernel/patch.c | 3 +-
arch/arm/probes/Makefile | 7 +
.../{kernel/probes-arm.c => probes/decode-arm.c} | 12 +-
.../{kernel/probes-arm.h => probes/decode-arm.h} | 10 +-
.../probes-thumb.c => probes/decode-thumb.c} | 16 +-
.../probes-thumb.h => probes/decode-thumb.h} | 10 +-
arch/arm/{kernel/probes.c => probes/decode.c} | 81 +++++-
arch/arm/{kernel/probes.h => probes/decode.h} | 13 +-
arch/arm/probes/kprobes/Makefile | 12 +
.../kprobes-arm.c => probes/kprobes/actions-arm.c} | 12 +-
.../kprobes/actions-common.c} | 4 +-
.../kprobes/actions-thumb.c} | 10 +-
arch/arm/probes/kprobes/checkers-arm.c | 223 +++++++++++++++
arch/arm/probes/kprobes/checkers-common.c | 101 +++++++
arch/arm/probes/kprobes/checkers-thumb.c | 110 +++++++
arch/arm/probes/kprobes/checkers.h | 55 ++++
.../{kernel/kprobes.c => probes/kprobes/core.c} | 49 +++-
.../{kernel/kprobes.h => probes/kprobes/core.h} | 12 +-
arch/arm/probes/kprobes/opt-arm.c | 317 +++++++++++++++++++++
.../kprobes/test-arm.c} | 37 ++-
.../kprobes-test.c => probes/kprobes/test-core.c} | 36 ++-
.../kprobes-test.h => probes/kprobes/test-core.h} | 35 ++-
.../kprobes/test-thumb.c} | 20 +-
arch/arm/probes/uprobes/Makefile | 1 +
.../uprobes-arm.c => probes/uprobes/actions-arm.c} | 9 +-
.../{kernel/uprobes.c => probes/uprobes/core.c} | 8 +-
.../{kernel/uprobes.h => probes/uprobes/core.h} | 0
arch/x86/kernel/kprobes/opt.c | 3 +-
include/linux/kprobes.h | 3 +-
kernel/kprobes.c | 4 +-
40 files changed, 1169 insertions(+), 126 deletions(-)
rename arch/arm/{kernel => include/asm}/insn.h (100%)
rename arch/arm/{kernel => include/asm}/patch.h (100%)
create mode 100644 arch/arm/probes/Makefile
rename arch/arm/{kernel/probes-arm.c => probes/decode-arm.c} (99%)
rename arch/arm/{kernel/probes-arm.h => probes/decode-arm.h} (92%)
rename arch/arm/{kernel/probes-thumb.c => probes/decode-thumb.c} (98%)
rename arch/arm/{kernel/probes-thumb.h => probes/decode-thumb.h} (90%)
rename arch/arm/{kernel/probes.c => probes/decode.c} (84%)
rename arch/arm/{kernel/probes.h => probes/decode.h} (97%)
create mode 100644 arch/arm/probes/kprobes/Makefile
rename arch/arm/{kernel/kprobes-arm.c => probes/kprobes/actions-arm.c} (97%)
rename arch/arm/{kernel/kprobes-common.c => probes/kprobes/actions-common.c} (98%)
rename arch/arm/{kernel/kprobes-thumb.c => probes/kprobes/actions-thumb.c} (98%)
create mode 100644 arch/arm/probes/kprobes/checkers-arm.c
create mode 100644 arch/arm/probes/kprobes/checkers-common.c
create mode 100644 arch/arm/probes/kprobes/checkers-thumb.c
create mode 100644 arch/arm/probes/kprobes/checkers.h
rename arch/arm/{kernel/kprobes.c => probes/kprobes/core.c} (94%)
rename arch/arm/{kernel/kprobes.h => probes/kprobes/core.h} (79%)
create mode 100644 arch/arm/probes/kprobes/opt-arm.c
rename arch/arm/{kernel/kprobes-test-arm.c => probes/kprobes/test-arm.c} (97%)
rename arch/arm/{kernel/kprobes-test.c => probes/kprobes/test-core.c} (98%)
rename arch/arm/{kernel/kprobes-test.h => probes/kprobes/test-core.h} (92%)
rename arch/arm/{kernel/kprobes-test-thumb.c => probes/kprobes/test-thumb.c} (97%)
create mode 100644 arch/arm/probes/uprobes/Makefile
rename arch/arm/{kernel/uprobes-arm.c => probes/uprobes/actions-arm.c} (96%)
rename arch/arm/{kernel/uprobes.c => probes/uprobes/core.c} (97%)
rename arch/arm/{kernel/uprobes.h => probes/uprobes/core.h} (100%)Signature · 1 line
1.8.4
PATCH v19 1/11 ARM: probes: move all probe code to dedicate directory
In discussion on LKML (https://lkml.org/lkml/2014/11/28/158), Russell King suggests to move all probe related code to arch/arm/probes. This patch does the work. Due to dependency on 'arch/arm/kernel/patch.h', this patch also moves patch.h to 'arch/arm/include/asm/patch.h', and related '#include' directives are also midified to '#include <asm/patch.h>'.
Following is an overview of this patch:
./arch/arm/kernel/ ./arch/arm/probes/ |-- Makefile |-- Makefile |-- probes-arm.c ==> |-- decode-arm.c |-- probes-arm.h ==> |-- decode-arm.h |-- probes-thumb.c ==> |-- decode-thumb.c |-- probes-thumb.h ==> |-- decode-thumb.h |-- probes.c ==> |-- decode.c |-- probes.h ==> |-- decode.h | |-- kprobes | | |-- Makefile |-- kprobes-arm.c ==> | |-- actions-arm.c |-- kprobes-common.c ==> | |-- actions-common.c |-- kprobes-thumb.c ==> | |-- actions-thumb.c |-- kprobes.c ==> | |-- core.c |-- kprobes.h ==> | |-- core.h |-- kprobes-test-arm.c ==> | |-- test-arm.c |-- kprobes-test.c ==> | |-- test-core.c |-- kprobes-test.h ==> | |-- test-core.h |-- kprobes-test-thumb.c ==> | `-- test-thumb.c | `-- uprobes | |-- Makefile |-- uprobes-arm.c ==> |-- actions-arm.c |-- uprobes.c ==> |-- core.c |-- uprobes.h ==> `-- core.h | `-- patch.h ==> arch/arm/include/asm/patch.h
---
arch/arm/Makefile | 1 +
arch/arm/{kernel => include/asm}/patch.h | 0
arch/arm/kernel/Makefile | 16 ++--------------
arch/arm/kernel/jump_label.c | 2 +-
arch/arm/kernel/patch.c | 3 +--
arch/arm/probes/Makefile | 7 +++++++
arch/arm/{kernel/probes-arm.c => probes/decode-arm.c} | 7 ++++---
arch/arm/{kernel/probes-arm.h => probes/decode-arm.h} | 4 +++-
.../arm/{kernel/probes-thumb.c => probes/decode-thumb.c} | 6 +++---
.../arm/{kernel/probes-thumb.h => probes/decode-thumb.h} | 4 +++-
arch/arm/{kernel/probes.c => probes/decode.c} | 4 ++--
arch/arm/{kernel/probes.h => probes/decode.h} | 2 +-
arch/arm/probes/kprobes/Makefile | 11 +++++++++++
.../kprobes-arm.c => probes/kprobes/actions-arm.c} | 6 +++---
.../kprobes-common.c => probes/kprobes/actions-common.c} | 4 ++--
.../kprobes-thumb.c => probes/kprobes/actions-thumb.c} | 6 +++---
arch/arm/{kernel/kprobes.c => probes/kprobes/core.c} | 8 ++++----
arch/arm/{kernel/kprobes.h => probes/kprobes/core.h} | 3 ++-
.../kprobes-test-arm.c => probes/kprobes/test-arm.c} | 2 +-
.../kprobes-test.c => probes/kprobes/test-core.c} | 8 ++++----
.../kprobes-test.h => probes/kprobes/test-core.h} | 2 +-
.../kprobes-test-thumb.c => probes/kprobes/test-thumb.c} | 4 ++--
arch/arm/probes/uprobes/Makefile | 1 +
.../uprobes-arm.c => probes/uprobes/actions-arm.c} | 6 +++---
arch/arm/{kernel/uprobes.c => probes/uprobes/core.c} | 6 +++---
arch/arm/{kernel/uprobes.h => probes/uprobes/core.h} | 0
26 files changed, 68 insertions(+), 55 deletions(-)
rename arch/arm/{kernel => include/asm}/patch.h (100%)
create mode 100644 arch/arm/probes/Makefile
rename arch/arm/{kernel/probes-arm.c => probes/decode-arm.c} (99%)
rename arch/arm/{kernel/probes-arm.h => probes/decode-arm.h} (97%)
rename arch/arm/{kernel/probes-thumb.c => probes/decode-thumb.c} (99%)
rename arch/arm/{kernel/probes-thumb.h => probes/decode-thumb.h} (97%)
rename arch/arm/{kernel/probes.c => probes/decode.c} (99%)
rename arch/arm/{kernel/probes.h => probes/decode.h} (99%)
create mode 100644 arch/arm/probes/kprobes/Makefile
rename arch/arm/{kernel/kprobes-arm.c => probes/kprobes/actions-arm.c} (99%)
rename arch/arm/{kernel/kprobes-common.c => probes/kprobes/actions-common.c} (98%)
rename arch/arm/{kernel/kprobes-thumb.c => probes/kprobes/actions-thumb.c} (99%)
rename arch/arm/{kernel/kprobes.c => probes/kprobes/core.c} (99%)
rename arch/arm/{kernel/kprobes.h => probes/kprobes/core.h} (96%)
rename arch/arm/{kernel/kprobes-test-arm.c => probes/kprobes/test-arm.c} (99%)
rename arch/arm/{kernel/kprobes-test.c => probes/kprobes/test-core.c} (99%)
rename arch/arm/{kernel/kprobes-test.h => probes/kprobes/test-core.h} (99%)
rename arch/arm/{kernel/kprobes-test-thumb.c => probes/kprobes/test-thumb.c} (99%)
create mode 100644 arch/arm/probes/uprobes/Makefile
rename arch/arm/{kernel/uprobes-arm.c => probes/uprobes/actions-arm.c} (98%)
rename arch/arm/{kernel/uprobes.c => probes/uprobes/core.c} (98%)
rename arch/arm/{kernel/uprobes.h => probes/uprobes/core.h} (100%)arch/arm/Makefile +1 -0
@@ -266,6 +266,7 @@ core-$(CONFIG_KVM_ARM_HOST) += arch/arm/kvm/ # If we have a machine-specific directory, then include it in the build. core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/ +core-y += arch/arm/probes/ core-y += arch/arm/net/ core-y += arch/arm/crypto/ core-y += arch/arm/firmware/
arch/arm/include/asm/patch.h renamed from arch/arm/kernel/patch.h +0 -0
arch/arm/kernel/Makefile +2 -14
@@ -51,20 +51,8 @@ obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o insn.o obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o insn.o obj-$(CONFIG_JUMP_LABEL) += jump_label.o insn.o patch.o obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o -obj-$(CONFIG_UPROBES) += probes.o probes-arm.o uprobes.o uprobes-arm.o -obj-$(CONFIG_KPROBES) += probes.o kprobes.o kprobes-common.o patch.o -ifdef CONFIG_THUMB2_KERNEL -obj-$(CONFIG_KPROBES) += kprobes-thumb.o probes-thumb.o -else -obj-$(CONFIG_KPROBES) += kprobes-arm.o probes-arm.o -endif -obj-$(CONFIG_ARM_KPROBES_TEST) += test-kprobes.o -test-kprobes-objs := kprobes-test.o -ifdef CONFIG_THUMB2_KERNEL -test-kprobes-objs += kprobes-test-thumb.o -else -test-kprobes-objs += kprobes-test-arm.o -endif +# Main staffs in KPROBES are in arch/arm/probes/ . +obj-$(CONFIG_KPROBES) += patch.o obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o obj-$(CONFIG_ARM_THUMBEE) += thumbee.o obj-$(CONFIG_KGDB) += kgdb.o patch.o
arch/arm/kernel/jump_label.c +1 -1
@@ -1,8 +1,8 @@#include <linux/kernel.h> #include <linux/jump_label.h> +#include <asm/patch.h> #include "insn.h" -#include "patch.h" #ifdef HAVE_JUMP_LABEL
arch/arm/kernel/patch.c +1 -2
@@ -8,8 +8,7 @@#include <asm/fixmap.h> #include <asm/smp_plat.h> #include <asm/opcodes.h> - -#include "patch.h" +#include <asm/patch.h> struct patch {void *addr;
arch/arm/probes/Makefile new file +7 -0
@@ -0,0 +1,7 @@ +obj-$(CONFIG_UPROBES) += decode.o decode-arm.o uprobes/ +obj-$(CONFIG_KPROBES) += decode.o kprobes/ +ifdef CONFIG_THUMB2_KERNEL +obj-$(CONFIG_KPROBES) += decode-thumb.o +else +obj-$(CONFIG_KPROBES) += decode-arm.o +endif
arch/arm/probes/decode-arm.c renamed from arch/arm/kernel/probes-arm.c +4 -3
@@ -1,5 +1,6 @@/* -* arch/arm/kernel/probes-arm.c +* +* arch/arm/probes/decode-arm.c * * Some code moved here from arch/arm/kernel/kprobes-arm.c *
@@ -20,8 +21,8 @@#include <linux/stddef.h> #include <linux/ptrace.h> -#include "probes.h" -#include "probes-arm.h" +#include "decode.h" +#include "decode-arm.h" #define sign_extend (x, signbit) ((x) | (0 - ((x) & (1 << (signbit)))))
arch/arm/probes/decode-arm.h renamed from arch/arm/kernel/probes-arm.h +3 -1
@@ -1,5 +1,5 @@/* -* arch/arm/kernel/probes-arm.h +* arch/arm/probes/decode-arm.h * * Copyright 2013 Linaro Ltd. * Written by: David A. Long
@@ -15,6 +15,8 @@#ifndef _ARM_KERNEL_PROBES_ARM_H#define _ARM_KERNEL_PROBES_ARM_H +#include "decode.h" +enum probes_arm_action {PROBES_EMULATE_NONE , PROBES_SIMULATE_NOP,
arch/arm/probes/decode-thumb.c renamed from arch/arm/kernel/probes-thumb.c +3 -3
@@ -1,5 +1,5 @@/* -* arch/arm/kernel/probes-thumb.c +* arch/arm/probes/decode-thumb.c * * Copyright (C) 2011 Jon Medhurst <[email protected]>. *
@@ -12,8 +12,8 @@#include <linux/kernel.h> #include <linux/module.h> -#include "probes.h" -#include "probes-thumb.h" +#include "decode.h" +#include "decode-thumb.h" static const union decode_item t32_table_1110_100x_x0xx[] = {
arch/arm/probes/decode-thumb.h renamed from arch/arm/kernel/probes-thumb.h +3 -1
@@ -1,5 +1,5 @@/* -* arch/arm/kernel/probes-thumb.h +* arch/arm/probes/decode-thumb.h * * Copyright 2013 Linaro Ltd. * Written by: David A. Long
@@ -15,6 +15,8 @@#ifndef _ARM_KERNEL_PROBES_THUMB_H#define _ARM_KERNEL_PROBES_THUMB_H +#include "decode.h" +/* * True if current instruction is in an IT block. */
arch/arm/probes/decode.c renamed from arch/arm/kernel/probes.c +2 -2
@@ -1,5 +1,5 @@/* -* arch/arm/kernel/probes.c +* arch/arm/probes/decode.c * * Copyright (C) 2011 Jon Medhurst <[email protected]>. *
@@ -17,7 +17,7 @@#include <asm/ptrace.h> #include <linux/bug.h> -#include "probes.h" +#include "decode.h" #ifndef find_str_pc_offset
arch/arm/probes/decode.h renamed from arch/arm/kernel/probes.h +1 -1
@@ -1,5 +1,5 @@/* -* arch/arm/kernel/probes.h +* arch/arm/probes/decode.h * * Copyright (C) 2011 Jon Medhurst <[email protected]>. *
arch/arm/probes/kprobes/Makefile new file +11 -0
@@ -0,0 +1,11 @@ +obj-$(CONFIG_KPROBES) += core.o actions-common.o +obj-$(CONFIG_ARM_KPROBES_TEST) += test-kprobes.o +test-kprobes-objs := test-core.o + +ifdef CONFIG_THUMB2_KERNEL +obj-$(CONFIG_KPROBES) += actions-thumb.o +test-kprobes-objs += test-thumb.o +else +obj-$(CONFIG_KPROBES) += actions-arm.o +test-kprobes-objs += test-arm.o +endif
arch/arm/probes/kprobes/actions-arm.c renamed from arch/arm/kernel/kprobes-arm.c +3 -3
@@ -1,5 +1,5 @@/* -* arch/arm/kernel/kprobes-decode.c +* arch/arm/probes/kprobes/actions-arm.c * * Copyright (C) 2006, 2007 Motorola Inc. *
@@ -62,8 +62,8 @@#include <linux/kprobes.h> #include <linux/ptrace.h> -#include "kprobes.h" -#include "probes-arm.h" +#include "../decode-arm.h" +#include "core.h" #if __LINUX_ARM_ARCH__ >=6 #define BLX (reg) "blx "reg" \n\t"
arch/arm/probes/kprobes/actions-common.c renamed from arch/arm/kernel/kprobes-common.c +2 -2
@@ -1,5 +1,5 @@/* -* arch/arm/kernel/kprobes-common.c +* arch/arm/probes/kprobes/actions-common.c * * Copyright (C) 2011 Jon Medhurst <[email protected]>. *
@@ -15,7 +15,7 @@#include <linux/kprobes.h> #include <asm/opcodes.h> -#include "kprobes.h" +#include "core.h" static void __kprobes simulate_ldm1stm1(probes_opcode_t insn,
arch/arm/probes/kprobes/actions-thumb.c renamed from arch/arm/kernel/kprobes-thumb.c +3 -3
@@ -1,5 +1,5 @@/* -* arch/arm/kernel/kprobes-thumb.c +* arch/arm/probes/kprobes/actions-thumb.c * * Copyright (C) 2011 Jon Medhurst <[email protected]>. *
@@ -13,8 +13,8 @@#include <linux/ptrace.h> #include <linux/kprobes.h> -#include "kprobes.h" -#include "probes-thumb.h" +#include "../decode-thumb.h" +#include "core.h" /* These emulation encodings are functionally equivalent... */ #define t32_emulate_rd8rn16rm0ra12_noflags \
arch/arm/probes/kprobes/core.c renamed from arch/arm/kernel/kprobes.c +4 -4
@@ -30,11 +30,11 @@#include <asm/cacheflush.h> #include <linux/percpu.h> #include <linux/bug.h> +#include <asm/patch.h> -#include "kprobes.h" -#include "probes-arm.h" -#include "probes-thumb.h" -#include "patch.h" +#include "../decode-arm.h" +#include "../decode-thumb.h" +#include "core.h" #define MIN_STACK_SIZE (addr) \ min((unsigned long)MAX_STACK_SIZE, \
arch/arm/probes/kprobes/core.h renamed from arch/arm/kernel/kprobes.h +2 -1
@@ -19,7 +19,8 @@#ifndef _ARM_KERNEL_KPROBES_H#define _ARM_KERNEL_KPROBES_H -#include "probes.h" +#include <asm/kprobes.h> +#include "../decode.h" /* * These undefined instructions must be unique and
arch/arm/probes/kprobes/test-arm.c renamed from arch/arm/kernel/kprobes-test-arm.c +1 -1
@@ -13,7 +13,7 @@#include <asm/system_info.h> #include <asm/opcodes.h> -#include "kprobes-test.h" +#include "test-core.h" #define TEST_ISA "32"
arch/arm/probes/kprobes/test-core.c renamed from arch/arm/kernel/kprobes-test.c +4 -4
@@ -209,10 +209,10 @@#include <linux/bug.h> #include <asm/opcodes.h> -#include "kprobes.h" -#include "probes-arm.h" -#include "probes-thumb.h" -#include "kprobes-test.h" +#include "core.h" +#include "test-core.h" +#include "../decode-arm.h" +#include "../decode-thumb.h" #define BENCHMARKING 1
arch/arm/probes/kprobes/test-core.h renamed from arch/arm/kernel/kprobes-test.h +1 -1
@@ -1,5 +1,5 @@/* -* arch/arm/kernel/kprobes-test.h +* arch/arm/probes/kprobes/test-core.h * * Copyright (C) 2011 Jon Medhurst <[email protected]>. *
arch/arm/probes/kprobes/test-thumb.c renamed from arch/arm/kernel/kprobes-test-thumb.c +2 -2
@@ -1,5 +1,5 @@/* -* arch/arm/kernel/kprobes-test-thumb.c +* arch/arm/probes/kprobes/test-thumb.c * * Copyright (C) 2011 Jon Medhurst <[email protected]>. *
@@ -12,7 +12,7 @@#include <linux/module.h> #include <asm/opcodes.h> -#include "kprobes-test.h" +#include "test-core.h" #define TEST_ISA "16"
arch/arm/probes/uprobes/Makefile new file +1 -0
@@ -0,0 +1 @@ +obj-$(CONFIG_UPROBES) += core.o actions-arm.o
arch/arm/probes/uprobes/actions-arm.c renamed from arch/arm/kernel/uprobes-arm.c +3 -3
@@ -13,9 +13,9 @@#include <linux/uprobes.h> #include <linux/module.h> -#include "probes.h" -#include "probes-arm.h" -#include "uprobes.h" +#include "../decode.h" +#include "../decode-arm.h" +#include "core.h" static int uprobes_substitute_pc (unsigned long *pinsn,u32 oregs) {
arch/arm/probes/uprobes/core.c renamed from arch/arm/kernel/uprobes.c +3 -3
@@ -17,9 +17,9 @@#include <asm/opcodes.h> #include <asm/traps.h> -#include "probes.h" -#include "probes-arm.h" -#include "uprobes.h" +#include "../decode.h" +#include "../decode-arm.h" +#include "core.h" #define UPROBE_TRAP_NR UINT_MAX
arch/arm/probes/uprobes/core.h renamed from arch/arm/kernel/uprobes.h +0 -0
Signature · 1 line
1.8.4
PATCH v20 1/11 ARM: probes: move all probe code to dedicate directory
In discussion on LKML (https://lkml.org/lkml/2014/11/28/158), Russell King suggests to move all probe related code to arch/arm/probes. This patch does the work. Due to dependency on 'arch/arm/kernel/patch.h', this patch also moves patch.h to 'arch/arm/include/asm/patch.h', and related '#include' directives are also midified to '#include <asm/patch.h>'.
Following is an overview of this patch:
./arch/arm/kernel/ ./arch/arm/probes/ |-- Makefile |-- Makefile |-- probes-arm.c ==> |-- decode-arm.c |-- probes-arm.h ==> |-- decode-arm.h |-- probes-thumb.c ==> |-- decode-thumb.c |-- probes-thumb.h ==> |-- decode-thumb.h |-- probes.c ==> |-- decode.c |-- probes.h ==> |-- decode.h | |-- kprobes | | |-- Makefile |-- kprobes-arm.c ==> | |-- actions-arm.c |-- kprobes-common.c ==> | |-- actions-common.c |-- kprobes-thumb.c ==> | |-- actions-thumb.c |-- kprobes.c ==> | |-- core.c |-- kprobes.h ==> | |-- core.h |-- kprobes-test-arm.c ==> | |-- test-arm.c |-- kprobes-test.c ==> | |-- test-core.c |-- kprobes-test.h ==> | |-- test-core.h |-- kprobes-test-thumb.c ==> | `-- test-thumb.c | `-- uprobes | |-- Makefile |-- uprobes-arm.c ==> |-- actions-arm.c |-- uprobes.c ==> |-- core.c |-- uprobes.h ==> `-- core.h | `-- patch.h ==> arch/arm/include/asm/patch.h
---
arch/arm/Makefile | 1 +
arch/arm/{kernel => include/asm}/patch.h | 0
arch/arm/kernel/Makefile | 16 ++--------------
arch/arm/kernel/jump_label.c | 2 +-
arch/arm/kernel/kgdb.c | 2 +-
arch/arm/kernel/patch.c | 3 +--
arch/arm/probes/Makefile | 7 +++++++
arch/arm/{kernel/probes-arm.c => probes/decode-arm.c} | 7 ++++---
arch/arm/{kernel/probes-arm.h => probes/decode-arm.h} | 4 +++-
.../arm/{kernel/probes-thumb.c => probes/decode-thumb.c} | 6 +++---
.../arm/{kernel/probes-thumb.h => probes/decode-thumb.h} | 4 +++-
arch/arm/{kernel/probes.c => probes/decode.c} | 4 ++--
arch/arm/{kernel/probes.h => probes/decode.h} | 2 +-
arch/arm/probes/kprobes/Makefile | 11 +++++++++++
.../kprobes-arm.c => probes/kprobes/actions-arm.c} | 6 +++---
.../kprobes-common.c => probes/kprobes/actions-common.c} | 4 ++--
.../kprobes-thumb.c => probes/kprobes/actions-thumb.c} | 6 +++---
arch/arm/{kernel/kprobes.c => probes/kprobes/core.c} | 8 ++++----
arch/arm/{kernel/kprobes.h => probes/kprobes/core.h} | 3 ++-
.../kprobes-test-arm.c => probes/kprobes/test-arm.c} | 2 +-
.../kprobes-test.c => probes/kprobes/test-core.c} | 8 ++++----
.../kprobes-test.h => probes/kprobes/test-core.h} | 2 +-
.../kprobes-test-thumb.c => probes/kprobes/test-thumb.c} | 4 ++--
arch/arm/probes/uprobes/Makefile | 1 +
.../uprobes-arm.c => probes/uprobes/actions-arm.c} | 6 +++---
arch/arm/{kernel/uprobes.c => probes/uprobes/core.c} | 6 +++---
arch/arm/{kernel/uprobes.h => probes/uprobes/core.h} | 0
27 files changed, 69 insertions(+), 56 deletions(-)
rename arch/arm/{kernel => include/asm}/patch.h (100%)
create mode 100644 arch/arm/probes/Makefile
rename arch/arm/{kernel/probes-arm.c => probes/decode-arm.c} (99%)
rename arch/arm/{kernel/probes-arm.h => probes/decode-arm.h} (97%)
rename arch/arm/{kernel/probes-thumb.c => probes/decode-thumb.c} (99%)
rename arch/arm/{kernel/probes-thumb.h => probes/decode-thumb.h} (97%)
rename arch/arm/{kernel/probes.c => probes/decode.c} (99%)
rename arch/arm/{kernel/probes.h => probes/decode.h} (99%)
create mode 100644 arch/arm/probes/kprobes/Makefile
rename arch/arm/{kernel/kprobes-arm.c => probes/kprobes/actions-arm.c} (99%)
rename arch/arm/{kernel/kprobes-common.c => probes/kprobes/actions-common.c} (98%)
rename arch/arm/{kernel/kprobes-thumb.c => probes/kprobes/actions-thumb.c} (99%)
rename arch/arm/{kernel/kprobes.c => probes/kprobes/core.c} (99%)
rename arch/arm/{kernel/kprobes.h => probes/kprobes/core.h} (96%)
rename arch/arm/{kernel/kprobes-test-arm.c => probes/kprobes/test-arm.c} (99%)
rename arch/arm/{kernel/kprobes-test.c => probes/kprobes/test-core.c} (99%)
rename arch/arm/{kernel/kprobes-test.h => probes/kprobes/test-core.h} (99%)
rename arch/arm/{kernel/kprobes-test-thumb.c => probes/kprobes/test-thumb.c} (99%)
create mode 100644 arch/arm/probes/uprobes/Makefile
rename arch/arm/{kernel/uprobes-arm.c => probes/uprobes/actions-arm.c} (98%)
rename arch/arm/{kernel/uprobes.c => probes/uprobes/core.c} (98%)
rename arch/arm/{kernel/uprobes.h => probes/uprobes/core.h} (100%)arch/arm/Makefile +1 -0
@@ -266,6 +266,7 @@ core-$(CONFIG_KVM_ARM_HOST) += arch/arm/kvm/ # If we have a machine-specific directory, then include it in the build. core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/ +core-y += arch/arm/probes/ core-y += arch/arm/net/ core-y += arch/arm/crypto/ core-y += arch/arm/firmware/
arch/arm/include/asm/patch.h renamed from arch/arm/kernel/patch.h +0 -0
arch/arm/kernel/Makefile +2 -14
@@ -51,20 +51,8 @@ obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o insn.o obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o insn.o obj-$(CONFIG_JUMP_LABEL) += jump_label.o insn.o patch.o obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o -obj-$(CONFIG_UPROBES) += probes.o probes-arm.o uprobes.o uprobes-arm.o -obj-$(CONFIG_KPROBES) += probes.o kprobes.o kprobes-common.o patch.o -ifdef CONFIG_THUMB2_KERNEL -obj-$(CONFIG_KPROBES) += kprobes-thumb.o probes-thumb.o -else -obj-$(CONFIG_KPROBES) += kprobes-arm.o probes-arm.o -endif -obj-$(CONFIG_ARM_KPROBES_TEST) += test-kprobes.o -test-kprobes-objs := kprobes-test.o -ifdef CONFIG_THUMB2_KERNEL -test-kprobes-objs += kprobes-test-thumb.o -else -test-kprobes-objs += kprobes-test-arm.o -endif +# Main staffs in KPROBES are in arch/arm/probes/ . +obj-$(CONFIG_KPROBES) += patch.o obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o obj-$(CONFIG_ARM_THUMBEE) += thumbee.o obj-$(CONFIG_KGDB) += kgdb.o patch.o
arch/arm/kernel/jump_label.c +1 -1
@@ -1,8 +1,8 @@#include <linux/kernel.h> #include <linux/jump_label.h> +#include <asm/patch.h> #include "insn.h" -#include "patch.h" #ifdef HAVE_JUMP_LABEL
arch/arm/kernel/kgdb.c +1 -1
@@ -16,7 +16,7 @@#include <asm/traps.h> -#include "patch.h" +#include <asm/patch.h> struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM ] = {
arch/arm/kernel/patch.c +1 -2
@@ -8,8 +8,7 @@#include <asm/fixmap.h> #include <asm/smp_plat.h> #include <asm/opcodes.h> - -#include "patch.h" +#include <asm/patch.h> struct patch {void *addr;
arch/arm/probes/Makefile new file +7 -0
@@ -0,0 +1,7 @@ +obj-$(CONFIG_UPROBES) += decode.o decode-arm.o uprobes/ +obj-$(CONFIG_KPROBES) += decode.o kprobes/ +ifdef CONFIG_THUMB2_KERNEL +obj-$(CONFIG_KPROBES) += decode-thumb.o +else +obj-$(CONFIG_KPROBES) += decode-arm.o +endif
arch/arm/probes/decode-arm.c renamed from arch/arm/kernel/probes-arm.c +4 -3
@@ -1,5 +1,6 @@/* -* arch/arm/kernel/probes-arm.c +* +* arch/arm/probes/decode-arm.c * * Some code moved here from arch/arm/kernel/kprobes-arm.c *
@@ -20,8 +21,8 @@#include <linux/stddef.h> #include <linux/ptrace.h> -#include "probes.h" -#include "probes-arm.h" +#include "decode.h" +#include "decode-arm.h" #define sign_extend (x, signbit) ((x) | (0 - ((x) & (1 << (signbit)))))
arch/arm/probes/decode-arm.h renamed from arch/arm/kernel/probes-arm.h +3 -1
@@ -1,5 +1,5 @@/* -* arch/arm/kernel/probes-arm.h +* arch/arm/probes/decode-arm.h * * Copyright 2013 Linaro Ltd. * Written by: David A. Long
@@ -15,6 +15,8 @@#ifndef _ARM_KERNEL_PROBES_ARM_H#define _ARM_KERNEL_PROBES_ARM_H +#include "decode.h" +enum probes_arm_action {PROBES_EMULATE_NONE , PROBES_SIMULATE_NOP,
arch/arm/probes/decode-thumb.c renamed from arch/arm/kernel/probes-thumb.c +3 -3
@@ -1,5 +1,5 @@/* -* arch/arm/kernel/probes-thumb.c +* arch/arm/probes/decode-thumb.c * * Copyright (C) 2011 Jon Medhurst <[email protected]>. *
@@ -12,8 +12,8 @@#include <linux/kernel.h> #include <linux/module.h> -#include "probes.h" -#include "probes-thumb.h" +#include "decode.h" +#include "decode-thumb.h" static const union decode_item t32_table_1110_100x_x0xx[] = {
arch/arm/probes/decode-thumb.h renamed from arch/arm/kernel/probes-thumb.h +3 -1
@@ -1,5 +1,5 @@/* -* arch/arm/kernel/probes-thumb.h +* arch/arm/probes/decode-thumb.h * * Copyright 2013 Linaro Ltd. * Written by: David A. Long
@@ -15,6 +15,8 @@#ifndef _ARM_KERNEL_PROBES_THUMB_H#define _ARM_KERNEL_PROBES_THUMB_H +#include "decode.h" +/* * True if current instruction is in an IT block. */
arch/arm/probes/decode.c renamed from arch/arm/kernel/probes.c +2 -2
@@ -1,5 +1,5 @@/* -* arch/arm/kernel/probes.c +* arch/arm/probes/decode.c * * Copyright (C) 2011 Jon Medhurst <[email protected]>. *
@@ -17,7 +17,7 @@#include <asm/ptrace.h> #include <linux/bug.h> -#include "probes.h" +#include "decode.h" #ifndef find_str_pc_offset
arch/arm/probes/decode.h renamed from arch/arm/kernel/probes.h +1 -1
@@ -1,5 +1,5 @@/* -* arch/arm/kernel/probes.h +* arch/arm/probes/decode.h * * Copyright (C) 2011 Jon Medhurst <[email protected]>. *
arch/arm/probes/kprobes/Makefile new file +11 -0
@@ -0,0 +1,11 @@ +obj-$(CONFIG_KPROBES) += core.o actions-common.o +obj-$(CONFIG_ARM_KPROBES_TEST) += test-kprobes.o +test-kprobes-objs := test-core.o + +ifdef CONFIG_THUMB2_KERNEL +obj-$(CONFIG_KPROBES) += actions-thumb.o +test-kprobes-objs += test-thumb.o +else +obj-$(CONFIG_KPROBES) += actions-arm.o +test-kprobes-objs += test-arm.o +endif
arch/arm/probes/kprobes/actions-arm.c renamed from arch/arm/kernel/kprobes-arm.c +3 -3
@@ -1,5 +1,5 @@/* -* arch/arm/kernel/kprobes-decode.c +* arch/arm/probes/kprobes/actions-arm.c * * Copyright (C) 2006, 2007 Motorola Inc. *
@@ -62,8 +62,8 @@#include <linux/kprobes.h> #include <linux/ptrace.h> -#include "kprobes.h" -#include "probes-arm.h" +#include "../decode-arm.h" +#include "core.h" #if __LINUX_ARM_ARCH__ >=6 #define BLX (reg) "blx "reg" \n\t"
arch/arm/probes/kprobes/actions-common.c renamed from arch/arm/kernel/kprobes-common.c +2 -2
@@ -1,5 +1,5 @@/* -* arch/arm/kernel/kprobes-common.c +* arch/arm/probes/kprobes/actions-common.c * * Copyright (C) 2011 Jon Medhurst <[email protected]>. *
@@ -15,7 +15,7 @@#include <linux/kprobes.h> #include <asm/opcodes.h> -#include "kprobes.h" +#include "core.h" static void __kprobes simulate_ldm1stm1(probes_opcode_t insn,
arch/arm/probes/kprobes/actions-thumb.c renamed from arch/arm/kernel/kprobes-thumb.c +3 -3
@@ -1,5 +1,5 @@/* -* arch/arm/kernel/kprobes-thumb.c +* arch/arm/probes/kprobes/actions-thumb.c * * Copyright (C) 2011 Jon Medhurst <[email protected]>. *
@@ -13,8 +13,8 @@#include <linux/ptrace.h> #include <linux/kprobes.h> -#include "kprobes.h" -#include "probes-thumb.h" +#include "../decode-thumb.h" +#include "core.h" /* These emulation encodings are functionally equivalent... */ #define t32_emulate_rd8rn16rm0ra12_noflags \
arch/arm/probes/kprobes/core.c renamed from arch/arm/kernel/kprobes.c +4 -4
@@ -30,11 +30,11 @@#include <asm/cacheflush.h> #include <linux/percpu.h> #include <linux/bug.h> +#include <asm/patch.h> -#include "kprobes.h" -#include "probes-arm.h" -#include "probes-thumb.h" -#include "patch.h" +#include "../decode-arm.h" +#include "../decode-thumb.h" +#include "core.h" #define MIN_STACK_SIZE (addr) \ min((unsigned long)MAX_STACK_SIZE, \
arch/arm/probes/kprobes/core.h renamed from arch/arm/kernel/kprobes.h +2 -1
@@ -19,7 +19,8 @@#ifndef _ARM_KERNEL_KPROBES_H#define _ARM_KERNEL_KPROBES_H -#include "probes.h" +#include <asm/kprobes.h> +#include "../decode.h" /* * These undefined instructions must be unique and
arch/arm/probes/kprobes/test-arm.c renamed from arch/arm/kernel/kprobes-test-arm.c +1 -1
@@ -13,7 +13,7 @@#include <asm/system_info.h> #include <asm/opcodes.h> -#include "kprobes-test.h" +#include "test-core.h" #define TEST_ISA "32"
arch/arm/probes/kprobes/test-core.c renamed from arch/arm/kernel/kprobes-test.c +4 -4
@@ -209,10 +209,10 @@#include <linux/bug.h> #include <asm/opcodes.h> -#include "kprobes.h" -#include "probes-arm.h" -#include "probes-thumb.h" -#include "kprobes-test.h" +#include "core.h" +#include "test-core.h" +#include "../decode-arm.h" +#include "../decode-thumb.h" #define BENCHMARKING 1
arch/arm/probes/kprobes/test-core.h renamed from arch/arm/kernel/kprobes-test.h +1 -1
@@ -1,5 +1,5 @@/* -* arch/arm/kernel/kprobes-test.h +* arch/arm/probes/kprobes/test-core.h * * Copyright (C) 2011 Jon Medhurst <[email protected]>. *
arch/arm/probes/kprobes/test-thumb.c renamed from arch/arm/kernel/kprobes-test-thumb.c +2 -2
@@ -1,5 +1,5 @@/* -* arch/arm/kernel/kprobes-test-thumb.c +* arch/arm/probes/kprobes/test-thumb.c * * Copyright (C) 2011 Jon Medhurst <[email protected]>. *
@@ -12,7 +12,7 @@#include <linux/module.h> #include <asm/opcodes.h> -#include "kprobes-test.h" +#include "test-core.h" #define TEST_ISA "16"
arch/arm/probes/uprobes/Makefile new file +1 -0
@@ -0,0 +1 @@ +obj-$(CONFIG_UPROBES) += core.o actions-arm.o
arch/arm/probes/uprobes/actions-arm.c renamed from arch/arm/kernel/uprobes-arm.c +3 -3
@@ -13,9 +13,9 @@#include <linux/uprobes.h> #include <linux/module.h> -#include "probes.h" -#include "probes-arm.h" -#include "uprobes.h" +#include "../decode.h" +#include "../decode-arm.h" +#include "core.h" static int uprobes_substitute_pc (unsigned long *pinsn,u32 oregs) {
arch/arm/probes/uprobes/core.c renamed from arch/arm/kernel/uprobes.c +3 -3
@@ -17,9 +17,9 @@#include <asm/opcodes.h> #include <asm/traps.h> -#include "probes.h" -#include "probes-arm.h" -#include "uprobes.h" +#include "../decode.h" +#include "../decode-arm.h" +#include "core.h" #define UPROBE_TRAP_NR UINT_MAX
arch/arm/probes/uprobes/core.h renamed from arch/arm/kernel/uprobes.h +0 -0
Signature · 1 line
1.8.4
Re: [PATCH v20 01/11] ARM: probes: move all probe code to dedicate directory
Quoted 35 lines · Wang Nan
In discussion on LKML (https://lkml.org/lkml/2014/11/28/158), Russell King suggests to move all probe related code to
arch/arm/probes. This patch does the work. Due to dependency on 'arch/arm/kernel/patch.h', this patch also movespatch.hto 'arch/arm/include/asm/patch.h', and related '#include' directives are also midified to '#include <asm/patch.h>'.Following is an overview of this patch:
./arch/arm/kernel/ ./arch/arm/probes/ |-- Makefile |-- Makefile |-- probes-arm.c ==> |-- decode-arm.c |-- probes-arm.h ==> |-- decode-arm.h |-- probes-thumb.c ==> |-- decode-thumb.c |-- probes-thumb.h ==> |-- decode-thumb.h |-- probes.c ==> |-- decode.c |-- probes.h ==> |-- decode.h | |-- kprobes | | |-- Makefile |-- kprobes-arm.c ==> | |-- actions-arm.c |-- kprobes-common.c ==> | |-- actions-common.c |-- kprobes-thumb.c ==> | |-- actions-thumb.c |-- kprobes.c ==> | |-- core.c |-- kprobes.h ==> | |-- core.h |-- kprobes-test-arm.c ==> | |-- test-arm.c |-- kprobes-test.c ==> | |-- test-core.c |-- kprobes-test.h ==> | |-- test-core.h |-- kprobes-test-thumb.c ==> | `-- test-thumb.c | `-- uprobes | |-- Makefile |-- uprobes-arm.c ==> |-- actions-arm.c |-- uprobes.c ==> |-- core.c |-- uprobes.h ==> `-- core.h | `-- patch.h ==> arch/arm/include/asm/patch.h
Quoted 3 lines
Signed-off-by Wang Nan <[email protected]>Acked-by Masami Hiramatsu <[email protected]>---
Might have been good to mention what's changed in this version, I worked out its kgdb.c, comments below...
[...]
arch/arm/kernel/kgdb.c line 19
Quoted 10 lines
arch/arm/kernel/kgdb.c +1
-1@@ -16,7 +16,7 @@#include <asm/traps.h> -#include "patch.h" +#include <asm/patch.h>
To keep alphabetical ordering of headers this should be above the #include <asm/traps.h>
Don't bother resending the patch, I'll just update the patch in the git branch I'm putting together.
Signature · 1 line
Tixy
Re: [PATCH v20 01/11] ARM: probes: move all probe code to dedicate directory
Quoted 53 lines · Jon Medhurst (Tixy)
Quoted 35 lines · Wang Nan
In discussion on LKML (https://lkml.org/lkml/2014/11/28/158), Russell King suggests to move all probe related code to
arch/arm/probes. This patch does the work. Due to dependency on 'arch/arm/kernel/patch.h', this patch also movespatch.hto 'arch/arm/include/asm/patch.h', and related '#include' directives are also midified to '#include <asm/patch.h>'.Following is an overview of this patch:
./arch/arm/kernel/ ./arch/arm/probes/ |-- Makefile |-- Makefile |-- probes-arm.c ==> |-- decode-arm.c |-- probes-arm.h ==> |-- decode-arm.h |-- probes-thumb.c ==> |-- decode-thumb.c |-- probes-thumb.h ==> |-- decode-thumb.h |-- probes.c ==> |-- decode.c |-- probes.h ==> |-- decode.h | |-- kprobes | | |-- Makefile |-- kprobes-arm.c ==> | |-- actions-arm.c |-- kprobes-common.c ==> | |-- actions-common.c |-- kprobes-thumb.c ==> | |-- actions-thumb.c |-- kprobes.c ==> | |-- core.c |-- kprobes.h ==> | |-- core.h |-- kprobes-test-arm.c ==> | |-- test-arm.c |-- kprobes-test.c ==> | |-- test-core.c |-- kprobes-test.h ==> | |-- test-core.h |-- kprobes-test-thumb.c ==> | `-- test-thumb.c | `-- uprobes | |-- Makefile |-- uprobes-arm.c ==> |-- actions-arm.c |-- uprobes.c ==> |-- core.c |-- uprobes.h ==> `-- core.h | `-- patch.h ==> arch/arm/include/asm/patch.hQuoted 3 lines
Signed-off-by Wang Nan <[email protected]>Acked-by Masami Hiramatsu <[email protected]>---
Might have been good to mention what's changed in this version, I worked out its
kgdb.c, comments below...[...]
Quoted 8 lines
arch/arm/kernel/kgdb.c +0
-0@@ -16,7 +16,7 @@#include <asm/traps.h>
Quoted 9 lines
arch/arm/kernel/kgdb.c line 19
Quoted 2 lines
arch/arm/kernel/kgdb.c +1
-1-#include "patch.h" +#include <asm/patch.h> To keep alphabetical ordering of headers this should be above the #include <
asm/traps.h>Don't bother resending the patch, I'll just update the patch in the git branch I'm putting together.
Thanks a lot!
Re: [PATCH v19 01/11] ARM: probes: move all probe code to dedicate directory
In reply to Wang NanQuoted 35 lines · Wang Nan
In discussion on LKML (https://lkml.org/lkml/2014/11/28/158), Russell King suggests to move all probe related code to
arch/arm/probes. This patch does the work. Due to dependency on 'arch/arm/kernel/patch.h', this patch also movespatch.hto 'arch/arm/include/asm/patch.h', and related '#include' directives are also midified to '#include <asm/patch.h>'.Following is an overview of this patch:
./arch/arm/kernel/ ./arch/arm/probes/ |-- Makefile |-- Makefile |-- probes-arm.c ==> |-- decode-arm.c |-- probes-arm.h ==> |-- decode-arm.h |-- probes-thumb.c ==> |-- decode-thumb.c |-- probes-thumb.h ==> |-- decode-thumb.h |-- probes.c ==> |-- decode.c |-- probes.h ==> |-- decode.h | |-- kprobes | | |-- Makefile |-- kprobes-arm.c ==> | |-- actions-arm.c |-- kprobes-common.c ==> | |-- actions-common.c |-- kprobes-thumb.c ==> | |-- actions-thumb.c |-- kprobes.c ==> | |-- core.c |-- kprobes.h ==> | |-- core.h |-- kprobes-test-arm.c ==> | |-- test-arm.c |-- kprobes-test.c ==> | |-- test-core.c |-- kprobes-test.h ==> | |-- test-core.h |-- kprobes-test-thumb.c ==> | `-- test-thumb.c | `-- uprobes | |-- Makefile |-- uprobes-arm.c ==> |-- actions-arm.c |-- uprobes.c ==> |-- core.c |-- uprobes.h ==> `-- core.h | `-- patch.h ==> arch/arm/include/asm/patch.h
Quoted 2 lines
Signed-off-by Wang Nan <[email protected]>Acked-by Masami Hiramatsu <[email protected]>
Hi,
Thanks to Tixy and his test robot, a bug is found in this patch: I forgot to change arch/arm/kernel/kgdb.c, which also includes patch.h. A small code modification is required.
I have posted a new version of this patch by replying.
Tixy, could you please collect it into your git repository and help me test it again?
http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/314520.html
Thanks.
PATCH v19 2/11 ARM: kprobes: remove unused ARM decoder actions.
In reply to Wang NanThere are 3 actions which is never used:
PROBES_MOV_HALFWORD,
PROBES_SEV,
PROBES_WFE,
This patch removes them.
--- arch/arm/probes/decode-arm.h | 3 --- arch/arm/probes/kprobes/actions-arm.c | 3 --- arch/arm/probes/uprobes/actions-arm.c | 3 --- 3 files changed, 9 deletions(-)
arch/arm/probes/decode-arm.h +0 -3
@@ -38,9 +38,6 @@ enum probes_arm_action {PROBES_MOV_IP_SP ,PROBES_DATA_PROCESSING_REG ,PROBES_DATA_PROCESSING_IMM , -PROBES_MOV_HALFWORD , -PROBES_SEV , -PROBES_WFE ,PROBES_SATURATE ,PROBES_REV , PROBES_MMI,
arch/arm/probes/kprobes/actions-arm.c +0 -3
@@ -325,9 +325,6 @@ const union decode_action kprobes_arm_actions[NUM_PROBES_ARM_ACTIONS] = { .handler = emulate_rd12rn16rm0rs8_rwflags}, [PROBES_DATA_PROCESSING_IMM] = { .handler = emulate_rd12rn16rm0rs8_rwflags}, - [PROBES_MOV_HALFWORD] = {.handler = emulate_rd12rm0_noflags_nopc}, - [PROBES_SEV] = {.handler = probes_emulate_none}, - [PROBES_WFE] = {.handler = probes_simulate_nop}, [PROBES_SATURATE] = {.handler = emulate_rd12rn16rm0_rwflags_nopc}, [PROBES_REV] = {.handler = emulate_rd12rm0_noflags_nopc}, [PROBES_MMI] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
arch/arm/probes/uprobes/actions-arm.c +0 -3
@@ -217,9 +217,6 @@ const union decode_action uprobes_probes_actions[] = { .decoder = decode_rd12rn16rm0rs8_rwflags}, [PROBES_DATA_PROCESSING_IMM] = { .decoder = decode_rd12rn16rm0rs8_rwflags}, - [PROBES_MOV_HALFWORD] = {.handler = probes_simulate_nop}, - [PROBES_SEV] = {.handler = probes_simulate_nop}, - [PROBES_WFE] = {.handler = probes_simulate_nop}, [PROBES_SATURATE] = {.handler = probes_simulate_nop}, [PROBES_REV] = {.handler = probes_simulate_nop}, [PROBES_MMI] = {.handler = probes_simulate_nop},
Signature · 1 line
1.8.4
Re: [PATCH v19 02/11] ARM: kprobes: remove unused ARM decoder actions.
Quoted 9 lines · Wang Nan
There are 3 actions which is never used:
PROBES_MOV_HALFWORD,
PROBES_SEV,
PROBES_WFE,This patch removes them.
Signed-off-by Wang Nan <[email protected]>
I think that PROBES_MOV_HALFWORD should be used, for MOVW and MOVT. Currently those instructions use PROBES_DATA_PROCESSING_IMM which, whilst it will work it ends up using a less efficient emulation routine than necessary.
The other unused actions, PROBES_SEV and PROBES_WFE, could possibly be removed as redundant, but there are are Thumb equivalents for those which are used, so for symmetry I think we should use them. That will let us remove PROBES_EMULATE_NONE and PROBES_SIMULATE_NOP.
So how about the following patch instead...
----------------------------------------------------------------------------
From: Jon Medhurst <[email protected]>
Date: Wed, 7 Jan 2015 11:42:30 +0000
Subject: [PATCH] ARM: probes: Use correct action types for MOVW, SEV and WFI
This doesn't correct any bugs when probing these instructions but makes MOVW slightly faster and makes everything more symmetric with the Thumb instruction cases.
We can also remove the now redundant PROBES_EMULATE_NONE and PROBES_SIMULATE_NOP actions.
--- arch/arm/probes/decode-arm.c | 6 +++--- arch/arm/probes/decode-arm.h | 2 -- arch/arm/probes/kprobes/actions-arm.c | 2 -- arch/arm/probes/uprobes/actions-arm.c | 2 -- 4 files changed, 3 insertions(+), 9 deletions(-)
arch/arm/probes/decode-arm.c +3 -3
@@ -370,17 +370,17 @@ static const union decode_item arm_cccc_001x_table[] = {/* MOVW cccc 0011 0000 xxxx xxxx xxxx xxxx xxxx */ /* MOVT cccc 0011 0100 xxxx xxxx xxxx xxxx xxxx */ -DECODE_EMULATEX (0x0fb00000 ,0x03000000 ,PROBES_DATA_PROCESSING_IMM , +DECODE_EMULATEX (0x0fb00000 ,0x03000000 ,PROBES_MOV_HALFWORD ,REGS (0 ,NOPC ,0 ,0 ,0 )),/* YIELD cccc 0011 0010 0000 xxxx xxxx 0000 0001 */ DECODE_OR (0x0fff00ff ,0x03200001 ),/* SEV cccc 0011 0010 0000 xxxx xxxx 0000 0100 */ -DECODE_EMULATE (0x0fff00ff ,0x03200004 ,PROBES_EMULATE_NONE ), +DECODE_EMULATE (0x0fff00ff ,0x03200004 ,PROBES_SEV ),/* NOP cccc 0011 0010 0000 xxxx xxxx 0000 0000 */ /* WFE cccc 0011 0010 0000 xxxx xxxx 0000 0010 */ /* WFI cccc 0011 0010 0000 xxxx xxxx 0000 0011 */ -DECODE_SIMULATE (0x0fff00fc ,0x03200000 ,PROBES_SIMULATE_NOP ), +DECODE_SIMULATE (0x0fff00fc ,0x03200000 ,PROBES_WFE ),/* DBG cccc 0011 0010 0000 xxxx xxxx ffff xxxx */ /* unallocated hints cccc 0011 0010 0000 xxxx xxxx xxxx xxxx */ /* MSR (immediate) cccc 0011 0x10 xxxx xxxx xxxx xxxx xxxx */
arch/arm/probes/decode-arm.h +0 -2
@@ -18,8 +18,6 @@#include "decode.h" enum probes_arm_action { -PROBES_EMULATE_NONE , -PROBES_SIMULATE_NOP ,PROBES_PRELOAD_IMM ,PROBES_PRELOAD_REG ,PROBES_BRANCH_IMM ,
arch/arm/probes/kprobes/actions-arm.c +0 -2
@@ -303,8 +303,6 @@ emulate_rdlo12rdhi16rn0rm8_rwflags_nopc(probes_opcode_t insn, }const union decode_action kprobes_arm_actions[NUM_PROBES_ARM_ACTIONS ] = { - [PROBES_EMULATE_NONE ] = {.handler = probes_emulate_none}, - [PROBES_SIMULATE_NOP ] = {.handler = probes_simulate_nop}, [PROBES_PRELOAD_IMM ] = {.handler = probes_simulate_nop}, [PROBES_PRELOAD_REG ] = {.handler = probes_simulate_nop}, [PROBES_BRANCH_IMM ] = {.handler = simulate_blx1},
arch/arm/probes/uprobes/actions-arm.c +0 -2
@@ -195,8 +195,6 @@ uprobe_decode_ldmstm(probes_opcode_t insn, }const union decode_action uprobes_probes_actions[] = { - [PROBES_EMULATE_NONE ] = {.handler = probes_simulate_nop}, - [PROBES_SIMULATE_NOP ] = {.handler = probes_simulate_nop}, [PROBES_PRELOAD_IMM ] = {.handler = probes_simulate_nop}, [PROBES_PRELOAD_REG ] = {.handler = probes_simulate_nop}, [PROBES_BRANCH_IMM ] = {.handler = simulate_blx1},
Signature · 1 line
2.1.4
PATCH v19 3/11 ARM: kprobes: introduces checker
In reply to Wang NanThis patch introdces 'checker' to decoding phase, and calls checkers when instruction decoding. This allows further decoding for specific instructions. This patch introduces a stub call of checkers in kprobe arch_prepare_kprobe() as an example and for further expansion.
--- arch/arm/probes/decode-arm.c | 5 +-- arch/arm/probes/decode-arm.h | 3 +- arch/arm/probes/decode-thumb.c | 10 +++--- arch/arm/probes/decode-thumb.h | 6 ++-- arch/arm/probes/decode.c | 60 +++++++++++++++++++++++++++++---- arch/arm/probes/decode.h | 11 +++++- arch/arm/probes/kprobes/actions-arm.c | 2 ++ arch/arm/probes/kprobes/actions-thumb.c | 3 ++ arch/arm/probes/kprobes/core.c | 6 +++- arch/arm/probes/kprobes/core.h | 7 ++-- arch/arm/probes/uprobes/core.c | 2 +- 11 files changed, 95 insertions(+), 20 deletions(-)
arch/arm/probes/decode-arm.c +3 -2
@@ -726,10 +726,11 @@ static void __kprobes arm_singlestep(probes_opcode_t insn,*/ enum probes_insn __kprobes arm_probes_decode_insn (probes_opcode_t insn,struct arch_probes_insn *asi, -bool emulate,const union decode_action *actions) +bool emulate,const union decode_action *actions, +const struct decode_checker *checkers[]) { asi->insn_singlestep = arm_singlestep; asi->insn_check_cc = probes_condition_checks[insn>>28 ];return probes_decode_insn (insn, asi, probes_decode_arm_table, false, - emulate, actions); + emulate, actions, checkers); }
arch/arm/probes/decode-arm.h +2 -1
@@ -67,6 +67,7 @@ extern const union decode_item probes_decode_arm_table[];enum probes_insn arm_probes_decode_insn (probes_opcode_t ,struct arch_probes_insn *,bool emulate, -const union decode_action *actions); +const union decode_action *actions, +const struct decode_checker *checkers[]);#endif
arch/arm/probes/decode-thumb.c +6 -4
@@ -863,20 +863,22 @@ static void __kprobes thumb32_singlestep(probes_opcode_t opcode,enum probes_insn __kprobes thumb16_probes_decode_insn (probes_opcode_t insn,struct arch_probes_insn *asi, -bool emulate,const union decode_action *actions) +bool emulate,const union decode_action *actions, +const struct decode_checker *checkers[]) { asi->insn_singlestep = thumb16_singlestep; asi->insn_check_cc = thumb_check_cc;return probes_decode_insn (insn, asi, probes_decode_thumb16_table, true, - emulate, actions); + emulate, actions, checkers); }enum probes_insn __kprobes thumb32_probes_decode_insn (probes_opcode_t insn,struct arch_probes_insn *asi, -bool emulate,const union decode_action *actions) +bool emulate,const union decode_action *actions, +const struct decode_checker *checkers[]) { asi->insn_singlestep = thumb32_singlestep; asi->insn_check_cc = thumb_check_cc;return probes_decode_insn (insn, asi, probes_decode_thumb32_table, true, - emulate, actions); + emulate, actions, checkers); }
arch/arm/probes/decode-thumb.h +4 -2
@@ -91,9 +91,11 @@ extern const union decode_item probes_decode_thumb16_table[];enum probes_insn __kprobes thumb16_probes_decode_insn (probes_opcode_t insn,struct arch_probes_insn *asi, -bool emulate,const union decode_action *actions); +bool emulate,const union decode_action *actions, +const struct decode_checker *checkers[]);enum probes_insn __kprobes thumb32_probes_decode_insn (probes_opcode_t insn,struct arch_probes_insn *asi, -bool emulate,const union decode_action *actions); +bool emulate,const union decode_action *actions, +const struct decode_checker *checkers[]);#endif
arch/arm/probes/decode.c +54 -6
95 lines not on this page · raw message
arch/arm/probes/decode.h +10 -1
@@ -314,6 +314,14 @@ union decode_action {probes_custom_decode_t *decoder; }; +typedef enum probes_insn (probes_check_t )(probes_opcode_t , +struct arch_probes_insn *, +const struct decode_header *); + +struct decode_checker { +probes_check_t *checker; +}; +#define DECODE_END \ {.bits = DECODE_TYPE_END}
@@ -402,6 +410,7 @@ probes_insn_handler_t probes_emulate_none;int __kprobes probes_decode_insn (probes_opcode_t insn,struct arch_probes_insn *asi,const union decode_item *table,bool thumb,bool emulate, -const union decode_action *actions); +const union decode_action *actions, +const struct decode_checker **checkers);#endif
arch/arm/probes/kprobes/actions-arm.c +2 -0
@@ -338,3 +338,5 @@ const union decode_action kprobes_arm_actions[NUM_PROBES_ARM_ACTIONS] = { [PROBES_BRANCH] = {.handler = simulate_bbl}, [PROBES_LDMSTM] = {.decoder = kprobe_decode_ldmstm} }; + +const struct decode_checker *kprobes_arm_checkers[] = {NULL };
arch/arm/probes/kprobes/actions-thumb.c +3 -0
@@ -664,3 +664,6 @@ const union decode_action kprobes_t32_actions[NUM_PROBES_T32_ACTIONS] = { [PROBES_T32_MUL_ADD_LONG ] = { .handler = t32_emulate_rdlo12rdhi8rn16rm0_noflags}, }; + +const struct decode_checker *kprobes_t32_checkers[] = {NULL }; +const struct decode_checker *kprobes_t16_checkers[] = {NULL };
arch/arm/probes/kprobes/core.c +5 -1
@@ -61,6 +61,7 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)kprobe_decode_insn_t *decode_insn;const union decode_action *actions;int is; +const struct decode_checker **checkers;if (in_exception_text (addr))return -EINVAL ;
@@ -74,9 +75,11 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) insn =__opcode_thumb32_compose (insn, inst2); decode_insn = thumb32_probes_decode_insn; actions = kprobes_t32_actions; + checkers = kprobes_t32_checkers; }else { decode_insn = thumb16_probes_decode_insn; actions = kprobes_t16_actions; + checkers = kprobes_t16_checkers; }#else /* !CONFIG_THUMB2_KERNEL */ thumb = false;
@@ -85,12 +88,13 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) insn =__mem_to_opcode_arm (*p->addr); decode_insn = arm_probes_decode_insn; actions = kprobes_arm_actions; + checkers = kprobes_arm_checkers;#endif p->opcode = insn; p->ainsn.insn = tmp_insn; -switch ((*decode_insn)(insn, &p->ainsn, true, actions)) { +switch ((*decode_insn)(insn, &p->ainsn, true, actions, checkers)) {case INSN_REJECTED :/* not supported */ return -EINVAL ;
arch/arm/probes/kprobes/core.h +5 -2
@@ -37,16 +37,19 @@ kprobe_decode_ldmstm(kprobe_opcode_t insn, struct arch_probes_insn *asi,typedef enum probes_insn (kprobe_decode_insn_t )(probes_opcode_t ,struct arch_probes_insn *,bool , -const union decode_action *); +const union decode_action *, +const struct decode_checker *[*]);#ifdef CONFIG_THUMB2_KERNEL extern const union decode_action kprobes_t32_actions[];extern const union decode_action kprobes_t16_actions[]; - +extern const struct decode_checker *kprobes_t32_checkers[]; +extern const struct decode_checker *kprobes_t16_checkers[];#else /* !CONFIG_THUMB2_KERNEL */ extern const union decode_action kprobes_arm_actions[]; +extern const struct decode_checker *kprobes_arm_checkers[];#endif
arch/arm/probes/uprobes/core.c +1 -1
@@ -88,7 +88,7 @@ int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm, auprobe->ixol[1 ] =__opcode_to_mem_arm (UPROBE_SS_ARM_INSN ); ret =arm_probes_decode_insn (insn, &auprobe->asi, false, - uprobes_probes_actions); + uprobes_probes_actions,NULL );switch (ret) {case INSN_REJECTED :return -EINVAL ;
Signature · 1 line
1.8.4
PATCH v19 4/11 ARM: kprobes: collects stack consumption for store instructions
In reply to Wang NanThis patch uses the previously introduced checker functionality on store instructions to record their stack consumption information to arch_probes_insn.
--- arch/arm/include/asm/probes.h | 1 + arch/arm/probes/decode.c | 10 +++ arch/arm/probes/kprobes/Makefile | 6 +- arch/arm/probes/kprobes/actions-arm.c | 3 +- arch/arm/probes/kprobes/actions-thumb.c | 5 +- arch/arm/probes/kprobes/checkers-arm.c | 99 +++++++++++++++++++++++++++ arch/arm/probes/kprobes/checkers-common.c | 101 +++++++++++++++++++++++++++ arch/arm/probes/kprobes/checkers-thumb.c | 110 ++++++++++++++++++++++++++++++ arch/arm/probes/kprobes/checkers.h | 54 +++++++++++++++ 9 files changed, 383 insertions(+), 6 deletions(-) create mode 100644 arch/arm/probes/kprobes/checkers-arm.c create mode 100644 arch/arm/probes/kprobes/checkers-common.c create mode 100644 arch/arm/probes/kprobes/checkers-thumb.c create mode 100644 arch/arm/probes/kprobes/checkers.h
arch/arm/include/asm/probes.h +1 -0
@@ -38,6 +38,7 @@ struct arch_probes_insn {probes_check_cc *insn_check_cc;probes_insn_singlestep_t *insn_singlestep;probes_insn_fn_t *insn_fn; + int stack_space; };#endif
arch/arm/probes/decode.c +10 -0
@@ -425,6 +425,16 @@ probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,*/ probes_opcode_t origin_insn = insn; +/* +* stack_space is initialized to 0 here. Checker functions +* should update is value if they find this is a stack store +* instruction: positive value means bytes of stack usage, +* negitive value means unable to determine stack usage +* statically. For instruction doesn't store to stack, checker +* do nothing with it. +*/ + asi->stack_space =0 ; +if (emulate) insn =prepare_emulated_insn (insn, asi, thumb);
arch/arm/probes/kprobes/Makefile +3 -3
@@ -1,11 +1,11 @@ -obj-$(CONFIG_KPROBES) += core.o actions-common.o +obj-$(CONFIG_KPROBES) += core.o actions-common.o checkers-common.o obj-$(CONFIG_ARM_KPROBES_TEST) += test-kprobes.o test-kprobes-objs := test-core.o ifdef CONFIG_THUMB2_KERNEL -obj-$(CONFIG_KPROBES) += actions-thumb.o +obj-$(CONFIG_KPROBES) += actions-thumb.o checkers-thumb.o test-kprobes-objs += test-thumb.o else -obj-$(CONFIG_KPROBES) += actions-arm.o +obj-$(CONFIG_KPROBES) += actions-arm.o checkers-arm.o test-kprobes-objs += test-arm.o endif
arch/arm/probes/kprobes/actions-arm.c +2 -1
@@ -64,6 +64,7 @@#include "../decode-arm.h" #include "core.h" +#include "checkers.h" #if __LINUX_ARM_ARCH__ >=6 #define BLX (reg) "blx "reg" \n\t"
@@ -339,4 +340,4 @@ const union decode_action kprobes_arm_actions[NUM_PROBES_ARM_ACTIONS] = { [PROBES_LDMSTM] = {.decoder = kprobe_decode_ldmstm} }; -const struct decode_checker *kprobes_arm_checkers[] = {NULL }; +const struct decode_checker *kprobes_arm_checkers[] = {arm_stack_checker,NULL };
arch/arm/probes/kprobes/actions-thumb.c +3 -2
@@ -15,6 +15,7 @@#include "../decode-thumb.h" #include "core.h" +#include "checkers.h" /* These emulation encodings are functionally equivalent... */ #define t32_emulate_rd8rn16rm0ra12_noflags \
@@ -665,5 +666,5 @@ const union decode_action kprobes_t32_actions[NUM_PROBES_T32_ACTIONS] = { .handler = t32_emulate_rdlo12rdhi8rn16rm0_noflags}, }; -const struct decode_checker *kprobes_t32_checkers[] = {NULL }; -const struct decode_checker *kprobes_t16_checkers[] = {NULL }; +const struct decode_checker *kprobes_t32_checkers[] = {t32_stack_checker,NULL }; +const struct decode_checker *kprobes_t16_checkers[] = {t16_stack_checker,NULL };
arch/arm/probes/kprobes/checkers-arm.c new file +99 -0
99 lines not on this page · raw message
arch/arm/probes/kprobes/checkers-common.c new file +101 -0
101 lines not on this page · raw message
arch/arm/probes/kprobes/checkers-thumb.c new file +110 -0
110 lines not on this page · raw message
arch/arm/probes/kprobes/checkers.h new file +54 -0
54 lines not on this page · raw message
Signature · 1 line
1.8.4
PATCH v19 5/11 ARM: kprobes: disallow probing stack consuming instructions
In reply to Wang NanThis patch prohibits probing instructions for which the stack requirements are unable to be determined statically. Some test cases are found not work again after the modification, this patch also removes them.
--- arch/arm/include/asm/kprobes.h | 1 - arch/arm/include/asm/probes.h | 12 ++++++++++++ arch/arm/kernel/entry-armv.S | 3 ++- arch/arm/probes/kprobes/core.c | 9 +++++++++ arch/arm/probes/kprobes/test-arm.c | 16 ++++++++++------ 5 files changed, 33 insertions(+), 8 deletions(-)
arch/arm/include/asm/kprobes.h +0 -1
@@ -22,7 +22,6 @@#define __ARCH_WANT_KPROBES_INSN_SLOT#define MAX_INSN_SIZE 2 -#define MAX_STACK_SIZE 64/* 32 would probably be OK */ #define flush_insn_slot (p) do { } while (0)#define kretprobe_blacklist_size 0
arch/arm/include/asm/probes.h +12 -0
@@ -19,6 +19,8 @@#ifndef _ASM_PROBES_H#define _ASM_PROBES_H +#ifndef __ASSEMBLY__ +typedef u32 probes_opcode_t ;struct arch_probes_insn ;
@@ -41,4 +43,14 @@ struct arch_probes_insn {int stack_space; }; +#endif /* __ASSEMBLY__ */ + +/* +* We assume one instruction can consume at most 64 bytes stack, which is +* 'push {r0-r15}'. Instructions consume more or unknown stack space like +* 'str r0, [sp, #-80]' and 'str r0, [sp, r1]' should be prohibit to probe. +* Both kprobe and jprobe use this macro. +*/ +#define MAX_STACK_SIZE 64 +#endif
arch/arm/kernel/entry-armv.S +2 -1
@@ -31,6 +31,7 @@ #include "entry-header.S" #include <asm/entry-macro-multi.S> +#include <asm/probes.h> /* * Interrupt handling.
@@ -249,7 +250,7 @@ __und_svc: @ If a kprobe is about to simulate a "stmdb sp..." instruction, @ it obviously needs free stack space which then will belong to @ the saved context. - svc_entry 64 + svc_entry MAX_STACK_SIZE #else svc_entry #endif
arch/arm/probes/kprobes/core.c +9 -0
@@ -115,6 +115,15 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)break ; } +/* +* Never instrument insn like 'str r0, [sp, +/-r1]'. Also, insn likes +* 'str r0, [sp, #-68]' should also be prohibited. +* See __und_svc. +*/ +if ((p->ainsn.stack_space <0 ) || + (p->ainsn.stack_space >MAX_STACK_SIZE )) +return -EINVAL ; +return 0 ; }
arch/arm/probes/kprobes/test-arm.c +10 -6
@@ -476,7 +476,8 @@ void kprobe_arm_test_cases(void) TEST_GROUP("Extra load/store instructions") TEST_RPR( "strh r",0, VAL1,", [r",1, 48,", -r",2, 24,"]") - TEST_RPR( "streqh r",14,VAL2,", [r",13,0, ", r",12, 48,"]") + TEST_RPR( "streqh r",14,VAL2,", [r",11,0, ", r",12, 48,"]") + TEST_UNSUPPORTED( "streqh r14, [r13, r12]") TEST_RPR( "strh r",1, VAL1,", [r",2, 24,", r",3, 48,"]!") TEST_RPR( "strneh r",12,VAL2,", [r",11,48,", -r",10,24,"]!")TEST_RPR ("strh r" ,2 ,VAL1 ,", [r" ,3 ,24 ,"], r" ,4 ,48 ,"" )
@@ -565,7 +566,8 @@ void kprobe_arm_test_cases(void)#if __LINUX_ARM_ARCH__ >=5 TEST_RPR( "strd r",0, VAL1,", [r",1, 48,", -r",2,24,"]") - TEST_RPR( "strccd r",8, VAL2,", [r",13,0, ", r",12,48,"]") + TEST_RPR( "strccd r",8, VAL2,", [r",11,0, ", r",12,48,"]") + TEST_UNSUPPORTED( "strccd r8, [r13, r12]") TEST_RPR( "strd r",4, VAL1,", [r",2, 24,", r",3, 48,"]!") TEST_RPR( "strcsd r",12,VAL2,", [r",11,48,", -r",10,24,"]!")TEST_RPR ("strd r" ,2 ,VAL1 ,", [r" ,5 ,24 ,"], r" ,4 ,48 ,"" )
@@ -638,13 +640,15 @@ void kprobe_arm_test_cases(void) TEST_RP( "str"byte" r",2, VAL1,", [r",3, 24,"], #48") \ TEST_RP( "str"byte" r",10,VAL2,", [r",9, 64,"], #-48") \ TEST_RPR("str"byte" r",0, VAL1,", [r",1, 48,", -r",2, 24,"]") \ - TEST_RPR("str"byte" r",14,VAL2,", [r",13,0, ", r",12, 48,"]") \ + TEST_RPR("str"byte" r",14,VAL2,", [r",11,0, ", r",12, 48,"]") \ + TEST_UNSUPPORTED("str"byte" r14, [r13, r12]") \ TEST_RPR("str"byte" r",1, VAL1,", [r",2, 24,", r",3, 48,"]!") \ TEST_RPR("str"byte" r",12,VAL2,", [r",11,48,", -r",10,24,"]!") \ TEST_RPR("str"byte" r",2, VAL1,", [r",3, 24,"], r",4, 48,"") \ TEST_RPR("str"byte" r",10,VAL2,", [r",9, 48,"], -r",11,24,"") \ TEST_RPR("str"byte" r",0, VAL1,", [r",1, 24,", r",2, 32,", asl #1]")\ - TEST_RPR("str"byte" r",14,VAL2,", [r",13,0, ", r",12, 32,", lsr #2]")\ + TEST_RPR("str"byte" r",14,VAL2,", [r",11,0, ", r",12, 32,", lsr #2]")\ + TEST_UNSUPPORTED("str"byte" r14, [r13, r12, lsr #2]")\ TEST_RPR("str"byte" r",1, VAL1,", [r",2, 24,", r",3, 32,", asr #3]!")\ TEST_RPR("str"byte" r",12,VAL2,", [r",11,24,", r",10, 4,", ror #31]!")\TEST_P ("ldr" byte" r0, [r" ,0 ,24 ,", #-2]" ) \
@@ -668,12 +672,12 @@ void kprobe_arm_test_cases(void) LOAD_STORE("") TEST_P( "str pc, [r",0,0,", #15*4]") - TEST_R( "str pc, [sp, r",2,15*4,"]") + TEST_UNSUPPORTED( "str pc, [sp, r2]") TEST_BF( "ldr pc, [sp, #15*4]") TEST_BF_R("ldr pc, [sp, r",2,15*4,"]") TEST_P( "str sp, [r",0,0,", #13*4]") - TEST_R( "str sp, [sp, r",2,13*4,"]") + TEST_UNSUPPORTED( "str sp, [sp, r2]") TEST_BF( "ldr sp, [sp, #13*4]")TEST_BF_R ("ldr sp, [sp, r" ,2 ,13 *4 ,"]" )
Signature · 1 line
1.8.4
PATCH v19 6/11 ARM: kprobes: Add test cases for stack consuming instructions
In reply to Wang NanFrom: "Jon Medhurst (Tixy)" <[email protected]>
These have extra 'checker' functions associated with them so lets make sure those get covered by testing. As they may create uninitialised space on the stack we also update the test code to ensure such space is consistent between test runs. This is done by disabling interrupts in setup_test_context().
--- arch/arm/probes/kprobes/test-arm.c | 17 +++++++++++++++-- arch/arm/probes/kprobes/test-core.c | 9 +++++++++ arch/arm/probes/kprobes/test-thumb.c | 12 ++++++++++++ 3 files changed, 36 insertions(+), 2 deletions(-)
arch/arm/probes/kprobes/test-arm.c +15 -2
@@ -12,6 +12,7 @@#include <linux/module.h> #include <asm/system_info.h> #include <asm/opcodes.h> +#include <asm/probes.h> #include "test-core.h"
@@ -478,6 +479,7 @@ void kprobe_arm_test_cases(void) TEST_RPR( "strh r",0, VAL1,", [r",1, 48,", -r",2, 24,"]") TEST_RPR( "streqh r",14,VAL2,", [r",11,0, ", r",12, 48,"]") TEST_UNSUPPORTED( "streqh r14, [r13, r12]") + TEST_UNSUPPORTED( "streqh r14, [r12, r13]") TEST_RPR( "strh r",1, VAL1,", [r",2, 24,", r",3, 48,"]!") TEST_RPR( "strneh r",12,VAL2,", [r",11,48,", -r",10,24,"]!")TEST_RPR ("strh r" ,2 ,VAL1 ,", [r" ,3 ,24 ,"], r" ,4 ,48 ,"" )
@@ -502,6 +504,9 @@ void kprobe_arm_test_cases(void) TEST_RP( "strplh r",12,VAL2,", [r",11,24,", #-4]!") TEST_RP( "strh r",2, VAL1,", [r",3, 24,"], #48") TEST_RP( "strh r",10,VAL2,", [r",9, 64,"], #-48") + TEST_RP( "strh r",3, VAL1,", [r",13,TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"]!") + TEST_UNSUPPORTED("strh r3, [r13, #-"__stringify(MAX_STACK_SIZE)"-8]!") + TEST_RP( "strh r",4, VAL1,", [r",14,TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"-8]!") TEST_UNSUPPORTED(__inst_arm(0xe1efc3b0) " @ strh r12, [pc, #48]!") TEST_UNSUPPORTED(__inst_arm(0xe0c9f3b0) " @ strh pc, [r9], #48")
@@ -568,6 +573,7 @@ void kprobe_arm_test_cases(void) TEST_RPR( "strd r",0, VAL1,", [r",1, 48,", -r",2,24,"]") TEST_RPR( "strccd r",8, VAL2,", [r",11,0, ", r",12,48,"]") TEST_UNSUPPORTED( "strccd r8, [r13, r12]") + TEST_UNSUPPORTED( "strccd r8, [r12, r13]") TEST_RPR( "strd r",4, VAL1,", [r",2, 24,", r",3, 48,"]!") TEST_RPR( "strcsd r",12,VAL2,", [r",11,48,", -r",10,24,"]!")TEST_RPR ("strd r" ,2 ,VAL1 ,", [r" ,5 ,24 ,"], r" ,4 ,48 ,"" )
@@ -591,6 +597,9 @@ void kprobe_arm_test_cases(void) TEST_RP( "strvcd r",12,VAL2,", [r",11,24,", #-16]!") TEST_RP( "strd r",2, VAL1,", [r",4, 24,"], #48") TEST_RP( "strd r",10,VAL2,", [r",9, 64,"], #-48") + TEST_RP( "strd r",6, VAL1,", [r",13,TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"]!") + TEST_UNSUPPORTED("strd r6, [r13, #-"__stringify(MAX_STACK_SIZE)"-8]!") + TEST_RP( "strd r",4, VAL1,", [r",12,TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"-8]!") TEST_UNSUPPORTED(__inst_arm(0xe1efc3f0) " @ strd r12, [pc, #48]!")TEST_P ("ldrd r0, [r" ,0 ,24 ,", #-8]" )
@@ -639,16 +648,20 @@ void kprobe_arm_test_cases(void) TEST_RP( "str"byte" r",12,VAL2,", [r",11,24,", #-4]!") \ TEST_RP( "str"byte" r",2, VAL1,", [r",3, 24,"], #48") \ TEST_RP( "str"byte" r",10,VAL2,", [r",9, 64,"], #-48") \ + TEST_RP( "str"byte" r",3, VAL1,", [r",13,TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"]!") \ + TEST_UNSUPPORTED("str"byte" r3, [r13, #-"__stringify(MAX_STACK_SIZE)"-8]!") \ + TEST_RP( "str"byte" r",4, VAL1,", [r",10,TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"-8]!") \ TEST_RPR("str"byte" r",0, VAL1,", [r",1, 48,", -r",2, 24,"]") \ TEST_RPR("str"byte" r",14,VAL2,", [r",11,0, ", r",12, 48,"]") \ - TEST_UNSUPPORTED("str"byte" r14, [r13, r12]") \ + TEST_UNSUPPORTED("str"byte" r14, [r13, r12]") \ + TEST_UNSUPPORTED("str"byte" r14, [r12, r13]") \ TEST_RPR("str"byte" r",1, VAL1,", [r",2, 24,", r",3, 48,"]!") \ TEST_RPR("str"byte" r",12,VAL2,", [r",11,48,", -r",10,24,"]!") \ TEST_RPR("str"byte" r",2, VAL1,", [r",3, 24,"], r",4, 48,"") \ TEST_RPR("str"byte" r",10,VAL2,", [r",9, 48,"], -r",11,24,"") \ TEST_RPR("str"byte" r",0, VAL1,", [r",1, 24,", r",2, 32,", asl #1]")\ TEST_RPR("str"byte" r",14,VAL2,", [r",11,0, ", r",12, 32,", lsr #2]")\ - TEST_UNSUPPORTED("str"byte" r14, [r13, r12, lsr #2]")\ + TEST_UNSUPPORTED("str"byte" r14, [r13, r12, lsr #2]") \ TEST_RPR("str"byte" r",1, VAL1,", [r",2, 24,", r",3, 32,", asr #3]!")\ TEST_RPR("str"byte" r",12,VAL2,", [r",11,24,", r",10, 4,", ror #31]!")\TEST_P ("ldr" byte" r0, [r" ,0 ,24 ,", #-2]" ) \
arch/arm/probes/kprobes/test-core.c +9 -0
@@ -1196,6 +1196,13 @@ static void setup_test_context(struct pt_regs *regs) regs->uregs[arg->reg] = (unsigned long )current_stack + arg->val; memory_needs_checking = true; +/* +* Test memory at an address below SP is in danger of +* being altered by an interrupt occurring and pushing +* data onto the stack. Disable interrupts to stop this. +*/ +if (arg->reg ==13 ) + regs->ARM_cpsr |=PSR_I_BIT ;break ; }case ARG_TYPE_MEM : {
@@ -1272,6 +1279,8 @@ test_after_pre_handler(struct kprobe *p, struct pt_regs *regs)/* Undo any changes done to SP by the test case */ regs->ARM_sp = (unsigned long )current_stack; +/* Enable interrupts in case setup_test_context disabled them */ + regs->ARM_cpsr &= ~PSR_I_BIT ; container_of(p, struct test_probe, kprobe)->hit = test_instance;return 0 ;
arch/arm/probes/kprobes/test-thumb.c +12 -0
@@ -11,6 +11,7 @@#include <linux/kernel.h> #include <linux/module.h> #include <asm/opcodes.h> +#include <asm/probes.h> #include "test-core.h"
@@ -416,6 +417,9 @@ void kprobe_thumb32_test_cases(void) TEST_RR( "strd r",14,VAL2,", r",12,VAL1,", [sp, #16]!") TEST_RRP("strd r",1, VAL1,", r",0, VAL2,", [r",7, 24,"], #16") TEST_RR( "strd r",7, VAL2,", r",8, VAL1,", [sp], #-16") + TEST_RRP("strd r",6, VAL1,", r",7, VAL2,", [r",13, TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"]!") + TEST_UNSUPPORTED("strd r6, r7, [r13, #-"__stringify(MAX_STACK_SIZE)"-8]!") + TEST_RRP("strd r",4, VAL1,", r",5, VAL2,", [r",14, TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"-8]!") TEST_UNSUPPORTED(__inst_thumb32(0xe9efec04) " @ strd r14, r12, [pc, #16]!") TEST_UNSUPPORTED(__inst_thumb32(0xe8efec04) " @ strd r14, r12, [pc], #16")
@@ -821,14 +825,22 @@ CONDITION_INSTRUCTIONS(22, TEST_RP( "str"size" r",14,VAL2,", [r",1, 256, ", #-128]!") \ TEST_RPR("str"size".w r",0, VAL1,", [r",1, 0,", r",2, 4,"]") \ TEST_RPR("str"size" r",14,VAL2,", [r",10,0,", r",11,4,", lsl #1]") \ + TEST_UNSUPPORTED("str"size" r0, [r13, r1]") \ TEST_R( "str"size".w r",7, VAL1,", [sp, #24]") \ TEST_RP( "str"size".w r",0, VAL2,", [r",0,0, "]") \ + TEST_RP( "str"size" r",6, VAL1,", [r",13, TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"]!") \ + TEST_UNSUPPORTED("str"size" r6, [r13, #-"__stringify(MAX_STACK_SIZE)"-8]!") \ + TEST_RP( "str"size" r",4, VAL2,", [r",12, TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"-8]!") \ TEST_UNSUPPORTED("str"size"t r0, [r1, #4]") SINGLE_STORE("b") SINGLE_STORE("h") SINGLE_STORE("") + TEST_UNSUPPORTED(__inst_thumb32(0xf801000d) " @ strb r0, [r1, r13]") + TEST_UNSUPPORTED(__inst_thumb32(0xf821000d) " @ strh r0, [r1, r13]") + TEST_UNSUPPORTED(__inst_thumb32(0xf841000d) " @ str r0, [r1, r13]") + TEST("str sp, [sp]") TEST_UNSUPPORTED(__inst_thumb32(0xf8cfe000) " @ str r14, [pc]") TEST_UNSUPPORTED(__inst_thumb32(0xf8cef000) " @ str pc, [r14]")
Signature · 1 line
1.8.4
PATCH v19 7/11 kprobes: Pass the original kprobe for preparing optimized kprobe
In reply to Wang NanFrom: Masami Hiramatsu <[email protected]>
Pass the original kprobe for preparing an optimized kprobe arch-dep part, since for some architecture (e.g. ARM32) requires the information in original kprobe.
--- arch/x86/kernel/kprobes/opt.c | 3 ++- include/linux/kprobes.h | 3 ++- kernel/kprobes.c | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-)
arch/x86/kernel/kprobes/opt.c +2 -1
@@ -322,7 +322,8 @@ void arch_remove_optimized_kprobe(struct optimized_kprobe *op)* Target instructions MUST be relocatable (checked inside) * This is called when new aggr(opt)probe is allocated or reused. */ -int arch_prepare_optimized_kprobe (struct optimized_kprobe *op) +int arch_prepare_optimized_kprobe (struct optimized_kprobe *op, +struct kprobe *__unused) {u8 *buf;int ret;
include/linux/kprobes.h +2 -1
@@ -308,7 +308,8 @@ struct optimized_kprobe {/* Architecture dependent functions for direct jump optimization */ extern int arch_prepared_optinsn (struct arch_optimized_insn *optinsn);extern int arch_check_optimized_kprobe (struct optimized_kprobe *op); -extern int arch_prepare_optimized_kprobe (struct optimized_kprobe *op); +extern int arch_prepare_optimized_kprobe (struct optimized_kprobe *op, +struct kprobe *orig);extern void arch_remove_optimized_kprobe (struct optimized_kprobe *op);extern void arch_optimize_kprobes (struct list_head *oplist); extern void arch_unoptimize_kprobes(struct list_head *oplist,
kernel/kprobes.c +2 -2
@@ -717,7 +717,7 @@ static void prepare_optimized_kprobe(struct kprobe *p)struct optimized_kprobe *op; op = container_of(p, struct optimized_kprobe, kp); -arch_prepare_optimized_kprobe (op); +arch_prepare_optimized_kprobe (op, p); }/* Allocate new optimized_kprobe and try to prepare optimized instructions */
@@ -731,7 +731,7 @@ static struct kprobe *alloc_aggr_kprobe(struct kprobe *p)INIT_LIST_HEAD (&op->list); op->kp.addr = p->addr; -arch_prepare_optimized_kprobe (op); +arch_prepare_optimized_kprobe (op, p);return &op->kp; }
Signature · 1 line
1.8.4
PATCH v19 8/11 ARM: kprobes: enable OPTPROBES for ARM 32
In reply to Wang NanThis patch introduce kprobeopt for ARM 32.
Limitations:
- Currently only kernel compiled with ARM ISA is supported.
- Offset between probe point and optinsn slot must not larger than 32MiB. Masami Hiramatsu suggests replacing 2 words, it will make things complex. Futher patch can make such optimization.
Kprobe opt on ARM is relatively simpler than kprobe opt on x86 because ARM instruction is always 4 bytes aligned and 4 bytes long. This patch replace probed instruction by a 'b', branch to trampoline code and then calls optimized_callback(). optimized_callback() calls opt_pre_handler() to execute kprobe handler. It also emulate/simulate replaced instruction.
When unregistering kprobe, the deferred manner of unoptimizer may leave branch instruction before optimizer is called. Different from x86_64, which only copy the probed insn after optprobe_template_end and reexecute them, this patch call singlestep to emulate/simulate the insn directly. Futher patch can optimize this behavior.
---
arch/arm/Kconfig | 1 +
arch/arm/{kernel => include/asm}/insn.h | 0
arch/arm/include/asm/kprobes.h | 29 +++
arch/arm/kernel/Makefile | 2 +-
arch/arm/kernel/ftrace.c | 3 +-
arch/arm/kernel/jump_label.c | 3 +-
arch/arm/probes/kprobes/Makefile | 1 +
arch/arm/probes/kprobes/core.c | 26 ++-
arch/arm/probes/kprobes/core.h | 2 +
arch/arm/probes/kprobes/opt-arm.c | 317 ++++++++++++++++++++++++++++++++
10 files changed, 372 insertions(+), 12 deletions(-)
rename arch/arm/{kernel => include/asm}/insn.h (100%)
create mode 100644 arch/arm/probes/kprobes/opt-arm.carch/arm/Kconfig +1 -0
@@ -60,6 +60,7 @@ config ARM select HAVE_MEMBLOCK select HAVE_MOD_ARCH_SPECIFIC if ARM_UNWIND select HAVE_OPROFILE if (HAVE_PERF_EVENTS) + select HAVE_OPTPROBES if !THUMB2_KERNEL select HAVE_PERF_EVENTS select HAVE_PERF_REGS select HAVE_PERF_USER_STACK_DUMP
arch/arm/include/asm/insn.h renamed from arch/arm/kernel/insn.h +0 -0
arch/arm/include/asm/kprobes.h +29 -0
@@ -50,5 +50,34 @@ int kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr);int kprobe_exceptions_notify (struct notifier_block *self,unsigned long val,void *data); +/* optinsn template addresses */ +extern __visible kprobe_opcode_t optprobe_template_entry; +extern __visible kprobe_opcode_t optprobe_template_val; +extern __visible kprobe_opcode_t optprobe_template_call; +extern __visible kprobe_opcode_t optprobe_template_end; +extern __visible kprobe_opcode_t optprobe_template_sub_sp; +extern __visible kprobe_opcode_t optprobe_template_add_sp; + +#define MAX_OPTIMIZED_LENGTH 4 +#define MAX_OPTINSN_SIZE \ + ((unsigned long)&optprobe_template_end - \ + (unsigned long)&optprobe_template_entry) +#define RELATIVEJUMP_SIZE 4 + +struct arch_optimized_insn { +/* +* copy of the original instructions. +* Different from x86, ARM kprobe_opcode_t is u32. +*/ +#define MAX_COPIED_INSN DIV_ROUND_UP(RELATIVEJUMP_SIZE, sizeof(kprobe_opcode_t)) +kprobe_opcode_t copied_insn[MAX_COPIED_INSN ]; +/* detour code buffer */ +kprobe_opcode_t *insn; +/* +* We always copy one instruction on ARM, +* so size will always be 4, and unlike x86, there is no +* need for a size field. +*/ +};#endif /* _ARM_KPROBES_H */
arch/arm/kernel/Makefile +1 -1
@@ -52,7 +52,7 @@ obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o insn.o obj-$(CONFIG_JUMP_LABEL) += jump_label.o insn.o patch.o obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o # Main staffs in KPROBES are in arch/arm/probes/ . -obj-$(CONFIG_KPROBES) += patch.o +obj-$(CONFIG_KPROBES) += patch.o insn.o obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o obj-$(CONFIG_ARM_THUMBEE) += thumbee.o obj-$(CONFIG_KGDB) += kgdb.o patch.o
arch/arm/kernel/ftrace.c +1 -2
@@ -20,8 +20,7 @@#include <asm/cacheflush.h> #include <asm/opcodes.h> #include <asm/ftrace.h> - -#include "insn.h" +#include <asm/insn.h> #ifdef CONFIG_THUMB2_KERNEL #define NOP 0xf85deb04/* pop.w {lr} */
arch/arm/kernel/jump_label.c +1 -2
@@ -1,8 +1,7 @@#include <linux/kernel.h> #include <linux/jump_label.h> #include <asm/patch.h> - -#include "insn.h" +#include <asm/insn.h> #ifdef HAVE_JUMP_LABEL
arch/arm/probes/kprobes/Makefile +1 -0
@@ -7,5 +7,6 @@ obj-$(CONFIG_KPROBES) += actions-thumb.o checkers-thumb.o test-kprobes-objs += test-thumb.o else obj-$(CONFIG_KPROBES) += actions-arm.o checkers-arm.o +obj-$(CONFIG_OPTPROBES) += opt-arm.o test-kprobes-objs += test-arm.o endif
arch/arm/probes/kprobes/core.c +19 -7
@@ -163,19 +163,31 @@ void __kprobes arch_arm_kprobe(struct kprobe *p)* memory. It is also needed to atomically set the two half-words of a 32-bit * Thumb breakpoint. */ -int __kprobes __arch_disarm_kprobe (void *p) -{ -struct kprobe *kp = p; -void *addr = (void *)((uintptr_t )kp->addr & ~1 ); - -__patch_text (addr, kp->opcode); +struct patch { +void *addr; +unsigned int insn; +}; +static int __kprobes_remove_breakpoint (void *data) +{ +struct patch *p = data; +__patch_text (p->addr, p->insn);return 0 ; } +void __kprobes kprobes_remove_breakpoint (void *addr,unsigned int insn) +{ +struct patch p = { + .addr = addr, + .insn = insn, + }; +stop_machine (__kprobes_remove_breakpoint, &p, cpu_online_mask); +} +void __kprobes arch_disarm_kprobe (struct kprobe *p) { -stop_machine (__arch_disarm_kprobe, p, cpu_online_mask); +kprobes_remove_breakpoint ((void *)((uintptr_t )p->addr & ~1 ), + p->opcode); }void __kprobes arch_remove_kprobe (struct kprobe *p)
arch/arm/probes/kprobes/core.h +2 -0
@@ -30,6 +30,8 @@#define KPROBE_THUMB16_BREAKPOINT_INSTRUCTION 0xde18#define KPROBE_THUMB32_BREAKPOINT_INSTRUCTION 0xf7f0a018 +extern void kprobes_remove_breakpoint (void *addr,unsigned int insn); +enum probes_insn __kprobes kprobe_decode_ldmstm (kprobe_opcode_t insn,struct arch_probes_insn *asi,const struct decode_header *h);
arch/arm/probes/kprobes/opt-arm.c new file +317 -0
317 lines not on this page · raw message
Signature · 1 line
1.8.4
Re: [PATCH v19 08/11] ARM: kprobes: enable OPTPROBES for ARM 32
Quoted 21 lines · Wang Nan
This patch introduce kprobeopt for ARM 32.
Limitations:
- Currently only kernel compiled with ARM ISA is supported.- Offset between probe point and optinsn slot must not larger than 32MiB. Masami Hiramatsu suggests replacing 2 words, it will make things complex. Futher patch can make such optimization.
Kprobe opt on ARM is relatively simpler than kprobe opt on x86 because ARM instruction is always 4 bytes aligned and 4 bytes long. This patch replace probed instruction by a 'b', branch to trampoline code and then calls
optimized_callback().optimized_callback()callsopt_pre_handler()to execute kprobe handler. It also emulate/simulate replaced instruction.When unregistering kprobe, the deferred manner of unoptimizer may leave branch instruction before optimizer is called. Different from
x86_64, which only copy the probed insn afteroptprobe_template_endand reexecute them, this patch call singlestep to emulate/simulate the insn directly. Futher patch can optimize this behavior.
Quoted 3 lines
Signed-off-by Wang Nan <[email protected]>Acked-by Masami Hiramatsu <[email protected]>Cc Jon Medhurst (Tixy) <[email protected]>
Quoted 503 lines
Cc Russell King - ARM Linux <[email protected]>Cc Will Deacon <[email protected]>--- arch/arm/Kconfig | 1 + arch/arm/{kernel => include/asm}/insn.h | 0 arch/arm/include/asm/kprobes.h | 29 +++ arch/arm/kernel/Makefile | 2 +- arch/arm/kernel/ftrace.c | 3 +- arch/arm/kernel/jump_label.c | 3 +- arch/arm/probes/kprobes/Makefile | 1 + arch/arm/probes/kprobes/core.c | 26 ++- arch/arm/probes/kprobes/core.h | 2 + arch/arm/probes/kprobes/opt-arm.c | 317 ++++++++++++++++++++++++++++++++ 10 files changed, 372 insertions(+), 12 deletions(-) rename arch/arm/{kernel => include/asm}/insn.h (100%) create mode 100644 arch/arm/probes/kprobes/opt-arm.carch/arm/Kconfig +1
-0@@ -60,6 +60,7 @@ config ARM select HAVE_MEMBLOCK select HAVE_MOD_ARCH_SPECIFIC if ARM_UNWIND select HAVE_OPROFILE if (HAVE_PERF_EVENTS) + select HAVE_OPTPROBES if !THUMB2_KERNEL select HAVE_PERF_EVENTS select HAVE_PERF_REGS select HAVE_PERF_USER_STACK_DUMParch/arm/include/asm/insn.h renamed from arch/arm/kernel/insn.h +0
-0arch/arm/include/asm/kprobes.h +29
-0@@ -50,5 +50,34 @@ int kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr);int kprobe_exceptions_notify (struct notifier_block *self,unsigned long val,void *data); +/* optinsn template addresses */ +extern __visible kprobe_opcode_t optprobe_template_entry; +extern __visible kprobe_opcode_t optprobe_template_val; +extern __visible kprobe_opcode_t optprobe_template_call; +extern __visible kprobe_opcode_t optprobe_template_end; +extern __visible kprobe_opcode_t optprobe_template_sub_sp; +extern __visible kprobe_opcode_t optprobe_template_add_sp; + +#define MAX_OPTIMIZED_LENGTH 4 +#define MAX_OPTINSN_SIZE \ + ((unsigned long)&optprobe_template_end - \ + (unsigned long)&optprobe_template_entry) +#define RELATIVEJUMP_SIZE 4 + +struct arch_optimized_insn { +/* +* copy of the original instructions. +* Different from x86, ARM kprobe_opcode_t is u32. +*/ +#define MAX_COPIED_INSN DIV_ROUND_UP(RELATIVEJUMP_SIZE, sizeof(kprobe_opcode_t)) +kprobe_opcode_t copied_insn[MAX_COPIED_INSN ]; +/* detour code buffer */ +kprobe_opcode_t *insn; +/* +* We always copy one instruction on ARM, +* so size will always be 4, and unlike x86, there is no +* need for a size field. +*/ +};#endif /* _ARM_KPROBES_H */ arch/arm/kernel/Makefile +1
-1@@ -52,7 +52,7 @@ obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o insn.o obj-$(CONFIG_JUMP_LABEL) += jump_label.o insn.o patch.o obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o # Main staffs in KPROBES are in arch/arm/probes/ . -obj-$(CONFIG_KPROBES) += patch.o +obj-$(CONFIG_KPROBES) += patch.o insn.o obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o obj-$(CONFIG_ARM_THUMBEE) += thumbee.o obj-$(CONFIG_KGDB) += kgdb.o patch.oarch/arm/kernel/ftrace.c +1
-2@@ -20,8 +20,7 @@#include <asm/cacheflush.h> #include <asm/opcodes.h> #include <asm/ftrace.h> - -#include "insn.h" +#include <asm/insn.h> #ifdef CONFIG_THUMB2_KERNEL #define NOP 0xf85deb04/* pop.w {lr} */ arch/arm/kernel/jump_label.c +1
-2@@ -1,8 +1,7 @@#include <linux/kernel.h> #include <linux/jump_label.h> #include <asm/patch.h> - -#include "insn.h" +#include <asm/insn.h> #ifdef HAVE_JUMP_LABEL arch/arm/probes/kprobes/Makefile +1
-0@@ -7,5 +7,6 @@ obj-$(CONFIG_KPROBES) += actions-thumb.o checkers-thumb.o test-kprobes-objs += test-thumb.o else obj-$(CONFIG_KPROBES) += actions-arm.o checkers-arm.o +obj-$(CONFIG_OPTPROBES) += opt-arm.o test-kprobes-objs += test-arm.o endifarch/arm/probes/kprobes/core.c +19
-7@@ -163,19 +163,31 @@ void __kprobes arch_arm_kprobe(struct kprobe *p)* memory. It is also needed to atomically set the two half-words of a 32-bit * Thumb breakpoint. */ -int __kprobes __arch_disarm_kprobe (void *p) -{ -struct kprobe *kp = p; -void *addr = (void *)((uintptr_t )kp->addr & ~1 ); - -__patch_text (addr, kp->opcode); +struct patch { +void *addr; +unsigned int insn; +}; +static int __kprobes_remove_breakpoint (void *data) +{ +struct patch *p = data; +__patch_text (p->addr, p->insn);return 0 ; } +void __kprobes kprobes_remove_breakpoint (void *addr,unsigned int insn) +{ +struct patch p = { + .addr = addr, + .insn = insn, + }; +stop_machine (__kprobes_remove_breakpoint, &p, cpu_online_mask); +} +void __kprobes arch_disarm_kprobe (struct kprobe *p) { -stop_machine (__arch_disarm_kprobe, p, cpu_online_mask); +kprobes_remove_breakpoint ((void *)((uintptr_t )p->addr & ~1 ), + p->opcode); }void __kprobes arch_remove_kprobe (struct kprobe *p)arch/arm/probes/kprobes/core.h +2
-0@@ -30,6 +30,8 @@#define KPROBE_THUMB16_BREAKPOINT_INSTRUCTION 0xde18#define KPROBE_THUMB32_BREAKPOINT_INSTRUCTION 0xf7f0a018 +extern void kprobes_remove_breakpoint (void *addr,unsigned int insn); +enum probes_insn __kprobes kprobe_decode_ldmstm (kprobe_opcode_t insn,struct arch_probes_insn *asi,const struct decode_header *h);arch/arm/probes/kprobes/opt-arm.c new file +317
-0@@ -0,0 +1,317 @@ +/* +* Kernel Probes Jump Optimization (Optprobes) +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +* Copyright (C) IBM Corporation, 2002, 2004 +* Copyright (C) Hitachi Ltd., 2012 +* Copyright (C) Huawei Inc., 2014 +*/ + +#include <linux/kprobes.h> +#include <linux/jump_label.h> +#include <asm/kprobes.h> +#include <asm/cacheflush.h> +/* for arm_gen_branch */ +#include <asm/insn.h> +/* for patch_text */ +#include <asm/patch.h> + +#include "core.h" + +/* +* NOTE: the first sub and add instruction will be modified according +* to the stack cost of the instruction. +*/ +asm ( +".global optprobe_template_entry\n" +"optprobe_template_entry:\n" +".global optprobe_template_sub_sp\n" +"optprobe_template_sub_sp:" +" sub sp, sp, #0xff\n" +" stmia sp, {r0 - r14} \n" +".global optprobe_template_add_sp\n" +"optprobe_template_add_sp:" +" add r3, sp, #0xff\n" +" str r3, [sp, #52]\n" +" mrs r4, cpsr\n" +" str r4, [sp, #64]\n" +" mov r1, sp\n" +" ldr r0, 1f\n" +" ldr r2, 2f\n" +/* +* AEABI requires an 8-bytes alignment stack. If +* SP % 8 != 0 (SP % 4 == 0 should be ensured), +* alloc more bytes here. +*/ +" and r4, sp, #4\n" +" sub sp, sp, r4\n" +" blx r2\n" +" add sp, sp, r4\n" +" ldr r1, [sp, #64]\n" + " tst r1, #"__stringify(PSR_T_BIT)"\n" +" ldrne r2, [sp, #60]\n" +" orrne r2, #1\n" +" strne r2, [sp, #60] @ set bit0 of PC for thumb\n" +" msr cpsr_cxsf, r1\n" +" ldmia sp, {r0 - r15}\n" +".global optprobe_template_val\n" +"optprobe_template_val:\n" +"1: .long 0\n" +".global optprobe_template_call\n" +"optprobe_template_call:\n" +"2: .long 0\n" +".global optprobe_template_end\n" + "optprobe_template_end:\n"); + +#define TMPL_VAL_IDX \ + ((unsigned long *)&optprobe_template_val - (unsigned long *)&optprobe_template_entry) +#define TMPL_CALL_IDX \ + ((unsigned long *)&optprobe_template_call - (unsigned long *)&optprobe_template_entry) +#define TMPL_END_IDX \ + ((unsigned long *)&optprobe_template_end - (unsigned long *)&optprobe_template_entry) +#define TMPL_ADD_SP \ + ((unsigned long *)&optprobe_template_add_sp - (unsigned long *)&optprobe_template_entry) +#define TMPL_SUB_SP \ + ((unsigned long *)&optprobe_template_sub_sp - (unsigned long *)&optprobe_template_entry) + +/* +* ARM can always optimize an instruction when using ARM ISA, except +* instructions like 'str r0, [sp, r1]' which store to stack and unable +* to determine stack space consumption statically. +*/ +int arch_prepared_optinsn (struct arch_optimized_insn *optinsn) +{ +return optinsn->insn !=NULL ; +} + +/* +* In ARM ISA, kprobe opt always replace one instruction (4 bytes +* aligned and 4 bytes long). It is impossible to encounter another +* kprobe in the address range. So always return 0. +*/ +int arch_check_optimized_kprobe (struct optimized_kprobe *op) +{ +return 0 ; +} + +/* Caller must ensure addr & 3 == 0 */ +static int can_optimize (struct kprobe *kp) +{ +if (kp->ainsn.stack_space <0 ) +return 0 ; +/* +* 255 is the biggest imm can be used in 'sub r0, r0, #<imm>'. +* Number larger than 255 needs special encoding. +*/ +if (kp->ainsn.stack_space >255 -sizeof (struct pt_regs )) +return 0 ; +return 1 ; +} + +/* Free optimized instruction slot */ +static void +__arch_remove_optimized_kprobe (struct optimized_kprobe *op,int dirty) +{ +if (op->optinsn.insn) { +free_optinsn_slot (op->optinsn.insn, dirty); + op->optinsn.insn =NULL ; + } +} + +extern void kprobe_handler (struct pt_regs *regs); + +static void +optimized_callback (struct optimized_kprobe *op,struct pt_regs *regs) +{ +unsigned long flags; +struct kprobe *p = &op->kp; +struct kprobe_ctlblk *kcb =get_kprobe_ctlblk (); + +/* Save skipped registers */ + regs->ARM_pc = (unsigned long )op->kp.addr; + regs->ARM_ORIG_r0 = ~0UL ; + +local_irq_save (flags); + +if (kprobe_running ()) { +kprobes_inc_nmissed_count (&op->kp); + }else { +__this_cpu_write (current_kprobe, &op->kp); + kcb->kprobe_status =KPROBE_HIT_ACTIVE ; +opt_pre_handler (&op->kp, regs); +__this_cpu_write (current_kprobe,NULL ); + } + +/* In each case, we must singlestep the replaced instruction. */ + op->kp.ainsn.insn_singlestep (p->opcode, &p->ainsn, regs); + +local_irq_restore (flags); +} + +int arch_prepare_optimized_kprobe (struct optimized_kprobe *op,struct kprobe *orig) +{ +kprobe_opcode_t *code; +unsigned long rel_chk; +unsigned long val; +unsigned long stack_protect =sizeof (struct pt_regs ); + +if (!can_optimize (orig)) +return -EILSEQ ; + + code =get_optinsn_slot (); +if (!code) +return -ENOMEM ; + +/* +* Verify if the address gap is in 32MiB range, because this uses +* a relative jump. +* +* kprobe opt use a 'b' instruction to branch to optinsn.insn. +* According to ARM manual, branch instruction is: +* +* 31 28 27 24 23 0 +* +------+---+---+---+---+----------------+ +* | cond | 1 | 0 | 1 | 0 | imm24 | +* +------+---+---+---+---+----------------+ +* +* imm24 is a signed 24 bits integer. The real branch offset is computed +* by: imm32 = SignExtend(imm24:'00', 32); +* +* So the maximum forward branch should be: +* (0x007fffff << 2) = 0x01fffffc = 0x1fffffc +* The maximum backword branch should be: +* (0xff800000 << 2) = 0xfe000000 = -0x2000000 +* +* We can simply check (rel & 0xfe000003): +* if rel is positive, (rel & 0xfe000000) shoule be 0 +* if rel is negitive, (rel & 0xfe000000) should be 0xfe000000 +* the last '3' is used for alignment checking. +*/ + rel_chk = (unsigned long )((long )code - + (long )orig->addr +8 ) &0xfe000003 ; + +if ((rel_chk !=0 ) && (rel_chk !=0xfe000000 )) { +/* +* Different from x86, we free code buf directly instead of +* calling __arch_remove_optimized_kprobe() because +* we have not fill any field in op. +*/ +free_optinsn_slot (code,0 ); +return -ERANGE ; + } + +/* Copy arch-dep-instance from template. */ +memcpy (code, &optprobe_template_entry, +TMPL_END_IDX *sizeof (kprobe_opcode_t)); + +/* Adjust buffer according to instruction. */ +BUG_ON (orig->ainsn.stack_space <0 ); + + stack_protect += orig->ainsn.stack_space; + +/* Should have been filtered by can_optimize(). */ +BUG_ON (stack_protect >255 ); + +/* Create a 'sub sp, sp, #<stack_protect>' */ + code[TMPL_SUB_SP ] =__opcode_to_mem_arm (0xe24dd000 | stack_protect); +/* Create a 'add r3, sp, #<stack_protect>' */ + code[TMPL_ADD_SP ] =__opcode_to_mem_arm (0xe28d3000 | stack_protect); + +/* Set probe information */ + val = (unsigned long )op; + code[TMPL_VAL_IDX ] = val; + +/* Set probe function call */ + val = (unsigned long )optimized_callback; + code[TMPL_CALL_IDX ] = val; + +flush_icache_range ((unsigned long )code, + (unsigned long )(&code[TMPL_END_IDX ])); + +/* Set op->optinsn.insn means prepared. */ + op->optinsn.insn = code; +return 0 ; +} + +void __kprobes arch_optimize_kprobes (struct list_head *oplist) +{ +struct optimized_kprobe *op, *tmp; + +list_for_each_entry_safe (op, tmp, oplist, list) { +unsigned long insn; +WARN_ON (kprobe_disabled (&op->kp)); + +/* +* Backup instructions which will be replaced +* by jump address +*/ +memcpy (op->optinsn.copied_insn, op->kp.addr, +RELATIVEJUMP_SIZE ); + + insn =arm_gen_branch ((unsigned long )op->kp.addr, + (unsigned long )op->optinsn.insn); +BUG_ON (insn ==0 ); + +/* +* Make it a conditional branch if replaced insn +* is consitional +*/ + insn = (__mem_to_opcode_arm ( + op->optinsn.copied_insn[0 ]) &0xf0000000 ) | + (insn &0x0fffffff ); + +/* +* Similar to __arch_disarm_kprobe, operations which +* removing breakpoints must be wrapped by stop_machine +* to avoid racing. +*/ +kprobes_remove_breakpoint (op->kp.addr, insn); + +list_del_init (&op->list); + } +} + +void arch_unoptimize_kprobe (struct optimized_kprobe *op) +{ +arch_arm_kprobe (&op->kp); +} + +/* +* Recover original instructions and breakpoints from relative jumps. +* Caller must call with locking kprobe_mutex. +*/ +void arch_unoptimize_kprobes (struct list_head *oplist, +struct list_head *done_list) +{ +struct optimized_kprobe *op, *tmp; + +list_for_each_entry_safe (op, tmp, oplist, list) { +arch_unoptimize_kprobe (op); +list_move (&op->list, done_list); + } +} + +int arch_within_optimized_kprobe (struct optimized_kprobe *op, +unsigned long addr) +{ +return ((unsigned long )op->kp.addr <= addr && + (unsigned long )op->kp.addr +RELATIVEJUMP_SIZE > addr); +} + +void arch_remove_optimized_kprobe (struct optimized_kprobe *op) +{ +__arch_remove_optimized_kprobe (op,1 ); +}
PATCH v20 8/11 ARM: kprobes: enable OPTPROBES for ARM 32
In reply to Wang NanThis patch introduce kprobeopt for ARM 32.
Limitations:
- Currently only kernel compiled with ARM ISA is supported.
- Offset between probe point and optinsn slot must not larger than 32MiB. Masami Hiramatsu suggests replacing 2 words, it will make things complex. Futher patch can make such optimization.
Kprobe opt on ARM is relatively simpler than kprobe opt on x86 because ARM instruction is always 4 bytes aligned and 4 bytes long. This patch replace probed instruction by a 'b', branch to trampoline code and then calls optimized_callback(). optimized_callback() calls opt_pre_handler() to execute kprobe handler. It also emulate/simulate replaced instruction.
When unregistering kprobe, the deferred manner of unoptimizer may leave branch instruction before optimizer is called. Different from x86_64, which only copy the probed insn after optprobe_template_end and reexecute them, this patch call singlestep to emulate/simulate the insn directly. Futher patch can optimize this behavior.
---
arch/arm/Kconfig | 1 +
arch/arm/{kernel => include/asm}/insn.h | 0
arch/arm/include/asm/kprobes.h | 29 +++
arch/arm/kernel/Makefile | 2 +-
arch/arm/kernel/ftrace.c | 3 +-
arch/arm/kernel/jump_label.c | 3 +-
arch/arm/probes/kprobes/Makefile | 1 +
arch/arm/probes/kprobes/core.c | 26 ++-
arch/arm/probes/kprobes/core.h | 2 +
arch/arm/probes/kprobes/opt-arm.c | 322 ++++++++++++++++++++++++++++++++
10 files changed, 377 insertions(+), 12 deletions(-)
rename arch/arm/{kernel => include/asm}/insn.h (100%)
create mode 100644 arch/arm/probes/kprobes/opt-arm.carch/arm/Kconfig +1 -0
@@ -60,6 +60,7 @@ config ARM select HAVE_MEMBLOCK select HAVE_MOD_ARCH_SPECIFIC if ARM_UNWIND select HAVE_OPROFILE if (HAVE_PERF_EVENTS) + select HAVE_OPTPROBES if !THUMB2_KERNEL select HAVE_PERF_EVENTS select HAVE_PERF_REGS select HAVE_PERF_USER_STACK_DUMP
arch/arm/include/asm/insn.h renamed from arch/arm/kernel/insn.h +0 -0
arch/arm/include/asm/kprobes.h +29 -0
@@ -50,5 +50,34 @@ int kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr);int kprobe_exceptions_notify (struct notifier_block *self,unsigned long val,void *data); +/* optinsn template addresses */ +extern __visible kprobe_opcode_t optprobe_template_entry; +extern __visible kprobe_opcode_t optprobe_template_val; +extern __visible kprobe_opcode_t optprobe_template_call; +extern __visible kprobe_opcode_t optprobe_template_end; +extern __visible kprobe_opcode_t optprobe_template_sub_sp; +extern __visible kprobe_opcode_t optprobe_template_add_sp; + +#define MAX_OPTIMIZED_LENGTH 4 +#define MAX_OPTINSN_SIZE \ + ((unsigned long)&optprobe_template_end - \ + (unsigned long)&optprobe_template_entry) +#define RELATIVEJUMP_SIZE 4 + +struct arch_optimized_insn { +/* +* copy of the original instructions. +* Different from x86, ARM kprobe_opcode_t is u32. +*/ +#define MAX_COPIED_INSN DIV_ROUND_UP(RELATIVEJUMP_SIZE, sizeof(kprobe_opcode_t)) +kprobe_opcode_t copied_insn[MAX_COPIED_INSN ]; +/* detour code buffer */ +kprobe_opcode_t *insn; +/* +* We always copy one instruction on ARM, +* so size will always be 4, and unlike x86, there is no +* need for a size field. +*/ +};#endif /* _ARM_KPROBES_H */
arch/arm/kernel/Makefile +1 -1
@@ -52,7 +52,7 @@ obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o insn.o obj-$(CONFIG_JUMP_LABEL) += jump_label.o insn.o patch.o obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o # Main staffs in KPROBES are in arch/arm/probes/ . -obj-$(CONFIG_KPROBES) += patch.o +obj-$(CONFIG_KPROBES) += patch.o insn.o obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o obj-$(CONFIG_ARM_THUMBEE) += thumbee.o obj-$(CONFIG_KGDB) += kgdb.o patch.o
arch/arm/kernel/ftrace.c +1 -2
@@ -20,8 +20,7 @@#include <asm/cacheflush.h> #include <asm/opcodes.h> #include <asm/ftrace.h> - -#include "insn.h" +#include <asm/insn.h> #ifdef CONFIG_THUMB2_KERNEL #define NOP 0xf85deb04/* pop.w {lr} */
arch/arm/kernel/jump_label.c +1 -2
@@ -1,8 +1,7 @@#include <linux/kernel.h> #include <linux/jump_label.h> #include <asm/patch.h> - -#include "insn.h" +#include <asm/insn.h> #ifdef HAVE_JUMP_LABEL
arch/arm/probes/kprobes/Makefile +1 -0
@@ -7,5 +7,6 @@ obj-$(CONFIG_KPROBES) += actions-thumb.o checkers-thumb.o test-kprobes-objs += test-thumb.o else obj-$(CONFIG_KPROBES) += actions-arm.o checkers-arm.o +obj-$(CONFIG_OPTPROBES) += opt-arm.o test-kprobes-objs += test-arm.o endif
arch/arm/probes/kprobes/core.c +19 -7
@@ -163,19 +163,31 @@ void __kprobes arch_arm_kprobe(struct kprobe *p)* memory. It is also needed to atomically set the two half-words of a 32-bit * Thumb breakpoint. */ -int __kprobes __arch_disarm_kprobe (void *p) -{ -struct kprobe *kp = p; -void *addr = (void *)((uintptr_t )kp->addr & ~1 ); - -__patch_text (addr, kp->opcode); +struct patch { +void *addr; +unsigned int insn; +}; +static int __kprobes_remove_breakpoint (void *data) +{ +struct patch *p = data; +__patch_text (p->addr, p->insn);return 0 ; } +void __kprobes kprobes_remove_breakpoint (void *addr,unsigned int insn) +{ +struct patch p = { + .addr = addr, + .insn = insn, + }; +stop_machine (__kprobes_remove_breakpoint, &p, cpu_online_mask); +} +void __kprobes arch_disarm_kprobe (struct kprobe *p) { -stop_machine (__arch_disarm_kprobe, p, cpu_online_mask); +kprobes_remove_breakpoint ((void *)((uintptr_t )p->addr & ~1 ), + p->opcode); }void __kprobes arch_remove_kprobe (struct kprobe *p)
arch/arm/probes/kprobes/core.h +2 -0
@@ -30,6 +30,8 @@#define KPROBE_THUMB16_BREAKPOINT_INSTRUCTION 0xde18#define KPROBE_THUMB32_BREAKPOINT_INSTRUCTION 0xf7f0a018 +extern void kprobes_remove_breakpoint (void *addr,unsigned int insn); +enum probes_insn __kprobes kprobe_decode_ldmstm (kprobe_opcode_t insn,struct arch_probes_insn *asi,const struct decode_header *h);
arch/arm/probes/kprobes/opt-arm.c new file +322 -0
322 lines not on this page · raw message
Signature · 1 line
1.8.4
Re: [PATCH v20 08/11] ARM: kprobes: enable OPTPROBES for ARM 32
Quoted 28 lines · Wang Nan
This patch introduce kprobeopt for ARM 32.
Limitations:
- Currently only kernel compiled with ARM ISA is supported.- Offset between probe point and optinsn slot must not larger than 32MiB. Masami Hiramatsu suggests replacing 2 words, it will make things complex. Futher patch can make such optimization.
Kprobe opt on ARM is relatively simpler than kprobe opt on x86 because ARM instruction is always 4 bytes aligned and 4 bytes long. This patch replace probed instruction by a 'b', branch to trampoline code and then calls
optimized_callback().optimized_callback()callsopt_pre_handler()to execute kprobe handler. It also emulate/simulate replaced instruction.When unregistering kprobe, the deferred manner of unoptimizer may leave branch instruction before optimizer is called. Different from
x86_64, which only copy the probed insn afteroptprobe_template_endand reexecute them, this patch call singlestep to emulate/simulate the insn directly. Futher patch can optimize this behavior.Signed-off-by Wang Nan <[email protected]>Acked-by Masami Hiramatsu <[email protected]>Cc Jon Medhurst (Tixy) <[email protected]>Reviewed-by Jon Medhurst (Tixy) <[email protected]>Cc Russell King - ARM Linux <[email protected]>Cc Will Deacon <[email protected]>---
[...]
Quoted 18 lines
arch/arm/probes/kprobes/opt-arm.c new file +18
-0+asm ( +".global optprobe_template_entry\n" +"optprobe_template_entry:\n" +".global optprobe_template_sub_sp\n" +"optprobe_template_sub_sp:" +" sub sp, sp, #0xff\n" +" stmia sp, {r0 - r14} \n" +".global optprobe_template_add_sp\n" +"optprobe_template_add_sp:" +" add r3, sp, #0xff\n" +" str r3, [sp, #52]\n" +" mrs r4, cpsr\n" +" str r4, [sp, #64]\n" +" mov r1, sp\n" +" ldr r0, 1f\n" +" ldr r2, 2f\n" +/* +* AEABI requires an 8-bytes alignment stack. If
arch/arm/probes/kprobes/opt-arm.c line 65
Quoted 10 lines
arch/arm/probes/kprobes/opt-arm.c new file +10
-0+* SP % 8 != 0 (SP % 4 == 0 should be ensured), +* alloc more bytes here. +*/ +" and r4, sp, #4\n" + " sub sp, sp, r4\n" +#if __LINUX_ARM_ARCH__ >=5 +" blx r2\n" +#else +" mov lr, pc\n" +" bx r2\n"
I think the BX instruction is not supported for ARMv4 chips that don't have Thumb support (e.g. SA110), at least an old ARM ARM I have says BX is supported on "Version 5 and above, and T variants of version 4". Though building assabet_defconfig with kprobes enabled doesn't produce an error for the BX instruction (!?)
To be safe I would be tempted to use "mov pc, r2" instead. Again, if you agree, I'll change this in the patch in the branch I'm putting together.
[...]
Signature · 1 line
Tixy
Re: [PATCH v20 08/11] ARM: kprobes: enable OPTPROBES for ARM 32
Quoted 67 lines · Jon Medhurst (Tixy)
Quoted 28 lines · Wang Nan
This patch introduce kprobeopt for ARM 32.
Limitations:
- Currently only kernel compiled with ARM ISA is supported.- Offset between probe point and optinsn slot must not larger than 32MiB. Masami Hiramatsu suggests replacing 2 words, it will make things complex. Futher patch can make such optimization.
Kprobe opt on ARM is relatively simpler than kprobe opt on x86 because ARM instruction is always 4 bytes aligned and 4 bytes long. This patch replace probed instruction by a 'b', branch to trampoline code and then calls
optimized_callback().optimized_callback()callsopt_pre_handler()to execute kprobe handler. It also emulate/simulate replaced instruction.When unregistering kprobe, the deferred manner of unoptimizer may leave branch instruction before optimizer is called. Different from
x86_64, which only copy the probed insn afteroptprobe_template_endand reexecute them, this patch call singlestep to emulate/simulate the insn directly. Futher patch can optimize this behavior.Signed-off-by Wang Nan <[email protected]>Acked-by Masami Hiramatsu <[email protected]>Cc Jon Medhurst (Tixy) <[email protected]>Reviewed-by Jon Medhurst (Tixy) <[email protected]>Cc Russell King - ARM Linux <[email protected]>Cc Will Deacon <[email protected]>---
[...]
Quoted 18 lines
arch/arm/probes/kprobes/opt-arm.c new file +18
-0+asm ( +".global optprobe_template_entry\n" +"optprobe_template_entry:\n" +".global optprobe_template_sub_sp\n" +"optprobe_template_sub_sp:" +" sub sp, sp, #0xff\n" +" stmia sp, {r0 - r14} \n" +".global optprobe_template_add_sp\n" +"optprobe_template_add_sp:" +" add r3, sp, #0xff\n" +" str r3, [sp, #52]\n" +" mrs r4, cpsr\n" +" str r4, [sp, #64]\n" +" mov r1, sp\n" +" ldr r0, 1f\n" +" ldr r2, 2f\n" +/* +* AEABI requires an 8-bytes alignment stack. If arch/arm/probes/kprobes/opt-arm.c line 65
Quoted 10 lines
arch/arm/probes/kprobes/opt-arm.c new file +10
-0+* SP % 8 != 0 (SP % 4 == 0 should be ensured), +* alloc more bytes here. +*/ +" and r4, sp, #4\n" + " sub sp, sp, r4\n" +#if __LINUX_ARM_ARCH__ >=5 +" blx r2\n" +#else +" mov lr, pc\n" +" bx r2\n" I think the BX instruction is not supported for ARMv4 chips that don't have Thumb support (e.g. SA110), at least an old ARM ARM I have says BX is supported on "Version 5 and above, and T variants of version 4". Though building
assabet_defconfigwith kprobes enabled doesn't produce an error for the BX instruction (!?)
Quoted 5 lines
To be safe I would be tempted to use "mov pc, r2" instead. Again, if you agree, I'll change this in the patch in the branch I'm putting together.
[...]
Sure. I tested a function pointer calling and found that gcc generates 'mov pc, r2', and there is no need for ISA switching.
Re: [PATCH v20 08/11] ARM: kprobes: enable OPTPROBES for ARM 32
In reply to Jon Medhurst (Tixy)Quoted 12 lines · Jon Medhurst (Tixy)
arch/arm/probes/kprobes/opt-arm.c line 65
Quoted 7 lines · Wang Nan
arch/arm/probes/kprobes/opt-arm.c new file +7
-0+" and r4, sp, #4\n" + " sub sp, sp, r4\n" +#if __LINUX_ARM_ARCH__ >=5 +" blx r2\n" +#else +" mov lr, pc\n" +" bx r2\n" I think the BX instruction is not supported for ARMv4 chips that don't have Thumb support (e.g. SA110), at least an old ARM ARM I have says BX is supported on "Version 5 and above, and T variants of version 4".
Correct.
Quoted 2 lines
Though building
assabet_defconfigwith kprobes enabled doesn't produce an error for the BX instruction (!?)
Which config are you using? Does it have CONFIG_CPU_32v4 enabled? That should result in "-D__LINUX_ARM_ARCH__=4 -march=armv4" being passed to the compiler (please check with make V=1).
Signature · 2 lines
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up according to speedtest.net.
Re: [PATCH v20 08/11] ARM: kprobes: enable OPTPROBES for ARM 32
Quoted 14 lines · Russell King - ARM Linux
Quoted 12 lines · Jon Medhurst (Tixy)
arch/arm/probes/kprobes/opt-arm.c line 65
Quoted 7 lines · Wang Nan
arch/arm/probes/kprobes/opt-arm.c new file +7
-0+" and r4, sp, #4\n" + " sub sp, sp, r4\n" +#if __LINUX_ARM_ARCH__ >=5 +" blx r2\n" +#else +" mov lr, pc\n" +" bx r2\n" I think the BX instruction is not supported for ARMv4 chips that don't have Thumb support (e.g. SA110), at least an old ARM ARM I have says BX is supported on "Version 5 and above, and T variants of version 4".
Quoted 6 lines
Correct.
Quoted 2 lines
Though building
assabet_defconfigwith kprobes enabled doesn't produce an error for the BX instruction (!?)Which config are you using? Does it have
CONFIG_CPU_32v4enabled?
Yes
Quoted 2 lines
That should result in "-D__LINUX_ARM_ARCH__=4 -march=armv4" being passed to the compiler (please check with make V=1).
I does have that, the arguments for compiling this source file include...
-mno-thumb-interwork -marm -D__LINUX_ARM_ARCH__=4 -march=armv4 -mtune=strongarm1100
Using objdump I can see that the BX instruction does indeed end up in the code, it hasn't been auto-magically turned into a MOV PC,R2.
Adding in a ".code 16" to the assembler produces "Error: selected processor does not support THUMB opcodes", so at least it's got that right.
I have "gcc version 4.9.1 (Ubuntu/Linaro 4.9.1-16ubuntu6)"
Interestingly...
$ echo 'asm ("bx r2\n");' | arm-linux-gnueabihf-gcc -x c -S -march=armv4 -
<stdin>:1:0: warning: target CPU does not support THUMB instructions
$but adding -marm gets rid of that error.
$ echo 'asm ("bx r2\n");' | arm-linux-gnueabihf-gcc -x c -S -marm -march=armv4 -
$Signature · 1 line
Tixy
Re: [PATCH v20 08/11] ARM: kprobes: enable OPTPROBES for ARM 32
Quoted 8 lines · Jon Medhurst (Tixy)
Using objdump I can see that the BX instruction does indeed end up in the code, it hasn't been auto-magically turned into a MOV PC,R2.
Adding in a ".code 16" to the assembler produces "Error: selected processor does not support THUMB opcodes", so at least it's got that right.
I have "gcc version 4.9.1 (Ubuntu/Linaro 4.9.1-16ubuntu6)"
Remember that it's binutils which issues the errors about the assembly.
Quoted 5 lines
Interestingly...
$ echo 'asm ("bx r2\n");' | arm-linux-gnueabihf-gcc -x c -S -march=armv4 - <stdin>:1:0: warning: target CPU does not support THUMB instructions $
Mine doesn't do that.
Quoted 4 lines
but adding -marm gets rid of that error.
$ echo 'asm ("bx r2\n");' | arm-linux-gnueabihf-gcc -x c -S -marm -march=armv4 - $
Yes - but check the -.s file for the output... this won't run the assembler so the assembler won't check that the instruction is legal.
For me:
$ echo 'asm ("bx r2\n");' | arm-linux-gcc -x c -c -marm -march=armv4 -v - -o o.ocalls the assembler thusly:
/usr/local/lib/gcc/arm-linux-gnueabi/4.7.4/../../../../arm-linux-gnueabi/bin/as \
-v -march=armv4 -meabi=5 --fix-v4bx -o o.o /tmp/ccB0cZgO.s
Sure enough, the object file contains:
00000000 <.text>:
0: e12fff12 bx r2
0: R_ARM_V4BX *ABS*
so it looks like it's been told... Then if you do:
$ arm-linux-ld --fix-v4bx -o o1.o o.o $ arm-linux-objdump -dr o1.o
you get:
8074: e1a0f002 mov pc, r2
Hmm, I wonder if this means we should have the kernel linker deal with V4BX relocations on ARMv4, converting them to their mov pc, X variant.
Also, do we need --fix-v4bx for the link of vmlinux?
Signature · 2 lines
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up according to speedtest.net.
Re: [PATCH v20 08/11] ARM: kprobes: enable OPTPROBES for ARM 32
On Fri, 2015-01-09 at 17:57 +0000, Russell King - ARM Linux wrote:
[...]
Quoted 15 lines
For me:
$ echo 'asm ("bx r2\n");' | arm-linux-gcc -x c -c -marm -march=armv4 -v - -o o.ocalls the assembler thusly:
/usr/local/lib/gcc/arm-linux-gnueabi/4.7.4/../../../../arm-linux-gnueabi/bin/as\
-v -march=armv4 -meabi=5 --fix-v4bx -o o.o/tmp/ccB0cZgO.sSure enough, the object file contains:
00000000 <.text>:
0:e12fff12bx r20: R_ARM_V4BX *ABS*
Quoted 8 lines
so it looks like it's been told... Then if you do:
$ arm-linux-ld --fix-v4bx -o o1.o o.o $ arm-linux-objdump -dr o1.oyou get:
8074: e1a0f002 mov pc, r2
I get results consistent with what you get above. A bit of googling seems to indicate the generate-BX-and-fix-it-in-the-linker came in many years ago with AEABI support.
Quoted 4 lines
Hmm, I wonder if this means we should have the kernel linker deal with V4BX relocations on ARMv4, converting them to their mov pc, X variant.
Also, do we need --fix-v4bx for the link of vmlinux?
I guess the answer is yes if we want to catch uses of BX in inline assembly. A quick and not very thorough grep of arch/arm for 'bx' doesn't seem to turn up any existing dodgy uses, except in the kprobes test code I wrote :-(
Signature · 1 line
Tixy
Re: [PATCH v19 08/11] ARM: kprobes: enable OPTPROBES for ARM 32
In reply to Wang NanHi Tixy and other,
Similar to patch 01/11, build robot found a building error in this patch when ARM version is lower than 4. In such processors 'blx' instruction is unusable.
I have posted a new version of this patch, which has following code change:
arch/arm/probes/kprobes/opt-arm.c +5 -0
@@ -58,7 +58,12 @@ asm (*/ " and r4, sp, #4\n" " sub sp, sp, r4\n" +#if __LINUX_ARM_ARCH__ >=5 " blx r2\n" +#else +" mov lr, pc\n" + " bx r2\n" +#endif " add sp, sp, r4\n" " ldr r1, [sp, #64]\n" " tst r1, #"__stringify(PSR_T_BIT)"\n"
http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/314542.html
Tixy, could you please collect it into your repository and test again?
Thank you!
PATCH v19 9/11 ARM: kprobes: Fix unreliable MRS instruction tests
In reply to Wang NanFrom: "Jon Medhurst (Tixy)" <[email protected]>
For the instruction 'mrs Rn, cpsr' the resulting value of Rn can vary due to external factors we can't control. So get the test code to mask out these indeterminate bits.
--- arch/arm/probes/kprobes/test-arm.c | 6 +++--- arch/arm/probes/kprobes/test-core.c | 19 ++++++++++--------- arch/arm/probes/kprobes/test-core.h | 33 ++++++++++++++++++++++++++++----- arch/arm/probes/kprobes/test-thumb.c | 4 ++-- 4 files changed, 43 insertions(+), 19 deletions(-)
arch/arm/probes/kprobes/test-arm.c +3 -3
@@ -204,9 +204,9 @@ void kprobe_arm_test_cases(void)#endif TEST_GROUP("Miscellaneous instructions") - TEST("mrs r0, cpsr") - TEST("mrspl r7, cpsr") - TEST("mrs r14, cpsr") + TEST_RMASKED("mrs r",0,~PSR_IGNORE_BITS,", cpsr") + TEST_RMASKED("mrspl r",7,~PSR_IGNORE_BITS,", cpsr") + TEST_RMASKED("mrs r",14,~PSR_IGNORE_BITS,", cpsr") TEST_UNSUPPORTED(__inst_arm(0xe10ff000) " @ mrs r15, cpsr") TEST_UNSUPPORTED("mrs r0, spsr")TEST_UNSUPPORTED ("mrs lr, spsr" )
arch/arm/probes/kprobes/test-core.c +10 -9
@@ -1056,15 +1056,6 @@ static int test_case_run_count;static bool test_case_is_thumb;static int test_instance; -/* -* We ignore the state of the imprecise abort disable flag (CPSR.A) because this -* can change randomly as the kernel doesn't take care to preserve or initialise -* this across context switches. Also, with Security Extentions, the flag may -* not be under control of the kernel; for this reason we ignore the state of -* the FIQ disable flag CPSR.F as well. -*/ -#define PSR_IGNORE_BITS (PSR_A_BIT | PSR_F_BIT) -static unsigned long test_check_cc (int cc,unsigned long cpsr) {int ret =arm_check_condition (cc <<28 , cpsr);
@@ -1271,11 +1262,21 @@ test_case_pre_handler(struct kprobe *p, struct pt_regs *regs)static int __kprobes test_after_pre_handler (struct kprobe *p,struct pt_regs *regs) { +struct test_arg *args; + if (container_of(p, struct test_probe, kprobe)->hit == test_instance)return 0 ;/* Already run for this test instance */ result_regs = *regs; + +/* Mask out results which are indeterminate */ result_regs.ARM_cpsr &= ~PSR_IGNORE_BITS ; +for (args = current_args; args[0 ].type !=ARG_TYPE_END ; ++args) +if (args[0 ].type ==ARG_TYPE_REG_MASKED ) { +struct test_arg_regptr *arg = + (struct test_arg_regptr *)args; + result_regs.uregs[arg->reg] &= arg->val; + }/* Undo any changes done to SP by the test case */ regs->ARM_sp = (unsigned long )current_stack;
arch/arm/probes/kprobes/test-core.h +28 -5
@@ -45,10 +45,11 @@ extern int kprobe_test_cc_position;* */ -#define ARG_TYPE_END 0 -#define ARG_TYPE_REG 1 -#define ARG_TYPE_PTR 2 -#define ARG_TYPE_MEM 3 +#define ARG_TYPE_END 0 +#define ARG_TYPE_REG 1 +#define ARG_TYPE_PTR 2 +#define ARG_TYPE_MEM 3 +#define ARG_TYPE_REG_MASKED 4#define ARG_FLAG_UNSUPPORTED 0x01#define ARG_FLAG_SUPPORTED 0x02
@@ -61,7 +62,7 @@ struct test_arg { };struct test_arg_regptr { -u8 type;/* ARG_TYPE_REG or ARG_TYPE_PTR */ +u8 type;/* ARG_TYPE_REG or ARG_TYPE_PTR or ARG_TYPE_REG_MASKED */ u8 reg;u8 _padding[2 ];u32 val;
@@ -138,6 +139,12 @@ struct test_arg_end {".short 0 \n\t" \ ".word "#val" \n\t" +#define TEST_ARG_REG_MASKED (reg, val) \ + ".byte "__stringify(ARG_TYPE_REG_MASKED)" \n\t" \ + ".byte "#reg" \n\t" \ + ".short 0 \n\t" \ + ".word "#val" \n\t" +#define TEST_ARG_END (flags) \ ".byte "__stringify(ARG_TYPE_END)" \n\t" \ ".byte "TEST_ISA flags" \n\t" \
@@ -395,6 +402,22 @@ struct test_arg_end {" " codex" \n\t" \ TESTCASE_END +#define TEST_RMASKED (code1, reg, mask, code2) \ + TESTCASE_START(code1 #reg code2) \ + TEST_ARG_REG_MASKED(reg, mask) \ + TEST_ARG_END("") \ + TEST_INSTRUCTION(code1 #reg code2) \ + TESTCASE_END + +/* +* We ignore the state of the imprecise abort disable flag (CPSR.A) because this +* can change randomly as the kernel doesn't take care to preserve or initialise +* this across context switches. Also, with Security Extensions, the flag may +* not be under control of the kernel; for this reason we ignore the state of +* the FIQ disable flag CPSR.F as well. +*/ +#define PSR_IGNORE_BITS (PSR_A_BIT | PSR_F_BIT) +/* * Macros for defining space directives spread over multiple lines.
arch/arm/probes/kprobes/test-thumb.c +2 -2
@@ -778,8 +778,8 @@ CONDITION_INSTRUCTIONS(22, TEST_UNSUPPORTED("subs pc, lr, #4") - TEST("mrs r0, cpsr") - TEST("mrs r14, cpsr") + TEST_RMASKED("mrs r",0,~PSR_IGNORE_BITS,", cpsr") + TEST_RMASKED("mrs r",14,~PSR_IGNORE_BITS,", cpsr") TEST_UNSUPPORTED(__inst_thumb32(0xf3ef8d00) " @ mrs sp, spsr") TEST_UNSUPPORTED(__inst_thumb32(0xf3ef8f00) " @ mrs pc, spsr")TEST_UNSUPPORTED ("mrs r0, spsr" )
Signature · 1 line
1.8.4
PATCH v19 10/11 ARM: kprobes: check register usage for probed instruction.
In reply to Wang NanThis patch utilizes previous introduced checker to check register usage for probed ARM instruction and saves it in a mask. Futher patch will use such information to avoid simuation or emulation.
--- arch/arm/include/asm/probes.h | 10 +++ arch/arm/probes/decode.c | 7 ++ arch/arm/probes/kprobes/actions-arm.c | 2 +- arch/arm/probes/kprobes/checkers-arm.c | 124 +++++++++++++++++++++++++++++++++ arch/arm/probes/kprobes/checkers.h | 1 + 5 files changed, 143 insertions(+), 1 deletion(-)
arch/arm/include/asm/probes.h +10 -0
@@ -41,6 +41,16 @@ struct arch_probes_insn {probes_insn_singlestep_t *insn_singlestep;probes_insn_fn_t *insn_fn;int stack_space; + +/* Use 1 bit for a register. */ +#define REG_NO_USE (0) +#define REG_USE (1) +#define __register_usage_flag (n, f) ((f) << (n)) +#define __clean_register_flag (m, n) ((m) & (~(1 << (n)))) +#define __set_register_flag (m, n, f) (__clean_register_flag(m, n) | __register_usage_flag(n, f)) +#define set_register_nouse (m, n) do {(m) = __set_register_flag(m, n, REG_NO_USE);} while(0) +#define set_register_use (m, n) do {(m) = __set_register_flag(m, n, REG_USE);} while(0) + unsigned long register_usage_flag; };#endif /* __ASSEMBLY__ */
arch/arm/probes/decode.c +7 -0
@@ -435,6 +435,13 @@ probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,*/ asi->stack_space =0 ; +/* +* Similay to stack_space, register_usage_flag is filled by +* checkers. Its default value is set to ~0, which is 'all +* registers are used', to prevent any potential optimization. +*/ + asi->register_usage_flag = ~(0UL ); +if (emulate) insn =prepare_emulated_insn (insn, asi, thumb);
arch/arm/probes/kprobes/actions-arm.c +1 -1
@@ -340,4 +340,4 @@ const union decode_action kprobes_arm_actions[NUM_PROBES_ARM_ACTIONS] = { [PROBES_LDMSTM] = {.decoder = kprobe_decode_ldmstm} }; -const struct decode_checker *kprobes_arm_checkers[] = {arm_stack_checker,NULL }; +const struct decode_checker *kprobes_arm_checkers[] = {arm_stack_checker, arm_regs_checker,NULL };
arch/arm/probes/kprobes/checkers-arm.c +124 -0
127 lines not on this page · raw message
arch/arm/probes/kprobes/checkers.h +1 -0
@@ -47,6 +47,7 @@ extern const union decode_action stack_check_actions[];#ifndef CONFIG_THUMB2_KERNEL extern const struct decode_checker arm_stack_checker[]; +extern const struct decode_checker arm_regs_checker[];#else #endif extern const struct decode_checker t32_stack_checker[];
Signature · 1 line
1.8.4
Re: [PATCH v19 10/11] ARM: kprobes: check register usage for probed instruction.
Quoted 3 lines · Wang Nan
This patch utilizes previous introduced checker to check register usage for probed ARM instruction and saves it in a mask. Futher patch will use such information to avoid simuation or emulation.
There's a couple of spelling mistakes above and minor grammar nitpicks, my suggestion to improve those would be to add the bits in [] in the following...
This patch utilizes [the] previous[ly] introduced checker to check register usage for probed ARM instruction and saves it in a mask. [A] fu[r]ther patch will use such information to avoid simu[l]ation or emulation.
My comments on the code below are mostly suggestions on how to simplify things, though the code is already quite re is one bug.
Quoted 14 lines
Signed-off-by Wang Nan <[email protected]>--- arch/arm/include/asm/probes.h | 10 +++ arch/arm/probes/decode.c | 7 ++ arch/arm/probes/kprobes/actions-arm.c | 2 +- arch/arm/probes/kprobes/checkers-arm.c | 124 +++++++++++++++++++++++++++++++++ arch/arm/probes/kprobes/checkers.h | 1 + 5 files changed, 143 insertions(+), 1 deletion(-)arch/arm/include/asm/probes.h +0
-0
arch/arm/include/asm/probes.h struct arch_probes_insn { · line 47
Quoted 7 lines
arch/arm/include/asm/probes.h +4
-0@@ -41,6 +41,16 @@ struct arch_probes_insn {probes_insn_singlestep_t *insn_singlestep;probes_insn_fn_t *insn_fn;int stack_space; + +/* Use 1 bit for a register. */ +#define REG_NO_USE (0) +#define REG_USE (1)
No need for () around the 0 and 1
arch/arm/include/asm/probes.h struct arch_probes_insn { · line 52
Quoted 5 lines
arch/arm/include/asm/probes.h +5
-0+#define __register_usage_flag (n, f) ((f) << (n)) +#define __clean_register_flag (m, n) ((m) & (~(1 << (n)))) +#define __set_register_flag (m, n, f) (__clean_register_flag(m, n) | __register_usage_flag(n, f)) +#define set_register_nouse (m, n) do {(m) = __set_register_flag(m, n, REG_NO_USE);} while(0) +#define set_register_use (m, n) do {(m) = __set_register_flag(m, n, REG_USE);} while(0)
All these macros seem a bit convoluted to me, and I don't think it makes things any clearer than open coding a bit set operation like
|= 1 << reg
especially as I don't thing those macros will end up getting much use.
arch/arm/include/asm/probes.h struct arch_probes_insn { · line 53
Quoted 1 line
arch/arm/include/asm/probes.h +1
-0+unsigned long register_usage_flag;
To nit-pick, as this isn't a single flag I would add an 's' to make the name plural, i.e. 'register_usage_flags'
arch/arm/probes/decode.c probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi, · line 439
Quoted 13 lines
arch/arm/include/asm/probes.h +0
-0};#endif /* __ASSEMBLY__ */ arch/arm/probes/decode.c +2
-0@@ -435,6 +435,13 @@ probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,*/ asi->stack_space =0 ; +/* +* Similay to stack_space, register_usage_flag is filled by
Typo, s/Similay/Similarly/
arch/arm/probes/decode.c probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi, · line 443
Quoted 4 lines
arch/arm/probes/decode.c +4
-0+* checkers. Its default value is set to ~0, which is 'all +* registers are used', to prevent any potential optimization. +*/ + asi->register_usage_flag = ~(0UL );
No need for () around 0UL
Quoted 30 lines
arch/arm/probes/decode.c +1
-0+if (emulate) insn =prepare_emulated_insn (insn, asi, thumb);arch/arm/probes/kprobes/actions-arm.c +1
-1@@ -340,4 +340,4 @@ const union decode_action kprobes_arm_actions[NUM_PROBES_ARM_ACTIONS] = { [PROBES_LDMSTM] = {.decoder = kprobe_decode_ldmstm} }; -const struct decode_checker *kprobes_arm_checkers[] = {arm_stack_checker,NULL }; +const struct decode_checker *kprobes_arm_checkers[] = {arm_stack_checker, arm_regs_checker,NULL };arch/arm/probes/kprobes/checkers-arm.c +8
-0@@ -97,3 +97,127 @@ const struct decode_checker arm_stack_checker[NUM_PROBES_ARM_ACTIONS] = { [PROBES_STORE] = {.checker = arm_check_stack}, [PROBES_LDMSTM] = {.checker = arm_check_stack}, }; + +static enum probes_insn __kprobes arm_check_regs_nouse (probes_opcode_t insn, +struct arch_probes_insn *asi, +const struct decode_header *h) +{ + asi->register_usage_flag =0 ; +return INSN_GOOD ; +}
arch/arm/probes/kprobes/checkers-arm.c const struct decode_checker arm_stack_checker[NUM_PROBES_ARM_ACTIONS] = { · line 117
Quoted 10 lines
arch/arm/probes/kprobes/checkers-arm.c +10
-0+ +static void __arm_check_regs (probes_opcode_t insn, +const struct decode_header *h, +int *quintuple) +{ +int i; +u32 regs = h->type_regs.bits >>DECODE_TYPE_BITS ; +probes_opcode_t mask, shifted; + +memset (quintuple,0xff ,sizeof (int ) *5 );
Not sure that filling with 0xff is a C standard compliant way of initialising int's to a negative value. Anyway, memset isn't really needed, see next comment.
arch/arm/probes/kprobes/checkers-arm.c const struct decode_checker arm_stack_checker[NUM_PROBES_ARM_ACTIONS] = { · line 121
Quoted 4 lines
arch/arm/probes/kprobes/checkers-arm.c +4
-0+for (i =0 , shifted = insn, mask =0xf ; regs !=0 ; + regs >>=4 , mask <<=4 , shifted >>=4 , i++) +if (regs &0xf ) + quintuple[i] = shifted &0xf ;
Looks a bit complicated, the last 6 lines could be more simply expressed as:
for (i = 0; i < 5; regs >>= 4, insn >>= 4, i++) quintuple[i] = regs & 0xf ? insn & 0xf : -1;
Though I think that this function may be a bit overkill anyway, it is only really needed in one place, so may as well be inlined there, that is the function below...
Quoted 6 lines
arch/arm/probes/kprobes/checkers-arm.c +6
-0+} + +static enum probes_insn arm_check_regs_normal (probes_opcode_t insn, +struct arch_probes_insn *asi, +const struct decode_header *h) +{
arch/arm/probes/kprobes/checkers-arm.c const struct decode_checker arm_stack_checker[NUM_PROBES_ARM_ACTIONS] = { · line 137
Quoted 10 lines
arch/arm/probes/kprobes/checkers-arm.c +10
-0+int quintuple[5 ], i; + asi->register_usage_flag =0 ; +__arm_check_regs (insn, h, quintuple); +for (i =0 ; i <5 ; i++) { +int r = quintuple[i]; +if (r <0 ) +continue ; +set_register_use (asi->register_usage_flag, r); + } +
The above can be as simply written without using _arm_check_regs like...
u32 regs = h->type_regs.bits >> DECODE_TYPE_BITS; int i; asi->register_usage_flag = 0; for (i = 0; i < 5; regs >>= 4, insn >>= 4, i++) if (regs & 0xf) asi->register_usage_flag |= 1 << (insn & 0xf);
arch/arm/probes/kprobes/checkers-arm.c const struct decode_checker arm_stack_checker[NUM_PROBES_ARM_ACTIONS] = { · line 148
Quoted 11 lines
arch/arm/probes/kprobes/checkers-arm.c +11
-0+return INSN_GOOD ; +} + +static enum probes_insn arm_check_regs_ldmstm (probes_opcode_t insn, +struct arch_probes_insn *asi, +const struct decode_header *h) +{ +unsigned int reglist = insn &0xffff ; +unsigned int rn = (insn >>16 ) &0xf ; +int i; +
Think you forgot to clear asi->register_usage_flag here, it will still contain 0xffffffff set by from probes_decode_insn(). However, we don't need this if we follow my next suggestion.
arch/arm/probes/kprobes/checkers-arm.c const struct decode_checker arm_stack_checker[NUM_PROBES_ARM_ACTIONS] = { · line 152
Quoted 4 lines
arch/arm/probes/kprobes/checkers-arm.c +4
-0+set_register_use (asi->register_usage_flag, rn); +for (i =0 ; reglist >0 ; i++, reglist >>=1 ) +if (reglist &1 ) +set_register_use (asi->register_usage_flag, i);
The preceding 5 lines are equivalent to
asi->register_usage_flag = reglist | (1 << rn);
so how about we just use that?
arch/arm/probes/kprobes/checkers-arm.c const struct decode_checker arm_stack_checker[NUM_PROBES_ARM_ACTIONS] = { · line 162
Quoted 10 lines
arch/arm/probes/kprobes/checkers-arm.c +10
-0+return INSN_GOOD ; +} + +static enum probes_insn arm_check_regs_mov_ip_sp (probes_opcode_t insn, +struct arch_probes_insn *asi, +const struct decode_header *h) +{ +/* should be 'mov ip, sp' */ +set_register_use (asi->register_usage_flag,12 ); +set_register_use (asi->register_usage_flag,13 );
register_usage_flag needs setting to zero before setting the flags. Or we could just write this function as
/* Instruction is 'mov ip, sp' i.e. 'mov r12, r13' */ asi->register_usage_flag = (1 << 12) | (1<< 13);
Quoted 21 lines
arch/arm/probes/kprobes/checkers-arm.c +21
-0+return INSN_GOOD ; +} + +/* +* | Rn |Rt/d| | Rm | +* LDRD (register) cccc 000x x0x0 xxxx xxxx xxxx 1101 xxxx +* STRD (register) cccc 000x x0x0 xxxx xxxx xxxx 1111 xxxx +* | Rn |Rt/d| |imm4L| +* LDRD (immediate) cccc 000x x1x0 xxxx xxxx xxxx 1101 xxxx +* STRD (immediate) cccc 000x x1x0 xxxx xxxx xxxx 1111 xxxx +* +* Such instructions access Rt/d and its next register, so different +* from others, a specific checker is required for Rt/d and Rt2/d2. +*/ +static enum probes_insn arm_check_regs_ldrdstrd (probes_opcode_t insn, +struct arch_probes_insn *asi, +const struct decode_header *h) +{ +int quintuple[5 ], rn, rdt, rm; + asi->register_usage_flag =0 ; +__arm_check_regs (insn, h, quintuple);
arch/arm/probes/kprobes/checkers-arm.c const struct decode_checker arm_stack_checker[NUM_PROBES_ARM_ACTIONS] = { · line 193
Quoted 10 lines
arch/arm/probes/kprobes/checkers-arm.c +10
-0+ + rn = quintuple[4 ]; + rdt = quintuple[3 ]; + rm = quintuple[0 ]; +set_register_use (asi->register_usage_flag, rn); +set_register_use (asi->register_usage_flag, rdt); +set_register_use (asi->register_usage_flag, rdt +1 ); +if (rm >=0 ) +set_register_use (asi->register_usage_flag, rm); +
We can avoid most of this code if we reuse arm_check_regs_normal and then add in the use of rdt+1, i.e. this function can be simply...
int rdt = (insn >> 12) & 0xf; arm_check_regs_normal(insn, asi, h); asi->register_usage_flag |= 1 << (rdt + 1);
Quoted 35 lines
arch/arm/probes/kprobes/checkers-arm.c +30
-0+return INSN_GOOD ; +} + + +const struct decode_checker arm_regs_checker[NUM_PROBES_ARM_ACTIONS ] = { + [PROBES_EMULATE_NONE ] = {.checker = arm_check_regs_nouse}, + [PROBES_SIMULATE_NOP ] = {.checker = arm_check_regs_nouse}, + [PROBES_MRS ] = {.checker = arm_check_regs_normal}, + [PROBES_SATURATING_ARITHMETIC ] = {.checker = arm_check_regs_normal}, + [PROBES_MUL1 ] = {.checker = arm_check_regs_normal}, + [PROBES_MUL2 ] = {.checker = arm_check_regs_normal}, + [PROBES_MUL_ADD_LONG ] = {.checker = arm_check_regs_normal}, + [PROBES_MUL_ADD ] = {.checker = arm_check_regs_normal}, + [PROBES_LOAD ] = {.checker = arm_check_regs_normal}, + [PROBES_LOAD_EXTRA ] = {.checker = arm_check_regs_normal}, + [PROBES_STORE ] = {.checker = arm_check_regs_normal}, + [PROBES_STORE_EXTRA ] = {.checker = arm_check_regs_normal}, + [PROBES_DATA_PROCESSING_REG ] = {.checker = arm_check_regs_normal}, + [PROBES_DATA_PROCESSING_IMM ] = {.checker = arm_check_regs_normal}, + [PROBES_SATURATE ] = {.checker = arm_check_regs_normal}, + [PROBES_REV ] = {.checker = arm_check_regs_normal}, + [PROBES_MMI ] = {.checker = arm_check_regs_normal}, + [PROBES_PACK ] = {.checker = arm_check_regs_normal}, + [PROBES_EXTEND ] = {.checker = arm_check_regs_normal}, + [PROBES_EXTEND_ADD ] = {.checker = arm_check_regs_normal}, + [PROBES_BITFIELD ] = {.checker = arm_check_regs_normal}, + [PROBES_LDMSTM ] = {.checker = arm_check_regs_ldmstm}, + [PROBES_MOV_IP_SP ] = {.checker = arm_check_regs_mov_ip_sp}, + [PROBES_LDRSTRD ] = {.checker = arm_check_regs_ldrdstrd}, +};arch/arm/probes/kprobes/checkers.h +0
-0
arch/arm/probes/kprobes/checkers.h extern const union decode_action stack_check_actions[]; · line 53
Quoted 7 lines
arch/arm/probes/kprobes/checkers.h +1
-0@@ -47,6 +47,7 @@ extern const union decode_action stack_check_actions[];#ifndef CONFIG_THUMB2_KERNEL extern const struct decode_checker arm_stack_checker[]; +extern const struct decode_checker arm_regs_checker[];#else #endif extern const struct decode_checker t32_stack_checker[];
I've made a lot, of suggestions for code changes, so I think it's best if I follow up to this email with a new version of this patch which applies them all so we can see what the bigger picture is...
Signature · 1 line
Tixy
PATCH 1/1 ARM: kprobes: check register usage for probed instruction
This patch utilizes the previously introduced checker to check register usage for probed ARM instruction and saves it in a mask. A further patch will use such information to avoid simulation or emulation.
---
This patch applies my review comments on "[PATCH v19 10/11] ARM:
kprobes: check register usage for probed instruction."
It is also rebased on top of the kprobes-opt branch atgit://git.linaro.org/people/tixy/kernel.git
arch/arm/include/asm/probes.h | 1 + arch/arm/probes/decode.c | 7 +++ arch/arm/probes/kprobes/actions-arm.c | 2 +- arch/arm/probes/kprobes/checkers-arm.c | 93 ++++++++++++++++++++++++++++++++++ arch/arm/probes/kprobes/checkers.h | 1 + 5 files changed, 103 insertions(+), 1 deletion(-)
arch/arm/include/asm/probes.h +1 -0
@@ -41,6 +41,7 @@ struct arch_probes_insn {probes_insn_singlestep_t *insn_singlestep;probes_insn_fn_t *insn_fn;int stack_space; + unsigned long register_usage_flags; };#endif /* __ASSEMBLY__ */
arch/arm/probes/decode.c +7 -0
@@ -435,6 +435,13 @@ probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,*/ asi->stack_space =0 ; +/* +* Similarly to stack_space, register_usage_flags is filled by +* checkers. Its default value is set to ~0, which is 'all +* registers are used', to prevent any potential optimization. +*/ + asi->register_usage_flags = ~0UL ; +if (emulate) insn =prepare_emulated_insn (insn, asi, thumb);
arch/arm/probes/kprobes/actions-arm.c +1 -1
@@ -341,4 +341,4 @@ const union decode_action kprobes_arm_actions[NUM_PROBES_ARM_ACTIONS] = { [PROBES_LDMSTM] = {.decoder = kprobe_decode_ldmstm} }; -const struct decode_checker *kprobes_arm_checkers[] = {arm_stack_checker,NULL }; +const struct decode_checker *kprobes_arm_checkers[] = {arm_stack_checker, arm_regs_checker,NULL };
arch/arm/probes/kprobes/checkers-arm.c +93 -0
96 lines not on this page · raw message
arch/arm/probes/kprobes/checkers.h +1 -0
@@ -47,6 +47,7 @@ extern const union decode_action stack_check_actions[];#ifndef CONFIG_THUMB2_KERNEL extern const struct decode_checker arm_stack_checker[]; +extern const struct decode_checker arm_regs_checker[];#else #endif extern const struct decode_checker t32_stack_checker[];
Signature · 1 line
2.1.4
Re: [PATCH] ARM: kprobes: check register usage for probed instruction
I think this patch is better than mo original one.
Thanks to Tixy.
Quoted 177 lines · Jon Medhurst (Tixy)
This patch utilizes the previously introduced checker to check register usage for probed ARM instruction and saves it in a mask. A further patch will use such information to avoid simulation or emulation.
Signed-off-by Wang Nan <[email protected]>Reviewed-by Jon Medhurst <[email protected]>Signed-off-by Jon Medhurst <[email protected]>---
This patch applies my review comments on "[PATCH v19 10/11] ARM:
kprobes: check register usage for probed instruction."It is also rebased on top of the kprobes-opt branch at
git://git.linaro.org/people/tixy/kernel.gitarch/arm/include/asm/probes.h | 1 + arch/arm/probes/decode.c | 7 +++ arch/arm/probes/kprobes/actions-arm.c | 2 +- arch/arm/probes/kprobes/checkers-arm.c | 93 ++++++++++++++++++++++++++++++++++ arch/arm/probes/kprobes/checkers.h | 1 + 5 files changed, 103 insertions(+), 1 deletion(-)arch/arm/include/asm/probes.h +1
-0@@ -41,6 +41,7 @@ struct arch_probes_insn {probes_insn_singlestep_t *insn_singlestep;probes_insn_fn_t *insn_fn;int stack_space; + unsigned long register_usage_flags; };#endif /* __ASSEMBLY__ */ arch/arm/probes/decode.c +7
-0@@ -435,6 +435,13 @@ probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,*/ asi->stack_space =0 ; +/* +* Similarly to stack_space, register_usage_flags is filled by +* checkers. Its default value is set to ~0, which is 'all +* registers are used', to prevent any potential optimization. +*/ + asi->register_usage_flags = ~0UL ; +if (emulate) insn =prepare_emulated_insn (insn, asi, thumb);arch/arm/probes/kprobes/actions-arm.c +1
-1@@ -341,4 +341,4 @@ const union decode_action kprobes_arm_actions[NUM_PROBES_ARM_ACTIONS] = { [PROBES_LDMSTM] = {.decoder = kprobe_decode_ldmstm} }; -const struct decode_checker *kprobes_arm_checkers[] = {arm_stack_checker,NULL }; +const struct decode_checker *kprobes_arm_checkers[] = {arm_stack_checker, arm_regs_checker,NULL };arch/arm/probes/kprobes/checkers-arm.c +93
-0@@ -97,3 +97,96 @@ const struct decode_checker arm_stack_checker[NUM_PROBES_ARM_ACTIONS] = { [PROBES_STORE] = {.checker = arm_check_stack}, [PROBES_LDMSTM] = {.checker = arm_check_stack}, }; + +static enum probes_insn __kprobes arm_check_regs_nouse (probes_opcode_t insn, +struct arch_probes_insn *asi, +const struct decode_header *h) +{ + asi->register_usage_flags =0 ; +return INSN_GOOD ; +} + +static enum probes_insn arm_check_regs_normal (probes_opcode_t insn, +struct arch_probes_insn *asi, +const struct decode_header *h) +{ +u32 regs = h->type_regs.bits >>DECODE_TYPE_BITS ; +int i; + + asi->register_usage_flags =0 ; +for (i =0 ; i <5 ; regs >>=4 , insn >>=4 , i++) +if (regs &0xf ) + asi->register_usage_flags |=1 << (insn &0xf ); + +return INSN_GOOD ; +} + + +static enum probes_insn arm_check_regs_ldmstm (probes_opcode_t insn, +struct arch_probes_insn *asi, +const struct decode_header *h) +{ +unsigned int reglist = insn &0xffff ; +unsigned int rn = (insn >>16 ) &0xf ; + asi->register_usage_flags = reglist | (1 << rn); +return INSN_GOOD ; +} + +static enum probes_insn arm_check_regs_mov_ip_sp (probes_opcode_t insn, +struct arch_probes_insn *asi, +const struct decode_header *h) +{ +/* Instruction is 'mov ip, sp' i.e. 'mov r12, r13' */ + asi->register_usage_flags = (1 <<12 ) | (1 <<13 ); +return INSN_GOOD ; +} + +/* +* | Rn |Rt/d| | Rm | +* LDRD (register) cccc 000x x0x0 xxxx xxxx xxxx 1101 xxxx +* STRD (register) cccc 000x x0x0 xxxx xxxx xxxx 1111 xxxx +* | Rn |Rt/d| |imm4L| +* LDRD (immediate) cccc 000x x1x0 xxxx xxxx xxxx 1101 xxxx +* STRD (immediate) cccc 000x x1x0 xxxx xxxx xxxx 1111 xxxx +* +* Such instructions access Rt/d and its next register, so different +* from others, a specific checker is required to handle this extra +* implicit register usage. +*/ +static enum probes_insn arm_check_regs_ldrdstrd (probes_opcode_t insn, +struct arch_probes_insn *asi, +const struct decode_header *h) +{ +int rdt = (insn >>12 ) &0xf ; +arm_check_regs_normal (insn, asi, h); + asi->register_usage_flags |=1 << (rdt +1 ); +return INSN_GOOD ; +} + + +const struct decode_checker arm_regs_checker[NUM_PROBES_ARM_ACTIONS ] = { + [PROBES_MRS ] = {.checker = arm_check_regs_normal}, + [PROBES_SATURATING_ARITHMETIC ] = {.checker = arm_check_regs_normal}, + [PROBES_MUL1 ] = {.checker = arm_check_regs_normal}, + [PROBES_MUL2 ] = {.checker = arm_check_regs_normal}, + [PROBES_MUL_ADD_LONG ] = {.checker = arm_check_regs_normal}, + [PROBES_MUL_ADD ] = {.checker = arm_check_regs_normal}, + [PROBES_LOAD ] = {.checker = arm_check_regs_normal}, + [PROBES_LOAD_EXTRA ] = {.checker = arm_check_regs_normal}, + [PROBES_STORE ] = {.checker = arm_check_regs_normal}, + [PROBES_STORE_EXTRA ] = {.checker = arm_check_regs_normal}, + [PROBES_DATA_PROCESSING_REG ] = {.checker = arm_check_regs_normal}, + [PROBES_DATA_PROCESSING_IMM ] = {.checker = arm_check_regs_normal}, + [PROBES_SEV ] = {.checker = arm_check_regs_nouse}, + [PROBES_WFE ] = {.checker = arm_check_regs_nouse}, + [PROBES_SATURATE ] = {.checker = arm_check_regs_normal}, + [PROBES_REV ] = {.checker = arm_check_regs_normal}, + [PROBES_MMI ] = {.checker = arm_check_regs_normal}, + [PROBES_PACK ] = {.checker = arm_check_regs_normal}, + [PROBES_EXTEND ] = {.checker = arm_check_regs_normal}, + [PROBES_EXTEND_ADD ] = {.checker = arm_check_regs_normal}, + [PROBES_BITFIELD ] = {.checker = arm_check_regs_normal}, + [PROBES_LDMSTM ] = {.checker = arm_check_regs_ldmstm}, + [PROBES_MOV_IP_SP ] = {.checker = arm_check_regs_mov_ip_sp}, + [PROBES_LDRSTRD ] = {.checker = arm_check_regs_ldrdstrd}, +};arch/arm/probes/kprobes/checkers.h +1
-0@@ -47,6 +47,7 @@ extern const union decode_action stack_check_actions[];#ifndef CONFIG_THUMB2_KERNEL extern const struct decode_checker arm_stack_checker[]; +extern const struct decode_checker arm_regs_checker[];#else #endif extern const struct decode_checker t32_stack_checker[];
PATCH v19 11/11 ARM: optprobes: execute instruction during restoring if possible.
In reply to Wang NanThis patch removes software emulation or simulation for most of probed instructions. If the instruction doesn't use PC relative addressing, it will be translated into following instructions in the restore code in code template:
ldmia {r0 - r14} // restore all instruction except PC
<instruction> // direct execute the probed instruction
b next_insn // branch to next instruction.--- arch/arm/include/asm/kprobes.h | 3 +++ arch/arm/include/asm/probes.h | 1 + arch/arm/probes/kprobes/opt-arm.c | 52 +++++++++++++++++++++++++++++++++++++-- 3 files changed, 54 insertions(+), 2 deletions(-)
arch/arm/include/asm/kprobes.h +3 -0
@@ -57,6 +57,9 @@ extern __visible kprobe_opcode_t optprobe_template_call; extern __visible kprobe_opcode_t optprobe_template_end; extern __visible kprobe_opcode_t optprobe_template_sub_sp; extern __visible kprobe_opcode_t optprobe_template_add_sp; +extern __visible kprobe_opcode_t optprobe_template_restore_begin; +extern __visible kprobe_opcode_t optprobe_template_restore_orig_insn; +extern __visible kprobe_opcode_t optprobe_template_restore_end;#define MAX_OPTIMIZED_LENGTH 4#define MAX_OPTINSN_SIZE \
arch/arm/include/asm/probes.h +1 -0
@@ -51,6 +51,7 @@ struct arch_probes_insn {#define set_register_nouse (m, n) do {(m) = __set_register_flag(m, n, REG_NO_USE);} while(0)#define set_register_use (m, n) do {(m) = __set_register_flag(m, n, REG_USE);} while(0)unsigned long register_usage_flag; + bool kprobe_direct_exec; };#endif /* __ASSEMBLY__ */
arch/arm/probes/kprobes/opt-arm.c +50 -2
83 lines not on this page · raw message
Signature · 1 line
1.8.4
I think that the patches up to 09/11 inclusive have been though more that enough review and revisions to think about getting them merged, there doesn't seem much point in continuously resending them whilst new features are built on top of them.
Masami Hiramatsu, are you happy for your patch to generic+X86 kprobes code [1] to go through the ARM maintainers tree, assuming Russell is also happy with that. Or should that go via a different route?
[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/313218.html
Wang Nan, assuming everyone is happy, can you put together a branch in a git repository for those patches, or I'm more than happy to do that if you like. Then I can give the series a final test and we can send a pull request to Russell King.
Thanks all
Signature · 1 line
Tixy
Quoted 8 lines · Jon Medhurst (Tixy)
I think that the patches up to 09/11 inclusive have been though more that enough review and revisions to think about getting them merged, there doesn't seem much point in continuously resending them whilst new features are built on top of them.
Masami Hiramatsu, are you happy for your patch to generic+X86 kprobes code [1] to go through the ARM maintainers tree, assuming Russell is also happy with that. Or should that go via a different route?
Yes, I'm OK to go it through the ARM maintainers tree :)
Thank you,
Quoted 10 lines
[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/313218.html
Wang Nan, assuming everyone is happy, can you put together a branch in a git repository for those patches, or I'm more than happy to do that if you like. Then I can give the series a final test and we can send a pull request to Russell King.
Thanks all
Signature · 4 lines
Masami HIRAMATSU Software Platform Research Dept. Linux Technology Research Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: masami.hiramatsu.pt at hitachi.com