@@ -76,6 +76,7 @@ struct jit_ctx {
7676 int * offset ;
7777 int exentry_idx ;
7878 __le32 * image ;
79+ __le32 * ro_image ;
7980 u32 stack_size ;
8081 int fpb_offset ;
8182};
@@ -205,6 +206,14 @@ static void jit_fill_hole(void *area, unsigned int size)
205206 * ptr ++ = cpu_to_le32 (AARCH64_BREAK_FAULT );
206207}
207208
209+ int bpf_arch_text_invalidate (void * dst , size_t len )
210+ {
211+ if (!aarch64_insn_set (dst , AARCH64_BREAK_FAULT , len ))
212+ return - EINVAL ;
213+
214+ return 0 ;
215+ }
216+
208217static inline int epilogue_offset (const struct jit_ctx * ctx )
209218{
210219 int to = ctx -> epilogue_offset ;
@@ -746,7 +755,8 @@ static int add_exception_handler(const struct bpf_insn *insn,
746755 struct jit_ctx * ctx ,
747756 int dst_reg )
748757{
749- off_t offset ;
758+ off_t ins_offset ;
759+ off_t fixup_offset ;
750760 unsigned long pc ;
751761 struct exception_table_entry * ex ;
752762
@@ -763,12 +773,17 @@ static int add_exception_handler(const struct bpf_insn *insn,
763773 return - EINVAL ;
764774
765775 ex = & ctx -> prog -> aux -> extable [ctx -> exentry_idx ];
766- pc = (unsigned long )& ctx -> image [ctx -> idx - 1 ];
776+ pc = (unsigned long )& ctx -> ro_image [ctx -> idx - 1 ];
767777
768- offset = pc - (long )& ex -> insn ;
769- if (WARN_ON_ONCE (offset >= 0 || offset < INT_MIN ))
778+ /*
779+ * This is the relative offset of the instruction that may fault from
780+ * the exception table itself. This will be written to the exception
781+ * table and if this instruction faults, the destination register will
782+ * be set to '0' and the execution will jump to the next instruction.
783+ */
784+ ins_offset = pc - (long )& ex -> insn ;
785+ if (WARN_ON_ONCE (ins_offset >= 0 || ins_offset < INT_MIN ))
770786 return - ERANGE ;
771- ex -> insn = offset ;
772787
773788 /*
774789 * Since the extable follows the program, the fixup offset is always
@@ -777,12 +792,25 @@ static int add_exception_handler(const struct bpf_insn *insn,
777792 * bits. We don't need to worry about buildtime or runtime sort
778793 * modifying the upper bits because the table is already sorted, and
779794 * isn't part of the main exception table.
795+ *
796+ * The fixup_offset is set to the next instruction from the instruction
797+ * that may fault. The execution will jump to this after handling the
798+ * fault.
780799 */
781- offset = (long )& ex -> fixup - (pc + AARCH64_INSN_SIZE );
782- if (!FIELD_FIT (BPF_FIXUP_OFFSET_MASK , offset ))
800+ fixup_offset = (long )& ex -> fixup - (pc + AARCH64_INSN_SIZE );
801+ if (!FIELD_FIT (BPF_FIXUP_OFFSET_MASK , fixup_offset ))
783802 return - ERANGE ;
784803
785- ex -> fixup = FIELD_PREP (BPF_FIXUP_OFFSET_MASK , offset ) |
804+ /*
805+ * The offsets above have been calculated using the RO buffer but we
806+ * need to use the R/W buffer for writes.
807+ * switch ex to rw buffer for writing.
808+ */
809+ ex = (void * )ctx -> image + ((void * )ex - (void * )ctx -> ro_image );
810+
811+ ex -> insn = ins_offset ;
812+
813+ ex -> fixup = FIELD_PREP (BPF_FIXUP_OFFSET_MASK , fixup_offset ) |
786814 FIELD_PREP (BPF_FIXUP_REG_MASK , dst_reg );
787815
788816 ex -> type = EX_TYPE_BPF ;
@@ -1550,7 +1578,8 @@ static inline void bpf_flush_icache(void *start, void *end)
15501578
15511579struct arm64_jit_data {
15521580 struct bpf_binary_header * header ;
1553- u8 * image ;
1581+ u8 * ro_image ;
1582+ struct bpf_binary_header * ro_header ;
15541583 struct jit_ctx ctx ;
15551584};
15561585
@@ -1559,12 +1588,14 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
15591588 int image_size , prog_size , extable_size , extable_align , extable_offset ;
15601589 struct bpf_prog * tmp , * orig_prog = prog ;
15611590 struct bpf_binary_header * header ;
1591+ struct bpf_binary_header * ro_header ;
15621592 struct arm64_jit_data * jit_data ;
15631593 bool was_classic = bpf_prog_was_classic (prog );
15641594 bool tmp_blinded = false;
15651595 bool extra_pass = false;
15661596 struct jit_ctx ctx ;
15671597 u8 * image_ptr ;
1598+ u8 * ro_image_ptr ;
15681599
15691600 if (!prog -> jit_requested )
15701601 return orig_prog ;
@@ -1591,8 +1622,11 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
15911622 }
15921623 if (jit_data -> ctx .offset ) {
15931624 ctx = jit_data -> ctx ;
1594- image_ptr = jit_data -> image ;
1625+ ro_image_ptr = jit_data -> ro_image ;
1626+ ro_header = jit_data -> ro_header ;
15951627 header = jit_data -> header ;
1628+ image_ptr = (void * )header + ((void * )ro_image_ptr
1629+ - (void * )ro_header );
15961630 extra_pass = true;
15971631 prog_size = sizeof (u32 ) * ctx .idx ;
15981632 goto skip_init_ctx ;
@@ -1637,63 +1671,81 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
16371671 /* also allocate space for plt target */
16381672 extable_offset = round_up (prog_size + PLT_TARGET_SIZE , extable_align );
16391673 image_size = extable_offset + extable_size ;
1640- header = bpf_jit_binary_alloc (image_size , & image_ptr ,
1641- sizeof (u32 ), jit_fill_hole );
1642- if (header == NULL ) {
1674+ ro_header = bpf_jit_binary_pack_alloc (image_size , & ro_image_ptr ,
1675+ sizeof (u32 ), & header , & image_ptr ,
1676+ jit_fill_hole );
1677+ if (!ro_header ) {
16431678 prog = orig_prog ;
16441679 goto out_off ;
16451680 }
16461681
16471682 /* 2. Now, the actual pass. */
16481683
1684+ /*
1685+ * Use the image(RW) for writing the JITed instructions. But also save
1686+ * the ro_image(RX) for calculating the offsets in the image. The RW
1687+ * image will be later copied to the RX image from where the program
1688+ * will run. The bpf_jit_binary_pack_finalize() will do this copy in the
1689+ * final step.
1690+ */
16491691 ctx .image = (__le32 * )image_ptr ;
1692+ ctx .ro_image = (__le32 * )ro_image_ptr ;
16501693 if (extable_size )
1651- prog -> aux -> extable = (void * )image_ptr + extable_offset ;
1694+ prog -> aux -> extable = (void * )ro_image_ptr + extable_offset ;
16521695skip_init_ctx :
16531696 ctx .idx = 0 ;
16541697 ctx .exentry_idx = 0 ;
16551698
16561699 build_prologue (& ctx , was_classic , prog -> aux -> exception_cb );
16571700
16581701 if (build_body (& ctx , extra_pass )) {
1659- bpf_jit_binary_free (header );
16601702 prog = orig_prog ;
1661- goto out_off ;
1703+ goto out_free_hdr ;
16621704 }
16631705
16641706 build_epilogue (& ctx , prog -> aux -> exception_cb );
16651707 build_plt (& ctx );
16661708
16671709 /* 3. Extra pass to validate JITed code. */
16681710 if (validate_ctx (& ctx )) {
1669- bpf_jit_binary_free (header );
16701711 prog = orig_prog ;
1671- goto out_off ;
1712+ goto out_free_hdr ;
16721713 }
16731714
16741715 /* And we're done. */
16751716 if (bpf_jit_enable > 1 )
16761717 bpf_jit_dump (prog -> len , prog_size , 2 , ctx .image );
16771718
1678- bpf_flush_icache (header , ctx .image + ctx .idx );
1679-
16801719 if (!prog -> is_func || extra_pass ) {
16811720 if (extra_pass && ctx .idx != jit_data -> ctx .idx ) {
16821721 pr_err_once ("multi-func JIT bug %d != %d\n" ,
16831722 ctx .idx , jit_data -> ctx .idx );
1684- bpf_jit_binary_free (header );
16851723 prog -> bpf_func = NULL ;
16861724 prog -> jited = 0 ;
16871725 prog -> jited_len = 0 ;
1726+ goto out_free_hdr ;
1727+ }
1728+ if (WARN_ON (bpf_jit_binary_pack_finalize (prog , ro_header ,
1729+ header ))) {
1730+ /* ro_header has been freed */
1731+ ro_header = NULL ;
1732+ prog = orig_prog ;
16881733 goto out_off ;
16891734 }
1690- bpf_jit_binary_lock_ro (header );
1735+ /*
1736+ * The instructions have now been copied to the ROX region from
1737+ * where they will execute. Now the data cache has to be cleaned to
1738+ * the PoU and the I-cache has to be invalidated for the VAs.
1739+ */
1740+ bpf_flush_icache (ro_header , ctx .ro_image + ctx .idx );
16911741 } else {
16921742 jit_data -> ctx = ctx ;
1693- jit_data -> image = image_ptr ;
1743+ jit_data -> ro_image = ro_image_ptr ;
16941744 jit_data -> header = header ;
1745+ jit_data -> ro_header = ro_header ;
16951746 }
1696- prog -> bpf_func = (void * )ctx .image ;
1747+
1748+ prog -> bpf_func = (void * )ctx .ro_image ;
16971749 prog -> jited = 1 ;
16981750 prog -> jited_len = prog_size ;
16991751
@@ -1714,13 +1766,28 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
17141766 bpf_jit_prog_release_other (prog , prog == orig_prog ?
17151767 tmp : orig_prog );
17161768 return prog ;
1769+
1770+ out_free_hdr :
1771+ if (header ) {
1772+ bpf_arch_text_copy (& ro_header -> size , & header -> size ,
1773+ sizeof (header -> size ));
1774+ bpf_jit_binary_pack_free (ro_header , header );
1775+ }
1776+ goto out_off ;
17171777}
17181778
17191779bool bpf_jit_supports_kfunc_call (void )
17201780{
17211781 return true;
17221782}
17231783
1784+ void * bpf_arch_text_copy (void * dst , void * src , size_t len )
1785+ {
1786+ if (!aarch64_insn_copy (dst , src , len ))
1787+ return ERR_PTR (- EINVAL );
1788+ return dst ;
1789+ }
1790+
17241791u64 bpf_jit_alloc_exec_limit (void )
17251792{
17261793 return VMALLOC_END - VMALLOC_START ;
@@ -2359,3 +2426,27 @@ bool bpf_jit_supports_exceptions(void)
23592426 */
23602427 return true;
23612428}
2429+
2430+ void bpf_jit_free (struct bpf_prog * prog )
2431+ {
2432+ if (prog -> jited ) {
2433+ struct arm64_jit_data * jit_data = prog -> aux -> jit_data ;
2434+ struct bpf_binary_header * hdr ;
2435+
2436+ /*
2437+ * If we fail the final pass of JIT (from jit_subprogs),
2438+ * the program may not be finalized yet. Call finalize here
2439+ * before freeing it.
2440+ */
2441+ if (jit_data ) {
2442+ bpf_arch_text_copy (& jit_data -> ro_header -> size , & jit_data -> header -> size ,
2443+ sizeof (jit_data -> header -> size ));
2444+ kfree (jit_data );
2445+ }
2446+ hdr = bpf_jit_binary_pack_hdr (prog );
2447+ bpf_jit_binary_pack_free (hdr , NULL );
2448+ WARN_ON_ONCE (!bpf_prog_kallsyms_verify_off (prog ));
2449+ }
2450+
2451+ bpf_prog_unlock_free (prog );
2452+ }
0 commit comments