test_kprobes: Add recursed kprobe test case
Add a recursed kprobe test case to the KUnit test module for kprobes. This will probe a function which is called from the pre_handler and post_handler itself. If the kprobe is correctly implemented, the recursed kprobe handlers will be skipped and the number of skipped kprobe will be counted on kprobe::nmissed. Link: https://lore.kernel.org/all/167414238758.2301956.258548940194352895.stgit@devnote3/ Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
This commit is contained in:
parent
8478cca1e3
commit
1fcd09fd4f
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
static u32 rand1, preh_val, posth_val;
|
static u32 rand1, preh_val, posth_val;
|
||||||
static u32 (*target)(u32 value);
|
static u32 (*target)(u32 value);
|
||||||
|
static u32 (*recursed_target)(u32 value);
|
||||||
static u32 (*target2)(u32 value);
|
static u32 (*target2)(u32 value);
|
||||||
static struct kunit *current_test;
|
static struct kunit *current_test;
|
||||||
|
|
||||||
@ -27,18 +28,27 @@ static noinline u32 kprobe_target(u32 value)
|
|||||||
return (value / div_factor);
|
return (value / div_factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static noinline u32 kprobe_recursed_target(u32 value)
|
||||||
|
{
|
||||||
|
return (value / div_factor);
|
||||||
|
}
|
||||||
|
|
||||||
static int kp_pre_handler(struct kprobe *p, struct pt_regs *regs)
|
static int kp_pre_handler(struct kprobe *p, struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
KUNIT_EXPECT_FALSE(current_test, preemptible());
|
KUNIT_EXPECT_FALSE(current_test, preemptible());
|
||||||
preh_val = (rand1 / div_factor);
|
|
||||||
|
preh_val = recursed_target(rand1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void kp_post_handler(struct kprobe *p, struct pt_regs *regs,
|
static void kp_post_handler(struct kprobe *p, struct pt_regs *regs,
|
||||||
unsigned long flags)
|
unsigned long flags)
|
||||||
{
|
{
|
||||||
|
u32 expval = recursed_target(rand1);
|
||||||
|
|
||||||
KUNIT_EXPECT_FALSE(current_test, preemptible());
|
KUNIT_EXPECT_FALSE(current_test, preemptible());
|
||||||
KUNIT_EXPECT_EQ(current_test, preh_val, (rand1 / div_factor));
|
KUNIT_EXPECT_EQ(current_test, preh_val, expval);
|
||||||
|
|
||||||
posth_val = preh_val + div_factor;
|
posth_val = preh_val + div_factor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,6 +146,29 @@ static void test_kprobes(struct kunit *test)
|
|||||||
unregister_kprobes(kps, 2);
|
unregister_kprobes(kps, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct kprobe kp_missed = {
|
||||||
|
.symbol_name = "kprobe_recursed_target",
|
||||||
|
.pre_handler = kp_pre_handler,
|
||||||
|
.post_handler = kp_post_handler,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void test_kprobe_missed(struct kunit *test)
|
||||||
|
{
|
||||||
|
current_test = test;
|
||||||
|
preh_val = 0;
|
||||||
|
posth_val = 0;
|
||||||
|
|
||||||
|
KUNIT_EXPECT_EQ(test, 0, register_kprobe(&kp_missed));
|
||||||
|
|
||||||
|
recursed_target(rand1);
|
||||||
|
|
||||||
|
KUNIT_EXPECT_EQ(test, 2, kp_missed.nmissed);
|
||||||
|
KUNIT_EXPECT_NE(test, 0, preh_val);
|
||||||
|
KUNIT_EXPECT_NE(test, 0, posth_val);
|
||||||
|
|
||||||
|
unregister_kprobe(&kp_missed);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_KRETPROBES
|
#ifdef CONFIG_KRETPROBES
|
||||||
static u32 krph_val;
|
static u32 krph_val;
|
||||||
|
|
||||||
@ -336,6 +369,7 @@ static int kprobes_test_init(struct kunit *test)
|
|||||||
{
|
{
|
||||||
target = kprobe_target;
|
target = kprobe_target;
|
||||||
target2 = kprobe_target2;
|
target2 = kprobe_target2;
|
||||||
|
recursed_target = kprobe_recursed_target;
|
||||||
stacktrace_target = kprobe_stacktrace_target;
|
stacktrace_target = kprobe_stacktrace_target;
|
||||||
internal_target = kprobe_stacktrace_internal_target;
|
internal_target = kprobe_stacktrace_internal_target;
|
||||||
stacktrace_driver = kprobe_stacktrace_driver;
|
stacktrace_driver = kprobe_stacktrace_driver;
|
||||||
@ -346,6 +380,7 @@ static int kprobes_test_init(struct kunit *test)
|
|||||||
static struct kunit_case kprobes_testcases[] = {
|
static struct kunit_case kprobes_testcases[] = {
|
||||||
KUNIT_CASE(test_kprobe),
|
KUNIT_CASE(test_kprobe),
|
||||||
KUNIT_CASE(test_kprobes),
|
KUNIT_CASE(test_kprobes),
|
||||||
|
KUNIT_CASE(test_kprobe_missed),
|
||||||
#ifdef CONFIG_KRETPROBES
|
#ifdef CONFIG_KRETPROBES
|
||||||
KUNIT_CASE(test_kretprobe),
|
KUNIT_CASE(test_kretprobe),
|
||||||
KUNIT_CASE(test_kretprobes),
|
KUNIT_CASE(test_kretprobes),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user