2019-05-19 16:51:55 +03:00
// SPDX-License-Identifier: GPL-2.0-or-later
2008-01-30 15:32:53 +03:00
/*
* test_kprobes . c - simple sanity test for * probes
*
* Copyright IBM Corp . 2008
*/
# include <linux/kernel.h>
# include <linux/kprobes.h>
# include <linux/random.h>
2021-10-21 03:54:24 +03:00
# include <kunit/test.h>
2008-01-30 15:32:53 +03:00
# define div_factor 3
2017-10-06 02:15:17 +03:00
static u32 rand1 , preh_val , posth_val ;
2009-01-07 01:41:47 +03:00
static u32 ( * target ) ( u32 value ) ;
2009-01-07 01:41:48 +03:00
static u32 ( * target2 ) ( u32 value ) ;
2021-10-21 03:54:24 +03:00
static struct kunit * current_test ;
2008-01-30 15:32:53 +03:00
static noinline u32 kprobe_target ( u32 value )
{
return ( value / div_factor ) ;
}
static int kp_pre_handler ( struct kprobe * p , struct pt_regs * regs )
{
2021-10-21 03:54:24 +03:00
KUNIT_EXPECT_FALSE ( current_test , preemptible ( ) ) ;
2008-01-30 15:32:53 +03:00
preh_val = ( rand1 / div_factor ) ;
return 0 ;
}
static void kp_post_handler ( struct kprobe * p , struct pt_regs * regs ,
unsigned long flags )
{
2021-10-21 03:54:24 +03:00
KUNIT_EXPECT_FALSE ( current_test , preemptible ( ) ) ;
KUNIT_EXPECT_EQ ( current_test , preh_val , ( rand1 / div_factor ) ) ;
2008-01-30 15:32:53 +03:00
posth_val = preh_val + div_factor ;
}
static struct kprobe kp = {
. symbol_name = " kprobe_target " ,
. pre_handler = kp_pre_handler ,
. post_handler = kp_post_handler
} ;
2021-10-21 03:54:24 +03:00
static void test_kprobe ( struct kunit * test )
2008-01-30 15:32:53 +03:00
{
2021-10-21 03:54:24 +03:00
current_test = test ;
KUNIT_EXPECT_EQ ( test , 0 , register_kprobe ( & kp ) ) ;
target ( rand1 ) ;
2008-01-30 15:32:53 +03:00
unregister_kprobe ( & kp ) ;
2021-10-21 03:54:24 +03:00
KUNIT_EXPECT_NE ( test , 0 , preh_val ) ;
KUNIT_EXPECT_NE ( test , 0 , posth_val ) ;
2008-01-30 15:32:53 +03:00
}
2009-01-07 01:41:48 +03:00
static noinline u32 kprobe_target2 ( u32 value )
{
return ( value / div_factor ) + 1 ;
}
static int kp_pre_handler2 ( struct kprobe * p , struct pt_regs * regs )
{
preh_val = ( rand1 / div_factor ) + 1 ;
return 0 ;
}
static void kp_post_handler2 ( struct kprobe * p , struct pt_regs * regs ,
unsigned long flags )
{
2021-10-21 03:54:24 +03:00
KUNIT_EXPECT_EQ ( current_test , preh_val , ( rand1 / div_factor ) + 1 ) ;
2009-01-07 01:41:48 +03:00
posth_val = preh_val + div_factor ;
}
static struct kprobe kp2 = {
. symbol_name = " kprobe_target2 " ,
. pre_handler = kp_pre_handler2 ,
. post_handler = kp_post_handler2
} ;
2021-10-21 03:54:24 +03:00
static void test_kprobes ( struct kunit * test )
2009-01-07 01:41:48 +03:00
{
struct kprobe * kps [ 2 ] = { & kp , & kp2 } ;
2021-10-21 03:54:24 +03:00
current_test = test ;
2010-10-14 07:10:24 +04:00
/* addr and flags should be cleard for reusing kprobe. */
kp . addr = NULL ;
kp . flags = 0 ;
2009-01-07 01:41:48 +03:00
2021-10-21 03:54:24 +03:00
KUNIT_EXPECT_EQ ( test , 0 , register_kprobes ( kps , 2 ) ) ;
2009-01-07 01:41:48 +03:00
preh_val = 0 ;
posth_val = 0 ;
2021-10-21 03:54:24 +03:00
target ( rand1 ) ;
2009-01-07 01:41:48 +03:00
2021-10-21 03:54:24 +03:00
KUNIT_EXPECT_NE ( test , 0 , preh_val ) ;
KUNIT_EXPECT_NE ( test , 0 , posth_val ) ;
2009-01-07 01:41:48 +03:00
preh_val = 0 ;
posth_val = 0 ;
2021-10-21 03:54:24 +03:00
target2 ( rand1 ) ;
2009-01-07 01:41:48 +03:00
2021-10-21 03:54:24 +03:00
KUNIT_EXPECT_NE ( test , 0 , preh_val ) ;
KUNIT_EXPECT_NE ( test , 0 , posth_val ) ;
2009-01-07 01:41:48 +03:00
unregister_kprobes ( kps , 2 ) ;
}
2008-01-30 15:32:53 +03:00
# ifdef CONFIG_KRETPROBES
static u32 krph_val ;
2008-02-06 12:38:22 +03:00
static int entry_handler ( struct kretprobe_instance * ri , struct pt_regs * regs )
{
2021-10-21 03:54:24 +03:00
KUNIT_EXPECT_FALSE ( current_test , preemptible ( ) ) ;
2008-02-06 12:38:22 +03:00
krph_val = ( rand1 / div_factor ) ;
return 0 ;
}
2008-01-30 15:32:53 +03:00
static int return_handler ( struct kretprobe_instance * ri , struct pt_regs * regs )
{
unsigned long ret = regs_return_value ( regs ) ;
2021-10-21 03:54:24 +03:00
KUNIT_EXPECT_FALSE ( current_test , preemptible ( ) ) ;
KUNIT_EXPECT_EQ ( current_test , ret , rand1 / div_factor ) ;
KUNIT_EXPECT_NE ( current_test , krph_val , 0 ) ;
2008-02-06 12:38:22 +03:00
krph_val = rand1 ;
2008-01-30 15:32:53 +03:00
return 0 ;
}
static struct kretprobe rp = {
. handler = return_handler ,
2008-02-06 12:38:22 +03:00
. entry_handler = entry_handler ,
2008-01-30 15:32:53 +03:00
. kp . symbol_name = " kprobe_target "
} ;
2021-10-21 03:54:24 +03:00
static void test_kretprobe ( struct kunit * test )
2008-01-30 15:32:53 +03:00
{
2021-10-21 03:54:24 +03:00
current_test = test ;
KUNIT_EXPECT_EQ ( test , 0 , register_kretprobe ( & rp ) ) ;
target ( rand1 ) ;
2008-01-30 15:32:53 +03:00
unregister_kretprobe ( & rp ) ;
2021-10-21 03:54:24 +03:00
KUNIT_EXPECT_EQ ( test , krph_val , rand1 ) ;
2008-01-30 15:32:53 +03:00
}
2009-01-07 01:41:48 +03:00
static int return_handler2 ( struct kretprobe_instance * ri , struct pt_regs * regs )
{
unsigned long ret = regs_return_value ( regs ) ;
2021-10-21 03:54:24 +03:00
KUNIT_EXPECT_EQ ( current_test , ret , ( rand1 / div_factor ) + 1 ) ;
KUNIT_EXPECT_NE ( current_test , krph_val , 0 ) ;
2009-01-07 01:41:48 +03:00
krph_val = rand1 ;
return 0 ;
}
static struct kretprobe rp2 = {
. handler = return_handler2 ,
. entry_handler = entry_handler ,
. kp . symbol_name = " kprobe_target2 "
} ;
2021-10-21 03:54:24 +03:00
static void test_kretprobes ( struct kunit * test )
2009-01-07 01:41:48 +03:00
{
struct kretprobe * rps [ 2 ] = { & rp , & rp2 } ;
2021-10-21 03:54:24 +03:00
current_test = test ;
2010-10-14 07:10:24 +04:00
/* addr and flags should be cleard for reusing kprobe. */
rp . kp . addr = NULL ;
rp . kp . flags = 0 ;
2021-10-21 03:54:24 +03:00
KUNIT_EXPECT_EQ ( test , 0 , register_kretprobes ( rps , 2 ) ) ;
2009-01-07 01:41:48 +03:00
krph_val = 0 ;
2021-10-21 03:54:24 +03:00
target ( rand1 ) ;
KUNIT_EXPECT_EQ ( test , krph_val , rand1 ) ;
2009-01-07 01:41:48 +03:00
krph_val = 0 ;
2021-10-21 03:54:24 +03:00
target2 ( rand1 ) ;
KUNIT_EXPECT_EQ ( test , krph_val , rand1 ) ;
2009-01-07 01:41:48 +03:00
unregister_kretprobes ( rps , 2 ) ;
}
2008-01-30 15:32:53 +03:00
# endif /* CONFIG_KRETPROBES */
2021-10-21 03:54:24 +03:00
static int kprobes_test_init ( struct kunit * test )
2008-01-30 15:32:53 +03:00
{
2009-01-07 01:41:47 +03:00
target = kprobe_target ;
2009-01-07 01:41:48 +03:00
target2 = kprobe_target2 ;
2009-01-07 01:41:47 +03:00
2008-01-30 15:32:53 +03:00
do {
2013-04-30 03:21:30 +04:00
rand1 = prandom_u32 ( ) ;
2008-01-30 15:32:53 +03:00
} while ( rand1 < = div_factor ) ;
2021-10-21 03:54:24 +03:00
return 0 ;
}
2008-01-30 15:32:53 +03:00
2021-10-21 03:54:24 +03:00
static struct kunit_case kprobes_testcases [ ] = {
KUNIT_CASE ( test_kprobe ) ,
KUNIT_CASE ( test_kprobes ) ,
2008-01-30 15:32:53 +03:00
# ifdef CONFIG_KRETPROBES
2021-10-21 03:54:24 +03:00
KUNIT_CASE ( test_kretprobe ) ,
KUNIT_CASE ( test_kretprobes ) ,
# endif
{ }
} ;
2008-01-30 15:32:53 +03:00
2021-10-21 03:54:24 +03:00
static struct kunit_suite kprobes_test_suite = {
. name = " kprobes_test " ,
. init = kprobes_test_init ,
. test_cases = kprobes_testcases ,
} ;
2008-01-30 15:32:53 +03:00
2021-10-21 03:54:24 +03:00
kunit_test_suites ( & kprobes_test_suite ) ;
MODULE_LICENSE ( " GPL " ) ;