2018-03-14 10:23:22 -07:00
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2018 Facebook
# include <linux/bpf.h>
2020-01-20 14:06:45 +01:00
# include <bpf/bpf_helpers.h>
2018-03-14 10:23:22 -07:00
# ifndef PERF_MAX_STACK_DEPTH
# define PERF_MAX_STACK_DEPTH 127
# endif
2019-06-17 12:26:59 -07:00
struct {
2019-07-05 08:50:11 -07:00
__uint ( type , BPF_MAP_TYPE_ARRAY ) ;
__uint ( max_entries , 1 ) ;
__type ( key , __u32 ) ;
__type ( value , __u32 ) ;
} control_map SEC ( " .maps " ) ;
2018-03-14 10:23:22 -07:00
2019-06-17 12:26:59 -07:00
struct {
2019-07-05 08:50:11 -07:00
__uint ( type , BPF_MAP_TYPE_HASH ) ;
__uint ( max_entries , 16384 ) ;
__type ( key , __u32 ) ;
__type ( value , __u32 ) ;
} stackid_hmap SEC ( " .maps " ) ;
2018-03-14 10:23:22 -07:00
2019-06-17 12:26:59 -07:00
typedef struct bpf_stack_build_id stack_trace_t [ PERF_MAX_STACK_DEPTH ] ;
struct {
2019-07-05 08:50:11 -07:00
__uint ( type , BPF_MAP_TYPE_STACK_TRACE ) ;
__uint ( max_entries , 128 ) ;
__uint ( map_flags , BPF_F_STACK_BUILD_ID ) ;
2021-10-01 00:14:56 +08:00
__type ( key , __u32 ) ;
__type ( value , stack_trace_t ) ;
2019-07-05 08:50:11 -07:00
} stackmap SEC ( " .maps " ) ;
2018-03-14 10:23:22 -07:00
2019-06-17 12:26:59 -07:00
struct {
2019-07-05 08:50:11 -07:00
__uint ( type , BPF_MAP_TYPE_ARRAY ) ;
__uint ( max_entries , 128 ) ;
__type ( key , __u32 ) ;
2019-07-12 10:25:57 -07:00
__type ( value , stack_trace_t ) ;
2019-07-05 08:50:11 -07:00
} stack_amap SEC ( " .maps " ) ;
2018-04-28 22:28:16 -07:00
2018-03-14 10:23:22 -07:00
/* taken from /sys/kernel/debug/tracing/events/random/urandom_read/format */
struct random_urandom_args {
unsigned long long pad ;
int got_bits ;
int pool_left ;
int input_left ;
} ;
SEC ( " tracepoint/random/urandom_read " )
int oncpu ( struct random_urandom_args * args )
{
2018-04-28 22:28:16 -07:00
__u32 max_len = sizeof ( struct bpf_stack_build_id )
* PERF_MAX_STACK_DEPTH ;
2018-03-14 10:23:22 -07:00
__u32 key = 0 , val = 0 , * value_p ;
2018-04-28 22:28:16 -07:00
void * stack_p ;
2018-03-14 10:23:22 -07:00
value_p = bpf_map_lookup_elem ( & control_map , & key ) ;
if ( value_p & & * value_p )
return 0 ; /* skip if non-zero *value_p */
/* The size of stackmap and stackid_hmap should be the same */
key = bpf_get_stackid ( args , & stackmap , BPF_F_USER_STACK ) ;
2018-04-28 22:28:16 -07:00
if ( ( int ) key > = 0 ) {
2018-03-14 10:23:22 -07:00
bpf_map_update_elem ( & stackid_hmap , & key , & val , 0 ) ;
2018-04-28 22:28:16 -07:00
stack_p = bpf_map_lookup_elem ( & stack_amap , & key ) ;
if ( stack_p )
bpf_get_stack ( args , stack_p , max_len ,
BPF_F_USER_STACK | BPF_F_USER_BUILD_ID ) ;
}
2018-03-14 10:23:22 -07:00
return 0 ;
}
char _license [ ] SEC ( " license " ) = " GPL " ;