ebpf: migrate bpf_prog's flags to bitfield
authorDaniel Borkmann <daniel@iogearbox.net>
Tue, 29 Sep 2015 23:41:50 +0000 (01:41 +0200)
committerDavid S. Miller <davem@davemloft.net>
Sat, 3 Oct 2015 12:02:39 +0000 (05:02 -0700)
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: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@plumgrid.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
arch/arm/net/bpf_jit_32.c
arch/arm64/net/bpf_jit_comp.c
arch/mips/net/bpf_jit.c
arch/powerpc/net/bpf_jit_comp.c
arch/s390/net/bpf_jit_comp.c
arch/sparc/net/bpf_jit_comp.c
arch/x86/net/bpf_jit_comp.c
include/linux/filter.h
kernel/bpf/core.c
kernel/bpf/syscall.c
net/core/filter.c

index 876060bcceeb3ea989e24fe18b42910f3cce4058..0df5fd561513b28a4b6b6cd99d342a6db23d3ac5 100644 (file)
@@ -1047,7 +1047,7 @@ void bpf_jit_compile(struct bpf_prog *fp)
 
        set_memory_ro((unsigned long)header, header->pages);
        fp->bpf_func = (void *)ctx.target;
-       fp->jited = true;
+       fp->jited = 1;
 out:
        kfree(ctx.offsets);
        return;
index c047598b09e051cfdad2b7e1f24c21bb6e6153f8..a44e5293c6f58adb288e9c0d0549fcbe26c98daa 100644 (file)
@@ -744,7 +744,7 @@ void bpf_int_jit_compile(struct bpf_prog *prog)
 
        set_memory_ro((unsigned long)header, header->pages);
        prog->bpf_func = (void *)ctx.image;
-       prog->jited = true;
+       prog->jited = 1;
 out:
        kfree(ctx.offset);
 }
index 0c4a133f6216012c303e2b4105214c422a327976..77cb27309db27f781ec9862037074d39e928401a 100644 (file)
@@ -1251,7 +1251,7 @@ void bpf_jit_compile(struct bpf_prog *fp)
                bpf_jit_dump(fp->len, alloc_size, 2, ctx.target);
 
        fp->bpf_func = (void *)ctx.target;
-       fp->jited = true;
+       fp->jited = 1;
 
 out:
        kfree(ctx.offsets);
index 17cea18a09d32f103aa453c645a7324739c58ffe..04782164ee67d8a570bcb4b4ee166dc6809753de 100644 (file)
@@ -679,7 +679,7 @@ void bpf_jit_compile(struct bpf_prog *fp)
                ((u64 *)image)[1] = local_paca->kernel_toc;
 #endif
                fp->bpf_func = (void *)image;
-               fp->jited = true;
+               fp->jited = 1;
        }
 out:
        kfree(addrs);
index eeda051442c3d0de0bec154b9aa3f15fe85e6de8..9a0c4c22e53670b1d813f3ddfb328b76c8e06c78 100644 (file)
@@ -1310,7 +1310,7 @@ void bpf_int_jit_compile(struct bpf_prog *fp)
        if (jit.prg_buf) {
                set_memory_ro((unsigned long)header, header->pages);
                fp->bpf_func = (void *) jit.prg_buf;
-               fp->jited = true;
+               fp->jited = 1;
        }
 free_addrs:
        kfree(jit.addrs);
index f8b9f71b9a2b631816df61ff9b95657786e7cd51..22564f5f23647a6f54752052091d2c74c194bccf 100644 (file)
@@ -812,7 +812,7 @@ cond_branch:                        f_offset = addrs[i + filter[i].jf];
        if (image) {
                bpf_flush_icache(image, image + proglen);
                fp->bpf_func = (void *)image;
-               fp->jited = true;
+               fp->jited = 1;
        }
 out:
        kfree(addrs);
index 70efcd0940f9f34b8649872b5b1ac44853a8e5f0..75991979f667f1b9e0e320fa47852969d1066983 100644 (file)
@@ -1109,7 +1109,7 @@ void bpf_int_jit_compile(struct bpf_prog *prog)
                bpf_flush_icache(header, image + proglen);
                set_memory_ro((unsigned long)header, header->pages);
                prog->bpf_func = (void *)image;
-               prog->jited = true;
+               prog->jited = 1;
        }
 out:
        kfree(addrs);
index fa2cab985e577681c801f8861c299ad938ec9ffc..bad618f316d7b23aea947bc0647ae1a42187c5e9 100644 (file)
@@ -326,8 +326,10 @@ struct bpf_binary_header {
 
 struct bpf_prog {
        u16                     pages;          /* Number of allocated pages */
-       bool                    jited;          /* Is our filter JIT'ed? */
-       bool                    gpl_compatible; /* Is our filter GPL compatible? */
+       kmemcheck_bitfield_begin(meta);
+       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 */
        enum bpf_prog_type      type;           /* Type of BPF program */
        struct bpf_prog_aux     *aux;           /* Auxiliary fields */
index 67c380cfa9ca5b6ed8e48b69b38ba3c611d51a65..c8855c2a7a480dfd2908b02ec63569e1c448f9fa 100644 (file)
@@ -82,6 +82,8 @@ struct bpf_prog *bpf_prog_alloc(unsigned int size, gfp_t gfp_extra_flags)
        if (fp == NULL)
                return NULL;
 
+       kmemcheck_annotate_bitfield(fp, meta);
+
        aux = kzalloc(sizeof(*aux), GFP_KERNEL | gfp_extra_flags);
        if (aux == NULL) {
                vfree(fp);
@@ -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);
        if (fp != NULL) {
+               kmemcheck_annotate_bitfield(fp, meta);
+
                memcpy(fp, fp_old, fp_old->pages * PAGE_SIZE);
                fp->pages = size / PAGE_SIZE;
 
index 35bac8e8b071ae5aa57e3837f4363d8dcd741158..2190ab14b76348aae596350a7f22b8809694b557 100644 (file)
@@ -553,10 +553,10 @@ static int bpf_prog_load(union bpf_attr *attr)
                goto free_prog;
 
        prog->orig_prog = NULL;
-       prog->jited = false;
+       prog->jited = 0;
 
        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 */
        err = find_prog_type(type, prog);
index 60e3fe7c59c0e6b15797f7f5af6f4e7765dd80ab..04664acb86ce43e97a636bfa6bd1258d7ce970b9 100644 (file)
@@ -1001,7 +1001,7 @@ static struct bpf_prog *bpf_prepare_filter(struct bpf_prog *fp,
        int err;
 
        fp->bpf_func = NULL;
-       fp->jited = false;
+       fp->jited = 0;
 
        err = bpf_check_classic(fp->insns, fp->len);
        if (err) {