Le 06/07/2021 à 09:32, Ravi Bangoria a écrit :
BPF load instruction with BPF_PROBE_MEM mode can cause a fault
inside kernel. Append exception table for such instructions
within BPF program.
Can you do the same for 32bit ?
@@ -89,6 +89,8 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
{
u32 proglen;
u32 alloclen;
+ u32 extable_len = 0;
+ u32 fixup_len = 0;
Setting those to 0 doesn't seem to be needed, as it doesn't seem to exist any path to skip the setting below. You should not perform unnecessary init at declaration as it is error prone.
@@ -234,7 +247,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
fp->bpf_func = (void *)image;
fp->jited = 1;
- fp->jited_len = alloclen;
+ fp->jited_len = proglen + FUNCTION_DESCR_SIZE;
bpf_flush_icache(bpf_hdr, (u8 *)bpf_hdr + (bpf_hdr->pages * PAGE_SIZE));
if (!fp->is_func || extra_pass) {
This hunk does not apply on latest powerpc tree. You are missing commit 62e3d4210ac9c
+static int add_extable_entry(struct bpf_prog *fp, u32 *image, int pass,
+ u32 code, struct codegen_context *ctx, int dst_reg)
+{
+ off_t offset;
+ unsigned long pc;
+ struct exception_table_entry *ex;
+ u32 *fixup;
+
+ /* Populate extable entries only in the last pass */
+ if (pass != 2 || BPF_MODE(code) != BPF_PROBE_MEM)
'code' is only used for that test, can you do the test before calling add_extable_entry() ?
+ return 0;
+
+ if (!fp->aux->extable ||
+ WARN_ON_ONCE(ctx->exentry_idx >= fp->aux->num_exentries))
+ return -EINVAL;
+
+ pc = (unsigned long)&image[ctx->idx - 1];
You should call this function before incrementing ctx->idx
+
+ fixup = (void *)fp->aux->extable -
+ (fp->aux->num_exentries * BPF_FIXUP_LEN) +
+ (ctx->exentry_idx * BPF_FIXUP_LEN);
+
+ fixup[0] = PPC_RAW_XOR(dst_reg, dst_reg, dst_reg);
Prefered way to clear a reg in according to ISA is to do 'li reg, 0'
+ fixup[1] = (PPC_INST_BRANCH |
+ (((long)(pc + 4) - (long)&fixup[1]) & 0x03fffffc));
Would be nice if we could have a PPC_RAW_BRANCH() stuff, we could do something like PPC_RAW_BRANCH((long)(pc + 4) - (long)&fixup[1])
@@ -710,25 +752,41 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
*/
/* dst = *(u8 *)(ul) (src + off) */
case BPF_LDX | BPF_MEM | BPF_B:
+ case BPF_LDX | BPF_PROBE_MEM | BPF_B:
Could do:
+ case BPF_LDX | BPF_PROBE_MEM | BPF_B:
+ ret = add_extable_entry(fp, image, pass, code, ctx, dst_reg);
+ if (ret)
+ return ret;
case BPF_LDX | BPF_MEM | BPF_B: