diff options
Diffstat (limited to 'kernel/bpf/core.c')
-rw-r--r-- | kernel/bpf/core.c | 38 |
1 files changed, 35 insertions, 3 deletions
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index 6377225b2082..b1a3545d0ec8 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c | |||
@@ -553,7 +553,6 @@ bool is_bpf_text_address(unsigned long addr) | |||
553 | int bpf_get_kallsym(unsigned int symnum, unsigned long *value, char *type, | 553 | int bpf_get_kallsym(unsigned int symnum, unsigned long *value, char *type, |
554 | char *sym) | 554 | char *sym) |
555 | { | 555 | { |
556 | unsigned long symbol_start, symbol_end; | ||
557 | struct bpf_prog_aux *aux; | 556 | struct bpf_prog_aux *aux; |
558 | unsigned int it = 0; | 557 | unsigned int it = 0; |
559 | int ret = -ERANGE; | 558 | int ret = -ERANGE; |
@@ -566,10 +565,9 @@ int bpf_get_kallsym(unsigned int symnum, unsigned long *value, char *type, | |||
566 | if (it++ != symnum) | 565 | if (it++ != symnum) |
567 | continue; | 566 | continue; |
568 | 567 | ||
569 | bpf_get_prog_addr_region(aux->prog, &symbol_start, &symbol_end); | ||
570 | bpf_get_prog_name(aux->prog, sym); | 568 | bpf_get_prog_name(aux->prog, sym); |
571 | 569 | ||
572 | *value = symbol_start; | 570 | *value = (unsigned long)aux->prog->bpf_func; |
573 | *type = BPF_SYM_ELF_TYPE; | 571 | *type = BPF_SYM_ELF_TYPE; |
574 | 572 | ||
575 | ret = 0; | 573 | ret = 0; |
@@ -674,6 +672,40 @@ void __weak bpf_jit_free(struct bpf_prog *fp) | |||
674 | bpf_prog_unlock_free(fp); | 672 | bpf_prog_unlock_free(fp); |
675 | } | 673 | } |
676 | 674 | ||
675 | int bpf_jit_get_func_addr(const struct bpf_prog *prog, | ||
676 | const struct bpf_insn *insn, bool extra_pass, | ||
677 | u64 *func_addr, bool *func_addr_fixed) | ||
678 | { | ||
679 | s16 off = insn->off; | ||
680 | s32 imm = insn->imm; | ||
681 | u8 *addr; | ||
682 | |||
683 | *func_addr_fixed = insn->src_reg != BPF_PSEUDO_CALL; | ||
684 | if (!*func_addr_fixed) { | ||
685 | /* Place-holder address till the last pass has collected | ||
686 | * all addresses for JITed subprograms in which case we | ||
687 | * can pick them up from prog->aux. | ||
688 | */ | ||
689 | if (!extra_pass) | ||
690 | addr = NULL; | ||
691 | else if (prog->aux->func && | ||
692 | off >= 0 && off < prog->aux->func_cnt) | ||
693 | addr = (u8 *)prog->aux->func[off]->bpf_func; | ||
694 | else | ||
695 | return -EINVAL; | ||
696 | } else { | ||
697 | /* Address of a BPF helper call. Since part of the core | ||
698 | * kernel, it's always at a fixed location. __bpf_call_base | ||
699 | * and the helper with imm relative to it are both in core | ||
700 | * kernel. | ||
701 | */ | ||
702 | addr = (u8 *)__bpf_call_base + imm; | ||
703 | } | ||
704 | |||
705 | *func_addr = (unsigned long)addr; | ||
706 | return 0; | ||
707 | } | ||
708 | |||
677 | static int bpf_jit_blind_insn(const struct bpf_insn *from, | 709 | static int bpf_jit_blind_insn(const struct bpf_insn *from, |
678 | const struct bpf_insn *aux, | 710 | const struct bpf_insn *aux, |
679 | struct bpf_insn *to_buff) | 711 | struct bpf_insn *to_buff) |