diff options
| author | Daniel Borkmann <dborkman@redhat.com> | 2014-09-10 09:01:02 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2014-09-10 17:05:07 -0400 |
| commit | b954d83421d51d822c42e5ab7b65069b25ad3005 (patch) | |
| tree | 0a419ab76ac8abbc459472b7c5b79800bc3cdc45 | |
| parent | 17fa1f983649580772e95ee95e2c096baa650219 (diff) | |
net: bpf: only build bpf_jit_binary_{alloc, free}() when jit selected
Since BPF JIT depends on the availability of module_alloc() and
module_free() helpers (HAVE_BPF_JIT and MODULES), we better build
that code only in case we have BPF_JIT in our config enabled, just
like with other JIT code. Fixes builds for arm/marzen_defconfig
and sh/rsk7269_defconfig.
====================
kernel/built-in.o: In function `bpf_jit_binary_alloc':
/home/cwang/linux/kernel/bpf/core.c:144: undefined reference to `module_alloc'
kernel/built-in.o: In function `bpf_jit_binary_free':
/home/cwang/linux/kernel/bpf/core.c:164: undefined reference to `module_free'
make: *** [vmlinux] Error 1
====================
Reported-by: Fengguang Wu <fengguang.wu@intel.com>
Fixes: 738cbe72adc5 ("net: bpf: consolidate JIT binary allocator")
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
Acked-by: Alexei Starovoitov <ast@plumgrid.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | include/linux/filter.h | 78 | ||||
| -rw-r--r-- | kernel/bpf/core.c | 2 |
2 files changed, 41 insertions, 39 deletions
diff --git a/include/linux/filter.h b/include/linux/filter.h index 4b59edead908..1a0bc6d134d7 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h | |||
| @@ -4,12 +4,18 @@ | |||
| 4 | #ifndef __LINUX_FILTER_H__ | 4 | #ifndef __LINUX_FILTER_H__ |
| 5 | #define __LINUX_FILTER_H__ | 5 | #define __LINUX_FILTER_H__ |
| 6 | 6 | ||
| 7 | #include <stdarg.h> | ||
| 8 | |||
| 7 | #include <linux/atomic.h> | 9 | #include <linux/atomic.h> |
| 8 | #include <linux/compat.h> | 10 | #include <linux/compat.h> |
| 9 | #include <linux/skbuff.h> | 11 | #include <linux/skbuff.h> |
| 12 | #include <linux/linkage.h> | ||
| 13 | #include <linux/printk.h> | ||
| 10 | #include <linux/workqueue.h> | 14 | #include <linux/workqueue.h> |
| 11 | #include <uapi/linux/filter.h> | 15 | |
| 12 | #include <asm/cacheflush.h> | 16 | #include <asm/cacheflush.h> |
| 17 | |||
| 18 | #include <uapi/linux/filter.h> | ||
| 13 | #include <uapi/linux/bpf.h> | 19 | #include <uapi/linux/bpf.h> |
| 14 | 20 | ||
| 15 | struct sk_buff; | 21 | struct sk_buff; |
| @@ -363,14 +369,6 @@ struct bpf_prog *bpf_prog_realloc(struct bpf_prog *fp_old, unsigned int size, | |||
| 363 | gfp_t gfp_extra_flags); | 369 | gfp_t gfp_extra_flags); |
| 364 | void __bpf_prog_free(struct bpf_prog *fp); | 370 | void __bpf_prog_free(struct bpf_prog *fp); |
| 365 | 371 | ||
| 366 | typedef void (*bpf_jit_fill_hole_t)(void *area, unsigned int size); | ||
| 367 | |||
| 368 | struct bpf_binary_header * | ||
| 369 | bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr, | ||
| 370 | unsigned int alignment, | ||
| 371 | bpf_jit_fill_hole_t bpf_fill_ill_insns); | ||
| 372 | void bpf_jit_binary_free(struct bpf_binary_header *hdr); | ||
| 373 | |||
| 374 | static inline void bpf_prog_unlock_free(struct bpf_prog *fp) | 372 | static inline void bpf_prog_unlock_free(struct bpf_prog *fp) |
| 375 | { | 373 | { |
| 376 | bpf_prog_unlock_ro(fp); | 374 | bpf_prog_unlock_ro(fp); |
| @@ -393,6 +391,38 @@ void sk_filter_uncharge(struct sock *sk, struct sk_filter *fp); | |||
| 393 | u64 __bpf_call_base(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5); | 391 | u64 __bpf_call_base(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5); |
| 394 | void bpf_int_jit_compile(struct bpf_prog *fp); | 392 | void bpf_int_jit_compile(struct bpf_prog *fp); |
| 395 | 393 | ||
| 394 | #ifdef CONFIG_BPF_JIT | ||
| 395 | typedef void (*bpf_jit_fill_hole_t)(void *area, unsigned int size); | ||
| 396 | |||
| 397 | struct bpf_binary_header * | ||
| 398 | bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr, | ||
| 399 | unsigned int alignment, | ||
| 400 | bpf_jit_fill_hole_t bpf_fill_ill_insns); | ||
| 401 | void bpf_jit_binary_free(struct bpf_binary_header *hdr); | ||
| 402 | |||
| 403 | void bpf_jit_compile(struct bpf_prog *fp); | ||
| 404 | void bpf_jit_free(struct bpf_prog *fp); | ||
| 405 | |||
| 406 | static inline void bpf_jit_dump(unsigned int flen, unsigned int proglen, | ||
| 407 | u32 pass, void *image) | ||
| 408 | { | ||
| 409 | pr_err("flen=%u proglen=%u pass=%u image=%pK\n", | ||
| 410 | flen, proglen, pass, image); | ||
| 411 | if (image) | ||
| 412 | print_hex_dump(KERN_ERR, "JIT code: ", DUMP_PREFIX_OFFSET, | ||
| 413 | 16, 1, image, proglen, false); | ||
| 414 | } | ||
| 415 | #else | ||
| 416 | static inline void bpf_jit_compile(struct bpf_prog *fp) | ||
| 417 | { | ||
| 418 | } | ||
| 419 | |||
| 420 | static inline void bpf_jit_free(struct bpf_prog *fp) | ||
| 421 | { | ||
| 422 | bpf_prog_unlock_free(fp); | ||
| 423 | } | ||
| 424 | #endif /* CONFIG_BPF_JIT */ | ||
| 425 | |||
| 396 | #define BPF_ANC BIT(15) | 426 | #define BPF_ANC BIT(15) |
| 397 | 427 | ||
| 398 | static inline u16 bpf_anc_helper(const struct sock_filter *ftest) | 428 | static inline u16 bpf_anc_helper(const struct sock_filter *ftest) |
| @@ -440,36 +470,6 @@ static inline void *bpf_load_pointer(const struct sk_buff *skb, int k, | |||
| 440 | return bpf_internal_load_pointer_neg_helper(skb, k, size); | 470 | return bpf_internal_load_pointer_neg_helper(skb, k, size); |
| 441 | } | 471 | } |
| 442 | 472 | ||
| 443 | #ifdef CONFIG_BPF_JIT | ||
| 444 | #include <stdarg.h> | ||
| 445 | #include <linux/linkage.h> | ||
| 446 | #include <linux/printk.h> | ||
| 447 | |||
| 448 | void bpf_jit_compile(struct bpf_prog *fp); | ||
| 449 | void bpf_jit_free(struct bpf_prog *fp); | ||
| 450 | |||
| 451 | static inline void bpf_jit_dump(unsigned int flen, unsigned int proglen, | ||
| 452 | u32 pass, void *image) | ||
| 453 | { | ||
| 454 | pr_err("flen=%u proglen=%u pass=%u image=%pK\n", | ||
| 455 | flen, proglen, pass, image); | ||
| 456 | if (image) | ||
| 457 | print_hex_dump(KERN_ERR, "JIT code: ", DUMP_PREFIX_OFFSET, | ||
| 458 | 16, 1, image, proglen, false); | ||
| 459 | } | ||
| 460 | #else | ||
| 461 | #include <linux/slab.h> | ||
| 462 | |||
| 463 | static inline void bpf_jit_compile(struct bpf_prog *fp) | ||
| 464 | { | ||
| 465 | } | ||
| 466 | |||
| 467 | static inline void bpf_jit_free(struct bpf_prog *fp) | ||
| 468 | { | ||
| 469 | bpf_prog_unlock_free(fp); | ||
| 470 | } | ||
| 471 | #endif /* CONFIG_BPF_JIT */ | ||
| 472 | |||
| 473 | static inline int bpf_tell_extensions(void) | 473 | static inline int bpf_tell_extensions(void) |
| 474 | { | 474 | { |
| 475 | return SKF_AD_MAX; | 475 | return SKF_AD_MAX; |
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index 8ee520f0ec70..8b7002488251 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c | |||
| @@ -128,6 +128,7 @@ void __bpf_prog_free(struct bpf_prog *fp) | |||
| 128 | } | 128 | } |
| 129 | EXPORT_SYMBOL_GPL(__bpf_prog_free); | 129 | EXPORT_SYMBOL_GPL(__bpf_prog_free); |
| 130 | 130 | ||
| 131 | #ifdef CONFIG_BPF_JIT | ||
| 131 | struct bpf_binary_header * | 132 | struct bpf_binary_header * |
| 132 | bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr, | 133 | bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr, |
| 133 | unsigned int alignment, | 134 | unsigned int alignment, |
| @@ -163,6 +164,7 @@ void bpf_jit_binary_free(struct bpf_binary_header *hdr) | |||
| 163 | { | 164 | { |
| 164 | module_free(NULL, hdr); | 165 | module_free(NULL, hdr); |
| 165 | } | 166 | } |
| 167 | #endif /* CONFIG_BPF_JIT */ | ||
| 166 | 168 | ||
| 167 | /* Base function for offset calculation. Needs to go into .text section, | 169 | /* Base function for offset calculation. Needs to go into .text section, |
| 168 | * therefore keeping it non-static as well; will also be used by JITs | 170 | * therefore keeping it non-static as well; will also be used by JITs |
