@@ -226,16 +226,23 @@ enum {
226
226
BTF_KFUNC_SET_MAX_CNT = 256 ,
227
227
BTF_DTOR_KFUNC_MAX_CNT = 256 ,
228
228
BTF_KFUNC_FILTER_MAX_CNT = 16 ,
229
+ BTF_KFUNC_REMAP_MAX_CNT = 16 ,
229
230
};
230
231
231
232
struct btf_kfunc_hook_filter {
232
233
btf_kfunc_filter_t filters [BTF_KFUNC_FILTER_MAX_CNT ];
233
234
u32 nr_filters ;
234
235
};
235
236
237
+ struct btf_kfunc_hook_remap {
238
+ btf_kfunc_remap_t remaps [BTF_KFUNC_REMAP_MAX_CNT ];
239
+ u32 nr_remaps ;
240
+ };
241
+
236
242
struct btf_kfunc_set_tab {
237
243
struct btf_id_set8 * sets [BTF_KFUNC_HOOK_MAX ];
238
244
struct btf_kfunc_hook_filter hook_filters [BTF_KFUNC_HOOK_MAX ];
245
+ struct btf_kfunc_hook_remap hook_remaps [BTF_KFUNC_HOOK_MAX ];
239
246
};
240
247
241
248
struct btf_id_dtor_kfunc_tab {
@@ -8372,31 +8379,52 @@ static int btf_check_kfunc_protos(struct btf *btf, u32 func_id, u32 func_flags)
8372
8379
8373
8380
/* Kernel Function (kfunc) BTF ID set registration API */
8374
8381
8382
+ static void btf_add_kfunc_to_set (struct btf * btf , struct btf_id_set8 * set ,
8383
+ struct btf_id_set8 * add_set )
8384
+ {
8385
+ u32 i ;
8386
+
8387
+ if (!add_set )
8388
+ return ;
8389
+ /* Concatenate the two sets */
8390
+ memcpy (set -> pairs + set -> cnt , add_set -> pairs , add_set -> cnt * sizeof (set -> pairs [0 ]));
8391
+ /* Now that the set is copied, update with relocated BTF ids */
8392
+ for (i = set -> cnt ; i < set -> cnt + add_set -> cnt ; i ++ )
8393
+ set -> pairs [i ].id = btf_relocate_id (btf , set -> pairs [i ].id );
8394
+
8395
+ set -> cnt += add_set -> cnt ;
8396
+
8397
+ sort (set -> pairs , set -> cnt , sizeof (set -> pairs [0 ]), btf_id_cmp_func , NULL );
8398
+ }
8399
+
8375
8400
static int btf_populate_kfunc_set (struct btf * btf , enum btf_kfunc_hook hook ,
8376
8401
const struct btf_kfunc_id_set * kset )
8377
8402
{
8378
8403
struct btf_kfunc_hook_filter * hook_filter ;
8379
- struct btf_id_set8 * add_set = kset -> set ;
8404
+ struct btf_kfunc_hook_remap * hook_remap ;
8380
8405
bool vmlinux_set = !btf_is_module (btf );
8381
8406
bool add_filter = !!kset -> filter ;
8407
+ bool add_remap = !!kset -> remap ;
8382
8408
struct btf_kfunc_set_tab * tab ;
8383
8409
struct btf_id_set8 * set ;
8384
- u32 set_cnt , i ;
8410
+ u32 set_cnt , add_cnt , i ;
8385
8411
int ret ;
8386
8412
8387
8413
if (hook >= BTF_KFUNC_HOOK_MAX ) {
8388
8414
ret = - EINVAL ;
8389
8415
goto end ;
8390
8416
}
8391
8417
8392
- if (!add_set -> cnt )
8418
+ add_cnt = kset -> set -> cnt ;
8419
+ if (kset -> hidden_set )
8420
+ add_cnt += kset -> hidden_set -> cnt ;
8421
+
8422
+ if (!add_cnt )
8393
8423
return 0 ;
8394
8424
8395
8425
tab = btf -> kfunc_set_tab ;
8396
8426
8397
8427
if (tab && add_filter ) {
8398
- u32 i ;
8399
-
8400
8428
hook_filter = & tab -> hook_filters [hook ];
8401
8429
for (i = 0 ; i < hook_filter -> nr_filters ; i ++ ) {
8402
8430
if (hook_filter -> filters [i ] == kset -> filter ) {
@@ -8411,6 +8439,21 @@ static int btf_populate_kfunc_set(struct btf *btf, enum btf_kfunc_hook hook,
8411
8439
}
8412
8440
}
8413
8441
8442
+ if (tab && add_remap ) {
8443
+ hook_remap = & tab -> hook_remaps [hook ];
8444
+ for (i = 0 ; i < hook_remap -> nr_remaps ; i ++ ) {
8445
+ if (hook_remap -> remaps [i ] == kset -> remap ) {
8446
+ add_remap = false;
8447
+ break ;
8448
+ }
8449
+ }
8450
+
8451
+ if (add_remap && hook_remap -> nr_remaps == BTF_KFUNC_REMAP_MAX_CNT ) {
8452
+ ret = - E2BIG ;
8453
+ goto end ;
8454
+ }
8455
+ }
8456
+
8414
8457
if (!tab ) {
8415
8458
tab = kzalloc (sizeof (* tab ), GFP_KERNEL | __GFP_NOWARN );
8416
8459
if (!tab )
@@ -8439,19 +8482,19 @@ static int btf_populate_kfunc_set(struct btf *btf, enum btf_kfunc_hook hook,
8439
8482
*/
8440
8483
set_cnt = set ? set -> cnt : 0 ;
8441
8484
8442
- if (set_cnt > U32_MAX - add_set -> cnt ) {
8485
+ if (set_cnt > U32_MAX - add_cnt ) {
8443
8486
ret = - EOVERFLOW ;
8444
8487
goto end ;
8445
8488
}
8446
8489
8447
- if (set_cnt + add_set -> cnt > BTF_KFUNC_SET_MAX_CNT ) {
8490
+ if (set_cnt + add_cnt > BTF_KFUNC_SET_MAX_CNT ) {
8448
8491
ret = - E2BIG ;
8449
8492
goto end ;
8450
8493
}
8451
8494
8452
8495
/* Grow set */
8453
8496
set = krealloc (tab -> sets [hook ],
8454
- offsetof(struct btf_id_set8 , pairs [set_cnt + add_set -> cnt ]),
8497
+ offsetof(struct btf_id_set8 , pairs [set_cnt + add_cnt ]),
8455
8498
GFP_KERNEL | __GFP_NOWARN );
8456
8499
if (!set ) {
8457
8500
ret = - ENOMEM ;
@@ -8463,20 +8506,18 @@ static int btf_populate_kfunc_set(struct btf *btf, enum btf_kfunc_hook hook,
8463
8506
set -> cnt = 0 ;
8464
8507
tab -> sets [hook ] = set ;
8465
8508
8466
- /* Concatenate the two sets */
8467
- memcpy (set -> pairs + set -> cnt , add_set -> pairs , add_set -> cnt * sizeof (set -> pairs [0 ]));
8468
- /* Now that the set is copied, update with relocated BTF ids */
8469
- for (i = set -> cnt ; i < set -> cnt + add_set -> cnt ; i ++ )
8470
- set -> pairs [i ].id = btf_relocate_id (btf , set -> pairs [i ].id );
8471
-
8472
- set -> cnt += add_set -> cnt ;
8473
-
8474
- sort (set -> pairs , set -> cnt , sizeof (set -> pairs [0 ]), btf_id_cmp_func , NULL );
8509
+ btf_add_kfunc_to_set (btf , set , kset -> set );
8510
+ btf_add_kfunc_to_set (btf , set , kset -> hidden_set );
8475
8511
8476
8512
if (add_filter ) {
8477
8513
hook_filter = & tab -> hook_filters [hook ];
8478
8514
hook_filter -> filters [hook_filter -> nr_filters ++ ] = kset -> filter ;
8479
8515
}
8516
+
8517
+ if (add_remap ) {
8518
+ hook_remap = & tab -> hook_remaps [hook ];
8519
+ hook_remap -> remaps [hook_remap -> nr_remaps ++ ] = kset -> remap ;
8520
+ }
8480
8521
return 0 ;
8481
8522
end :
8482
8523
btf_free_kfunc_set_tab (btf );
@@ -8511,6 +8552,28 @@ static u32 *__btf_kfunc_id_set_contains(const struct btf *btf,
8511
8552
return id + 1 ;
8512
8553
}
8513
8554
8555
+ static u32 __btf_kfunc_id_remap (const struct btf * btf ,
8556
+ enum btf_kfunc_hook hook ,
8557
+ u32 kfunc_btf_id ,
8558
+ const struct bpf_prog * prog )
8559
+ {
8560
+ struct btf_kfunc_hook_remap * hook_remap ;
8561
+ u32 i , remap_id = 0 ;
8562
+
8563
+ if (hook >= BTF_KFUNC_HOOK_MAX )
8564
+ return 0 ;
8565
+ if (!btf -> kfunc_set_tab )
8566
+ return 0 ;
8567
+ hook_remap = & btf -> kfunc_set_tab -> hook_remaps [hook ];
8568
+
8569
+ for (i = 0 ; i < hook_remap -> nr_remaps ; i ++ ) {
8570
+ remap_id = hook_remap -> remaps [i ](prog , kfunc_btf_id );
8571
+ if (remap_id )
8572
+ break ;
8573
+ }
8574
+ return remap_id ;
8575
+ }
8576
+
8514
8577
static int bpf_prog_type_to_kfunc_hook (enum bpf_prog_type prog_type )
8515
8578
{
8516
8579
switch (prog_type ) {
@@ -8579,6 +8642,26 @@ u32 *btf_kfunc_id_set_contains(const struct btf *btf,
8579
8642
return __btf_kfunc_id_set_contains (btf , hook , kfunc_btf_id , prog );
8580
8643
}
8581
8644
8645
+ /* Reference to the module (obtained using btf_try_get_module)
8646
+ * corresponding to the struct btf *MUST* be held when calling this
8647
+ * function from the verifier
8648
+ */
8649
+ u32 btf_kfunc_id_remap (const struct btf * btf , u32 kfunc_btf_id ,
8650
+ const struct bpf_prog * prog )
8651
+ {
8652
+ enum bpf_prog_type prog_type = resolve_prog_type (prog );
8653
+ enum btf_kfunc_hook hook ;
8654
+ u32 remap_id ;
8655
+
8656
+ remap_id = __btf_kfunc_id_remap (btf , BTF_KFUNC_HOOK_COMMON , kfunc_btf_id , prog );
8657
+ if (remap_id )
8658
+ return remap_id ;
8659
+
8660
+ hook = bpf_prog_type_to_kfunc_hook (prog_type );
8661
+ remap_id = __btf_kfunc_id_remap (btf , hook , kfunc_btf_id , prog );
8662
+ return remap_id ?: kfunc_btf_id ;
8663
+ }
8664
+
8582
8665
u32 * btf_kfunc_is_modify_return (const struct btf * btf , u32 kfunc_btf_id ,
8583
8666
const struct bpf_prog * prog )
8584
8667
{
0 commit comments