Commit a91263d5 authored by Daniel Borkmann's avatar Daniel Borkmann Committed by David S. Miller

ebpf: migrate bpf_prog's flags to bitfield

As we need to add further flags to the bpf_prog structure, lets migrate
both bools to a bitfield representation. The size of the base structure
(excluding insns) remains unchanged at 40 bytes.

Add also tags for the kmemchecker, so that it doesn't throw false
positives. Even in case gcc would generate suboptimal code, it's not
being accessed in performance critical paths.
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Acked-by: default avatarAlexei Starovoitov <ast@plumgrid.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent bd8762be
...@@ -1047,7 +1047,7 @@ void bpf_jit_compile(struct bpf_prog *fp) ...@@ -1047,7 +1047,7 @@ void bpf_jit_compile(struct bpf_prog *fp)
set_memory_ro((unsigned long)header, header->pages); set_memory_ro((unsigned long)header, header->pages);
fp->bpf_func = (void *)ctx.target; fp->bpf_func = (void *)ctx.target;
fp->jited = true; fp->jited = 1;
out: out:
kfree(ctx.offsets); kfree(ctx.offsets);
return; return;
......
...@@ -744,7 +744,7 @@ void bpf_int_jit_compile(struct bpf_prog *prog) ...@@ -744,7 +744,7 @@ void bpf_int_jit_compile(struct bpf_prog *prog)
set_memory_ro((unsigned long)header, header->pages); set_memory_ro((unsigned long)header, header->pages);
prog->bpf_func = (void *)ctx.image; prog->bpf_func = (void *)ctx.image;
prog->jited = true; prog->jited = 1;
out: out:
kfree(ctx.offset); kfree(ctx.offset);
} }
......
...@@ -1251,7 +1251,7 @@ void bpf_jit_compile(struct bpf_prog *fp) ...@@ -1251,7 +1251,7 @@ void bpf_jit_compile(struct bpf_prog *fp)
bpf_jit_dump(fp->len, alloc_size, 2, ctx.target); bpf_jit_dump(fp->len, alloc_size, 2, ctx.target);
fp->bpf_func = (void *)ctx.target; fp->bpf_func = (void *)ctx.target;
fp->jited = true; fp->jited = 1;
out: out:
kfree(ctx.offsets); kfree(ctx.offsets);
......
...@@ -679,7 +679,7 @@ void bpf_jit_compile(struct bpf_prog *fp) ...@@ -679,7 +679,7 @@ void bpf_jit_compile(struct bpf_prog *fp)
((u64 *)image)[1] = local_paca->kernel_toc; ((u64 *)image)[1] = local_paca->kernel_toc;
#endif #endif
fp->bpf_func = (void *)image; fp->bpf_func = (void *)image;
fp->jited = true; fp->jited = 1;
} }
out: out:
kfree(addrs); kfree(addrs);
......
...@@ -1310,7 +1310,7 @@ void bpf_int_jit_compile(struct bpf_prog *fp) ...@@ -1310,7 +1310,7 @@ void bpf_int_jit_compile(struct bpf_prog *fp)
if (jit.prg_buf) { if (jit.prg_buf) {
set_memory_ro((unsigned long)header, header->pages); set_memory_ro((unsigned long)header, header->pages);
fp->bpf_func = (void *) jit.prg_buf; fp->bpf_func = (void *) jit.prg_buf;
fp->jited = true; fp->jited = 1;
} }
free_addrs: free_addrs:
kfree(jit.addrs); kfree(jit.addrs);
......
...@@ -812,7 +812,7 @@ cond_branch: f_offset = addrs[i + filter[i].jf]; ...@@ -812,7 +812,7 @@ cond_branch: f_offset = addrs[i + filter[i].jf];
if (image) { if (image) {
bpf_flush_icache(image, image + proglen); bpf_flush_icache(image, image + proglen);
fp->bpf_func = (void *)image; fp->bpf_func = (void *)image;
fp->jited = true; fp->jited = 1;
} }
out: out:
kfree(addrs); kfree(addrs);
......
...@@ -1109,7 +1109,7 @@ void bpf_int_jit_compile(struct bpf_prog *prog) ...@@ -1109,7 +1109,7 @@ void bpf_int_jit_compile(struct bpf_prog *prog)
bpf_flush_icache(header, image + proglen); bpf_flush_icache(header, image + proglen);
set_memory_ro((unsigned long)header, header->pages); set_memory_ro((unsigned long)header, header->pages);
prog->bpf_func = (void *)image; prog->bpf_func = (void *)image;
prog->jited = true; prog->jited = 1;
} }
out: out:
kfree(addrs); kfree(addrs);
......
...@@ -326,8 +326,10 @@ struct bpf_binary_header { ...@@ -326,8 +326,10 @@ struct bpf_binary_header {
struct bpf_prog { struct bpf_prog {
u16 pages; /* Number of allocated pages */ u16 pages; /* Number of allocated pages */
bool jited; /* Is our filter JIT'ed? */ kmemcheck_bitfield_begin(meta);
bool gpl_compatible; /* Is our filter GPL compatible? */ u16 jited:1, /* Is our filter JIT'ed? */
gpl_compatible:1; /* Is filter GPL compatible? */
kmemcheck_bitfield_end(meta);
u32 len; /* Number of filter blocks */ u32 len; /* Number of filter blocks */
enum bpf_prog_type type; /* Type of BPF program */ enum bpf_prog_type type; /* Type of BPF program */
struct bpf_prog_aux *aux; /* Auxiliary fields */ struct bpf_prog_aux *aux; /* Auxiliary fields */
......
...@@ -82,6 +82,8 @@ struct bpf_prog *bpf_prog_alloc(unsigned int size, gfp_t gfp_extra_flags) ...@@ -82,6 +82,8 @@ struct bpf_prog *bpf_prog_alloc(unsigned int size, gfp_t gfp_extra_flags)
if (fp == NULL) if (fp == NULL)
return NULL; return NULL;
kmemcheck_annotate_bitfield(fp, meta);
aux = kzalloc(sizeof(*aux), GFP_KERNEL | gfp_extra_flags); aux = kzalloc(sizeof(*aux), GFP_KERNEL | gfp_extra_flags);
if (aux == NULL) { if (aux == NULL) {
vfree(fp); vfree(fp);
...@@ -110,6 +112,8 @@ struct bpf_prog *bpf_prog_realloc(struct bpf_prog *fp_old, unsigned int size, ...@@ -110,6 +112,8 @@ struct bpf_prog *bpf_prog_realloc(struct bpf_prog *fp_old, unsigned int size,
fp = __vmalloc(size, gfp_flags, PAGE_KERNEL); fp = __vmalloc(size, gfp_flags, PAGE_KERNEL);
if (fp != NULL) { if (fp != NULL) {
kmemcheck_annotate_bitfield(fp, meta);
memcpy(fp, fp_old, fp_old->pages * PAGE_SIZE); memcpy(fp, fp_old, fp_old->pages * PAGE_SIZE);
fp->pages = size / PAGE_SIZE; fp->pages = size / PAGE_SIZE;
......
...@@ -553,10 +553,10 @@ static int bpf_prog_load(union bpf_attr *attr) ...@@ -553,10 +553,10 @@ static int bpf_prog_load(union bpf_attr *attr)
goto free_prog; goto free_prog;
prog->orig_prog = NULL; prog->orig_prog = NULL;
prog->jited = false; prog->jited = 0;
atomic_set(&prog->aux->refcnt, 1); atomic_set(&prog->aux->refcnt, 1);
prog->gpl_compatible = is_gpl; prog->gpl_compatible = is_gpl ? 1 : 0;
/* find program type: socket_filter vs tracing_filter */ /* find program type: socket_filter vs tracing_filter */
err = find_prog_type(type, prog); err = find_prog_type(type, prog);
......
...@@ -1001,7 +1001,7 @@ static struct bpf_prog *bpf_prepare_filter(struct bpf_prog *fp, ...@@ -1001,7 +1001,7 @@ static struct bpf_prog *bpf_prepare_filter(struct bpf_prog *fp,
int err; int err;
fp->bpf_func = NULL; fp->bpf_func = NULL;
fp->jited = false; fp->jited = 0;
err = bpf_check_classic(fp->insns, fp->len); err = bpf_check_classic(fp->insns, fp->len);
if (err) { if (err) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment