@@ -44,9 +44,12 @@ int bpf_jit_emit_exit_insn(u32 *image, struct codegen_context *ctx, int tmp_reg,
4444}
4545
4646struct powerpc_jit_data {
47- struct bpf_binary_header * header ;
47+ /* address of rw header */
48+ struct bpf_binary_header * hdr ;
49+ /* address of ro final header */
50+ struct bpf_binary_header * fhdr ;
4851 u32 * addrs ;
49- u8 * image ;
52+ u8 * fimage ;
5053 u32 proglen ;
5154 struct codegen_context ctx ;
5255};
@@ -67,11 +70,14 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
6770 struct codegen_context cgctx ;
6871 int pass ;
6972 int flen ;
70- struct bpf_binary_header * bpf_hdr ;
73+ struct bpf_binary_header * fhdr = NULL ;
74+ struct bpf_binary_header * hdr = NULL ;
7175 struct bpf_prog * org_fp = fp ;
7276 struct bpf_prog * tmp_fp ;
7377 bool bpf_blinded = false;
7478 bool extra_pass = false;
79+ u8 * fimage = NULL ;
80+ u32 * fcode_base ;
7581 u32 extable_len ;
7682 u32 fixup_len ;
7783
@@ -101,9 +107,16 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
101107 addrs = jit_data -> addrs ;
102108 if (addrs ) {
103109 cgctx = jit_data -> ctx ;
104- image = jit_data -> image ;
105- bpf_hdr = jit_data -> header ;
110+ /*
111+ * JIT compiled to a writable location (image/code_base) first.
112+ * It is then moved to the readonly final location (fimage/fcode_base)
113+ * using instruction patching.
114+ */
115+ fimage = jit_data -> fimage ;
116+ fhdr = jit_data -> fhdr ;
106117 proglen = jit_data -> proglen ;
118+ hdr = jit_data -> hdr ;
119+ image = (void * )hdr + ((void * )fimage - (void * )fhdr );
107120 extra_pass = true;
108121 /* During extra pass, ensure index is reset before repopulating extable entries */
109122 cgctx .exentry_idx = 0 ;
@@ -123,7 +136,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
123136 cgctx .stack_size = round_up (fp -> aux -> stack_depth , 16 );
124137
125138 /* Scouting faux-generate pass 0 */
126- if (bpf_jit_build_body (fp , 0 , & cgctx , addrs , 0 , false)) {
139+ if (bpf_jit_build_body (fp , NULL , NULL , & cgctx , addrs , 0 , false)) {
127140 /* We hit something illegal or unsupported. */
128141 fp = org_fp ;
129142 goto out_addrs ;
@@ -138,7 +151,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
138151 */
139152 if (cgctx .seen & SEEN_TAILCALL || !is_offset_in_branch_range ((long )cgctx .idx * 4 )) {
140153 cgctx .idx = 0 ;
141- if (bpf_jit_build_body (fp , 0 , & cgctx , addrs , 0 , false)) {
154+ if (bpf_jit_build_body (fp , NULL , NULL , & cgctx , addrs , 0 , false)) {
142155 fp = org_fp ;
143156 goto out_addrs ;
144157 }
@@ -160,26 +173,30 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
160173 proglen = cgctx .idx * 4 ;
161174 alloclen = proglen + FUNCTION_DESCR_SIZE + fixup_len + extable_len ;
162175
163- bpf_hdr = bpf_jit_binary_alloc (alloclen , & image , 4 , bpf_jit_fill_ill_insns );
164- if (!bpf_hdr ) {
176+ fhdr = bpf_jit_binary_pack_alloc (alloclen , & fimage , 4 , & hdr , & image ,
177+ bpf_jit_fill_ill_insns );
178+ if (!fhdr ) {
165179 fp = org_fp ;
166180 goto out_addrs ;
167181 }
168182
169183 if (extable_len )
170- fp -> aux -> extable = (void * )image + FUNCTION_DESCR_SIZE + proglen + fixup_len ;
184+ fp -> aux -> extable = (void * )fimage + FUNCTION_DESCR_SIZE + proglen + fixup_len ;
171185
172186skip_init_ctx :
173187 code_base = (u32 * )(image + FUNCTION_DESCR_SIZE );
188+ fcode_base = (u32 * )(fimage + FUNCTION_DESCR_SIZE );
174189
175190 /* Code generation passes 1-2 */
176191 for (pass = 1 ; pass < 3 ; pass ++ ) {
177192 /* Now build the prologue, body code & epilogue for real. */
178193 cgctx .idx = 0 ;
179194 cgctx .alt_exit_addr = 0 ;
180195 bpf_jit_build_prologue (code_base , & cgctx );
181- if (bpf_jit_build_body (fp , code_base , & cgctx , addrs , pass , extra_pass )) {
182- bpf_jit_binary_free (bpf_hdr );
196+ if (bpf_jit_build_body (fp , code_base , fcode_base , & cgctx , addrs , pass ,
197+ extra_pass )) {
198+ bpf_arch_text_copy (& fhdr -> size , & hdr -> size , sizeof (hdr -> size ));
199+ bpf_jit_binary_pack_free (fhdr , hdr );
183200 fp = org_fp ;
184201 goto out_addrs ;
185202 }
@@ -199,17 +216,19 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
199216
200217#ifdef CONFIG_PPC64_ELF_ABI_V1
201218 /* Function descriptor nastiness: Address + TOC */
202- ((u64 * )image )[0 ] = (u64 )code_base ;
219+ ((u64 * )image )[0 ] = (u64 )fcode_base ;
203220 ((u64 * )image )[1 ] = local_paca -> kernel_toc ;
204221#endif
205222
206- fp -> bpf_func = (void * )image ;
223+ fp -> bpf_func = (void * )fimage ;
207224 fp -> jited = 1 ;
208225 fp -> jited_len = proglen + FUNCTION_DESCR_SIZE ;
209226
210- bpf_flush_icache (bpf_hdr , (u8 * )bpf_hdr + bpf_hdr -> size );
211227 if (!fp -> is_func || extra_pass ) {
212- bpf_jit_binary_lock_ro (bpf_hdr );
228+ if (bpf_jit_binary_pack_finalize (fp , fhdr , hdr )) {
229+ fp = org_fp ;
230+ goto out_addrs ;
231+ }
213232 bpf_prog_fill_jited_linfo (fp , addrs );
214233out_addrs :
215234 kfree (addrs );
@@ -219,8 +238,9 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
219238 jit_data -> addrs = addrs ;
220239 jit_data -> ctx = cgctx ;
221240 jit_data -> proglen = proglen ;
222- jit_data -> image = image ;
223- jit_data -> header = bpf_hdr ;
241+ jit_data -> fimage = fimage ;
242+ jit_data -> fhdr = fhdr ;
243+ jit_data -> hdr = hdr ;
224244 }
225245
226246out :
@@ -234,12 +254,13 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
234254 * The caller should check for (BPF_MODE(code) == BPF_PROBE_MEM) before calling
235255 * this function, as this only applies to BPF_PROBE_MEM, for now.
236256 */
237- int bpf_add_extable_entry (struct bpf_prog * fp , u32 * image , int pass , struct codegen_context * ctx ,
238- int insn_idx , int jmp_off , int dst_reg )
257+ int bpf_add_extable_entry (struct bpf_prog * fp , u32 * image , u32 * fimage , int pass ,
258+ struct codegen_context * ctx , int insn_idx , int jmp_off ,
259+ int dst_reg )
239260{
240261 off_t offset ;
241262 unsigned long pc ;
242- struct exception_table_entry * ex ;
263+ struct exception_table_entry * ex , * ex_entry ;
243264 u32 * fixup ;
244265
245266 /* Populate extable entries only in the last pass */
@@ -250,9 +271,16 @@ int bpf_add_extable_entry(struct bpf_prog *fp, u32 *image, int pass, struct code
250271 WARN_ON_ONCE (ctx -> exentry_idx >= fp -> aux -> num_exentries ))
251272 return - EINVAL ;
252273
274+ /*
275+ * Program is first written to image before copying to the
276+ * final location (fimage). Accordingly, update in the image first.
277+ * As all offsets used are relative, copying as is to the
278+ * final location should be alright.
279+ */
253280 pc = (unsigned long )& image [insn_idx ];
281+ ex = (void * )fp -> aux -> extable - (void * )fimage + (void * )image ;
254282
255- fixup = (void * )fp -> aux -> extable -
283+ fixup = (void * )ex -
256284 (fp -> aux -> num_exentries * BPF_FIXUP_LEN * 4 ) +
257285 (ctx -> exentry_idx * BPF_FIXUP_LEN * 4 );
258286
@@ -263,17 +291,17 @@ int bpf_add_extable_entry(struct bpf_prog *fp, u32 *image, int pass, struct code
263291 fixup [BPF_FIXUP_LEN - 1 ] =
264292 PPC_RAW_BRANCH ((long )(pc + jmp_off ) - (long )& fixup [BPF_FIXUP_LEN - 1 ]);
265293
266- ex = & fp -> aux -> extable [ctx -> exentry_idx ];
294+ ex_entry = & ex [ctx -> exentry_idx ];
267295
268- offset = pc - (long )& ex -> insn ;
296+ offset = pc - (long )& ex_entry -> insn ;
269297 if (WARN_ON_ONCE (offset >= 0 || offset < INT_MIN ))
270298 return - ERANGE ;
271- ex -> insn = offset ;
299+ ex_entry -> insn = offset ;
272300
273- offset = (long )fixup - (long )& ex -> fixup ;
301+ offset = (long )fixup - (long )& ex_entry -> fixup ;
274302 if (WARN_ON_ONCE (offset >= 0 || offset < INT_MIN ))
275303 return - ERANGE ;
276- ex -> fixup = offset ;
304+ ex_entry -> fixup = offset ;
277305
278306 ctx -> exentry_idx ++ ;
279307 return 0 ;
@@ -307,3 +335,27 @@ int bpf_arch_text_invalidate(void *dst, size_t len)
307335
308336 return ret ;
309337}
338+
339+ void bpf_jit_free (struct bpf_prog * fp )
340+ {
341+ if (fp -> jited ) {
342+ struct powerpc_jit_data * jit_data = fp -> aux -> jit_data ;
343+ struct bpf_binary_header * hdr ;
344+
345+ /*
346+ * If we fail the final pass of JIT (from jit_subprogs),
347+ * the program may not be finalized yet. Call finalize here
348+ * before freeing it.
349+ */
350+ if (jit_data ) {
351+ bpf_jit_binary_pack_finalize (fp , jit_data -> fhdr , jit_data -> hdr );
352+ kvfree (jit_data -> addrs );
353+ kfree (jit_data );
354+ }
355+ hdr = bpf_jit_binary_pack_hdr (fp );
356+ bpf_jit_binary_pack_free (hdr , NULL );
357+ WARN_ON_ONCE (!bpf_prog_kallsyms_verify_off (fp ));
358+ }
359+
360+ bpf_prog_unlock_free (fp );
361+ }
0 commit comments