@@ -461,10 +461,10 @@ static int add_exception_handler(const struct bpf_insn *insn,
461461 int dst_reg )
462462{
463463 unsigned long pc ;
464- off_t offset ;
464+ off_t ins_offset , fixup_offset ;
465465 struct exception_table_entry * ex ;
466466
467- if (!ctx -> image || !ctx -> prog -> aux -> extable )
467+ if (!ctx -> image || !ctx -> ro_image || ! ctx -> prog -> aux -> extable )
468468 return 0 ;
469469
470470 if (BPF_MODE (insn -> code ) != BPF_PROBE_MEM &&
@@ -475,28 +475,42 @@ static int add_exception_handler(const struct bpf_insn *insn,
475475 return - EINVAL ;
476476
477477 ex = & ctx -> prog -> aux -> extable [ctx -> num_exentries ];
478- pc = (unsigned long )& ctx -> image [ctx -> idx - 1 ];
478+ pc = (unsigned long )& ctx -> ro_image [ctx -> idx - 1 ];
479479
480- offset = pc - (long )& ex -> insn ;
481- if (WARN_ON_ONCE (offset >= 0 || offset < INT_MIN ))
480+ /*
481+ * This is the relative offset of the instruction that may fault from
482+ * the exception table itself. This will be written to the exception
483+ * table and if this instruction faults, the destination register will
484+ * be set to '0' and the execution will jump to the next instruction.
485+ */
486+ ins_offset = pc - (long )& ex -> insn ;
487+ if (WARN_ON_ONCE (ins_offset >= 0 || ins_offset < INT_MIN ))
482488 return - ERANGE ;
483489
484- ex -> insn = offset ;
485-
486490 /*
487491 * Since the extable follows the program, the fixup offset is always
488492 * negative and limited to BPF_JIT_REGION_SIZE. Store a positive value
489493 * to keep things simple, and put the destination register in the upper
490494 * bits. We don't need to worry about buildtime or runtime sort
491495 * modifying the upper bits because the table is already sorted, and
492496 * isn't part of the main exception table.
497+ *
498+ * The fixup_offset is set to the next instruction from the instruction
499+ * that may fault. The execution will jump to this after handling the fault.
493500 */
494- offset = (long )& ex -> fixup - (pc + LOONGARCH_INSN_SIZE );
495- if (!FIELD_FIT (BPF_FIXUP_OFFSET_MASK , offset ))
501+ fixup_offset = (long )& ex -> fixup - (pc + LOONGARCH_INSN_SIZE );
502+ if (!FIELD_FIT (BPF_FIXUP_OFFSET_MASK , fixup_offset ))
496503 return - ERANGE ;
497504
505+ /*
506+ * The offsets above have been calculated using the RO buffer but we
507+ * need to use the R/W buffer for writes. Switch ex to rw buffer for writing.
508+ */
509+ ex = (void * )ctx -> image + ((void * )ex - (void * )ctx -> ro_image );
510+ ex -> insn = ins_offset ;
511+ ex -> fixup = FIELD_PREP (BPF_FIXUP_OFFSET_MASK , fixup_offset ) |
512+ FIELD_PREP (BPF_FIXUP_REG_MASK , dst_reg );
498513 ex -> type = EX_TYPE_BPF ;
499- ex -> fixup = FIELD_PREP (BPF_FIXUP_OFFSET_MASK , offset ) | FIELD_PREP (BPF_FIXUP_REG_MASK , dst_reg );
500514
501515 ctx -> num_exentries ++ ;
502516
@@ -1829,11 +1843,12 @@ int arch_bpf_trampoline_size(const struct btf_func_model *m, u32 flags,
18291843struct bpf_prog * bpf_int_jit_compile (struct bpf_prog * prog )
18301844{
18311845 bool tmp_blinded = false, extra_pass = false;
1832- u8 * image_ptr ;
1846+ u8 * image_ptr , * ro_image_ptr ;
18331847 int image_size , prog_size , extable_size ;
18341848 struct jit_ctx ctx ;
18351849 struct jit_data * jit_data ;
18361850 struct bpf_binary_header * header ;
1851+ struct bpf_binary_header * ro_header ;
18371852 struct bpf_prog * tmp , * orig_prog = prog ;
18381853
18391854 /*
@@ -1868,8 +1883,10 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
18681883 }
18691884 if (jit_data -> ctx .offset ) {
18701885 ctx = jit_data -> ctx ;
1871- image_ptr = jit_data -> image ;
1886+ ro_header = jit_data -> ro_header ;
1887+ ro_image_ptr = (void * )ctx .ro_image ;
18721888 header = jit_data -> header ;
1889+ image_ptr = (void * )header + ((void * )ro_image_ptr - (void * )ro_header );
18731890 extra_pass = true;
18741891 prog_size = sizeof (u32 ) * ctx .idx ;
18751892 goto skip_init_ctx ;
@@ -1903,66 +1920,73 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
19031920 prog_size = sizeof (u32 ) * ctx .idx ;
19041921 image_size = prog_size + extable_size ;
19051922 /* Now we know the size of the structure to make */
1906- header = bpf_jit_binary_alloc (image_size , & image_ptr ,
1907- sizeof ( u32 ) , jit_fill_hole );
1908- if (header == NULL ) {
1923+ ro_header = bpf_jit_binary_pack_alloc (image_size , & ro_image_ptr , sizeof ( u32 ) ,
1924+ & header , & image_ptr , jit_fill_hole );
1925+ if (! ro_header ) {
19091926 prog = orig_prog ;
19101927 goto out_offset ;
19111928 }
19121929
19131930 /* 2. Now, the actual pass to generate final JIT code */
1931+ /*
1932+ * Use the image (RW) for writing the JITed instructions. But also save
1933+ * the ro_image (RX) for calculating the offsets in the image. The RW
1934+ * image will be later copied to the RX image from where the program will
1935+ * run. The bpf_jit_binary_pack_finalize() will do this copy in the final
1936+ * step.
1937+ */
19141938 ctx .image = (union loongarch_instruction * )image_ptr ;
1939+ ctx .ro_image = (union loongarch_instruction * )ro_image_ptr ;
19151940 if (extable_size )
1916- prog -> aux -> extable = (void * )image_ptr + prog_size ;
1941+ prog -> aux -> extable = (void * )ro_image_ptr + prog_size ;
19171942
19181943skip_init_ctx :
19191944 ctx .idx = 0 ;
19201945 ctx .num_exentries = 0 ;
19211946
19221947 build_prologue (& ctx );
19231948 if (build_body (& ctx , extra_pass )) {
1924- bpf_jit_binary_free (header );
19251949 prog = orig_prog ;
1926- goto out_offset ;
1950+ goto out_free ;
19271951 }
19281952 build_epilogue (& ctx );
19291953
19301954 /* 3. Extra pass to validate JITed code */
19311955 if (validate_ctx (& ctx )) {
1932- bpf_jit_binary_free (header );
19331956 prog = orig_prog ;
1934- goto out_offset ;
1957+ goto out_free ;
19351958 }
19361959
19371960 /* And we're done */
19381961 if (bpf_jit_enable > 1 )
19391962 bpf_jit_dump (prog -> len , prog_size , 2 , ctx .image );
19401963
1941- /* Update the icache */
1942- flush_icache_range ((unsigned long )header , (unsigned long )(ctx .image + ctx .idx ));
1943-
19441964 if (!prog -> is_func || extra_pass ) {
1945- int err ;
1946-
19471965 if (extra_pass && ctx .idx != jit_data -> ctx .idx ) {
19481966 pr_err_once ("multi-func JIT bug %d != %d\n" ,
19491967 ctx .idx , jit_data -> ctx .idx );
19501968 goto out_free ;
19511969 }
1952- err = bpf_jit_binary_lock_ro ( header );
1953- if ( err ) {
1954- pr_err_once ( "bpf_jit_binary_lock_ro() returned %d\n" ,
1955- err ) ;
1970+ if ( WARN_ON ( bpf_jit_binary_pack_finalize ( ro_header , header ))) {
1971+ /* ro_header has been freed */
1972+ ro_header = NULL ;
1973+ prog = orig_prog ;
19561974 goto out_free ;
19571975 }
1976+ /*
1977+ * The instructions have now been copied to the ROX region from
1978+ * where they will execute. Now the data cache has to be cleaned
1979+ * to the PoU and the I-cache has to be invalidated for the VAs.
1980+ */
1981+ bpf_flush_icache (ro_header , ctx .ro_image + ctx .idx );
19581982 } else {
19591983 jit_data -> ctx = ctx ;
1960- jit_data -> image = image_ptr ;
19611984 jit_data -> header = header ;
1985+ jit_data -> ro_header = ro_header ;
19621986 }
19631987 prog -> jited = 1 ;
19641988 prog -> jited_len = prog_size ;
1965- prog -> bpf_func = (void * )ctx .image ;
1989+ prog -> bpf_func = (void * )ctx .ro_image ;
19661990
19671991 if (!prog -> is_func || extra_pass ) {
19681992 int i ;
@@ -1982,17 +2006,39 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
19822006 if (tmp_blinded )
19832007 bpf_jit_prog_release_other (prog , prog == orig_prog ? tmp : orig_prog );
19842008
1985-
19862009 return prog ;
19872010
19882011out_free :
1989- bpf_jit_binary_free (header );
1990- prog -> bpf_func = NULL ;
1991- prog -> jited = 0 ;
1992- prog -> jited_len = 0 ;
2012+ if (header ) {
2013+ bpf_arch_text_copy ( & ro_header -> size , & header -> size , sizeof ( header -> size )) ;
2014+ bpf_jit_binary_pack_free ( ro_header , header ) ;
2015+ }
19932016 goto out_offset ;
19942017}
19952018
2019+ void bpf_jit_free (struct bpf_prog * prog )
2020+ {
2021+ if (prog -> jited ) {
2022+ struct jit_data * jit_data = prog -> aux -> jit_data ;
2023+ struct bpf_binary_header * hdr ;
2024+
2025+ /*
2026+ * If we fail the final pass of JIT (from jit_subprogs), the
2027+ * program may not be finalized yet. Call finalize here before
2028+ * freeing it.
2029+ */
2030+ if (jit_data ) {
2031+ bpf_jit_binary_pack_finalize (jit_data -> ro_header , jit_data -> header );
2032+ kfree (jit_data );
2033+ }
2034+ hdr = bpf_jit_binary_pack_hdr (prog );
2035+ bpf_jit_binary_pack_free (hdr , NULL );
2036+ WARN_ON_ONCE (!bpf_prog_kallsyms_verify_off (prog ));
2037+ }
2038+
2039+ bpf_prog_unlock_free (prog );
2040+ }
2041+
19962042bool bpf_jit_bypass_spec_v1 (void )
19972043{
19982044 return true;
0 commit comments