diff options
author | Leo Yan <leo.yan@linaro.org> | 2019-08-06 06:00:14 -0400 |
---|---|---|
committer | Will Deacon <will@kernel.org> | 2019-08-07 08:53:09 -0400 |
commit | 42d038c4fb00f1ec1a4c4616784da4561385b628 (patch) | |
tree | c8c5335e01986c073ae56ca1df94eeed5c13fe1e | |
parent | 45880f7b7b19e043ce0aaa4cb7d05369425c82fa (diff) |
arm64: Add support for function error injection
Inspired by the commit 7cd01b08d35f ("powerpc: Add support for function
error injection"), this patch supports function error injection for
Arm64.
This patch mainly support two functions: one is regs_set_return_value()
which is used to overwrite the return value; the another function is
override_function_with_return() which is to override the probed
function returning and jump to its caller.
Reviewed-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Leo Yan <leo.yan@linaro.org>
Signed-off-by: Will Deacon <will@kernel.org>
-rw-r--r-- | arch/arm64/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm64/include/asm/ptrace.h | 5 | ||||
-rw-r--r-- | arch/arm64/lib/Makefile | 2 | ||||
-rw-r--r-- | arch/arm64/lib/error-inject.c | 18 |
4 files changed, 26 insertions, 0 deletions
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 3adcec05b1f6..b15803afb2a0 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig | |||
@@ -148,6 +148,7 @@ config ARM64 | |||
148 | select HAVE_FAST_GUP | 148 | select HAVE_FAST_GUP |
149 | select HAVE_FTRACE_MCOUNT_RECORD | 149 | select HAVE_FTRACE_MCOUNT_RECORD |
150 | select HAVE_FUNCTION_TRACER | 150 | select HAVE_FUNCTION_TRACER |
151 | select HAVE_FUNCTION_ERROR_INJECTION | ||
151 | select HAVE_FUNCTION_GRAPH_TRACER | 152 | select HAVE_FUNCTION_GRAPH_TRACER |
152 | select HAVE_GCC_PLUGINS | 153 | select HAVE_GCC_PLUGINS |
153 | select HAVE_HW_BREAKPOINT if PERF_EVENTS | 154 | select HAVE_HW_BREAKPOINT if PERF_EVENTS |
diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h index 1dcf63a9ac1f..fbebb411ae20 100644 --- a/arch/arm64/include/asm/ptrace.h +++ b/arch/arm64/include/asm/ptrace.h | |||
@@ -301,6 +301,11 @@ static inline unsigned long regs_return_value(struct pt_regs *regs) | |||
301 | return regs->regs[0]; | 301 | return regs->regs[0]; |
302 | } | 302 | } |
303 | 303 | ||
304 | static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc) | ||
305 | { | ||
306 | regs->regs[0] = rc; | ||
307 | } | ||
308 | |||
304 | /** | 309 | /** |
305 | * regs_get_kernel_argument() - get Nth function argument in kernel | 310 | * regs_get_kernel_argument() - get Nth function argument in kernel |
306 | * @regs: pt_regs of that context | 311 | * @regs: pt_regs of that context |
diff --git a/arch/arm64/lib/Makefile b/arch/arm64/lib/Makefile index 33c2a4abda04..f182ccb0438e 100644 --- a/arch/arm64/lib/Makefile +++ b/arch/arm64/lib/Makefile | |||
@@ -33,3 +33,5 @@ UBSAN_SANITIZE_atomic_ll_sc.o := n | |||
33 | lib-$(CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE) += uaccess_flushcache.o | 33 | lib-$(CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE) += uaccess_flushcache.o |
34 | 34 | ||
35 | obj-$(CONFIG_CRC32) += crc32.o | 35 | obj-$(CONFIG_CRC32) += crc32.o |
36 | |||
37 | obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o | ||
diff --git a/arch/arm64/lib/error-inject.c b/arch/arm64/lib/error-inject.c new file mode 100644 index 000000000000..ed15021da3ed --- /dev/null +++ b/arch/arm64/lib/error-inject.c | |||
@@ -0,0 +1,18 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | |||
3 | #include <linux/error-injection.h> | ||
4 | #include <linux/kprobes.h> | ||
5 | |||
6 | void override_function_with_return(struct pt_regs *regs) | ||
7 | { | ||
8 | /* | ||
9 | * 'regs' represents the state on entry of a predefined function in | ||
10 | * the kernel/module and which is captured on a kprobe. | ||
11 | * | ||
12 | * When kprobe returns back from exception it will override the end | ||
13 | * of probed function and directly return to the predefined | ||
14 | * function's caller. | ||
15 | */ | ||
16 | instruction_pointer_set(regs, procedure_link_pointer(regs)); | ||
17 | } | ||
18 | NOKPROBE_SYMBOL(override_function_with_return); | ||