Hi Russell, On Tue, Aug 06, 2019 at 06:00:15PM +0800, Leo Yan wrote: > This patch implements arm specific functions regs_set_return_value() and > override_function_with_return() to support function error injection. > > In the exception flow, it updates pt_regs::ARM_pc with pt_regs::ARM_lr > so can override the probed function return. Gentle ping ... Could you review this patch? Thanks, Leo. > Signed-off-by: Leo Yan <leo.yan@xxxxxxxxxx> > --- > arch/arm/Kconfig | 1 + > arch/arm/include/asm/ptrace.h | 5 +++++ > arch/arm/lib/Makefile | 2 ++ > arch/arm/lib/error-inject.c | 19 +++++++++++++++++++ > 4 files changed, 27 insertions(+) > create mode 100644 arch/arm/lib/error-inject.c > > diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig > index 33b00579beff..2d3d44a037f6 100644 > --- a/arch/arm/Kconfig > +++ b/arch/arm/Kconfig > @@ -77,6 +77,7 @@ config ARM > select HAVE_EXIT_THREAD > select HAVE_FAST_GUP if ARM_LPAE > select HAVE_FTRACE_MCOUNT_RECORD if !XIP_KERNEL > + select HAVE_FUNCTION_ERROR_INJECTION if !THUMB2_KERNEL > select HAVE_FUNCTION_GRAPH_TRACER if !THUMB2_KERNEL && !CC_IS_CLANG > select HAVE_FUNCTION_TRACER if !XIP_KERNEL > select HAVE_GCC_PLUGINS > diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h > index 91d6b7856be4..3b41f37b361a 100644 > --- a/arch/arm/include/asm/ptrace.h > +++ b/arch/arm/include/asm/ptrace.h > @@ -89,6 +89,11 @@ static inline long regs_return_value(struct pt_regs *regs) > return regs->ARM_r0; > } > > +static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc) > +{ > + regs->ARM_r0 = rc; > +} > + > #define instruction_pointer(regs) (regs)->ARM_pc > > #ifdef CONFIG_THUMB2_KERNEL > diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile > index b25c54585048..8f56484a7156 100644 > --- a/arch/arm/lib/Makefile > +++ b/arch/arm/lib/Makefile > @@ -42,3 +42,5 @@ ifeq ($(CONFIG_KERNEL_MODE_NEON),y) > CFLAGS_xor-neon.o += $(NEON_FLAGS) > obj-$(CONFIG_XOR_BLOCKS) += xor-neon.o > endif > + > +obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o > diff --git a/arch/arm/lib/error-inject.c b/arch/arm/lib/error-inject.c > new file mode 100644 > index 000000000000..2d696dc94893 > --- /dev/null > +++ b/arch/arm/lib/error-inject.c > @@ -0,0 +1,19 @@ > +// SPDX-License-Identifier: GPL-2.0 > + > +#include <linux/error-injection.h> > +#include <linux/kprobes.h> > + > +void override_function_with_return(struct pt_regs *regs) > +{ > + /* > + * 'regs' represents the state on entry of a predefined function in > + * the kernel/module and which is captured on a kprobe. > + * > + * 'regs->ARM_lr' contains the the link register for the probed > + * function, when kprobe returns back from exception it will override > + * the end of probed function and directly return to the predefined > + * function's caller. > + */ > + instruction_pointer_set(regs, regs->ARM_lr); > +} > +NOKPROBE_SYMBOL(override_function_with_return); > -- > 2.17.1 >