Skip to content

Commit ce698c3

Browse files
committed
tetragon: Wire extra process event tail call
Split generic_[ku]probe_process_event into two separate tail calls so we have space (there's 4096 instructions limit on 4.19 kernels) for new features in processing event code. Before: generic_kprobe_process_event 4029 insns generic_uprobe_process_event 4029 insns Now: generic_uprobe_process_event 2795 insns generic_uprobe_process_event_2 3147 insns generic_kprobe_process_event 2795 insns generic_kprobe_process_event_2 3147 insns Signed-off-by: Jiri Olsa <[email protected]>
1 parent fe2c768 commit ce698c3

File tree

11 files changed

+107
-27
lines changed

11 files changed

+107
-27
lines changed

bpf/include/api.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,4 +323,10 @@ static int BPF_FUNC(seq_write, struct seq_file *m, const void *data, uint32_t le
323323
# define lock_and(ptr, val) (*(ptr) &= val)
324324
#endif
325325

326+
enum {
327+
__READ_ARG_1,
328+
__READ_ARG_2,
329+
__READ_ARG_ALL,
330+
};
331+
326332
#endif /* __BPF_API__ */

bpf/process/bpf_generic_kprobe.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ char _license[] __attribute__((section("license"), used)) = "Dual BSD/GPL";
1818

1919
int generic_kprobe_setup_event(void *ctx);
2020
int generic_kprobe_process_event(void *ctx);
21+
int generic_kprobe_process_event_2(void *ctx);
2122
int generic_kprobe_process_filter(void *ctx);
2223
int generic_kprobe_filter_arg(void *ctx);
2324
int generic_kprobe_actions(void *ctx);
@@ -39,6 +40,9 @@ struct {
3940
[TAIL_CALL_SEND] = (void *)&generic_kprobe_output,
4041
#ifndef __V61_BPF_PROG
4142
[TAIL_CALL_PATH] = (void *)&generic_kprobe_path,
43+
#endif
44+
#ifndef __LARGE_BPF_PROG
45+
[TAIL_CALL_PROCESS_2] = (void *)&generic_kprobe_process_event_2,
4246
#endif
4347
},
4448
};
@@ -91,12 +95,26 @@ generic_kprobe_setup_event(void *ctx)
9195
return generic_process_event_and_setup(ctx, (struct bpf_map_def *)&kprobe_calls);
9296
}
9397

98+
#ifdef __LARGE_BPF_PROG
99+
__attribute__((section(COMMON), used)) int
100+
generic_kprobe_process_event(void *ctx)
101+
{
102+
return generic_process_event(ctx, (struct bpf_map_def *)&kprobe_calls, __READ_ARG_ALL);
103+
}
104+
#else
94105
__attribute__((section(COMMON), used)) int
95106
generic_kprobe_process_event(void *ctx)
96107
{
97-
return generic_process_event(ctx, (struct bpf_map_def *)&kprobe_calls);
108+
return generic_process_event(ctx, (struct bpf_map_def *)&kprobe_calls, __READ_ARG_1);
98109
}
99110

111+
__attribute__((section(COMMON), used)) int
112+
generic_kprobe_process_event_2(void *ctx)
113+
{
114+
return generic_process_event(ctx, (struct bpf_map_def *)&kprobe_calls, __READ_ARG_2);
115+
}
116+
#endif
117+
100118
__attribute__((section(COMMON), used)) int
101119
generic_kprobe_process_filter(void *ctx)
102120
{

bpf/process/bpf_generic_lsm_core.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ generic_lsm_setup_event(void *ctx)
6363
__attribute__((section("lsm"), used)) int
6464
generic_lsm_process_event(void *ctx)
6565
{
66-
return generic_process_event(ctx, (struct bpf_map_def *)&lsm_calls);
66+
return generic_process_event(ctx, (struct bpf_map_def *)&lsm_calls, __READ_ARG_ALL);
6767
}
6868

6969
__attribute__((section("lsm"), used)) int

bpf/process/bpf_generic_rawtp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ generic_rawtp_setup_event(void *ctx)
8484
__attribute__((section("raw_tp"), used)) int
8585
generic_rawtp_process_event(void *ctx)
8686
{
87-
return generic_process_event(ctx, (struct bpf_map_def *)&tp_calls);
87+
return generic_process_event(ctx, (struct bpf_map_def *)&tp_calls, __READ_ARG_ALL);
8888
}
8989

9090
__attribute__((section("raw_tp"), used)) int

bpf/process/bpf_generic_tracepoint.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ generic_tracepoint_event(struct generic_tracepoint_event_arg *ctx)
263263
__attribute__((section("tracepoint"), used)) int
264264
generic_tracepoint_process_event(void *ctx)
265265
{
266-
return generic_process_event(ctx, (struct bpf_map_def *)&tp_calls);
266+
return generic_process_event(ctx, (struct bpf_map_def *)&tp_calls, __READ_ARG_ALL);
267267
}
268268

269269
__attribute__((section("tracepoint"), used)) int

bpf/process/bpf_generic_uprobe.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ char _license[] __attribute__((section("license"), used)) = "Dual BSD/GPL";
1818

1919
int generic_uprobe_setup_event(void *ctx);
2020
int generic_uprobe_process_event(void *ctx);
21+
int generic_uprobe_process_event_2(void *ctx);
2122
int generic_uprobe_process_filter(void *ctx);
2223
int generic_uprobe_filter_arg(void *ctx);
2324
int generic_uprobe_actions(void *ctx);
@@ -39,6 +40,9 @@ struct {
3940
[TAIL_CALL_SEND] = (void *)&generic_uprobe_output,
4041
#ifndef __V61_BPF_PROG
4142
[TAIL_CALL_PATH] = (void *)&generic_uprobe_path,
43+
#endif
44+
#ifndef __LARGE_BPF_PROG
45+
[TAIL_CALL_PROCESS_2] = (void *)&generic_uprobe_process_event_2,
4246
#endif
4347
},
4448
};
@@ -68,12 +72,26 @@ generic_uprobe_setup_event(void *ctx)
6872
return generic_process_event_and_setup(ctx, (struct bpf_map_def *)&uprobe_calls);
6973
}
7074

75+
#ifdef __LARGE_BPF_PROG
76+
__attribute__((section(COMMON), used)) int
77+
generic_uprobe_process_event(void *ctx)
78+
{
79+
return generic_process_event(ctx, (struct bpf_map_def *)&uprobe_calls, __READ_ARG_ALL);
80+
}
81+
#else
7182
__attribute__((section(COMMON), used)) int
7283
generic_uprobe_process_event(void *ctx)
7384
{
74-
return generic_process_event(ctx, (struct bpf_map_def *)&uprobe_calls);
85+
return generic_process_event(ctx, (struct bpf_map_def *)&uprobe_calls, __READ_ARG_1);
7586
}
7687

88+
__attribute__((section(COMMON), used)) int
89+
generic_uprobe_process_event_2(void *ctx)
90+
{
91+
return generic_process_event(ctx, (struct bpf_map_def *)&uprobe_calls, __READ_ARG_2);
92+
}
93+
#endif
94+
7795
__attribute__((section(COMMON), used)) int
7896
generic_uprobe_process_filter(void *ctx)
7997
{

bpf/process/bpf_generic_usdt.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ generic_usdt_setup_event(void *ctx)
7272
__attribute__((section(COMMON), used)) int
7373
generic_usdt_process_event(void *ctx)
7474
{
75-
return generic_process_event(ctx, (struct bpf_map_def *)&usdt_calls);
75+
return generic_process_event(ctx, (struct bpf_map_def *)&usdt_calls, __READ_ARG_ALL);
7676
}
7777

7878
__attribute__((section(COMMON), used)) int

bpf/process/generic_calls.h

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ __read_arg_2(void *ctx, int type, long orig_off, unsigned long arg, int argm, ch
423423
* Returns the size of data appended to @args.
424424
*/
425425
FUNC_INLINE long
426-
read_arg(void *ctx, int index, int type, long orig_off, unsigned long arg, int argm)
426+
read_arg(void *ctx, int index, int type, long orig_off, unsigned long arg, int argm, int process)
427427
{
428428
size_t min_size = type_to_min_size(type, argm);
429429
struct msg_generic_kprobe *e;
@@ -449,6 +449,16 @@ read_arg(void *ctx, int index, int type, long orig_off, unsigned long arg, int a
449449
if (path_arg)
450450
return copy_path(args, path_arg);
451451

452+
/*
453+
* Separate argument processing based on the process const
454+
* for 4.19 kernels..
455+
*/
456+
if (process == __READ_ARG_1)
457+
return __read_arg_1(ctx, type, orig_off, arg, argm, args);
458+
if (process == __READ_ARG_2)
459+
return __read_arg_2(ctx, type, orig_off, arg, argm, args);
460+
461+
/* .. and the rest of the world */
452462
if (is_read_arg_1(type))
453463
return __read_arg_1(ctx, type, orig_off, arg, argm, args);
454464
else
@@ -558,7 +568,8 @@ FUNC_INLINE long get_pt_regs_arg(struct pt_regs *ctx, struct event_config *confi
558568
}
559569
#endif /* __TARGET_ARCH_x86 && (GENERIC_KPROBE || GENERIC_UPROBE) */
560570

561-
FUNC_INLINE long generic_read_arg(void *ctx, int index, long off, struct bpf_map_def *tailcals)
571+
FUNC_INLINE long generic_read_arg(void *ctx, int index, long off, struct bpf_map_def *tailcals,
572+
int process)
562573
{
563574
struct msg_generic_kprobe *e;
564575
struct event_config *config;
@@ -580,6 +591,13 @@ FUNC_INLINE long generic_read_arg(void *ctx, int index, long off, struct bpf_map
580591
ty = config->arg[index];
581592
am = config->arm[index];
582593

594+
#ifndef __LARGE_BPF_PROG
595+
#if defined(GENERIC_KPROBE) || defined(GENERIC_UPROBE)
596+
if (!is_read_arg_1(ty) && process == __READ_ARG_1)
597+
tail_call(ctx, tailcals, TAIL_CALL_PROCESS_2);
598+
#endif
599+
#endif
600+
583601
#if defined(GENERIC_TRACEPOINT) || defined(GENERIC_USDT)
584602
a = (&e->a0)[index];
585603
extract_arg(config, index, &a);
@@ -609,11 +627,11 @@ FUNC_INLINE long generic_read_arg(void *ctx, int index, long off, struct bpf_map
609627
return generic_path_offload(ctx, ty, a, index, off, tailcals);
610628
#endif
611629

612-
return read_arg(ctx, index, ty, off, a, am);
630+
return read_arg(ctx, index, ty, off, a, am, process);
613631
}
614632

615633
FUNC_INLINE int
616-
generic_process_event(void *ctx, struct bpf_map_def *tailcals)
634+
generic_process_event(void *ctx, struct bpf_map_def *tailcals, int process)
617635
{
618636
struct msg_generic_kprobe *e;
619637
int index, zero = 0;
@@ -630,7 +648,7 @@ generic_process_event(void *ctx, struct bpf_map_def *tailcals)
630648
if (total < MAX_TOTAL) {
631649
long errv;
632650

633-
errv = generic_read_arg(ctx, index, total, tailcals);
651+
errv = generic_read_arg(ctx, index, total, tailcals, process);
634652
if (errv > 0)
635653
total += errv;
636654
/* Follow filter lookup failed so lets abort the event.
@@ -1271,7 +1289,7 @@ FUNC_INLINE int generic_retprobe(void *ctx, struct bpf_map_def *calls, unsigned
12711289
ty_arg = config->argreturn;
12721290
do_copy = config->argreturncopy;
12731291
if (ty_arg) {
1274-
size += read_arg(ctx, 0, ty_arg, size, ret, 0);
1292+
size += read_arg(ctx, 0, ty_arg, size, ret, 0, __READ_ARG_ALL);
12751293
#if defined(__LARGE_BPF_PROG) && defined(GENERIC_KRETPROBE)
12761294
struct socket_owner owner;
12771295

bpf/process/types/basic.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ enum {
138138
TAIL_CALL_ACTIONS = 4,
139139
TAIL_CALL_SEND = 5,
140140
TAIL_CALL_PATH = 6,
141+
TAIL_CALL_PROCESS_2 = 7,
141142
};
142143

143144
struct selector_action {

pkg/sensors/tracing/kprobe_test.go

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4424,12 +4424,6 @@ func TestLoadKprobeSensor(t *testing.T) {
44244424
}
44254425

44264426
sensorMaps = []tus.SensorMap{
4427-
// all kprobe programs
4428-
{Name: "process_call_heap", Progs: []uint{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}},
4429-
4430-
// all but generic_kprobe_output
4431-
{Name: "kprobe_calls", Progs: []uint{0, 1, 2, 3, 4, 5, 7}},
4432-
44334427
// generic_retkprobe_event
44344428
{Name: "retkprobe_calls", Progs: []uint{8, 9, 10}},
44354429

@@ -4440,14 +4434,20 @@ func TestLoadKprobeSensor(t *testing.T) {
44404434
// generic_kprobe_actions
44414435
{Name: "override_tasks", Progs: []uint{5}},
44424436

4443-
// all kprobe but generic_kprobe_process_filter,generic_retkprobe_event
4444-
{Name: "config_map", Progs: []uint{0, 1, 2}},
4445-
44464437
// generic_kprobe_process_event*,generic_kprobe_actions,retkprobe
44474438
{Name: "fdinstall_map", Progs: []uint{2, 5, 8, 10}},
44484439
}
44494440

44504441
if config.EnableLargeProgs() {
4442+
// all kprobe programs
4443+
sensorMaps = append(sensorMaps, tus.SensorMap{Name: "process_call_heap", Progs: []uint{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}})
4444+
4445+
// all but generic_kprobe_output
4446+
sensorMaps = append(sensorMaps, tus.SensorMap{Name: "kprobe_calls", Progs: []uint{0, 1, 2, 3, 4, 5, 7}})
4447+
4448+
// all kprobe but generic_kprobe_process_filter,generic_retkprobe_event
4449+
sensorMaps = append(sensorMaps, tus.SensorMap{Name: "config_map", Progs: []uint{0, 1, 2}})
4450+
44514451
// shared with base sensor
44524452
sensorMaps = append(sensorMaps, tus.SensorMap{Name: "execve_map", Progs: []uint{4, 5, 6, 8, 10}})
44534453

@@ -4468,6 +4468,17 @@ func TestLoadKprobeSensor(t *testing.T) {
44684468
sensorMaps = append(sensorMaps, tus.SensorMap{Name: "tg_conf_map", Progs: []uint{0}})
44694469
}
44704470
} else {
4471+
sensorProgs = append(sensorProgs, tus.SensorProg{Name: "generic_kprobe_process_event_2", Type: ebpf.Kprobe})
4472+
4473+
// all kprobe programs
4474+
sensorMaps = append(sensorMaps, tus.SensorMap{Name: "process_call_heap", Progs: []uint{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}})
4475+
4476+
// all but generic_kprobe_output
4477+
sensorMaps = append(sensorMaps, tus.SensorMap{Name: "kprobe_calls", Progs: []uint{0, 1, 2, 3, 4, 5, 7, 12}})
4478+
4479+
// all kprobe but generic_kprobe_process_filter,generic_retkprobe_event
4480+
sensorMaps = append(sensorMaps, tus.SensorMap{Name: "config_map", Progs: []uint{0, 1, 2, 12}})
4481+
44714482
// shared with base sensor
44724483
sensorMaps = append(sensorMaps, tus.SensorMap{Name: "execve_map", Progs: []uint{4, 8}})
44734484

0 commit comments

Comments
 (0)