Inspired by the commit 42d038c4fb00 ("arm64: Add support for function error
injection") and commit ee55ff803b38 ("riscv: Add support for function error
injection"), support function error injection for LoongArch.
Mainly implement two functions:
(1) regs_set_return_value() which is used to overwrite the return value,
(2) override_function_with_return() which is used to override the probed
function returning and jump to its caller.
Here is a simple test under CONFIG_FUNCTION_ERROR_INJECTION and
CONFIG_FAIL_FUNCTION:
# echo sys_clone > /sys/kernel/debug/fail_function/inject
# echo 100 > /sys/kernel/debug/fail_function/probability
# dmesg
bash: fork: Invalid argument
# dmesg
...
FAULT_INJECTION: forcing a failure.
name fail_function, interval 1, probability 100, space 0, times 1
...
Call Trace:
[<90000000002238f4>] show_stack+0x5c/0x180
[<90000000012e384c>] dump_stack_lvl+0x60/0x88
[<9000000000b1879c>] should_fail_ex+0x1b0/0x1f4
[<900000000032ead4>] fei_kprobe_handler+0x28/0x6c
[<9000000000230970>] kprobe_breakpoint_handler+0xf0/0x118
[<90000000012e3e60>] do_bp+0x2c4/0x358
[<9000000002241924>] exception_handlers+0x1924/0x10000
[<900000000023b7d0>] sys_clone+0x0/0x4
[<90000000012e4744>] do_syscall+0x7c/0x94
[<9000000000221e44>] handle_syscall+0xc4/0x160
Signed-off-by: Tiezhu Yang <[email protected]>
---
arch/loongarch/Kconfig | 1 +
arch/loongarch/include/asm/ptrace.h | 6 ++++++
arch/loongarch/lib/Makefile | 2 ++
arch/loongarch/lib/error-inject.c | 10 ++++++++++
4 files changed, 19 insertions(+)
create mode 100644 arch/loongarch/lib/error-inject.c
diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
index 7fd5125..b16ff7e 100644
--- a/arch/loongarch/Kconfig
+++ b/arch/loongarch/Kconfig
@@ -99,6 +99,7 @@ config LOONGARCH
select HAVE_FAST_GUP
select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_FUNCTION_ARG_ACCESS_API
+ select HAVE_FUNCTION_ERROR_INJECTION
select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_FUNCTION_TRACER
select HAVE_GENERIC_VDSO
diff --git a/arch/loongarch/include/asm/ptrace.h b/arch/loongarch/include/asm/ptrace.h
index d761db9..db7332a 100644
--- a/arch/loongarch/include/asm/ptrace.h
+++ b/arch/loongarch/include/asm/ptrace.h
@@ -154,6 +154,12 @@ static inline long regs_return_value(struct pt_regs *regs)
return regs->regs[4];
}
+static inline void regs_set_return_value(struct pt_regs *regs,
+ unsigned long val)
+{
+ regs->regs[4] = val;
+}
+
#define instruction_pointer(regs) ((regs)->csr_era)
#define profile_pc(regs) instruction_pointer(regs)
diff --git a/arch/loongarch/lib/Makefile b/arch/loongarch/lib/Makefile
index 40bde63..30b1595 100644
--- a/arch/loongarch/lib/Makefile
+++ b/arch/loongarch/lib/Makefile
@@ -5,3 +5,5 @@
lib-y += delay.o memset.o memcpy.o memmove.o \
clear_user.o copy_user.o dump_tlb.o unaligned.o
+
+obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
diff --git a/arch/loongarch/lib/error-inject.c b/arch/loongarch/lib/error-inject.c
new file mode 100644
index 0000000..afc9e1c
--- /dev/null
+++ b/arch/loongarch/lib/error-inject.c
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/error-injection.h>
+#include <linux/kprobes.h>
+
+void override_function_with_return(struct pt_regs *regs)
+{
+ instruction_pointer_set(regs, regs->regs[1]);
+}
+NOKPROBE_SYMBOL(override_function_with_return);
--
2.1.0
This feature is related with kprobes, add Masami to CC.
On 03/07/2023 03:10 PM, Tiezhu Yang wrote:
> Inspired by the commit 42d038c4fb00 ("arm64: Add support for function error
> injection") and commit ee55ff803b38 ("riscv: Add support for function error
> injection"), support function error injection for LoongArch.
>
> Mainly implement two functions:
> (1) regs_set_return_value() which is used to overwrite the return value,
> (2) override_function_with_return() which is used to override the probed
> function returning and jump to its caller.
>
> Here is a simple test under CONFIG_FUNCTION_ERROR_INJECTION and
> CONFIG_FAIL_FUNCTION:
>
> # echo sys_clone > /sys/kernel/debug/fail_function/inject
> # echo 100 > /sys/kernel/debug/fail_function/probability
> # dmesg
> bash: fork: Invalid argument
> # dmesg
> ...
> FAULT_INJECTION: forcing a failure.
> name fail_function, interval 1, probability 100, space 0, times 1
> ...
> Call Trace:
> [<90000000002238f4>] show_stack+0x5c/0x180
> [<90000000012e384c>] dump_stack_lvl+0x60/0x88
> [<9000000000b1879c>] should_fail_ex+0x1b0/0x1f4
> [<900000000032ead4>] fei_kprobe_handler+0x28/0x6c
> [<9000000000230970>] kprobe_breakpoint_handler+0xf0/0x118
> [<90000000012e3e60>] do_bp+0x2c4/0x358
> [<9000000002241924>] exception_handlers+0x1924/0x10000
> [<900000000023b7d0>] sys_clone+0x0/0x4
> [<90000000012e4744>] do_syscall+0x7c/0x94
> [<9000000000221e44>] handle_syscall+0xc4/0x160
>
> Signed-off-by: Tiezhu Yang <[email protected]>
> ---
> arch/loongarch/Kconfig | 1 +
> arch/loongarch/include/asm/ptrace.h | 6 ++++++
> arch/loongarch/lib/Makefile | 2 ++
> arch/loongarch/lib/error-inject.c | 10 ++++++++++
> 4 files changed, 19 insertions(+)
> create mode 100644 arch/loongarch/lib/error-inject.c
>
> diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
> index 7fd5125..b16ff7e 100644
> --- a/arch/loongarch/Kconfig
> +++ b/arch/loongarch/Kconfig
> @@ -99,6 +99,7 @@ config LOONGARCH
> select HAVE_FAST_GUP
> select HAVE_FTRACE_MCOUNT_RECORD
> select HAVE_FUNCTION_ARG_ACCESS_API
> + select HAVE_FUNCTION_ERROR_INJECTION
> select HAVE_FUNCTION_GRAPH_TRACER
> select HAVE_FUNCTION_TRACER
> select HAVE_GENERIC_VDSO
> diff --git a/arch/loongarch/include/asm/ptrace.h b/arch/loongarch/include/asm/ptrace.h
> index d761db9..db7332a 100644
> --- a/arch/loongarch/include/asm/ptrace.h
> +++ b/arch/loongarch/include/asm/ptrace.h
> @@ -154,6 +154,12 @@ static inline long regs_return_value(struct pt_regs *regs)
> return regs->regs[4];
> }
>
> +static inline void regs_set_return_value(struct pt_regs *regs,
> + unsigned long val)
> +{
> + regs->regs[4] = val;
> +}
> +
> #define instruction_pointer(regs) ((regs)->csr_era)
> #define profile_pc(regs) instruction_pointer(regs)
>
> diff --git a/arch/loongarch/lib/Makefile b/arch/loongarch/lib/Makefile
> index 40bde63..30b1595 100644
> --- a/arch/loongarch/lib/Makefile
> +++ b/arch/loongarch/lib/Makefile
> @@ -5,3 +5,5 @@
>
> lib-y += delay.o memset.o memcpy.o memmove.o \
> clear_user.o copy_user.o dump_tlb.o unaligned.o
> +
> +obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
> diff --git a/arch/loongarch/lib/error-inject.c b/arch/loongarch/lib/error-inject.c
> new file mode 100644
> index 0000000..afc9e1c
> --- /dev/null
> +++ b/arch/loongarch/lib/error-inject.c
> @@ -0,0 +1,10 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +#include <linux/error-injection.h>
> +#include <linux/kprobes.h>
> +
> +void override_function_with_return(struct pt_regs *regs)
> +{
> + instruction_pointer_set(regs, regs->regs[1]);
> +}
> +NOKPROBE_SYMBOL(override_function_with_return);
>
On Fri, 10 Mar 2023 10:07:09 +0800
Tiezhu Yang <[email protected]> wrote:
> This feature is related with kprobes, add Masami to CC.
>
> On 03/07/2023 03:10 PM, Tiezhu Yang wrote:
> > Inspired by the commit 42d038c4fb00 ("arm64: Add support for function error
> > injection") and commit ee55ff803b38 ("riscv: Add support for function error
> > injection"), support function error injection for LoongArch.
> >
> > Mainly implement two functions:
> > (1) regs_set_return_value() which is used to overwrite the return value,
> > (2) override_function_with_return() which is used to override the probed
> > function returning and jump to its caller.
> >
> > Here is a simple test under CONFIG_FUNCTION_ERROR_INJECTION and
> > CONFIG_FAIL_FUNCTION:
> >
> > # echo sys_clone > /sys/kernel/debug/fail_function/inject
> > # echo 100 > /sys/kernel/debug/fail_function/probability
> > # dmesg
> > bash: fork: Invalid argument
> > # dmesg
> > ...
> > FAULT_INJECTION: forcing a failure.
> > name fail_function, interval 1, probability 100, space 0, times 1
> > ...
> > Call Trace:
> > [<90000000002238f4>] show_stack+0x5c/0x180
> > [<90000000012e384c>] dump_stack_lvl+0x60/0x88
> > [<9000000000b1879c>] should_fail_ex+0x1b0/0x1f4
> > [<900000000032ead4>] fei_kprobe_handler+0x28/0x6c
> > [<9000000000230970>] kprobe_breakpoint_handler+0xf0/0x118
> > [<90000000012e3e60>] do_bp+0x2c4/0x358
> > [<9000000002241924>] exception_handlers+0x1924/0x10000
> > [<900000000023b7d0>] sys_clone+0x0/0x4
> > [<90000000012e4744>] do_syscall+0x7c/0x94
> > [<9000000000221e44>] handle_syscall+0xc4/0x160
> >
> > Signed-off-by: Tiezhu Yang <[email protected]>
Thanks for porting! This looks good to me.
Acked-by: Masami Hiramatsu (Google) <[email protected]>
Thanks!
> > ---
> > arch/loongarch/Kconfig | 1 +
> > arch/loongarch/include/asm/ptrace.h | 6 ++++++
> > arch/loongarch/lib/Makefile | 2 ++
> > arch/loongarch/lib/error-inject.c | 10 ++++++++++
> > 4 files changed, 19 insertions(+)
> > create mode 100644 arch/loongarch/lib/error-inject.c
> >
> > diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
> > index 7fd5125..b16ff7e 100644
> > --- a/arch/loongarch/Kconfig
> > +++ b/arch/loongarch/Kconfig
> > @@ -99,6 +99,7 @@ config LOONGARCH
> > select HAVE_FAST_GUP
> > select HAVE_FTRACE_MCOUNT_RECORD
> > select HAVE_FUNCTION_ARG_ACCESS_API
> > + select HAVE_FUNCTION_ERROR_INJECTION
> > select HAVE_FUNCTION_GRAPH_TRACER
> > select HAVE_FUNCTION_TRACER
> > select HAVE_GENERIC_VDSO
> > diff --git a/arch/loongarch/include/asm/ptrace.h b/arch/loongarch/include/asm/ptrace.h
> > index d761db9..db7332a 100644
> > --- a/arch/loongarch/include/asm/ptrace.h
> > +++ b/arch/loongarch/include/asm/ptrace.h
> > @@ -154,6 +154,12 @@ static inline long regs_return_value(struct pt_regs *regs)
> > return regs->regs[4];
> > }
> >
> > +static inline void regs_set_return_value(struct pt_regs *regs,
> > + unsigned long val)
> > +{
> > + regs->regs[4] = val;
> > +}
> > +
> > #define instruction_pointer(regs) ((regs)->csr_era)
> > #define profile_pc(regs) instruction_pointer(regs)
> >
> > diff --git a/arch/loongarch/lib/Makefile b/arch/loongarch/lib/Makefile
> > index 40bde63..30b1595 100644
> > --- a/arch/loongarch/lib/Makefile
> > +++ b/arch/loongarch/lib/Makefile
> > @@ -5,3 +5,5 @@
> >
> > lib-y += delay.o memset.o memcpy.o memmove.o \
> > clear_user.o copy_user.o dump_tlb.o unaligned.o
> > +
> > +obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
> > diff --git a/arch/loongarch/lib/error-inject.c b/arch/loongarch/lib/error-inject.c
> > new file mode 100644
> > index 0000000..afc9e1c
> > --- /dev/null
> > +++ b/arch/loongarch/lib/error-inject.c
> > @@ -0,0 +1,10 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +
> > +#include <linux/error-injection.h>
> > +#include <linux/kprobes.h>
> > +
> > +void override_function_with_return(struct pt_regs *regs)
> > +{
> > + instruction_pointer_set(regs, regs->regs[1]);
> > +}
> > +NOKPROBE_SYMBOL(override_function_with_return);
> >
>
--
Masami Hiramatsu (Google) <[email protected]>
Queued for loongarch-next, thanks.
Huacai
On Fri, Mar 10, 2023 at 11:22 PM Masami Hiramatsu <[email protected]> wrote:
>
> On Fri, 10 Mar 2023 10:07:09 +0800
> Tiezhu Yang <[email protected]> wrote:
>
> > This feature is related with kprobes, add Masami to CC.
> >
> > On 03/07/2023 03:10 PM, Tiezhu Yang wrote:
> > > Inspired by the commit 42d038c4fb00 ("arm64: Add support for function error
> > > injection") and commit ee55ff803b38 ("riscv: Add support for function error
> > > injection"), support function error injection for LoongArch.
> > >
> > > Mainly implement two functions:
> > > (1) regs_set_return_value() which is used to overwrite the return value,
> > > (2) override_function_with_return() which is used to override the probed
> > > function returning and jump to its caller.
> > >
> > > Here is a simple test under CONFIG_FUNCTION_ERROR_INJECTION and
> > > CONFIG_FAIL_FUNCTION:
> > >
> > > # echo sys_clone > /sys/kernel/debug/fail_function/inject
> > > # echo 100 > /sys/kernel/debug/fail_function/probability
> > > # dmesg
> > > bash: fork: Invalid argument
> > > # dmesg
> > > ...
> > > FAULT_INJECTION: forcing a failure.
> > > name fail_function, interval 1, probability 100, space 0, times 1
> > > ...
> > > Call Trace:
> > > [<90000000002238f4>] show_stack+0x5c/0x180
> > > [<90000000012e384c>] dump_stack_lvl+0x60/0x88
> > > [<9000000000b1879c>] should_fail_ex+0x1b0/0x1f4
> > > [<900000000032ead4>] fei_kprobe_handler+0x28/0x6c
> > > [<9000000000230970>] kprobe_breakpoint_handler+0xf0/0x118
> > > [<90000000012e3e60>] do_bp+0x2c4/0x358
> > > [<9000000002241924>] exception_handlers+0x1924/0x10000
> > > [<900000000023b7d0>] sys_clone+0x0/0x4
> > > [<90000000012e4744>] do_syscall+0x7c/0x94
> > > [<9000000000221e44>] handle_syscall+0xc4/0x160
> > >
> > > Signed-off-by: Tiezhu Yang <[email protected]>
>
> Thanks for porting! This looks good to me.
>
> Acked-by: Masami Hiramatsu (Google) <[email protected]>
>
> Thanks!
>
> > > ---
> > > arch/loongarch/Kconfig | 1 +
> > > arch/loongarch/include/asm/ptrace.h | 6 ++++++
> > > arch/loongarch/lib/Makefile | 2 ++
> > > arch/loongarch/lib/error-inject.c | 10 ++++++++++
> > > 4 files changed, 19 insertions(+)
> > > create mode 100644 arch/loongarch/lib/error-inject.c
> > >
> > > diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
> > > index 7fd5125..b16ff7e 100644
> > > --- a/arch/loongarch/Kconfig
> > > +++ b/arch/loongarch/Kconfig
> > > @@ -99,6 +99,7 @@ config LOONGARCH
> > > select HAVE_FAST_GUP
> > > select HAVE_FTRACE_MCOUNT_RECORD
> > > select HAVE_FUNCTION_ARG_ACCESS_API
> > > + select HAVE_FUNCTION_ERROR_INJECTION
> > > select HAVE_FUNCTION_GRAPH_TRACER
> > > select HAVE_FUNCTION_TRACER
> > > select HAVE_GENERIC_VDSO
> > > diff --git a/arch/loongarch/include/asm/ptrace.h b/arch/loongarch/include/asm/ptrace.h
> > > index d761db9..db7332a 100644
> > > --- a/arch/loongarch/include/asm/ptrace.h
> > > +++ b/arch/loongarch/include/asm/ptrace.h
> > > @@ -154,6 +154,12 @@ static inline long regs_return_value(struct pt_regs *regs)
> > > return regs->regs[4];
> > > }
> > >
> > > +static inline void regs_set_return_value(struct pt_regs *regs,
> > > + unsigned long val)
> > > +{
> > > + regs->regs[4] = val;
> > > +}
> > > +
> > > #define instruction_pointer(regs) ((regs)->csr_era)
> > > #define profile_pc(regs) instruction_pointer(regs)
> > >
> > > diff --git a/arch/loongarch/lib/Makefile b/arch/loongarch/lib/Makefile
> > > index 40bde63..30b1595 100644
> > > --- a/arch/loongarch/lib/Makefile
> > > +++ b/arch/loongarch/lib/Makefile
> > > @@ -5,3 +5,5 @@
> > >
> > > lib-y += delay.o memset.o memcpy.o memmove.o \
> > > clear_user.o copy_user.o dump_tlb.o unaligned.o
> > > +
> > > +obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
> > > diff --git a/arch/loongarch/lib/error-inject.c b/arch/loongarch/lib/error-inject.c
> > > new file mode 100644
> > > index 0000000..afc9e1c
> > > --- /dev/null
> > > +++ b/arch/loongarch/lib/error-inject.c
> > > @@ -0,0 +1,10 @@
> > > +// SPDX-License-Identifier: GPL-2.0
> > > +
> > > +#include <linux/error-injection.h>
> > > +#include <linux/kprobes.h>
> > > +
> > > +void override_function_with_return(struct pt_regs *regs)
> > > +{
> > > + instruction_pointer_set(regs, regs->regs[1]);
> > > +}
> > > +NOKPROBE_SYMBOL(override_function_with_return);
> > >
> >
>
>
> --
> Masami Hiramatsu (Google) <[email protected]>
On 2023/3/10 10:07, Tiezhu Yang wrote:
> This feature is related with kprobes, add Masami to CC.
>
> On 03/07/2023 03:10 PM, Tiezhu Yang wrote:
>> Inspired by the commit 42d038c4fb00 ("arm64: Add support for function error
>> injection") and commit ee55ff803b38 ("riscv: Add support for function error
>> injection"), support function error injection for LoongArch.
>>
>> Mainly implement two functions:
>> (1) regs_set_return_value() which is used to overwrite the return value,
>> (2) override_function_with_return() which is used to override the probed
>> function returning and jump to its caller.
>>
>> Here is a simple test under CONFIG_FUNCTION_ERROR_INJECTION and
>> CONFIG_FAIL_FUNCTION:
>>
>> # echo sys_clone > /sys/kernel/debug/fail_function/inject
>> # echo 100 > /sys/kernel/debug/fail_function/probability
>> # dmesg
>> bash: fork: Invalid argument
>> # dmesg
>> ...
>> FAULT_INJECTION: forcing a failure.
>> name fail_function, interval 1, probability 100, space 0, times 1
>> ...
>> Call Trace:
>> [<90000000002238f4>] show_stack+0x5c/0x180
>> [<90000000012e384c>] dump_stack_lvl+0x60/0x88
>> [<9000000000b1879c>] should_fail_ex+0x1b0/0x1f4
>> [<900000000032ead4>] fei_kprobe_handler+0x28/0x6c
>> [<9000000000230970>] kprobe_breakpoint_handler+0xf0/0x118
>> [<90000000012e3e60>] do_bp+0x2c4/0x358
>> [<9000000002241924>] exception_handlers+0x1924/0x10000
>> [<900000000023b7d0>] sys_clone+0x0/0x4
>> [<90000000012e4744>] do_syscall+0x7c/0x94
>> [<9000000000221e44>] handle_syscall+0xc4/0x160
>>
>> Signed-off-by: Tiezhu Yang <[email protected]>
>> ---
>> arch/loongarch/Kconfig | 1 +
>> arch/loongarch/include/asm/ptrace.h | 6 ++++++
>> arch/loongarch/lib/Makefile | 2 ++
>> arch/loongarch/lib/error-inject.c | 10 ++++++++++
>> 4 files changed, 19 insertions(+)
>> create mode 100644 arch/loongarch/lib/error-inject.c
>>
>> diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
>> index 7fd5125..b16ff7e 100644
>> --- a/arch/loongarch/Kconfig
>> +++ b/arch/loongarch/Kconfig
>> @@ -99,6 +99,7 @@ config LOONGARCH
>> select HAVE_FAST_GUP
>> select HAVE_FTRACE_MCOUNT_RECORD
>> select HAVE_FUNCTION_ARG_ACCESS_API
>> + select HAVE_FUNCTION_ERROR_INJECTION
>> select HAVE_FUNCTION_GRAPH_TRACER
>> select HAVE_FUNCTION_TRACER
>> select HAVE_GENERIC_VDSO
>> diff --git a/arch/loongarch/include/asm/ptrace.h b/arch/loongarch/include/asm/ptrace.h
>> index d761db9..db7332a 100644
>> --- a/arch/loongarch/include/asm/ptrace.h
>> +++ b/arch/loongarch/include/asm/ptrace.h
>> @@ -154,6 +154,12 @@ static inline long regs_return_value(struct pt_regs *regs)
>> return regs->regs[4];
>> }
>>
>> +static inline void regs_set_return_value(struct pt_regs *regs,
>> + unsigned long val)
>> +{
>> + regs->regs[4] = val;
>> +}
>> +
>> #define instruction_pointer(regs) ((regs)->csr_era)
>> #define profile_pc(regs) instruction_pointer(regs)
>>
>> diff --git a/arch/loongarch/lib/Makefile b/arch/loongarch/lib/Makefile
>> index 40bde63..30b1595 100644
>> --- a/arch/loongarch/lib/Makefile
>> +++ b/arch/loongarch/lib/Makefile
>> @@ -5,3 +5,5 @@
>>
>> lib-y += delay.o memset.o memcpy.o memmove.o \
>> clear_user.o copy_user.o dump_tlb.o unaligned.o
>> +
>> +obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
>> diff --git a/arch/loongarch/lib/error-inject.c b/arch/loongarch/lib/error-inject.c
>> new file mode 100644
>> index 0000000..afc9e1c
>> --- /dev/null
>> +++ b/arch/loongarch/lib/error-inject.c
>> @@ -0,0 +1,10 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +
>> +#include <linux/error-injection.h>
>> +#include <linux/kprobes.h>
>> +
>> +void override_function_with_return(struct pt_regs *regs)
>> +{
>> + instruction_pointer_set(regs, regs->regs[1]);
>> +}
>> +NOKPROBE_SYMBOL(override_function_with_return);
>>
>
>
Tested-by: Hengqi Chen <[email protected]>