bpf: x64: add JIT support for multi-function programs
[linux-2.6-block.git] / kernel / bpf / core.c
index bda911644b1cba4fe6b05033df9593886ff89f1f..768e0a02d8c8a94229f26f6bfda68fc3f7ce6383 100644 (file)
@@ -722,7 +722,7 @@ struct bpf_prog *bpf_jit_blind_constants(struct bpf_prog *prog)
        struct bpf_insn *insn;
        int i, rewritten;
 
-       if (!bpf_jit_blinding_enabled(prog))
+       if (!bpf_jit_blinding_enabled(prog) || prog->blinded)
                return prog;
 
        clone = bpf_prog_clone_create(prog, GFP_USER);
@@ -764,6 +764,7 @@ struct bpf_prog *bpf_jit_blind_constants(struct bpf_prog *prog)
                i        += insn_delta;
        }
 
+       clone->blinded = 1;
        return clone;
 }
 #endif /* CONFIG_BPF_JIT */
@@ -1629,11 +1630,19 @@ int bpf_prog_array_copy_info(struct bpf_prog_array __rcu *array,
 static void bpf_prog_free_deferred(struct work_struct *work)
 {
        struct bpf_prog_aux *aux;
+       int i;
 
        aux = container_of(work, struct bpf_prog_aux, work);
        if (bpf_prog_is_dev_bound(aux))
                bpf_prog_offload_destroy(aux->prog);
-       bpf_jit_free(aux->prog);
+       for (i = 0; i < aux->func_cnt; i++)
+               bpf_jit_free(aux->func[i]);
+       if (aux->func_cnt) {
+               kfree(aux->func);
+               bpf_prog_unlock_free(aux->prog);
+       } else {
+               bpf_jit_free(aux->prog);
+       }
 }
 
 /* Free internal BPF program */