@@ -1581,6 +1581,17 @@ static inline bool is_kprobe_session(const struct bpf_prog *prog)
1581
1581
return prog -> expected_attach_type == BPF_TRACE_KPROBE_SESSION ;
1582
1582
}
1583
1583
1584
+ static inline bool is_uprobe_multi (const struct bpf_prog * prog )
1585
+ {
1586
+ return prog -> expected_attach_type == BPF_TRACE_UPROBE_MULTI ||
1587
+ prog -> expected_attach_type == BPF_TRACE_UPROBE_SESSION ;
1588
+ }
1589
+
1590
+ static inline bool is_uprobe_session (const struct bpf_prog * prog )
1591
+ {
1592
+ return prog -> expected_attach_type == BPF_TRACE_UPROBE_SESSION ;
1593
+ }
1594
+
1584
1595
static const struct bpf_func_proto *
1585
1596
kprobe_prog_func_proto (enum bpf_func_id func_id , const struct bpf_prog * prog )
1586
1597
{
@@ -1598,13 +1609,13 @@ kprobe_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
1598
1609
case BPF_FUNC_get_func_ip :
1599
1610
if (is_kprobe_multi (prog ))
1600
1611
return & bpf_get_func_ip_proto_kprobe_multi ;
1601
- if (prog -> expected_attach_type == BPF_TRACE_UPROBE_MULTI )
1612
+ if (is_uprobe_multi ( prog ) )
1602
1613
return & bpf_get_func_ip_proto_uprobe_multi ;
1603
1614
return & bpf_get_func_ip_proto_kprobe ;
1604
1615
case BPF_FUNC_get_attach_cookie :
1605
1616
if (is_kprobe_multi (prog ))
1606
1617
return & bpf_get_attach_cookie_proto_kmulti ;
1607
- if (prog -> expected_attach_type == BPF_TRACE_UPROBE_MULTI )
1618
+ if (is_uprobe_multi ( prog ) )
1608
1619
return & bpf_get_attach_cookie_proto_umulti ;
1609
1620
return & bpf_get_attach_cookie_proto_trace ;
1610
1621
default :
@@ -3096,6 +3107,7 @@ struct bpf_uprobe {
3096
3107
u64 cookie ;
3097
3108
struct uprobe * uprobe ;
3098
3109
struct uprobe_consumer consumer ;
3110
+ bool session ;
3099
3111
};
3100
3112
3101
3113
struct bpf_uprobe_multi_link {
@@ -3108,7 +3120,7 @@ struct bpf_uprobe_multi_link {
3108
3120
};
3109
3121
3110
3122
struct bpf_uprobe_multi_run_ctx {
3111
- struct bpf_run_ctx run_ctx ;
3123
+ struct bpf_session_run_ctx session_ctx ;
3112
3124
unsigned long entry_ip ;
3113
3125
struct bpf_uprobe * uprobe ;
3114
3126
};
@@ -3219,17 +3231,22 @@ static const struct bpf_link_ops bpf_uprobe_multi_link_lops = {
3219
3231
3220
3232
static int uprobe_prog_run (struct bpf_uprobe * uprobe ,
3221
3233
unsigned long entry_ip ,
3222
- struct pt_regs * regs )
3234
+ struct pt_regs * regs ,
3235
+ bool is_return , void * data )
3223
3236
{
3224
3237
struct bpf_uprobe_multi_link * link = uprobe -> link ;
3225
3238
struct bpf_uprobe_multi_run_ctx run_ctx = {
3239
+ .session_ctx = {
3240
+ .is_return = is_return ,
3241
+ .data = data ,
3242
+ },
3226
3243
.entry_ip = entry_ip ,
3227
3244
.uprobe = uprobe ,
3228
3245
};
3229
3246
struct bpf_prog * prog = link -> link .prog ;
3230
3247
bool sleepable = prog -> sleepable ;
3231
3248
struct bpf_run_ctx * old_run_ctx ;
3232
- int err = 0 ;
3249
+ int err ;
3233
3250
3234
3251
if (link -> task && !same_thread_group (current , link -> task ))
3235
3252
return 0 ;
@@ -3241,7 +3258,7 @@ static int uprobe_prog_run(struct bpf_uprobe *uprobe,
3241
3258
3242
3259
migrate_disable ();
3243
3260
3244
- old_run_ctx = bpf_set_run_ctx (& run_ctx .run_ctx );
3261
+ old_run_ctx = bpf_set_run_ctx (& run_ctx .session_ctx . run_ctx );
3245
3262
err = bpf_prog_run (link -> link .prog , regs );
3246
3263
bpf_reset_run_ctx (old_run_ctx );
3247
3264
@@ -3268,9 +3285,13 @@ uprobe_multi_link_handler(struct uprobe_consumer *con, struct pt_regs *regs,
3268
3285
__u64 * data )
3269
3286
{
3270
3287
struct bpf_uprobe * uprobe ;
3288
+ int ret ;
3271
3289
3272
3290
uprobe = container_of (con , struct bpf_uprobe , consumer );
3273
- return uprobe_prog_run (uprobe , instruction_pointer (regs ), regs );
3291
+ ret = uprobe_prog_run (uprobe , instruction_pointer (regs ), regs , false, data );
3292
+ if (uprobe -> session )
3293
+ return ret ? UPROBE_HANDLER_IGNORE : 0 ;
3294
+ return 0 ;
3274
3295
}
3275
3296
3276
3297
static int
@@ -3280,22 +3301,25 @@ uprobe_multi_link_ret_handler(struct uprobe_consumer *con, unsigned long func, s
3280
3301
struct bpf_uprobe * uprobe ;
3281
3302
3282
3303
uprobe = container_of (con , struct bpf_uprobe , consumer );
3283
- return uprobe_prog_run (uprobe , func , regs );
3304
+ uprobe_prog_run (uprobe , func , regs , true, data );
3305
+ return 0 ;
3284
3306
}
3285
3307
3286
3308
static u64 bpf_uprobe_multi_entry_ip (struct bpf_run_ctx * ctx )
3287
3309
{
3288
3310
struct bpf_uprobe_multi_run_ctx * run_ctx ;
3289
3311
3290
- run_ctx = container_of (current -> bpf_ctx , struct bpf_uprobe_multi_run_ctx , run_ctx );
3312
+ run_ctx = container_of (current -> bpf_ctx , struct bpf_uprobe_multi_run_ctx ,
3313
+ session_ctx .run_ctx );
3291
3314
return run_ctx -> entry_ip ;
3292
3315
}
3293
3316
3294
3317
static u64 bpf_uprobe_multi_cookie (struct bpf_run_ctx * ctx )
3295
3318
{
3296
3319
struct bpf_uprobe_multi_run_ctx * run_ctx ;
3297
3320
3298
- run_ctx = container_of (current -> bpf_ctx , struct bpf_uprobe_multi_run_ctx , run_ctx );
3321
+ run_ctx = container_of (current -> bpf_ctx , struct bpf_uprobe_multi_run_ctx ,
3322
+ session_ctx .run_ctx );
3299
3323
return run_ctx -> uprobe -> cookie ;
3300
3324
}
3301
3325
@@ -3319,7 +3343,7 @@ int bpf_uprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr
3319
3343
if (sizeof (u64 ) != sizeof (void * ))
3320
3344
return - EOPNOTSUPP ;
3321
3345
3322
- if (prog -> expected_attach_type != BPF_TRACE_UPROBE_MULTI )
3346
+ if (! is_uprobe_multi ( prog ) )
3323
3347
return - EINVAL ;
3324
3348
3325
3349
flags = attr -> link_create .uprobe_multi .flags ;
@@ -3395,11 +3419,12 @@ int bpf_uprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr
3395
3419
3396
3420
uprobes [i ].link = link ;
3397
3421
3398
- if (flags & BPF_F_UPROBE_MULTI_RETURN )
3399
- uprobes [i ].consumer .ret_handler = uprobe_multi_link_ret_handler ;
3400
- else
3422
+ if (!(flags & BPF_F_UPROBE_MULTI_RETURN ))
3401
3423
uprobes [i ].consumer .handler = uprobe_multi_link_handler ;
3402
-
3424
+ if (flags & BPF_F_UPROBE_MULTI_RETURN || is_uprobe_session (prog ))
3425
+ uprobes [i ].consumer .ret_handler = uprobe_multi_link_ret_handler ;
3426
+ if (is_uprobe_session (prog ))
3427
+ uprobes [i ].session = true;
3403
3428
if (pid )
3404
3429
uprobes [i ].consumer .filter = uprobe_multi_link_filter ;
3405
3430
}
@@ -3488,7 +3513,7 @@ static int bpf_kprobe_multi_filter(const struct bpf_prog *prog, u32 kfunc_id)
3488
3513
if (!btf_id_set8_contains (& kprobe_multi_kfunc_set_ids , kfunc_id ))
3489
3514
return 0 ;
3490
3515
3491
- if (!is_kprobe_session (prog ))
3516
+ if (!is_kprobe_session (prog ) && ! is_uprobe_session ( prog ) )
3492
3517
return - EACCES ;
3493
3518
3494
3519
return 0 ;
0 commit comments