Re: [PATCH v2 4/4] powerpc/bpf: use bpf_jit_binary_pack_[alloc|finalize|free]

2023-08-25 Thread Hari Bathini




On 11/03/23 4:05 am, Song Liu wrote:

On Thu, Mar 9, 2023 at 10:03 AM Hari Bathini  wrote:


Use bpf_jit_binary_pack_alloc in powerpc jit. The jit engine first
writes the program to the rw buffer. When the jit is done, the program
is copied to the final location with bpf_jit_binary_pack_finalize.
With multiple jit_subprogs, bpf_jit_free is called on some subprograms
that haven't got bpf_jit_binary_pack_finalize() yet. Implement custom
bpf_jit_free() like in commit 1d5f82d9dd47 ("bpf, x86: fix freeing of
not-finalized bpf_prog_pack") to call bpf_jit_binary_pack_finalize(),
if necessary. While here, correct the misnomer powerpc64_jit_data to
powerpc_jit_data as it is meant for both ppc32 and ppc64.

Signed-off-by: Hari Bathini 
---
  arch/powerpc/net/bpf_jit.h|   7 +-
  arch/powerpc/net/bpf_jit_comp.c   | 104 +-
  arch/powerpc/net/bpf_jit_comp32.c |   4 +-
  arch/powerpc/net/bpf_jit_comp64.c |   6 +-
  4 files changed, 83 insertions(+), 38 deletions(-)

diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h
index d767e39d5645..a8b7480c4d43 100644
--- a/arch/powerpc/net/bpf_jit.h
+++ b/arch/powerpc/net/bpf_jit.h
@@ -168,15 +168,16 @@ static inline void bpf_clear_seen_register(struct 
codegen_context *ctx, int i)

  void bpf_jit_init_reg_mapping(struct codegen_context *ctx);
  int bpf_jit_emit_func_call_rel(u32 *image, struct codegen_context *ctx, u64 
func);
-int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context 
*ctx,
+int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct 
codegen_context *ctx,
u32 *addrs, int pass, bool extra_pass);
  void bpf_jit_build_prologue(u32 *image, struct codegen_context *ctx);
  void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx);
  void bpf_jit_realloc_regs(struct codegen_context *ctx);
  int bpf_jit_emit_exit_insn(u32 *image, struct codegen_context *ctx, int 
tmp_reg, long exit_addr);

-int bpf_add_extable_entry(struct bpf_prog *fp, u32 *image, int pass, struct 
codegen_context *ctx,
- int insn_idx, int jmp_off, int dst_reg);
+int bpf_add_extable_entry(struct bpf_prog *fp, u32 *image, u32 *fimage, int 
pass,
+ struct codegen_context *ctx, int insn_idx,
+ int jmp_off, int dst_reg);

  #endif

diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
index d1794d9f0154..ece75c829499 100644
--- a/arch/powerpc/net/bpf_jit_comp.c
+++ b/arch/powerpc/net/bpf_jit_comp.c
@@ -42,10 +42,11 @@ int bpf_jit_emit_exit_insn(u32 *image, struct 
codegen_context *ctx, int tmp_reg,
 return 0;
  }

-struct powerpc64_jit_data {
-   struct bpf_binary_header *header;
+struct powerpc_jit_data {
+   struct bpf_binary_header *hdr;
+   struct bpf_binary_header *fhdr;
 u32 *addrs;
-   u8 *image;
+   u8 *fimage;
 u32 proglen;
 struct codegen_context ctx;
  };


Some comments about the f- prefix will be helpful. (Yes, I should have done
better job adding comments for the x86 counterpart..)


@@ -62,15 +63,18 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
 u8 *image = NULL;
 u32 *code_base;
 u32 *addrs;
-   struct powerpc64_jit_data *jit_data;
+   struct powerpc_jit_data *jit_data;
 struct codegen_context cgctx;
 int pass;
 int flen;
-   struct bpf_binary_header *bpf_hdr;
+   struct bpf_binary_header *fhdr = NULL;
+   struct bpf_binary_header *hdr = NULL;
 struct bpf_prog *org_fp = fp;
 struct bpf_prog *tmp_fp;
 bool bpf_blinded = false;
 bool extra_pass = false;
+   u8 *fimage = NULL;
+   u32 *fcode_base;
 u32 extable_len;
 u32 fixup_len;

@@ -100,9 +104,11 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
 addrs = jit_data->addrs;
 if (addrs) {
 cgctx = jit_data->ctx;
-   image = jit_data->image;
-   bpf_hdr = jit_data->header;
+   fimage = jit_data->fimage;
+   fhdr = jit_data->fhdr;
 proglen = jit_data->proglen;
+   hdr = jit_data->hdr;
+   image = (void *)hdr + ((void *)fimage - (void *)fhdr);
 extra_pass = true;
 goto skip_init_ctx;
 }
@@ -120,7 +126,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
 cgctx.stack_size = round_up(fp->aux->stack_depth, 16);

 /* Scouting faux-generate pass 0 */
-   if (bpf_jit_build_body(fp, 0, , addrs, 0, false)) {
+   if (bpf_jit_build_body(fp, NULL, NULL, , addrs, 0, false)) {
 /* We hit something illegal or unsupported. */
 fp = org_fp;
 goto out_addrs;
@@ -135,7 +141,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
  */
 if (cgctx.seen & SEEN_TAILCALL || 

Re: [PATCH v2 4/4] powerpc/bpf: use bpf_jit_binary_pack_[alloc|finalize|free]

2023-08-25 Thread Hari Bathini




On 11/03/23 3:46 pm, Christophe Leroy wrote:



Le 09/03/2023 à 19:02, Hari Bathini a écrit :

Use bpf_jit_binary_pack_alloc in powerpc jit. The jit engine first
writes the program to the rw buffer. When the jit is done, the program
is copied to the final location with bpf_jit_binary_pack_finalize.
With multiple jit_subprogs, bpf_jit_free is called on some subprograms
that haven't got bpf_jit_binary_pack_finalize() yet. Implement custom
bpf_jit_free() like in commit 1d5f82d9dd47 ("bpf, x86: fix freeing of
not-finalized bpf_prog_pack") to call bpf_jit_binary_pack_finalize(),
if necessary. While here, correct the misnomer powerpc64_jit_data to
powerpc_jit_data as it is meant for both ppc32 and ppc64.


root@vgoip:~# echo 1 > /proc/sys/net/core/bpf_jit_enable
root@vgoip:~# insmod test_bpf.ko
[  570.270983] kernel tried to execute exec-protected page (bd42c198) -
exploit attempt? (uid: 0)
[  570.279414] BUG: Unable to handle kernel instruction fetch
[  570.284822] Faulting instruction address: 0xbd42c198
[  570.289734] Oops: Kernel access of bad area, sig: 11 [#1]
[  570.295062] BE PAGE_SIZE=16K PREEMPT CMPC885
[  570.302811] Modules linked in: test_bpf(+) test_module
[  570.307891] CPU: 0 PID: 559 Comm: insmod Not tainted
6.3.0-rc1-s3k-dev-g4ae0418b3500 #258
[  570.315975] Hardware name: MIAE 8xx 0x50 CMPC885
[  570.320882] NIP:  bd42c198 LR: be8180ec CTR: be818010
[  570.325873] REGS: cae2bc40 TRAP: 0400   Not tainted
(6.3.0-rc1-s3k-dev-g4ae0418b3500)
[  570.333704] MSR:  40009032   CR: 88008222  XER: 
[  570.340503]
[  570.340503] GPR00: be806eac cae2bd00 c2977340  c2c40900
 c1a18a80 
[  570.340503] GPR08: 0002 0001   
100d815e ca6a 0001
[  570.340503] GPR16: 1234 ca242250 c118 0001 1234aaab
c9050030  
[  570.340503] GPR24: c2c40900    c1a18a80
 0002 ca24225c
[  570.376819] NIP [bd42c198] 0xbd42c198
[  570.380436] LR [be8180ec] 0xbe8180ec
[  570.383965] Call Trace:
[  570.386373] [cae2bd00] [000b] 0xb (unreliable)
[  570.391107] [cae2bd50] [be806eac] __run_one+0x58/0x224 [test_bpf]
[  570.397390] [cae2bd90] [be80ca94] test_bpf_init+0x8d8/0x1010 [test_bpf]
[  570.404189] [cae2be20] [c00049f0] do_one_initcall+0x38/0x1e4
[  570.409782] [cae2be80] [c0090aa8] do_init_module+0x50/0x234
[  570.415291] [cae2bea0] [c0092e08] sys_finit_module+0xb4/0xf8
[  570.420884] [cae2bf20] [c000e344] system_call_exception+0x94/0x150
[  570.426995] [cae2bf30] [c00120a8] ret_from_syscall+0x0/0x28
[  570.432502] --- interrupt: c00 at 0xfd5fca0
[  570.436632] NIP:  0fd5fca0 LR: 10014568 CTR: 10013294
[  570.441625] REGS: cae2bf40 TRAP: 0c00   Not tainted
(6.3.0-rc1-s3k-dev-g4ae0418b3500)
[  570.449455] MSR:  d032   CR: 44002224  XER:

[  570.456513]
[  570.456513] GPR00: 0161 7f868d30 77ed34d0 0003 100bc4ef
 0fd51868 d032
[  570.456513] GPR08: 07b1 10013294  0002 52454753
100d815e 100a44b8 
[  570.456513] GPR16: 100d167c 100b 1198426c 119854cd 100d
100d  100a4498
[  570.456513] GPR24: ffa2  11984244 0003 1198426c
100bc4ef 11984288 1198426c
[  570.492828] NIP [0fd5fca0] 0xfd5fca0
[  570.496358] LR [10014568] 0x10014568
[  570.499887] --- interrupt: c00
[  570.502902] Code:     
       
  
[  570.517973] ---[ end trace  ]---
[  570.522523]
[  570.523986] note: insmod[559] exited with irqs disabled
Segmentation fault


Thanks a lot for reviewing v2, Christophe.
Posted v3 for reviewing..

Thanks
Hari


Re: [PATCH v2 4/4] powerpc/bpf: use bpf_jit_binary_pack_[alloc|finalize|free]

2023-03-11 Thread Christophe Leroy


Le 09/03/2023 à 19:02, Hari Bathini a écrit :
> Use bpf_jit_binary_pack_alloc in powerpc jit. The jit engine first
> writes the program to the rw buffer. When the jit is done, the program
> is copied to the final location with bpf_jit_binary_pack_finalize.
> With multiple jit_subprogs, bpf_jit_free is called on some subprograms
> that haven't got bpf_jit_binary_pack_finalize() yet. Implement custom
> bpf_jit_free() like in commit 1d5f82d9dd47 ("bpf, x86: fix freeing of
> not-finalized bpf_prog_pack") to call bpf_jit_binary_pack_finalize(),
> if necessary. While here, correct the misnomer powerpc64_jit_data to
> powerpc_jit_data as it is meant for both ppc32 and ppc64.

root@vgoip:~# echo 1 > /proc/sys/net/core/bpf_jit_enable
root@vgoip:~# insmod test_bpf.ko
[  570.270983] kernel tried to execute exec-protected page (bd42c198) - 
exploit attempt? (uid: 0)
[  570.279414] BUG: Unable to handle kernel instruction fetch
[  570.284822] Faulting instruction address: 0xbd42c198
[  570.289734] Oops: Kernel access of bad area, sig: 11 [#1]
[  570.295062] BE PAGE_SIZE=16K PREEMPT CMPC885
[  570.302811] Modules linked in: test_bpf(+) test_module
[  570.307891] CPU: 0 PID: 559 Comm: insmod Not tainted 
6.3.0-rc1-s3k-dev-g4ae0418b3500 #258
[  570.315975] Hardware name: MIAE 8xx 0x50 CMPC885
[  570.320882] NIP:  bd42c198 LR: be8180ec CTR: be818010
[  570.325873] REGS: cae2bc40 TRAP: 0400   Not tainted 
(6.3.0-rc1-s3k-dev-g4ae0418b3500)
[  570.333704] MSR:  40009032   CR: 88008222  XER: 
[  570.340503]
[  570.340503] GPR00: be806eac cae2bd00 c2977340  c2c40900 
 c1a18a80 
[  570.340503] GPR08: 0002 0001    
100d815e ca6a 0001
[  570.340503] GPR16: 1234 ca242250 c118 0001 1234aaab 
c9050030  
[  570.340503] GPR24: c2c40900    c1a18a80 
 0002 ca24225c
[  570.376819] NIP [bd42c198] 0xbd42c198
[  570.380436] LR [be8180ec] 0xbe8180ec
[  570.383965] Call Trace:
[  570.386373] [cae2bd00] [000b] 0xb (unreliable)
[  570.391107] [cae2bd50] [be806eac] __run_one+0x58/0x224 [test_bpf]
[  570.397390] [cae2bd90] [be80ca94] test_bpf_init+0x8d8/0x1010 [test_bpf]
[  570.404189] [cae2be20] [c00049f0] do_one_initcall+0x38/0x1e4
[  570.409782] [cae2be80] [c0090aa8] do_init_module+0x50/0x234
[  570.415291] [cae2bea0] [c0092e08] sys_finit_module+0xb4/0xf8
[  570.420884] [cae2bf20] [c000e344] system_call_exception+0x94/0x150
[  570.426995] [cae2bf30] [c00120a8] ret_from_syscall+0x0/0x28
[  570.432502] --- interrupt: c00 at 0xfd5fca0
[  570.436632] NIP:  0fd5fca0 LR: 10014568 CTR: 10013294
[  570.441625] REGS: cae2bf40 TRAP: 0c00   Not tainted 
(6.3.0-rc1-s3k-dev-g4ae0418b3500)
[  570.449455] MSR:  d032   CR: 44002224  XER: 

[  570.456513]
[  570.456513] GPR00: 0161 7f868d30 77ed34d0 0003 100bc4ef 
 0fd51868 d032
[  570.456513] GPR08: 07b1 10013294  0002 52454753 
100d815e 100a44b8 
[  570.456513] GPR16: 100d167c 100b 1198426c 119854cd 100d 
100d  100a4498
[  570.456513] GPR24: ffa2  11984244 0003 1198426c 
100bc4ef 11984288 1198426c
[  570.492828] NIP [0fd5fca0] 0xfd5fca0
[  570.496358] LR [10014568] 0x10014568
[  570.499887] --- interrupt: c00
[  570.502902] Code:      
        
  
[  570.517973] ---[ end trace  ]---
[  570.522523]
[  570.523986] note: insmod[559] exited with irqs disabled
Segmentation fault

Christophe

> 
> Signed-off-by: Hari Bathini 
> ---
>   arch/powerpc/net/bpf_jit.h|   7 +-
>   arch/powerpc/net/bpf_jit_comp.c   | 104 +-
>   arch/powerpc/net/bpf_jit_comp32.c |   4 +-
>   arch/powerpc/net/bpf_jit_comp64.c |   6 +-
>   4 files changed, 83 insertions(+), 38 deletions(-)
> 
> diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h
> index d767e39d5645..a8b7480c4d43 100644
> --- a/arch/powerpc/net/bpf_jit.h
> +++ b/arch/powerpc/net/bpf_jit.h
> @@ -168,15 +168,16 @@ static inline void bpf_clear_seen_register(struct 
> codegen_context *ctx, int i)
>   
>   void bpf_jit_init_reg_mapping(struct codegen_context *ctx);
>   int bpf_jit_emit_func_call_rel(u32 *image, struct codegen_context *ctx, u64 
> func);
> -int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct 
> codegen_context *ctx,
> +int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct 
> codegen_context *ctx,
>  u32 *addrs, int pass, bool extra_pass);
>   void bpf_jit_build_prologue(u32 *image, struct codegen_context *ctx);
>   void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx);
>   void bpf_jit_realloc_regs(struct codegen_context *ctx);
>   int bpf_jit_emit_exit_insn(u32 *image, struct codegen_context *ctx, int 
> tmp_reg, long exit_addr);
>   
> -int bpf_add_extable_entry(struct 

Re: [PATCH v2 4/4] powerpc/bpf: use bpf_jit_binary_pack_[alloc|finalize|free]

2023-03-10 Thread Song Liu
On Thu, Mar 9, 2023 at 10:03 AM Hari Bathini  wrote:
>
> Use bpf_jit_binary_pack_alloc in powerpc jit. The jit engine first
> writes the program to the rw buffer. When the jit is done, the program
> is copied to the final location with bpf_jit_binary_pack_finalize.
> With multiple jit_subprogs, bpf_jit_free is called on some subprograms
> that haven't got bpf_jit_binary_pack_finalize() yet. Implement custom
> bpf_jit_free() like in commit 1d5f82d9dd47 ("bpf, x86: fix freeing of
> not-finalized bpf_prog_pack") to call bpf_jit_binary_pack_finalize(),
> if necessary. While here, correct the misnomer powerpc64_jit_data to
> powerpc_jit_data as it is meant for both ppc32 and ppc64.
>
> Signed-off-by: Hari Bathini 
> ---
>  arch/powerpc/net/bpf_jit.h|   7 +-
>  arch/powerpc/net/bpf_jit_comp.c   | 104 +-
>  arch/powerpc/net/bpf_jit_comp32.c |   4 +-
>  arch/powerpc/net/bpf_jit_comp64.c |   6 +-
>  4 files changed, 83 insertions(+), 38 deletions(-)
>
> diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h
> index d767e39d5645..a8b7480c4d43 100644
> --- a/arch/powerpc/net/bpf_jit.h
> +++ b/arch/powerpc/net/bpf_jit.h
> @@ -168,15 +168,16 @@ static inline void bpf_clear_seen_register(struct 
> codegen_context *ctx, int i)
>
>  void bpf_jit_init_reg_mapping(struct codegen_context *ctx);
>  int bpf_jit_emit_func_call_rel(u32 *image, struct codegen_context *ctx, u64 
> func);
> -int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct 
> codegen_context *ctx,
> +int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct 
> codegen_context *ctx,
>u32 *addrs, int pass, bool extra_pass);
>  void bpf_jit_build_prologue(u32 *image, struct codegen_context *ctx);
>  void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx);
>  void bpf_jit_realloc_regs(struct codegen_context *ctx);
>  int bpf_jit_emit_exit_insn(u32 *image, struct codegen_context *ctx, int 
> tmp_reg, long exit_addr);
>
> -int bpf_add_extable_entry(struct bpf_prog *fp, u32 *image, int pass, struct 
> codegen_context *ctx,
> - int insn_idx, int jmp_off, int dst_reg);
> +int bpf_add_extable_entry(struct bpf_prog *fp, u32 *image, u32 *fimage, int 
> pass,
> + struct codegen_context *ctx, int insn_idx,
> + int jmp_off, int dst_reg);
>
>  #endif
>
> diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
> index d1794d9f0154..ece75c829499 100644
> --- a/arch/powerpc/net/bpf_jit_comp.c
> +++ b/arch/powerpc/net/bpf_jit_comp.c
> @@ -42,10 +42,11 @@ int bpf_jit_emit_exit_insn(u32 *image, struct 
> codegen_context *ctx, int tmp_reg,
> return 0;
>  }
>
> -struct powerpc64_jit_data {
> -   struct bpf_binary_header *header;
> +struct powerpc_jit_data {
> +   struct bpf_binary_header *hdr;
> +   struct bpf_binary_header *fhdr;
> u32 *addrs;
> -   u8 *image;
> +   u8 *fimage;
> u32 proglen;
> struct codegen_context ctx;
>  };

Some comments about the f- prefix will be helpful. (Yes, I should have done
better job adding comments for the x86 counterpart..)

> @@ -62,15 +63,18 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
> u8 *image = NULL;
> u32 *code_base;
> u32 *addrs;
> -   struct powerpc64_jit_data *jit_data;
> +   struct powerpc_jit_data *jit_data;
> struct codegen_context cgctx;
> int pass;
> int flen;
> -   struct bpf_binary_header *bpf_hdr;
> +   struct bpf_binary_header *fhdr = NULL;
> +   struct bpf_binary_header *hdr = NULL;
> struct bpf_prog *org_fp = fp;
> struct bpf_prog *tmp_fp;
> bool bpf_blinded = false;
> bool extra_pass = false;
> +   u8 *fimage = NULL;
> +   u32 *fcode_base;
> u32 extable_len;
> u32 fixup_len;
>
> @@ -100,9 +104,11 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
> addrs = jit_data->addrs;
> if (addrs) {
> cgctx = jit_data->ctx;
> -   image = jit_data->image;
> -   bpf_hdr = jit_data->header;
> +   fimage = jit_data->fimage;
> +   fhdr = jit_data->fhdr;
> proglen = jit_data->proglen;
> +   hdr = jit_data->hdr;
> +   image = (void *)hdr + ((void *)fimage - (void *)fhdr);
> extra_pass = true;
> goto skip_init_ctx;
> }
> @@ -120,7 +126,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
> cgctx.stack_size = round_up(fp->aux->stack_depth, 16);
>
> /* Scouting faux-generate pass 0 */
> -   if (bpf_jit_build_body(fp, 0, , addrs, 0, false)) {
> +   if (bpf_jit_build_body(fp, NULL, NULL, , addrs, 0, false)) {
> /* We hit something illegal or unsupported. */
> fp = org_fp;
> goto out_addrs;
> @@ -135,7 +141,7 

[PATCH v2 4/4] powerpc/bpf: use bpf_jit_binary_pack_[alloc|finalize|free]

2023-03-09 Thread Hari Bathini
Use bpf_jit_binary_pack_alloc in powerpc jit. The jit engine first
writes the program to the rw buffer. When the jit is done, the program
is copied to the final location with bpf_jit_binary_pack_finalize.
With multiple jit_subprogs, bpf_jit_free is called on some subprograms
that haven't got bpf_jit_binary_pack_finalize() yet. Implement custom
bpf_jit_free() like in commit 1d5f82d9dd47 ("bpf, x86: fix freeing of
not-finalized bpf_prog_pack") to call bpf_jit_binary_pack_finalize(),
if necessary. While here, correct the misnomer powerpc64_jit_data to
powerpc_jit_data as it is meant for both ppc32 and ppc64.

Signed-off-by: Hari Bathini 
---
 arch/powerpc/net/bpf_jit.h|   7 +-
 arch/powerpc/net/bpf_jit_comp.c   | 104 +-
 arch/powerpc/net/bpf_jit_comp32.c |   4 +-
 arch/powerpc/net/bpf_jit_comp64.c |   6 +-
 4 files changed, 83 insertions(+), 38 deletions(-)

diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h
index d767e39d5645..a8b7480c4d43 100644
--- a/arch/powerpc/net/bpf_jit.h
+++ b/arch/powerpc/net/bpf_jit.h
@@ -168,15 +168,16 @@ static inline void bpf_clear_seen_register(struct 
codegen_context *ctx, int i)
 
 void bpf_jit_init_reg_mapping(struct codegen_context *ctx);
 int bpf_jit_emit_func_call_rel(u32 *image, struct codegen_context *ctx, u64 
func);
-int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context 
*ctx,
+int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct 
codegen_context *ctx,
   u32 *addrs, int pass, bool extra_pass);
 void bpf_jit_build_prologue(u32 *image, struct codegen_context *ctx);
 void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx);
 void bpf_jit_realloc_regs(struct codegen_context *ctx);
 int bpf_jit_emit_exit_insn(u32 *image, struct codegen_context *ctx, int 
tmp_reg, long exit_addr);
 
-int bpf_add_extable_entry(struct bpf_prog *fp, u32 *image, int pass, struct 
codegen_context *ctx,
- int insn_idx, int jmp_off, int dst_reg);
+int bpf_add_extable_entry(struct bpf_prog *fp, u32 *image, u32 *fimage, int 
pass,
+ struct codegen_context *ctx, int insn_idx,
+ int jmp_off, int dst_reg);
 
 #endif
 
diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
index d1794d9f0154..ece75c829499 100644
--- a/arch/powerpc/net/bpf_jit_comp.c
+++ b/arch/powerpc/net/bpf_jit_comp.c
@@ -42,10 +42,11 @@ int bpf_jit_emit_exit_insn(u32 *image, struct 
codegen_context *ctx, int tmp_reg,
return 0;
 }
 
-struct powerpc64_jit_data {
-   struct bpf_binary_header *header;
+struct powerpc_jit_data {
+   struct bpf_binary_header *hdr;
+   struct bpf_binary_header *fhdr;
u32 *addrs;
-   u8 *image;
+   u8 *fimage;
u32 proglen;
struct codegen_context ctx;
 };
@@ -62,15 +63,18 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
u8 *image = NULL;
u32 *code_base;
u32 *addrs;
-   struct powerpc64_jit_data *jit_data;
+   struct powerpc_jit_data *jit_data;
struct codegen_context cgctx;
int pass;
int flen;
-   struct bpf_binary_header *bpf_hdr;
+   struct bpf_binary_header *fhdr = NULL;
+   struct bpf_binary_header *hdr = NULL;
struct bpf_prog *org_fp = fp;
struct bpf_prog *tmp_fp;
bool bpf_blinded = false;
bool extra_pass = false;
+   u8 *fimage = NULL;
+   u32 *fcode_base;
u32 extable_len;
u32 fixup_len;
 
@@ -100,9 +104,11 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
addrs = jit_data->addrs;
if (addrs) {
cgctx = jit_data->ctx;
-   image = jit_data->image;
-   bpf_hdr = jit_data->header;
+   fimage = jit_data->fimage;
+   fhdr = jit_data->fhdr;
proglen = jit_data->proglen;
+   hdr = jit_data->hdr;
+   image = (void *)hdr + ((void *)fimage - (void *)fhdr);
extra_pass = true;
goto skip_init_ctx;
}
@@ -120,7 +126,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
cgctx.stack_size = round_up(fp->aux->stack_depth, 16);
 
/* Scouting faux-generate pass 0 */
-   if (bpf_jit_build_body(fp, 0, , addrs, 0, false)) {
+   if (bpf_jit_build_body(fp, NULL, NULL, , addrs, 0, false)) {
/* We hit something illegal or unsupported. */
fp = org_fp;
goto out_addrs;
@@ -135,7 +141,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
 */
if (cgctx.seen & SEEN_TAILCALL || 
!is_offset_in_branch_range((long)cgctx.idx * 4)) {
cgctx.idx = 0;
-   if (bpf_jit_build_body(fp, 0, , addrs, 0, false)) {
+   if (bpf_jit_build_body(fp, NULL, NULL, , addrs, 0, 
false)) {
fp = org_fp;

[PATCH v2 4/4] powerpc/bpf: use bpf_jit_binary_pack_[alloc|finalize|free]

2023-03-09 Thread Hari Bathini
Use bpf_jit_binary_pack_alloc in powerpc jit. The jit engine first
writes the program to the rw buffer. When the jit is done, the program
is copied to the final location with bpf_jit_binary_pack_finalize.
With multiple jit_subprogs, bpf_jit_free is called on some subprograms
that haven't got bpf_jit_binary_pack_finalize() yet. Implement custom
bpf_jit_free() like in commit 1d5f82d9dd47 ("bpf, x86: fix freeing of
not-finalized bpf_prog_pack") to call bpf_jit_binary_pack_finalize(),
if necessary. While here, correct the misnomer powerpc64_jit_data to
powerpc_jit_data as it is meant for both ppc32 and ppc64.

Signed-off-by: Hari Bathini 
---
 arch/powerpc/net/bpf_jit.h|   7 +-
 arch/powerpc/net/bpf_jit_comp.c   | 104 +-
 arch/powerpc/net/bpf_jit_comp32.c |   4 +-
 arch/powerpc/net/bpf_jit_comp64.c |   6 +-
 4 files changed, 83 insertions(+), 38 deletions(-)

diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h
index d767e39d5645..a8b7480c4d43 100644
--- a/arch/powerpc/net/bpf_jit.h
+++ b/arch/powerpc/net/bpf_jit.h
@@ -168,15 +168,16 @@ static inline void bpf_clear_seen_register(struct 
codegen_context *ctx, int i)
 
 void bpf_jit_init_reg_mapping(struct codegen_context *ctx);
 int bpf_jit_emit_func_call_rel(u32 *image, struct codegen_context *ctx, u64 
func);
-int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context 
*ctx,
+int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct 
codegen_context *ctx,
   u32 *addrs, int pass, bool extra_pass);
 void bpf_jit_build_prologue(u32 *image, struct codegen_context *ctx);
 void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx);
 void bpf_jit_realloc_regs(struct codegen_context *ctx);
 int bpf_jit_emit_exit_insn(u32 *image, struct codegen_context *ctx, int 
tmp_reg, long exit_addr);
 
-int bpf_add_extable_entry(struct bpf_prog *fp, u32 *image, int pass, struct 
codegen_context *ctx,
- int insn_idx, int jmp_off, int dst_reg);
+int bpf_add_extable_entry(struct bpf_prog *fp, u32 *image, u32 *fimage, int 
pass,
+ struct codegen_context *ctx, int insn_idx,
+ int jmp_off, int dst_reg);
 
 #endif
 
diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
index d1794d9f0154..ece75c829499 100644
--- a/arch/powerpc/net/bpf_jit_comp.c
+++ b/arch/powerpc/net/bpf_jit_comp.c
@@ -42,10 +42,11 @@ int bpf_jit_emit_exit_insn(u32 *image, struct 
codegen_context *ctx, int tmp_reg,
return 0;
 }
 
-struct powerpc64_jit_data {
-   struct bpf_binary_header *header;
+struct powerpc_jit_data {
+   struct bpf_binary_header *hdr;
+   struct bpf_binary_header *fhdr;
u32 *addrs;
-   u8 *image;
+   u8 *fimage;
u32 proglen;
struct codegen_context ctx;
 };
@@ -62,15 +63,18 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
u8 *image = NULL;
u32 *code_base;
u32 *addrs;
-   struct powerpc64_jit_data *jit_data;
+   struct powerpc_jit_data *jit_data;
struct codegen_context cgctx;
int pass;
int flen;
-   struct bpf_binary_header *bpf_hdr;
+   struct bpf_binary_header *fhdr = NULL;
+   struct bpf_binary_header *hdr = NULL;
struct bpf_prog *org_fp = fp;
struct bpf_prog *tmp_fp;
bool bpf_blinded = false;
bool extra_pass = false;
+   u8 *fimage = NULL;
+   u32 *fcode_base;
u32 extable_len;
u32 fixup_len;
 
@@ -100,9 +104,11 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
addrs = jit_data->addrs;
if (addrs) {
cgctx = jit_data->ctx;
-   image = jit_data->image;
-   bpf_hdr = jit_data->header;
+   fimage = jit_data->fimage;
+   fhdr = jit_data->fhdr;
proglen = jit_data->proglen;
+   hdr = jit_data->hdr;
+   image = (void *)hdr + ((void *)fimage - (void *)fhdr);
extra_pass = true;
goto skip_init_ctx;
}
@@ -120,7 +126,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
cgctx.stack_size = round_up(fp->aux->stack_depth, 16);
 
/* Scouting faux-generate pass 0 */
-   if (bpf_jit_build_body(fp, 0, , addrs, 0, false)) {
+   if (bpf_jit_build_body(fp, NULL, NULL, , addrs, 0, false)) {
/* We hit something illegal or unsupported. */
fp = org_fp;
goto out_addrs;
@@ -135,7 +141,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
 */
if (cgctx.seen & SEEN_TAILCALL || 
!is_offset_in_branch_range((long)cgctx.idx * 4)) {
cgctx.idx = 0;
-   if (bpf_jit_build_body(fp, 0, , addrs, 0, false)) {
+   if (bpf_jit_build_body(fp, NULL, NULL, , addrs, 0, 
false)) {
fp = org_fp;