@@ -2198,7 +2198,8 @@ static void restore_regs(const struct btf_func_model *m, u8 **prog,
2198
2198
2199
2199
static int invoke_bpf_prog (const struct btf_func_model * m , u8 * * pprog ,
2200
2200
struct bpf_tramp_link * l , int stack_size ,
2201
- int run_ctx_off , bool save_ret )
2201
+ int run_ctx_off , bool save_ret ,
2202
+ void * image , void * rw_image )
2202
2203
{
2203
2204
u8 * prog = * pprog ;
2204
2205
u8 * jmp_insn ;
@@ -2226,7 +2227,7 @@ static int invoke_bpf_prog(const struct btf_func_model *m, u8 **pprog,
2226
2227
else
2227
2228
EMIT4 (0x48 , 0x8D , 0x75 , - run_ctx_off );
2228
2229
2229
- if (emit_rsb_call (& prog , bpf_trampoline_enter (p ), prog ))
2230
+ if (emit_rsb_call (& prog , bpf_trampoline_enter (p ), image + ( prog - ( u8 * ) rw_image ) ))
2230
2231
return - EINVAL ;
2231
2232
/* remember prog start time returned by __bpf_prog_enter */
2232
2233
emit_mov_reg (& prog , true, BPF_REG_6 , BPF_REG_0 );
@@ -2250,7 +2251,7 @@ static int invoke_bpf_prog(const struct btf_func_model *m, u8 **pprog,
2250
2251
(long ) p -> insnsi >> 32 ,
2251
2252
(u32 ) (long ) p -> insnsi );
2252
2253
/* call JITed bpf program or interpreter */
2253
- if (emit_rsb_call (& prog , p -> bpf_func , prog ))
2254
+ if (emit_rsb_call (& prog , p -> bpf_func , image + ( prog - ( u8 * ) rw_image ) ))
2254
2255
return - EINVAL ;
2255
2256
2256
2257
/*
@@ -2277,7 +2278,7 @@ static int invoke_bpf_prog(const struct btf_func_model *m, u8 **pprog,
2277
2278
EMIT3_off32 (0x48 , 0x8D , 0x95 , - run_ctx_off );
2278
2279
else
2279
2280
EMIT4 (0x48 , 0x8D , 0x55 , - run_ctx_off );
2280
- if (emit_rsb_call (& prog , bpf_trampoline_exit (p ), prog ))
2281
+ if (emit_rsb_call (& prog , bpf_trampoline_exit (p ), image + ( prog - ( u8 * ) rw_image ) ))
2281
2282
return - EINVAL ;
2282
2283
2283
2284
* pprog = prog ;
@@ -2312,14 +2313,15 @@ static int emit_cond_near_jump(u8 **pprog, void *func, void *ip, u8 jmp_cond)
2312
2313
2313
2314
static int invoke_bpf (const struct btf_func_model * m , u8 * * pprog ,
2314
2315
struct bpf_tramp_links * tl , int stack_size ,
2315
- int run_ctx_off , bool save_ret )
2316
+ int run_ctx_off , bool save_ret ,
2317
+ void * image , void * rw_image )
2316
2318
{
2317
2319
int i ;
2318
2320
u8 * prog = * pprog ;
2319
2321
2320
2322
for (i = 0 ; i < tl -> nr_links ; i ++ ) {
2321
2323
if (invoke_bpf_prog (m , & prog , tl -> links [i ], stack_size ,
2322
- run_ctx_off , save_ret ))
2324
+ run_ctx_off , save_ret , image , rw_image ))
2323
2325
return - EINVAL ;
2324
2326
}
2325
2327
* pprog = prog ;
@@ -2328,7 +2330,8 @@ static int invoke_bpf(const struct btf_func_model *m, u8 **pprog,
2328
2330
2329
2331
static int invoke_bpf_mod_ret (const struct btf_func_model * m , u8 * * pprog ,
2330
2332
struct bpf_tramp_links * tl , int stack_size ,
2331
- int run_ctx_off , u8 * * branches )
2333
+ int run_ctx_off , u8 * * branches ,
2334
+ void * image , void * rw_image )
2332
2335
{
2333
2336
u8 * prog = * pprog ;
2334
2337
int i ;
@@ -2339,7 +2342,8 @@ static int invoke_bpf_mod_ret(const struct btf_func_model *m, u8 **pprog,
2339
2342
emit_mov_imm32 (& prog , false, BPF_REG_0 , 0 );
2340
2343
emit_stx (& prog , BPF_DW , BPF_REG_FP , BPF_REG_0 , -8 );
2341
2344
for (i = 0 ; i < tl -> nr_links ; i ++ ) {
2342
- if (invoke_bpf_prog (m , & prog , tl -> links [i ], stack_size , run_ctx_off , true))
2345
+ if (invoke_bpf_prog (m , & prog , tl -> links [i ], stack_size , run_ctx_off , true,
2346
+ image , rw_image ))
2343
2347
return - EINVAL ;
2344
2348
2345
2349
/* mod_ret prog stored return value into [rbp - 8]. Emit:
@@ -2422,7 +2426,8 @@ static int invoke_bpf_mod_ret(const struct btf_func_model *m, u8 **pprog,
2422
2426
* add rsp, 8 // skip eth_type_trans's frame
2423
2427
* ret // return to its caller
2424
2428
*/
2425
- static int __arch_prepare_bpf_trampoline (struct bpf_tramp_image * im , void * image , void * image_end ,
2429
+ static int __arch_prepare_bpf_trampoline (struct bpf_tramp_image * im , void * rw_image ,
2430
+ void * rw_image_end , void * image ,
2426
2431
const struct btf_func_model * m , u32 flags ,
2427
2432
struct bpf_tramp_links * tlinks ,
2428
2433
void * func_addr )
@@ -2521,7 +2526,7 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image
2521
2526
orig_call += X86_PATCH_SIZE ;
2522
2527
}
2523
2528
2524
- prog = image ;
2529
+ prog = rw_image ;
2525
2530
2526
2531
EMIT_ENDBR ();
2527
2532
/*
@@ -2563,15 +2568,16 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image
2563
2568
if (flags & BPF_TRAMP_F_CALL_ORIG ) {
2564
2569
/* arg1: mov rdi, im */
2565
2570
emit_mov_imm64 (& prog , BPF_REG_1 , (long ) im >> 32 , (u32 ) (long ) im );
2566
- if (emit_rsb_call (& prog , __bpf_tramp_enter , prog )) {
2571
+ if (emit_rsb_call (& prog , __bpf_tramp_enter ,
2572
+ image + (prog - (u8 * )rw_image ))) {
2567
2573
ret = - EINVAL ;
2568
2574
goto cleanup ;
2569
2575
}
2570
2576
}
2571
2577
2572
2578
if (fentry -> nr_links )
2573
2579
if (invoke_bpf (m , & prog , fentry , regs_off , run_ctx_off ,
2574
- flags & BPF_TRAMP_F_RET_FENTRY_RET ))
2580
+ flags & BPF_TRAMP_F_RET_FENTRY_RET , image , rw_image ))
2575
2581
return - EINVAL ;
2576
2582
2577
2583
if (fmod_ret -> nr_links ) {
@@ -2581,7 +2587,7 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image
2581
2587
return - ENOMEM ;
2582
2588
2583
2589
if (invoke_bpf_mod_ret (m , & prog , fmod_ret , regs_off ,
2584
- run_ctx_off , branches )) {
2590
+ run_ctx_off , branches , image , rw_image )) {
2585
2591
ret = - EINVAL ;
2586
2592
goto cleanup ;
2587
2593
}
@@ -2602,14 +2608,14 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image
2602
2608
EMIT2 (0xff , 0xd3 ); /* call *rbx */
2603
2609
} else {
2604
2610
/* call original function */
2605
- if (emit_rsb_call (& prog , orig_call , prog )) {
2611
+ if (emit_rsb_call (& prog , orig_call , image + ( prog - ( u8 * ) rw_image ) )) {
2606
2612
ret = - EINVAL ;
2607
2613
goto cleanup ;
2608
2614
}
2609
2615
}
2610
2616
/* remember return value in a stack for bpf prog to access */
2611
2617
emit_stx (& prog , BPF_DW , BPF_REG_FP , BPF_REG_0 , -8 );
2612
- im -> ip_after_call = prog ;
2618
+ im -> ip_after_call = image + ( prog - ( u8 * ) rw_image ) ;
2613
2619
memcpy (prog , x86_nops [5 ], X86_PATCH_SIZE );
2614
2620
prog += X86_PATCH_SIZE ;
2615
2621
}
@@ -2625,12 +2631,13 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image
2625
2631
* aligned address of do_fexit.
2626
2632
*/
2627
2633
for (i = 0 ; i < fmod_ret -> nr_links ; i ++ )
2628
- emit_cond_near_jump (& branches [i ], prog , branches [ i ] ,
2629
- X86_JNE );
2634
+ emit_cond_near_jump (& branches [i ], image + ( prog - ( u8 * ) rw_image ) ,
2635
+ image + ( branches [ i ] - ( u8 * ) rw_image ), X86_JNE );
2630
2636
}
2631
2637
2632
2638
if (fexit -> nr_links )
2633
- if (invoke_bpf (m , & prog , fexit , regs_off , run_ctx_off , false)) {
2639
+ if (invoke_bpf (m , & prog , fexit , regs_off , run_ctx_off ,
2640
+ false, image , rw_image )) {
2634
2641
ret = - EINVAL ;
2635
2642
goto cleanup ;
2636
2643
}
@@ -2643,10 +2650,10 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image
2643
2650
* restored to R0.
2644
2651
*/
2645
2652
if (flags & BPF_TRAMP_F_CALL_ORIG ) {
2646
- im -> ip_epilogue = prog ;
2653
+ im -> ip_epilogue = image + ( prog - ( u8 * ) rw_image ) ;
2647
2654
/* arg1: mov rdi, im */
2648
2655
emit_mov_imm64 (& prog , BPF_REG_1 , (long ) im >> 32 , (u32 ) (long ) im );
2649
- if (emit_rsb_call (& prog , __bpf_tramp_exit , prog )) {
2656
+ if (emit_rsb_call (& prog , __bpf_tramp_exit , image + ( prog - ( u8 * ) rw_image ) )) {
2650
2657
ret = - EINVAL ;
2651
2658
goto cleanup ;
2652
2659
}
@@ -2665,25 +2672,64 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image
2665
2672
if (flags & BPF_TRAMP_F_SKIP_FRAME )
2666
2673
/* skip our return address and return to parent */
2667
2674
EMIT4 (0x48 , 0x83 , 0xC4 , 8 ); /* add rsp, 8 */
2668
- emit_return (& prog , prog );
2675
+ emit_return (& prog , image + ( prog - ( u8 * ) rw_image ) );
2669
2676
/* Make sure the trampoline generation logic doesn't overflow */
2670
- if (WARN_ON_ONCE (prog > (u8 * )image_end - BPF_INSN_SAFETY )) {
2677
+ if (WARN_ON_ONCE (prog > (u8 * )rw_image_end - BPF_INSN_SAFETY )) {
2671
2678
ret = - EFAULT ;
2672
2679
goto cleanup ;
2673
2680
}
2674
- ret = prog - (u8 * )image + BPF_INSN_SAFETY ;
2681
+ ret = prog - (u8 * )rw_image + BPF_INSN_SAFETY ;
2675
2682
2676
2683
cleanup :
2677
2684
kfree (branches );
2678
2685
return ret ;
2679
2686
}
2680
2687
2688
+ void * arch_alloc_bpf_trampoline (unsigned int size )
2689
+ {
2690
+ return bpf_prog_pack_alloc (size , jit_fill_hole );
2691
+ }
2692
+
2693
+ void arch_free_bpf_trampoline (void * image , unsigned int size )
2694
+ {
2695
+ bpf_prog_pack_free (image , size );
2696
+ }
2697
+
2698
+ void arch_protect_bpf_trampoline (void * image , unsigned int size )
2699
+ {
2700
+ }
2701
+
2702
+ void arch_unprotect_bpf_trampoline (void * image , unsigned int size )
2703
+ {
2704
+ }
2705
+
2681
2706
int arch_prepare_bpf_trampoline (struct bpf_tramp_image * im , void * image , void * image_end ,
2682
2707
const struct btf_func_model * m , u32 flags ,
2683
2708
struct bpf_tramp_links * tlinks ,
2684
2709
void * func_addr )
2685
2710
{
2686
- return __arch_prepare_bpf_trampoline (im , image , image_end , m , flags , tlinks , func_addr );
2711
+ void * rw_image , * tmp ;
2712
+ int ret ;
2713
+ u32 size = image_end - image ;
2714
+
2715
+ /* rw_image doesn't need to be in module memory range, so we can
2716
+ * use kvmalloc.
2717
+ */
2718
+ rw_image = kvmalloc (size , GFP_KERNEL );
2719
+ if (!rw_image )
2720
+ return - ENOMEM ;
2721
+
2722
+ ret = __arch_prepare_bpf_trampoline (im , rw_image , rw_image + size , image , m ,
2723
+ flags , tlinks , func_addr );
2724
+ if (ret < 0 )
2725
+ goto out ;
2726
+
2727
+ tmp = bpf_arch_text_copy (image , rw_image , size );
2728
+ if (IS_ERR (tmp ))
2729
+ ret = PTR_ERR (tmp );
2730
+ out :
2731
+ kvfree (rw_image );
2732
+ return ret ;
2687
2733
}
2688
2734
2689
2735
int arch_bpf_trampoline_size (const struct btf_func_model * m , u32 flags ,
@@ -2704,8 +2750,8 @@ int arch_bpf_trampoline_size(const struct btf_func_model *m, u32 flags,
2704
2750
if (!image )
2705
2751
return - ENOMEM ;
2706
2752
2707
- ret = __arch_prepare_bpf_trampoline (& im , image , image + PAGE_SIZE , m , flags ,
2708
- tlinks , func_addr );
2753
+ ret = __arch_prepare_bpf_trampoline (& im , image , image + PAGE_SIZE , image ,
2754
+ m , flags , tlinks , func_addr );
2709
2755
bpf_jit_free_exec (image );
2710
2756
return ret ;
2711
2757
}
0 commit comments