@@ -21,11 +21,12 @@ or GPL2.txt for full copies of the license.
2121
2222#include "../ppm_flag_helpers.h"
2323#include "../ppm_version.h"
24+ #include "types.h"
2425
2526#include <linux/tty.h>
2627#include <linux/audit.h>
2728#include <linux/tcp.h>
28-
29+ #include <linux/eventpoll.h>
2930
3031/*
3132 * Linux 5.6 kernels no longer include the old 32-bit timeval
@@ -344,7 +345,86 @@ FILLER(sys_write_x, true)
344345
345346 return res ;
346347}
348+ #define EPOLL_MAXFDS 16
349+ static __always_inline int bpf_epoll_parse_fds (struct filler_data * data )
350+ {
351+ unsigned long ret = bpf_syscall_get_retval (data -> ctx );
352+ unsigned int size = ret * sizeof (struct epoll_event );
353+ if (size > SCRATCH_SIZE_MAX )
354+ return PPM_FAILURE_BUFFER_FULL ;
355+ struct epoll_event * events = (struct epoll_event * ) data -> tmp_scratch ;
356+ unsigned long val = bpf_syscall_get_argument (data , 1 );
357+
358+ #ifdef BPF_FORBIDS_ZERO_ACCESS
359+ if (size )
360+ if (bpf_probe_read (events ,
361+ ((size - 1 ) & SCRATCH_SIZE_MAX ) + 1 ,
362+ (void * )val ))
363+ #else
364+ if (bpf_probe_read (events , size & SCRATCH_SIZE_MAX , (void * )val ))
365+ #endif
366+ return PPM_FAILURE_INVALID_USER_MEMORY ;
367+
368+ if (data -> state -> tail_ctx .curoff > SCRATCH_SIZE_HALF )
369+ return PPM_FAILURE_BUFFER_FULL ;
370+ #if 1
371+ /*
372+ * SYSDIG -- generate code which satisfies kernel verifier on ARM
373+ * - Declare parameter as volatile to force re-evaluation
374+ */
375+ volatile unsigned long off ;
376+ #else /* SYSDIG */
377+ unsigned long off ;
378+ #endif /* SYSDIG */
379+
380+ int j ;
381+ off = data -> state -> tail_ctx .curoff + sizeof (u16 );
382+ unsigned int fds_count = 0 ;
383+
384+ #pragma unroll
385+ for (j = 0 ; j < EPOLL_MAXFDS ; ++ j ) {
386+ if (off > SCRATCH_SIZE_HALF )
387+ return PPM_FAILURE_BUFFER_FULL ;
388+
389+ if (j == ret )
390+ break ;
391+
392+ u16 flags = epoll_events_to_scap (events [j ].events );
393+ * (s64 * )& data -> buf [off & SCRATCH_SIZE_HALF ] = (int )events [j ].data ;
394+ off += sizeof (s64 );
395+ if (off > SCRATCH_SIZE_HALF )
396+ return PPM_FAILURE_BUFFER_FULL ;
397+
398+ * (s16 * )& data -> buf [off & SCRATCH_SIZE_HALF ] = flags ;
399+ * (s16 * )& data -> buf [off & SCRATCH_SIZE_HALF ] = 0 ;
400+ off += sizeof (s16 );
401+ ++ fds_count ;
402+ }
403+
404+ * ((u16 * )& data -> buf [data -> state -> tail_ctx .curoff & SCRATCH_SIZE_HALF ]) = fds_count ;
405+ data -> curarg_already_on_frame = true;
406+ return __bpf_val_to_ring (data , 0 , off - data -> state -> tail_ctx .curoff , PT_FDLIST , -1 , false);
407+ }
408+ FILLER (sys_epoll_wait_x , true)
409+ {
410+ long retval ;
411+ int res ;
412+
413+ /*
414+ * res
415+ */
416+ retval = bpf_syscall_get_retval (data -> ctx );
417+ res = bpf_val_to_ring_type (data , retval , PT_ERRNO );
418+ if (res != PPM_SUCCESS )
419+ return res ;
420+
421+ /*
422+ * fds
423+ */
424+ res = bpf_epoll_parse_fds (data );
347425
426+ return res ;
427+ }
348428#define POLL_MAXFDS 16
349429
350430static __always_inline int bpf_poll_parse_fds (struct filler_data * data ,
@@ -3833,7 +3913,7 @@ FILLER(sys_pagefault_e, false)
38333913 struct pt_regs * regs = (struct pt_regs * )ctx -> regs ;
38343914
38353915 address = ctx -> address ;
3836- ip = _READ (regs -> ip );
3916+ ip = _READ (PT_REGS_IP ( regs ) );
38373917 error_code = ctx -> error_code ;
38383918#else
38393919 address = ctx -> address ;
@@ -4672,7 +4752,7 @@ KP_FILLER(tcp_drop_kprobe_e)
46724752{
46734753
46744754 struct pt_regs * args = (struct pt_regs * )data -> ctx ;
4675- struct sock * sk = (struct sock * )_READ (args -> di );
4755+ struct sock * sk = (struct sock * )_READ (PT_REGS_PARAM1 ( args ) );
46764756
46774757 int res ;
46784758 res = sock_to_ring (data , sk );
@@ -4684,8 +4764,8 @@ KP_FILLER(tcp_drop_kprobe_e)
46844764KP_FILLER (rtt_kprobe_e )
46854765{
46864766 struct pt_regs * args = (struct pt_regs * )data -> ctx ;
4687- struct sock * sk = (struct sock * )_READ (args -> di );
4688- struct sk_buff * skb = (struct sk_buff * )_READ (args -> si );
4767+ struct sock * sk = (struct sock * )_READ (PT_REGS_PARAM1 ( args ) );
4768+ struct sk_buff * skb = (struct sk_buff * )_READ (PT_REGS_PARAM2 ( args ) );
46894769 struct tcp_sock * ts = tcp_sk (sk );
46904770
46914771 u32 srtt = _READ (ts -> srtt_us ) >> 3 ;
@@ -4704,7 +4784,7 @@ KP_FILLER(rtt_kprobe_e)
47044784KP_FILLER (tcp_retransmit_skb_kprobe_e )
47054785{
47064786 struct pt_regs * args = (struct pt_regs * )data -> ctx ;
4707- struct sock * sk = (struct sock * )_READ (args -> di );
4787+ struct sock * sk = (struct sock * )_READ (PT_REGS_PARAM1 ( args ) );
47084788
47094789 int res ;
47104790 res = sock_to_ring (data , sk );
@@ -4737,10 +4817,10 @@ KP_FILLER(tcp_connect_kprobe_x)
47374817KP_FILLER (tcp_set_state_kprobe_e )
47384818{
47394819 struct pt_regs * args = (struct pt_regs * )data -> ctx ;
4740- struct sock * sk = (struct sock * )_READ (args -> di );
4820+ struct sock * sk = (struct sock * )_READ (PT_REGS_PARAM1 ( args ) );
47414821 u8 old_state = 0 ;
47424822 bpf_probe_read (& old_state , sizeof (old_state ), (void * )& sk -> sk_state );
4743- int new_state = _READ (args -> si );
4823+ int new_state = _READ (PT_REGS_PARAM2 ( args ) );
47444824
47454825 int res ;
47464826 res = sock_to_ring (data , sk );
@@ -4791,8 +4871,8 @@ FILLER(net_dev_start_xmit_e, false)
47914871 struct sk_buff * skb ;
47924872 char dev_name [16 ] = {0 };
47934873#ifdef BPF_SUPPORTS_RAW_TRACEPOINTS
4794- skb = args -> skb ;
4795- bpf_probe_read ((void * )dev_name , 16 , args -> dev -> name );
4874+ skb = ctx -> skb ;
4875+ bpf_probe_read ((void * )dev_name , 16 , ctx -> dev -> name );
47964876#else
47974877 skb = (struct sk_buff * ) ctx -> skbaddr ;
47984878 TP_DATA_LOC_READ (dev_name , name , 16 );
@@ -4823,7 +4903,7 @@ FILLER(netif_receive_skb_e, false)
48234903 struct sk_buff * skb ;
48244904 char dev_name [16 ] = {0 };
48254905#ifdef BPF_SUPPORTS_RAW_TRACEPOINTS
4826- skb = args -> skb ;
4906+ skb = ctx -> skb ;
48274907 struct net_device * dev ;
48284908 dev = _READ (skb -> dev );
48294909 bpf_probe_read ((void * )dev_name , 16 , dev -> name );
@@ -4899,5 +4979,62 @@ FILLER(tcp_receive_reset_e, false)
48994979 return res ;
49004980 return 0 ;
49014981}
4982+ static __always_inline int __bpf_cpu_analysis (struct filler_data * data , u32 tid )
4983+ {
4984+ int res ;
4985+ struct info_t * infop = bpf_map_lookup_elem (& cpu_records , & tid );
4986+ if (infop == 0 )
4987+ return 0 ;
4988+
4989+ // {"start_ts", PT_ABSTIME, PF_DEC},
4990+ res = bpf_val_to_ring (data , infop -> start_ts );
4991+ // {"end_ts", PT_ABSTIME, PF_DEC},
4992+ res = bpf_val_to_ring (data , infop -> end_ts );
4993+ // {"cnt", PT_UINT32, PF_DEC},
4994+ res = bpf_val_to_ring (data , infop -> index );
4995+ // {"time_specs", PT_BYTEBUF, PF_NA},
4996+ int size = sizeof (infop -> times_specs );
4997+ memcpy (& data -> buf [(data -> state -> tail_ctx .curoff ) & SCRATCH_SIZE_HALF ], & infop -> times_specs , size );
4998+ data -> curarg_already_on_frame = true;
4999+ res = bpf_val_to_ring_len (data , 0 , size );
5000+ // {"runq_latency", PT_BYTEBUF, PF_NA},
5001+ size = sizeof (infop -> rq );
5002+ memcpy (& data -> buf [(data -> state -> tail_ctx .curoff ) & SCRATCH_SIZE_HALF ], & infop -> rq , size );
5003+ data -> curarg_already_on_frame = true;
5004+ res = bpf_val_to_ring_len (data , 0 , size );
5005+ // {"time_type", PT_BYTEBUF, PF_NA}}
5006+ size = sizeof (infop -> time_type );
5007+ memcpy (& data -> buf [(data -> state -> tail_ctx .curoff ) & SCRATCH_SIZE_HALF ], & infop -> time_type , size );
5008+ data -> curarg_already_on_frame = true;
5009+ res = bpf_val_to_ring_len (data , 0 , size );
5010+
5011+ return 0 ;
5012+ }
49025013
5014+ static __always_inline int bpf_cpu_analysis (void * ctx , u32 tid )
5015+ {
5016+ struct filler_data data ;
5017+ int res ;
5018+
5019+ res = init_filler_data (ctx , & data , false);
5020+ if (res == PPM_SUCCESS ) {
5021+ if (!data .state -> tail_ctx .len )
5022+ write_evt_hdr (& data );
5023+ res = __bpf_cpu_analysis (& data , tid );
5024+ }
5025+
5026+ if (res == PPM_SUCCESS )
5027+ res = push_evt_frame (ctx , & data );
5028+
5029+ if (data .state )
5030+ data .state -> tail_ctx .prev_res = res ;
5031+
5032+ bpf_kp_terminate_filler (& data );
5033+ return 0 ;
5034+ }
5035+
5036+ FILLER (cpu_analysis_e , false)
5037+ {
5038+ return 0 ;
5039+ }
49035040#endif
0 commit comments