Commit e90b1fd8 authored by David S. Miller's avatar David S. Miller

Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next

Daniel Borkmann says:

====================
pull-request: bpf-next 2019-02-07

The following pull-request contains BPF updates for your *net-next* tree.

The main changes are:

1) Add a riscv64 JIT for BPF, from Björn.

2) Implement BTF deduplication algorithm for libbpf which takes BTF type
   information containing duplicate per-compilation unit information and
   reduces it to an equivalent set of BTF types with no duplication and
   without loss of information, from Andrii.

3) Offloaded and native BPF XDP programs can coexist today, enable also
   offloaded and generic ones as well, from Jakub.

4) Expose various BTF related helper functions in libbpf as API which
   are in particular helpful for JITed programs, from Yonghong.

5) Fix the recently added JMP32 code emission in s390x JIT, from Heiko.

6) Fix BPF kselftests' tcp_{server,client}.py to be able to run inside
   a network namespace, also add a fix for libbpf to get libbpf_print()
   working, from Stanislav.

7) Fixes for bpftool documentation, from Prashant.

8) Type cleanup in BPF kselftests' test_maps.c to silence a gcc8 warning,
   from Breno.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 907bea9c dd9cef43
...@@ -464,10 +464,11 @@ breakpoints: 0 1 ...@@ -464,10 +464,11 @@ breakpoints: 0 1
JIT compiler JIT compiler
------------ ------------
The Linux kernel has a built-in BPF JIT compiler for x86_64, SPARC, PowerPC, The Linux kernel has a built-in BPF JIT compiler for x86_64, SPARC,
ARM, ARM64, MIPS and s390 and can be enabled through CONFIG_BPF_JIT. The JIT PowerPC, ARM, ARM64, MIPS, RISC-V and s390 and can be enabled through
compiler is transparently invoked for each attached filter from user space CONFIG_BPF_JIT. The JIT compiler is transparently invoked for each
or for internal kernel users if it has been previously enabled by root: attached filter from user space or for internal kernel users if it has
been previously enabled by root:
echo 1 > /proc/sys/net/core/bpf_jit_enable echo 1 > /proc/sys/net/core/bpf_jit_enable
...@@ -603,9 +604,10 @@ got from bpf_prog_create(), and 'ctx' the given context (e.g. ...@@ -603,9 +604,10 @@ got from bpf_prog_create(), and 'ctx' the given context (e.g.
skb pointer). All constraints and restrictions from bpf_check_classic() apply skb pointer). All constraints and restrictions from bpf_check_classic() apply
before a conversion to the new layout is being done behind the scenes! before a conversion to the new layout is being done behind the scenes!
Currently, the classic BPF format is being used for JITing on most 32-bit Currently, the classic BPF format is being used for JITing on most
architectures, whereas x86-64, aarch64, s390x, powerpc64, sparc64, arm32 perform 32-bit architectures, whereas x86-64, aarch64, s390x, powerpc64,
JIT compilation from eBPF instruction set. sparc64, arm32, riscv (RV64G) perform JIT compilation from eBPF
instruction set.
Some core changes of the new internal format: Some core changes of the new internal format:
......
...@@ -52,6 +52,7 @@ two flavors of JITs, the newer eBPF JIT currently supported on: ...@@ -52,6 +52,7 @@ two flavors of JITs, the newer eBPF JIT currently supported on:
- sparc64 - sparc64
- mips64 - mips64
- s390x - s390x
- riscv
And the older cBPF JIT supported on the following archs: And the older cBPF JIT supported on the following archs:
- mips - mips
......
...@@ -2907,6 +2907,12 @@ L: netdev@vger.kernel.org ...@@ -2907,6 +2907,12 @@ L: netdev@vger.kernel.org
S: Maintained S: Maintained
F: arch/powerpc/net/ F: arch/powerpc/net/
BPF JIT for RISC-V (RV64G)
M: Björn Töpel <bjorn.topel@gmail.com>
L: netdev@vger.kernel.org
S: Maintained
F: arch/riscv/net/
BPF JIT for S390 BPF JIT for S390
M: Martin Schwidefsky <schwidefsky@de.ibm.com> M: Martin Schwidefsky <schwidefsky@de.ibm.com>
M: Heiko Carstens <heiko.carstens@de.ibm.com> M: Heiko Carstens <heiko.carstens@de.ibm.com>
......
...@@ -49,6 +49,7 @@ config RISCV ...@@ -49,6 +49,7 @@ config RISCV
select RISCV_TIMER select RISCV_TIMER
select GENERIC_IRQ_MULTI_HANDLER select GENERIC_IRQ_MULTI_HANDLER
select ARCH_HAS_PTE_SPECIAL select ARCH_HAS_PTE_SPECIAL
select HAVE_EBPF_JIT if 64BIT
config MMU config MMU
def_bool y def_bool y
......
...@@ -77,7 +77,7 @@ KBUILD_IMAGE := $(boot)/Image.gz ...@@ -77,7 +77,7 @@ KBUILD_IMAGE := $(boot)/Image.gz
head-y := arch/riscv/kernel/head.o head-y := arch/riscv/kernel/head.o
core-y += arch/riscv/kernel/ arch/riscv/mm/ core-y += arch/riscv/kernel/ arch/riscv/mm/ arch/riscv/net/
libs-y += arch/riscv/lib/ libs-y += arch/riscv/lib/
......
obj-$(CONFIG_BPF_JIT) += bpf_jit_comp.o
This diff is collapsed.
...@@ -1154,7 +1154,7 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i ...@@ -1154,7 +1154,7 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i
mask = 0x7000; /* jnz */ mask = 0x7000; /* jnz */
if (BPF_CLASS(insn->code) == BPF_JMP32) { if (BPF_CLASS(insn->code) == BPF_JMP32) {
/* llilf %w1,imm (load zero extend imm) */ /* llilf %w1,imm (load zero extend imm) */
EMIT6_IMM(0xc0010000, REG_W1, imm); EMIT6_IMM(0xc00f0000, REG_W1, imm);
/* nr %w1,%dst */ /* nr %w1,%dst */
EMIT2(0x1400, REG_W1, dst_reg); EMIT2(0x1400, REG_W1, dst_reg);
} else { } else {
...@@ -1216,6 +1216,7 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i ...@@ -1216,6 +1216,7 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i
REG_W1, dst_reg, src_reg); REG_W1, dst_reg, src_reg);
goto branch_oc; goto branch_oc;
branch_ks: branch_ks:
is_jmp32 = BPF_CLASS(insn->code) == BPF_JMP32;
/* lgfi %w1,imm (load sign extend imm) */ /* lgfi %w1,imm (load sign extend imm) */
EMIT6_IMM(0xc0010000, REG_W1, imm); EMIT6_IMM(0xc0010000, REG_W1, imm);
/* crj or cgrj %dst,%w1,mask,off */ /* crj or cgrj %dst,%w1,mask,off */
...@@ -1223,6 +1224,7 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i ...@@ -1223,6 +1224,7 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i
dst_reg, REG_W1, i, off, mask); dst_reg, REG_W1, i, off, mask);
break; break;
branch_ku: branch_ku:
is_jmp32 = BPF_CLASS(insn->code) == BPF_JMP32;
/* lgfi %w1,imm (load sign extend imm) */ /* lgfi %w1,imm (load sign extend imm) */
EMIT6_IMM(0xc0010000, REG_W1, imm); EMIT6_IMM(0xc0010000, REG_W1, imm);
/* clrj or clgrj %dst,%w1,mask,off */ /* clrj or clgrj %dst,%w1,mask,off */
...@@ -1230,11 +1232,13 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i ...@@ -1230,11 +1232,13 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i
dst_reg, REG_W1, i, off, mask); dst_reg, REG_W1, i, off, mask);
break; break;
branch_xs: branch_xs:
is_jmp32 = BPF_CLASS(insn->code) == BPF_JMP32;
/* crj or cgrj %dst,%src,mask,off */ /* crj or cgrj %dst,%src,mask,off */
EMIT6_PCREL(0xec000000, (is_jmp32 ? 0x0076 : 0x0064), EMIT6_PCREL(0xec000000, (is_jmp32 ? 0x0076 : 0x0064),
dst_reg, src_reg, i, off, mask); dst_reg, src_reg, i, off, mask);
break; break;
branch_xu: branch_xu:
is_jmp32 = BPF_CLASS(insn->code) == BPF_JMP32;
/* clrj or clgrj %dst,%src,mask,off */ /* clrj or clgrj %dst,%src,mask,off */
EMIT6_PCREL(0xec000000, (is_jmp32 ? 0x0077 : 0x0065), EMIT6_PCREL(0xec000000, (is_jmp32 ? 0x0077 : 0x0065),
dst_reg, src_reg, i, off, mask); dst_reg, src_reg, i, off, mask);
......
...@@ -8033,11 +8033,13 @@ int dev_change_xdp_fd(struct net_device *dev, struct netlink_ext_ack *extack, ...@@ -8033,11 +8033,13 @@ int dev_change_xdp_fd(struct net_device *dev, struct netlink_ext_ack *extack,
enum bpf_netdev_command query; enum bpf_netdev_command query;
struct bpf_prog *prog = NULL; struct bpf_prog *prog = NULL;
bpf_op_t bpf_op, bpf_chk; bpf_op_t bpf_op, bpf_chk;
bool offload;
int err; int err;
ASSERT_RTNL(); ASSERT_RTNL();
query = flags & XDP_FLAGS_HW_MODE ? XDP_QUERY_PROG_HW : XDP_QUERY_PROG; offload = flags & XDP_FLAGS_HW_MODE;
query = offload ? XDP_QUERY_PROG_HW : XDP_QUERY_PROG;
bpf_op = bpf_chk = ops->ndo_bpf; bpf_op = bpf_chk = ops->ndo_bpf;
if (!bpf_op && (flags & (XDP_FLAGS_DRV_MODE | XDP_FLAGS_HW_MODE))) { if (!bpf_op && (flags & (XDP_FLAGS_DRV_MODE | XDP_FLAGS_HW_MODE))) {
...@@ -8050,8 +8052,7 @@ int dev_change_xdp_fd(struct net_device *dev, struct netlink_ext_ack *extack, ...@@ -8050,8 +8052,7 @@ int dev_change_xdp_fd(struct net_device *dev, struct netlink_ext_ack *extack,
bpf_chk = generic_xdp_install; bpf_chk = generic_xdp_install;
if (fd >= 0) { if (fd >= 0) {
if (__dev_xdp_query(dev, bpf_chk, XDP_QUERY_PROG) || if (!offload && __dev_xdp_query(dev, bpf_chk, XDP_QUERY_PROG)) {
__dev_xdp_query(dev, bpf_chk, XDP_QUERY_PROG_HW)) {
NL_SET_ERR_MSG(extack, "native and generic XDP can't be active at the same time"); NL_SET_ERR_MSG(extack, "native and generic XDP can't be active at the same time");
return -EEXIST; return -EEXIST;
} }
...@@ -8066,8 +8067,7 @@ int dev_change_xdp_fd(struct net_device *dev, struct netlink_ext_ack *extack, ...@@ -8066,8 +8067,7 @@ int dev_change_xdp_fd(struct net_device *dev, struct netlink_ext_ack *extack,
if (IS_ERR(prog)) if (IS_ERR(prog))
return PTR_ERR(prog); return PTR_ERR(prog);
if (!(flags & XDP_FLAGS_HW_MODE) && if (!offload && bpf_prog_is_dev_bound(prog->aux)) {
bpf_prog_is_dev_bound(prog->aux)) {
NL_SET_ERR_MSG(extack, "using device-bound program without HW_MODE flag is not supported"); NL_SET_ERR_MSG(extack, "using device-bound program without HW_MODE flag is not supported");
bpf_prog_put(prog); bpf_prog_put(prog);
return -EINVAL; return -EINVAL;
......
...@@ -17,8 +17,8 @@ SYNOPSIS ...@@ -17,8 +17,8 @@ SYNOPSIS
*COMMANDS* := *COMMANDS* :=
{ **show** | **list** | **tree** | **attach** | **detach** | **help** } { **show** | **list** | **tree** | **attach** | **detach** | **help** }
MAP COMMANDS CGROUP COMMANDS
============= ===============
| **bpftool** **cgroup { show | list }** *CGROUP* | **bpftool** **cgroup { show | list }** *CGROUP*
| **bpftool** **cgroup tree** [*CGROUP_ROOT*] | **bpftool** **cgroup tree** [*CGROUP_ROOT*]
......
...@@ -16,8 +16,8 @@ SYNOPSIS ...@@ -16,8 +16,8 @@ SYNOPSIS
*COMMANDS* := { **probe** | **help** } *COMMANDS* := { **probe** | **help** }
MAP COMMANDS FEATURE COMMANDS
============= ================
| **bpftool** **feature probe** [*COMPONENT*] [**macros** [**prefix** *PREFIX*]] | **bpftool** **feature probe** [*COMPONENT*] [**macros** [**prefix** *PREFIX*]]
| **bpftool** **feature help** | **bpftool** **feature help**
......
...@@ -18,7 +18,7 @@ SYNOPSIS ...@@ -18,7 +18,7 @@ SYNOPSIS
{ **show** | **list** | **dump xlated** | **dump jited** | **pin** | **load** { **show** | **list** | **dump xlated** | **dump jited** | **pin** | **load**
| **loadall** | **help** } | **loadall** | **help** }
MAP COMMANDS PROG COMMANDS
============= =============
| **bpftool** **prog { show | list }** [*PROG*] | **bpftool** **prog { show | list }** [*PROG*]
......
This diff is collapsed.
...@@ -55,33 +55,44 @@ struct btf_ext_header { ...@@ -55,33 +55,44 @@ struct btf_ext_header {
__u32 line_info_len; __u32 line_info_len;
}; };
typedef int (*btf_print_fn_t)(const char *, ...)
__attribute__((format(printf, 1, 2)));
LIBBPF_API void btf__free(struct btf *btf); LIBBPF_API void btf__free(struct btf *btf);
LIBBPF_API struct btf *btf__new(__u8 *data, __u32 size, btf_print_fn_t err_log); LIBBPF_API struct btf *btf__new(__u8 *data, __u32 size);
LIBBPF_API __s32 btf__find_by_name(const struct btf *btf, LIBBPF_API __s32 btf__find_by_name(const struct btf *btf,
const char *type_name); const char *type_name);
LIBBPF_API __u32 btf__get_nr_types(const struct btf *btf);
LIBBPF_API const struct btf_type *btf__type_by_id(const struct btf *btf, LIBBPF_API const struct btf_type *btf__type_by_id(const struct btf *btf,
__u32 id); __u32 id);
LIBBPF_API __s64 btf__resolve_size(const struct btf *btf, __u32 type_id); LIBBPF_API __s64 btf__resolve_size(const struct btf *btf, __u32 type_id);
LIBBPF_API int btf__resolve_type(const struct btf *btf, __u32 type_id); LIBBPF_API int btf__resolve_type(const struct btf *btf, __u32 type_id);
LIBBPF_API int btf__fd(const struct btf *btf); LIBBPF_API int btf__fd(const struct btf *btf);
LIBBPF_API void btf__get_strings(const struct btf *btf, const char **strings,
__u32 *str_len);
LIBBPF_API const char *btf__name_by_offset(const struct btf *btf, __u32 offset); LIBBPF_API const char *btf__name_by_offset(const struct btf *btf, __u32 offset);
LIBBPF_API int btf__get_from_id(__u32 id, struct btf **btf); LIBBPF_API int btf__get_from_id(__u32 id, struct btf **btf);
LIBBPF_API int btf__get_map_kv_tids(const struct btf *btf, const char *map_name,
__u32 expected_key_size,
__u32 expected_value_size,
__u32 *key_type_id, __u32 *value_type_id);
LIBBPF_API struct btf_ext *btf_ext__new(__u8 *data, __u32 size);
LIBBPF_API void btf_ext__free(struct btf_ext *btf_ext);
LIBBPF_API int btf_ext__reloc_func_info(const struct btf *btf,
const struct btf_ext *btf_ext,
const char *sec_name, __u32 insns_cnt,
void **func_info, __u32 *cnt);
LIBBPF_API int btf_ext__reloc_line_info(const struct btf *btf,
const struct btf_ext *btf_ext,
const char *sec_name, __u32 insns_cnt,
void **line_info, __u32 *cnt);
LIBBPF_API __u32 btf_ext__func_info_rec_size(const struct btf_ext *btf_ext);
LIBBPF_API __u32 btf_ext__line_info_rec_size(const struct btf_ext *btf_ext);
struct btf_dedup_opts {
bool dont_resolve_fwds;
};
struct btf_ext *btf_ext__new(__u8 *data, __u32 size, btf_print_fn_t err_log); LIBBPF_API int btf__dedup(struct btf *btf, struct btf_ext *btf_ext,
void btf_ext__free(struct btf_ext *btf_ext); const struct btf_dedup_opts *opts);
int btf_ext__reloc_func_info(const struct btf *btf,
const struct btf_ext *btf_ext,
const char *sec_name, __u32 insns_cnt,
void **func_info, __u32 *func_info_len);
int btf_ext__reloc_line_info(const struct btf *btf,
const struct btf_ext *btf_ext,
const char *sec_name, __u32 insns_cnt,
void **line_info, __u32 *cnt);
__u32 btf_ext__func_info_rec_size(const struct btf_ext *btf_ext);
__u32 btf_ext__line_info_rec_size(const struct btf_ext *btf_ext);
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */
......
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#include "bpf.h" #include "bpf.h"
#include "btf.h" #include "btf.h"
#include "str_error.h" #include "str_error.h"
#include "libbpf_util.h"
#ifndef EM_BPF #ifndef EM_BPF
#define EM_BPF 247 #define EM_BPF 247
...@@ -53,39 +54,33 @@ ...@@ -53,39 +54,33 @@
#define __printf(a, b) __attribute__((format(printf, a, b))) #define __printf(a, b) __attribute__((format(printf, a, b)))
__printf(1, 2) static int __base_pr(enum libbpf_print_level level, const char *format,
static int __base_pr(const char *format, ...) va_list args)
{ {
va_list args; if (level == LIBBPF_DEBUG)
int err; return 0;
va_start(args, format); return vfprintf(stderr, format, args);
err = vfprintf(stderr, format, args);
va_end(args);
return err;
} }
static __printf(1, 2) libbpf_print_fn_t __pr_warning = __base_pr; static libbpf_print_fn_t __libbpf_pr = __base_pr;
static __printf(1, 2) libbpf_print_fn_t __pr_info = __base_pr;
static __printf(1, 2) libbpf_print_fn_t __pr_debug;
#define __pr(func, fmt, ...) \
do { \
if ((func)) \
(func)("libbpf: " fmt, ##__VA_ARGS__); \
} while (0)
#define pr_warning(fmt, ...) __pr(__pr_warning, fmt, ##__VA_ARGS__) void libbpf_set_print(libbpf_print_fn_t fn)
#define pr_info(fmt, ...) __pr(__pr_info, fmt, ##__VA_ARGS__) {
#define pr_debug(fmt, ...) __pr(__pr_debug, fmt, ##__VA_ARGS__) __libbpf_pr = fn;
}
void libbpf_set_print(libbpf_print_fn_t warn, __printf(2, 3)
libbpf_print_fn_t info, void libbpf_print(enum libbpf_print_level level, const char *format, ...)
libbpf_print_fn_t debug)
{ {
__pr_warning = warn; va_list args;
__pr_info = info;
__pr_debug = debug; if (!__libbpf_pr)
return;
va_start(args, format);
__libbpf_pr(level, format, args);
va_end(args);
} }
#define STRERR_BUFSIZE 128 #define STRERR_BUFSIZE 128
...@@ -839,8 +834,7 @@ static int bpf_object__elf_collect(struct bpf_object *obj, int flags) ...@@ -839,8 +834,7 @@ static int bpf_object__elf_collect(struct bpf_object *obj, int flags)
else if (strcmp(name, "maps") == 0) else if (strcmp(name, "maps") == 0)
obj->efile.maps_shndx = idx; obj->efile.maps_shndx = idx;
else if (strcmp(name, BTF_ELF_SEC) == 0) { else if (strcmp(name, BTF_ELF_SEC) == 0) {
obj->btf = btf__new(data->d_buf, data->d_size, obj->btf = btf__new(data->d_buf, data->d_size);
__pr_debug);
if (IS_ERR(obj->btf)) { if (IS_ERR(obj->btf)) {
pr_warning("Error loading ELF section %s: %ld. Ignored and continue.\n", pr_warning("Error loading ELF section %s: %ld. Ignored and continue.\n",
BTF_ELF_SEC, PTR_ERR(obj->btf)); BTF_ELF_SEC, PTR_ERR(obj->btf));
...@@ -915,8 +909,7 @@ static int bpf_object__elf_collect(struct bpf_object *obj, int flags) ...@@ -915,8 +909,7 @@ static int bpf_object__elf_collect(struct bpf_object *obj, int flags)
BTF_EXT_ELF_SEC, BTF_ELF_SEC); BTF_EXT_ELF_SEC, BTF_ELF_SEC);
} else { } else {
obj->btf_ext = btf_ext__new(btf_ext_data->d_buf, obj->btf_ext = btf_ext__new(btf_ext_data->d_buf,
btf_ext_data->d_size, btf_ext_data->d_size);
__pr_debug);
if (IS_ERR(obj->btf_ext)) { if (IS_ERR(obj->btf_ext)) {
pr_warning("Error loading ELF section %s: %ld. Ignored and continue.\n", pr_warning("Error loading ELF section %s: %ld. Ignored and continue.\n",
BTF_EXT_ELF_SEC, BTF_EXT_ELF_SEC,
...@@ -1057,72 +1050,18 @@ bpf_program__collect_reloc(struct bpf_program *prog, GElf_Shdr *shdr, ...@@ -1057,72 +1050,18 @@ bpf_program__collect_reloc(struct bpf_program *prog, GElf_Shdr *shdr,
static int bpf_map_find_btf_info(struct bpf_map *map, const struct btf *btf) static int bpf_map_find_btf_info(struct bpf_map *map, const struct btf *btf)
{ {
const struct btf_type *container_type;
const struct btf_member *key, *value;
struct bpf_map_def *def = &map->def; struct bpf_map_def *def = &map->def;
const size_t max_name = 256; __u32 key_type_id, value_type_id;
char container_name[max_name]; int ret;
__s64 key_size, value_size;
__s32 container_id;
if (snprintf(container_name, max_name, "____btf_map_%s", map->name) ==
max_name) {
pr_warning("map:%s length of '____btf_map_%s' is too long\n",
map->name, map->name);
return -EINVAL;
}
container_id = btf__find_by_name(btf, container_name);
if (container_id < 0) {
pr_debug("map:%s container_name:%s cannot be found in BTF. Missing BPF_ANNOTATE_KV_PAIR?\n",
map->name, container_name);
return container_id;
}
container_type = btf__type_by_id(btf, container_id);
if (!container_type) {
pr_warning("map:%s cannot find BTF type for container_id:%u\n",
map->name, container_id);
return -EINVAL;
}
if (BTF_INFO_KIND(container_type->info) != BTF_KIND_STRUCT ||
BTF_INFO_VLEN(container_type->info) < 2) {
pr_warning("map:%s container_name:%s is an invalid container struct\n",
map->name, container_name);
return -EINVAL;
}
key = (struct btf_member *)(container_type + 1);
value = key + 1;
key_size = btf__resolve_size(btf, key->type);
if (key_size < 0) {
pr_warning("map:%s invalid BTF key_type_size\n",
map->name);
return key_size;
}
if (def->key_size != key_size) {
pr_warning("map:%s btf_key_type_size:%u != map_def_key_size:%u\n",
map->name, (__u32)key_size, def->key_size);
return -EINVAL;
}
value_size = btf__resolve_size(btf, value->type);
if (value_size < 0) {
pr_warning("map:%s invalid BTF value_type_size\n", map->name);
return value_size;
}
if (def->value_size != value_size) { ret = btf__get_map_kv_tids(btf, map->name, def->key_size,
pr_warning("map:%s btf_value_type_size:%u != map_def_value_size:%u\n", def->value_size, &key_type_id,
map->name, (__u32)value_size, def->value_size); &value_type_id);
return -EINVAL; if (ret)
} return ret;
map->btf_key_type_id = key->type; map->btf_key_type_id = key_type_id;
map->btf_value_type_id = value->type; map->btf_value_type_id = value_type_id;
return 0; return 0;
} }
......
...@@ -47,17 +47,16 @@ enum libbpf_errno { ...@@ -47,17 +47,16 @@ enum libbpf_errno {
LIBBPF_API int libbpf_strerror(int err, char *buf, size_t size); LIBBPF_API int libbpf_strerror(int err, char *buf, size_t size);
/* enum libbpf_print_level {
* __printf is defined in include/linux/compiler-gcc.h. However, LIBBPF_WARN,
* it would be better if libbpf.h didn't depend on Linux header files. LIBBPF_INFO,
* So instead of __printf, here we use gcc attribute directly. LIBBPF_DEBUG,
*/ };
typedef int (*libbpf_print_fn_t)(const char *, ...)
__attribute__((format(printf, 1, 2))); typedef int (*libbpf_print_fn_t)(enum libbpf_print_level level,
const char *, va_list ap);
LIBBPF_API void libbpf_set_print(libbpf_print_fn_t warn, LIBBPF_API void libbpf_set_print(libbpf_print_fn_t fn);
libbpf_print_fn_t info,
libbpf_print_fn_t debug);
/* Hide internal to user */ /* Hide internal to user */
struct bpf_object; struct bpf_object;
......
...@@ -133,4 +133,14 @@ LIBBPF_0.0.2 { ...@@ -133,4 +133,14 @@ LIBBPF_0.0.2 {
bpf_map_lookup_elem_flags; bpf_map_lookup_elem_flags;
bpf_object__find_map_fd_by_name; bpf_object__find_map_fd_by_name;
bpf_get_link_xdp_id; bpf_get_link_xdp_id;
btf__dedup;
btf__get_map_kv_tids;
btf__get_nr_types;
btf__get_strings;
btf_ext__free;
btf_ext__func_info_rec_size;
btf_ext__line_info_rec_size;
btf_ext__new;
btf_ext__reloc_func_info;
btf_ext__reloc_line_info;
} LIBBPF_0.0.1; } LIBBPF_0.0.1;
/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
/* Copyright (c) 2019 Facebook */
#ifndef __LIBBPF_LIBBPF_UTIL_H
#define __LIBBPF_LIBBPF_UTIL_H
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
extern void libbpf_print(enum libbpf_print_level level,
const char *format, ...)
__attribute__((format(printf, 2, 3)));
#define __pr(level, fmt, ...) \
do { \
libbpf_print(level, "libbpf: " fmt, ##__VA_ARGS__); \
} while (0)
#define pr_warning(fmt, ...) __pr(LIBBPF_WARN, fmt, ##__VA_ARGS__)
#define pr_info(fmt, ...) __pr(LIBBPF_INFO, fmt, ##__VA_ARGS__)
#define pr_debug(fmt, ...) __pr(LIBBPF_DEBUG, fmt, ##__VA_ARGS__)
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif
...@@ -8,11 +8,11 @@ ...@@ -8,11 +8,11 @@
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
/* libbpf.h */ /* libbpf.h */
libbpf_set_print(NULL, NULL, NULL); libbpf_set_print(NULL);
/* bpf.h */ /* bpf.h */
bpf_prog_get_fd_by_id(0); bpf_prog_get_fd_by_id(0);
/* btf.h */ /* btf.h */
btf__new(NULL, 0, NULL); btf__new(NULL, 0);
} }
...@@ -24,22 +24,12 @@ ...@@ -24,22 +24,12 @@
#include "llvm-utils.h" #include "llvm-utils.h"
#include "c++/clang-c.h" #include "c++/clang-c.h"
#define DEFINE_PRINT_FN(name, level) \ static int libbpf_perf_print(enum libbpf_print_level level __attribute__((unused)),
static int libbpf_##name(const char *fmt, ...) \ const char *fmt, va_list args)
{ \ {
va_list args; \ return veprintf(1, verbose, pr_fmt(fmt), args);
int ret; \
\
va_start(args, fmt); \
ret = veprintf(level, verbose, pr_fmt(fmt), args);\
va_end(args); \
return ret; \
} }
DEFINE_PRINT_FN(warning, 1)
DEFINE_PRINT_FN(info, 1)
DEFINE_PRINT_FN(debug, 1)
struct bpf_prog_priv { struct bpf_prog_priv {
bool is_tp; bool is_tp;
char *sys_name; char *sys_name;
...@@ -59,9 +49,7 @@ bpf__prepare_load_buffer(void *obj_buf, size_t obj_buf_sz, const char *name) ...@@ -59,9 +49,7 @@ bpf__prepare_load_buffer(void *obj_buf, size_t obj_buf_sz, const char *name)
struct bpf_object *obj; struct bpf_object *obj;
if (!libbpf_initialized) { if (!libbpf_initialized) {
libbpf_set_print(libbpf_warning, libbpf_set_print(libbpf_perf_print);
libbpf_info,
libbpf_debug);
libbpf_initialized = true; libbpf_initialized = true;
} }
...@@ -79,9 +67,7 @@ struct bpf_object *bpf__prepare_load(const char *filename, bool source) ...@@ -79,9 +67,7 @@ struct bpf_object *bpf__prepare_load(const char *filename, bool source)
struct bpf_object *obj; struct bpf_object *obj;
if (!libbpf_initialized) { if (!libbpf_initialized) {
libbpf_set_print(libbpf_warning, libbpf_set_print(libbpf_perf_print);
libbpf_info,
libbpf_debug);
libbpf_initialized = true; libbpf_initialized = true;
} }
......
...@@ -30,12 +30,11 @@ def send(sock, s): ...@@ -30,12 +30,11 @@ def send(sock, s):
serverPort = int(sys.argv[1]) serverPort = int(sys.argv[1])
HostName = socket.gethostname()
# create active socket # create active socket
sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
try: try:
sock.connect((HostName, serverPort)) sock.connect(('localhost', serverPort))
except socket.error as e: except socket.error as e:
sys.exit(1) sys.exit(1)
......
...@@ -35,13 +35,10 @@ MAX_PORTS = 2 ...@@ -35,13 +35,10 @@ MAX_PORTS = 2
serverPort = SERVER_PORT serverPort = SERVER_PORT
serverSocket = None serverSocket = None
HostName = socket.gethostname()
# create passive socket # create passive socket
serverSocket = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) serverSocket = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
host = socket.gethostname()
try: serverSocket.bind((host, 0)) try: serverSocket.bind(('localhost', 0))
except socket.error as msg: except socket.error as msg:
print('bind fails: ' + str(msg)) print('bind fails: ' + str(msg))
......
This diff is collapsed.
...@@ -34,23 +34,16 @@ static void usage(char *argv[]) ...@@ -34,23 +34,16 @@ static void usage(char *argv[])
printf("\n"); printf("\n");
} }
#define DEFINE_PRINT_FN(name, enabled) \ static bool debug = 0;
static int libbpf_##name(const char *fmt, ...) \ static int libbpf_debug_print(enum libbpf_print_level level,
{ \ const char *fmt, va_list args)
va_list args; \ {
int ret; \ if (level == LIBBPF_DEBUG && !debug)
\ return 0;
va_start(args, fmt); \
if (enabled) { \ fprintf(stderr, "[%d] ", level);
fprintf(stderr, "[" #name "] "); \ return vfprintf(stderr, fmt, args);
ret = vfprintf(stderr, fmt, args); \
} \
va_end(args); \
return ret; \
} }
DEFINE_PRINT_FN(warning, 1)
DEFINE_PRINT_FN(info, 1)
DEFINE_PRINT_FN(debug, 1)
#define EXIT_FAIL_LIBBPF EXIT_FAILURE #define EXIT_FAIL_LIBBPF EXIT_FAILURE
#define EXIT_FAIL_OPTION 2 #define EXIT_FAIL_OPTION 2
...@@ -120,15 +113,14 @@ int main(int argc, char **argv) ...@@ -120,15 +113,14 @@ int main(int argc, char **argv)
int longindex = 0; int longindex = 0;
int opt; int opt;
libbpf_set_print(libbpf_warning, libbpf_info, NULL); libbpf_set_print(libbpf_debug_print);
/* Parse commands line args */ /* Parse commands line args */
while ((opt = getopt_long(argc, argv, "hDq", while ((opt = getopt_long(argc, argv, "hDq",
long_options, &longindex)) != -1) { long_options, &longindex)) != -1) {
switch (opt) { switch (opt) {
case 'D': case 'D':
libbpf_set_print(libbpf_warning, libbpf_info, debug = 1;
libbpf_debug);
break; break;
case 'q': /* Use in scripting mode */ case 'q': /* Use in scripting mode */
verbose = 0; verbose = 0;
......
...@@ -45,7 +45,7 @@ static int map_flags; ...@@ -45,7 +45,7 @@ static int map_flags;
} \ } \
}) })
static void test_hashmap(int task, void *data) static void test_hashmap(unsigned int task, void *data)
{ {
long long key, next_key, first_key, value; long long key, next_key, first_key, value;
int fd; int fd;
...@@ -135,7 +135,7 @@ static void test_hashmap(int task, void *data) ...@@ -135,7 +135,7 @@ static void test_hashmap(int task, void *data)
close(fd); close(fd);
} }
static void test_hashmap_sizes(int task, void *data) static void test_hashmap_sizes(unsigned int task, void *data)
{ {
int fd, i, j; int fd, i, j;
...@@ -155,7 +155,7 @@ static void test_hashmap_sizes(int task, void *data) ...@@ -155,7 +155,7 @@ static void test_hashmap_sizes(int task, void *data)
} }
} }
static void test_hashmap_percpu(int task, void *data) static void test_hashmap_percpu(unsigned int task, void *data)
{ {
unsigned int nr_cpus = bpf_num_possible_cpus(); unsigned int nr_cpus = bpf_num_possible_cpus();
BPF_DECLARE_PERCPU(long, value); BPF_DECLARE_PERCPU(long, value);
...@@ -282,7 +282,7 @@ static int helper_fill_hashmap(int max_entries) ...@@ -282,7 +282,7 @@ static int helper_fill_hashmap(int max_entries)
return fd; return fd;
} }
static void test_hashmap_walk(int task, void *data) static void test_hashmap_walk(unsigned int task, void *data)
{ {
int fd, i, max_entries = 1000; int fd, i, max_entries = 1000;
long long key, value, next_key; long long key, value, next_key;
...@@ -353,7 +353,7 @@ static void test_hashmap_zero_seed(void) ...@@ -353,7 +353,7 @@ static void test_hashmap_zero_seed(void)
close(second); close(second);
} }
static void test_arraymap(int task, void *data) static void test_arraymap(unsigned int task, void *data)
{ {
int key, next_key, fd; int key, next_key, fd;
long long value; long long value;
...@@ -408,7 +408,7 @@ static void test_arraymap(int task, void *data) ...@@ -408,7 +408,7 @@ static void test_arraymap(int task, void *data)
close(fd); close(fd);
} }
static void test_arraymap_percpu(int task, void *data) static void test_arraymap_percpu(unsigned int task, void *data)
{ {
unsigned int nr_cpus = bpf_num_possible_cpus(); unsigned int nr_cpus = bpf_num_possible_cpus();
BPF_DECLARE_PERCPU(long, values); BPF_DECLARE_PERCPU(long, values);
...@@ -504,7 +504,7 @@ static void test_arraymap_percpu_many_keys(void) ...@@ -504,7 +504,7 @@ static void test_arraymap_percpu_many_keys(void)
close(fd); close(fd);
} }
static void test_devmap(int task, void *data) static void test_devmap(unsigned int task, void *data)
{ {
int fd; int fd;
__u32 key, value; __u32 key, value;
...@@ -519,7 +519,7 @@ static void test_devmap(int task, void *data) ...@@ -519,7 +519,7 @@ static void test_devmap(int task, void *data)
close(fd); close(fd);
} }
static void test_queuemap(int task, void *data) static void test_queuemap(unsigned int task, void *data)
{ {
const int MAP_SIZE = 32; const int MAP_SIZE = 32;
__u32 vals[MAP_SIZE + MAP_SIZE/2], val; __u32 vals[MAP_SIZE + MAP_SIZE/2], val;
...@@ -577,7 +577,7 @@ static void test_queuemap(int task, void *data) ...@@ -577,7 +577,7 @@ static void test_queuemap(int task, void *data)
close(fd); close(fd);
} }
static void test_stackmap(int task, void *data) static void test_stackmap(unsigned int task, void *data)
{ {
const int MAP_SIZE = 32; const int MAP_SIZE = 32;
__u32 vals[MAP_SIZE + MAP_SIZE/2], val; __u32 vals[MAP_SIZE + MAP_SIZE/2], val;
...@@ -642,7 +642,7 @@ static void test_stackmap(int task, void *data) ...@@ -642,7 +642,7 @@ static void test_stackmap(int task, void *data)
#define SOCKMAP_PARSE_PROG "./sockmap_parse_prog.o" #define SOCKMAP_PARSE_PROG "./sockmap_parse_prog.o"
#define SOCKMAP_VERDICT_PROG "./sockmap_verdict_prog.o" #define SOCKMAP_VERDICT_PROG "./sockmap_verdict_prog.o"
#define SOCKMAP_TCP_MSG_PROG "./sockmap_tcp_msg_prog.o" #define SOCKMAP_TCP_MSG_PROG "./sockmap_tcp_msg_prog.o"
static void test_sockmap(int tasks, void *data) static void test_sockmap(unsigned int tasks, void *data)
{ {
struct bpf_map *bpf_map_rx, *bpf_map_tx, *bpf_map_msg, *bpf_map_break; struct bpf_map *bpf_map_rx, *bpf_map_tx, *bpf_map_msg, *bpf_map_break;
int map_fd_msg = 0, map_fd_rx = 0, map_fd_tx = 0, map_fd_break; int map_fd_msg = 0, map_fd_rx = 0, map_fd_tx = 0, map_fd_break;
...@@ -1268,10 +1268,11 @@ static void test_map_large(void) ...@@ -1268,10 +1268,11 @@ static void test_map_large(void)
} }
#define run_parallel(N, FN, DATA) \ #define run_parallel(N, FN, DATA) \
printf("Fork %d tasks to '" #FN "'\n", N); \ printf("Fork %u tasks to '" #FN "'\n", N); \
__run_parallel(N, FN, DATA) __run_parallel(N, FN, DATA)
static void __run_parallel(int tasks, void (*fn)(int task, void *data), static void __run_parallel(unsigned int tasks,
void (*fn)(unsigned int task, void *data),
void *data) void *data)
{ {
pid_t pid[tasks]; pid_t pid[tasks];
...@@ -1312,7 +1313,7 @@ static void test_map_stress(void) ...@@ -1312,7 +1313,7 @@ static void test_map_stress(void)
#define DO_UPDATE 1 #define DO_UPDATE 1
#define DO_DELETE 0 #define DO_DELETE 0
static void test_update_delete(int fn, void *data) static void test_update_delete(unsigned int fn, void *data)
{ {
int do_update = ((int *)data)[1]; int do_update = ((int *)data)[1];
int fd = ((int *)data)[0]; int fd = ((int *)data)[0];
......
...@@ -23,6 +23,7 @@ import string ...@@ -23,6 +23,7 @@ import string
import struct import struct
import subprocess import subprocess
import time import time
import traceback
logfile = None logfile = None
log_level = 1 log_level = 1
...@@ -78,7 +79,9 @@ def fail(cond, msg): ...@@ -78,7 +79,9 @@ def fail(cond, msg):
if not cond: if not cond:
return return
print("FAIL: " + msg) print("FAIL: " + msg)
log("FAIL: " + msg, "", level=1) tb = "".join(traceback.extract_stack().format())
print(tb)
log("FAIL: " + msg, tb, level=1)
os.sys.exit(1) os.sys.exit(1)
def start_test(msg): def start_test(msg):
...@@ -589,6 +592,15 @@ def check_verifier_log(output, reference): ...@@ -589,6 +592,15 @@ def check_verifier_log(output, reference):
return return
fail(True, "Missing or incorrect message from netdevsim in verifier log") fail(True, "Missing or incorrect message from netdevsim in verifier log")
def check_multi_basic(two_xdps):
fail(two_xdps["mode"] != 4, "Bad mode reported with multiple programs")
fail("prog" in two_xdps, "Base program reported in multi program mode")
fail(len(two_xdps["attached"]) != 2,
"Wrong attached program count with two programs")
fail(two_xdps["attached"][0]["prog"]["id"] ==
two_xdps["attached"][1]["prog"]["id"],
"Offloaded and other programs have the same id")
def test_spurios_extack(sim, obj, skip_hw, needle): def test_spurios_extack(sim, obj, skip_hw, needle):
res = sim.cls_bpf_add_filter(obj, prio=1, handle=1, skip_hw=skip_hw, res = sim.cls_bpf_add_filter(obj, prio=1, handle=1, skip_hw=skip_hw,
include_stderr=True) include_stderr=True)
...@@ -600,6 +612,67 @@ def test_spurios_extack(sim, obj, skip_hw, needle): ...@@ -600,6 +612,67 @@ def test_spurios_extack(sim, obj, skip_hw, needle):
include_stderr=True) include_stderr=True)
check_no_extack(res, needle) check_no_extack(res, needle)
def test_multi_prog(sim, obj, modename, modeid):
start_test("Test multi-attachment XDP - %s + offload..." %
(modename or "default", ))
sim.set_xdp(obj, "offload")
xdp = sim.ip_link_show(xdp=True)["xdp"]
offloaded = sim.dfs_read("bpf_offloaded_id")
fail("prog" not in xdp, "Base program not reported in single program mode")
fail(len(xdp["attached"]) != 1,
"Wrong attached program count with one program")
sim.set_xdp(obj, modename)
two_xdps = sim.ip_link_show(xdp=True)["xdp"]
fail(xdp["attached"][0] not in two_xdps["attached"],
"Offload program not reported after other activated")
check_multi_basic(two_xdps)
offloaded2 = sim.dfs_read("bpf_offloaded_id")
fail(offloaded != offloaded2,
"Offload ID changed after loading other program")
start_test("Test multi-attachment XDP - replace...")
ret, _, err = sim.set_xdp(obj, "offload", fail=False, include_stderr=True)
fail(ret == 0, "Replaced one of programs without -force")
check_extack(err, "XDP program already attached.", args)
if modename == "" or modename == "drv":
othermode = "" if modename == "drv" else "drv"
start_test("Test multi-attachment XDP - detach...")
ret, _, err = sim.unset_xdp(othermode, force=True,
fail=False, include_stderr=True)
fail(ret == 0, "Removed program with a bad mode")
check_extack(err, "program loaded with different flags.", args)
sim.unset_xdp("offload")
xdp = sim.ip_link_show(xdp=True)["xdp"]
offloaded = sim.dfs_read("bpf_offloaded_id")
fail(xdp["mode"] != modeid, "Bad mode reported after multiple programs")
fail("prog" not in xdp,
"Base program not reported after multi program mode")
fail(xdp["attached"][0] not in two_xdps["attached"],
"Offload program not reported after other activated")
fail(len(xdp["attached"]) != 1,
"Wrong attached program count with remaining programs")
fail(offloaded != "0", "Offload ID reported with only other program left")
start_test("Test multi-attachment XDP - reattach...")
sim.set_xdp(obj, "offload")
two_xdps = sim.ip_link_show(xdp=True)["xdp"]
fail(xdp["attached"][0] not in two_xdps["attached"],
"Other program not reported after offload activated")
check_multi_basic(two_xdps)
start_test("Test multi-attachment XDP - device remove...")
sim.remove()
sim = NetdevSim()
sim.set_ethtool_tc_offloads(True)
return sim
# Parse command line # Parse command line
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
...@@ -842,7 +915,9 @@ try: ...@@ -842,7 +915,9 @@ try:
ret, _, err = sim.set_xdp(obj, "generic", force=True, ret, _, err = sim.set_xdp(obj, "generic", force=True,
fail=False, include_stderr=True) fail=False, include_stderr=True)
fail(ret == 0, "Replaced XDP program with a program in different mode") fail(ret == 0, "Replaced XDP program with a program in different mode")
fail(err.count("File exists") != 1, "Replaced driver XDP with generic") check_extack(err,
"native and generic XDP can't be active at the same time.",
args)
ret, _, err = sim.set_xdp(obj, "", force=True, ret, _, err = sim.set_xdp(obj, "", force=True,
fail=False, include_stderr=True) fail=False, include_stderr=True)
fail(ret == 0, "Replaced XDP program with a program in different mode") fail(ret == 0, "Replaced XDP program with a program in different mode")
...@@ -931,59 +1006,9 @@ try: ...@@ -931,59 +1006,9 @@ try:
rm(pin_file) rm(pin_file)
bpftool_prog_list_wait(expected=0) bpftool_prog_list_wait(expected=0)
start_test("Test multi-attachment XDP - attach...") sim = test_multi_prog(sim, obj, "", 1)
sim.set_xdp(obj, "offload") sim = test_multi_prog(sim, obj, "drv", 1)
xdp = sim.ip_link_show(xdp=True)["xdp"] sim = test_multi_prog(sim, obj, "generic", 2)
offloaded = sim.dfs_read("bpf_offloaded_id")
fail("prog" not in xdp, "Base program not reported in single program mode")
fail(len(ipl["xdp"]["attached"]) != 1,
"Wrong attached program count with one program")
sim.set_xdp(obj, "")
two_xdps = sim.ip_link_show(xdp=True)["xdp"]
offloaded2 = sim.dfs_read("bpf_offloaded_id")
fail(two_xdps["mode"] != 4, "Bad mode reported with multiple programs")
fail("prog" in two_xdps, "Base program reported in multi program mode")
fail(xdp["attached"][0] not in two_xdps["attached"],
"Offload program not reported after driver activated")
fail(len(two_xdps["attached"]) != 2,
"Wrong attached program count with two programs")
fail(two_xdps["attached"][0]["prog"]["id"] ==
two_xdps["attached"][1]["prog"]["id"],
"offloaded and drv programs have the same id")
fail(offloaded != offloaded2,
"offload ID changed after loading driver program")
start_test("Test multi-attachment XDP - replace...")
ret, _, err = sim.set_xdp(obj, "offload", fail=False, include_stderr=True)
fail(err.count("busy") != 1, "Replaced one of programs without -force")
start_test("Test multi-attachment XDP - detach...")
ret, _, err = sim.unset_xdp("drv", force=True,
fail=False, include_stderr=True)
fail(ret == 0, "Removed program with a bad mode")
check_extack(err, "program loaded with different flags.", args)
sim.unset_xdp("offload")
xdp = sim.ip_link_show(xdp=True)["xdp"]
offloaded = sim.dfs_read("bpf_offloaded_id")
fail(xdp["mode"] != 1, "Bad mode reported after multiple programs")
fail("prog" not in xdp,
"Base program not reported after multi program mode")
fail(xdp["attached"][0] not in two_xdps["attached"],
"Offload program not reported after driver activated")
fail(len(ipl["xdp"]["attached"]) != 1,
"Wrong attached program count with remaining programs")
fail(offloaded != "0", "offload ID reported with only driver program left")
start_test("Test multi-attachment XDP - device remove...")
sim.set_xdp(obj, "offload")
sim.remove()
sim = NetdevSim()
sim.set_ethtool_tc_offloads(True)
start_test("Test mixing of TC and XDP...") start_test("Test mixing of TC and XDP...")
sim.tc_add_ingress() sim.tc_add_ingress()
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h>
#include <time.h> #include <time.h>
#include <linux/types.h> #include <linux/types.h>
...@@ -1783,6 +1784,15 @@ static void test_task_fd_query_tp(void) ...@@ -1783,6 +1784,15 @@ static void test_task_fd_query_tp(void)
"sys_enter_read"); "sys_enter_read");
} }
static int libbpf_debug_print(enum libbpf_print_level level,
const char *format, va_list args)
{
if (level == LIBBPF_DEBUG)
return 0;
return vfprintf(stderr, format, args);
}
static void test_reference_tracking() static void test_reference_tracking()
{ {
const char *file = "./test_sk_lookup_kern.o"; const char *file = "./test_sk_lookup_kern.o";
...@@ -1809,9 +1819,9 @@ static void test_reference_tracking() ...@@ -1809,9 +1819,9 @@ static void test_reference_tracking()
/* Expect verifier failure if test name has 'fail' */ /* Expect verifier failure if test name has 'fail' */
if (strstr(title, "fail") != NULL) { if (strstr(title, "fail") != NULL) {
libbpf_set_print(NULL, NULL, NULL); libbpf_set_print(NULL);
err = !bpf_program__load(prog, "GPL", 0); err = !bpf_program__load(prog, "GPL", 0);
libbpf_set_print(printf, printf, NULL); libbpf_set_print(libbpf_debug_print);
} else { } else {
err = bpf_program__load(prog, "GPL", 0); err = bpf_program__load(prog, "GPL", 0);
} }
......
...@@ -100,6 +100,7 @@ ...@@ -100,6 +100,7 @@
.errstr = "invalid bpf_context access", .errstr = "invalid bpf_context access",
.result = REJECT, .result = REJECT,
.prog_type = BPF_PROG_TYPE_SK_MSG, .prog_type = BPF_PROG_TYPE_SK_MSG,
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
}, },
{ {
"invalid read past end of SK_MSG", "invalid read past end of SK_MSG",
......
...@@ -687,6 +687,7 @@ ...@@ -687,6 +687,7 @@
}, },
.errstr = "invalid bpf_context access", .errstr = "invalid bpf_context access",
.result = REJECT, .result = REJECT,
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
}, },
{ {
"check skb->hash half load not permitted, unaligned 3", "check skb->hash half load not permitted, unaligned 3",
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
.data64 = { 1ULL << 63 | 1, } .data64 = { 1ULL << 63 | 1, }
}, },
}, },
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
}, },
{ {
"jset32: BPF_X", "jset32: BPF_X",
...@@ -58,6 +59,7 @@ ...@@ -58,6 +59,7 @@
.data64 = { 1ULL << 63 | 1, } .data64 = { 1ULL << 63 | 1, }
}, },
}, },
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
}, },
{ {
"jset32: min/max deduction", "jset32: min/max deduction",
...@@ -93,6 +95,7 @@ ...@@ -93,6 +95,7 @@
.data64 = { -1, } .data64 = { -1, }
}, },
}, },
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
}, },
{ {
"jeq32: BPF_X", "jeq32: BPF_X",
...@@ -119,6 +122,7 @@ ...@@ -119,6 +122,7 @@
.data64 = { 1ULL << 63 | 1, } .data64 = { 1ULL << 63 | 1, }
}, },
}, },
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
}, },
{ {
"jeq32: min/max deduction", "jeq32: min/max deduction",
...@@ -154,6 +158,7 @@ ...@@ -154,6 +158,7 @@
.data64 = { -1, } .data64 = { -1, }
}, },
}, },
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
}, },
{ {
"jne32: BPF_X", "jne32: BPF_X",
...@@ -180,6 +185,7 @@ ...@@ -180,6 +185,7 @@
.data64 = { 1ULL << 63 | 2, } .data64 = { 1ULL << 63 | 2, }
}, },
}, },
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
}, },
{ {
"jne32: min/max deduction", "jne32: min/max deduction",
...@@ -218,6 +224,7 @@ ...@@ -218,6 +224,7 @@
.data64 = { 0, } .data64 = { 0, }
}, },
}, },
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
}, },
{ {
"jge32: BPF_X", "jge32: BPF_X",
...@@ -244,6 +251,7 @@ ...@@ -244,6 +251,7 @@
.data64 = { (UINT_MAX - 1) | 2ULL << 32, } .data64 = { (UINT_MAX - 1) | 2ULL << 32, }
}, },
}, },
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
}, },
{ {
"jge32: min/max deduction", "jge32: min/max deduction",
...@@ -284,6 +292,7 @@ ...@@ -284,6 +292,7 @@
.data64 = { 0, } .data64 = { 0, }
}, },
}, },
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
}, },
{ {
"jgt32: BPF_X", "jgt32: BPF_X",
...@@ -310,6 +319,7 @@ ...@@ -310,6 +319,7 @@
.data64 = { (UINT_MAX - 1) | 2ULL << 32, } .data64 = { (UINT_MAX - 1) | 2ULL << 32, }
}, },
}, },
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
}, },
{ {
"jgt32: min/max deduction", "jgt32: min/max deduction",
...@@ -350,6 +360,7 @@ ...@@ -350,6 +360,7 @@
.data64 = { INT_MAX, } .data64 = { INT_MAX, }
}, },
}, },
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
}, },
{ {
"jle32: BPF_X", "jle32: BPF_X",
...@@ -376,6 +387,7 @@ ...@@ -376,6 +387,7 @@
.data64 = { UINT_MAX, } .data64 = { UINT_MAX, }
}, },
}, },
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
}, },
{ {
"jle32: min/max deduction", "jle32: min/max deduction",
...@@ -416,6 +428,7 @@ ...@@ -416,6 +428,7 @@
.data64 = { INT_MAX - 1, } .data64 = { INT_MAX - 1, }
}, },
}, },
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
}, },
{ {
"jlt32: BPF_X", "jlt32: BPF_X",
...@@ -442,6 +455,7 @@ ...@@ -442,6 +455,7 @@
.data64 = { (INT_MAX - 1) | 3ULL << 32, } .data64 = { (INT_MAX - 1) | 3ULL << 32, }
}, },
}, },
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
}, },
{ {
"jlt32: min/max deduction", "jlt32: min/max deduction",
...@@ -482,6 +496,7 @@ ...@@ -482,6 +496,7 @@
.data64 = { -2, } .data64 = { -2, }
}, },
}, },
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
}, },
{ {
"jsge32: BPF_X", "jsge32: BPF_X",
...@@ -508,6 +523,7 @@ ...@@ -508,6 +523,7 @@
.data64 = { -2, } .data64 = { -2, }
}, },
}, },
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
}, },
{ {
"jsge32: min/max deduction", "jsge32: min/max deduction",
...@@ -548,6 +564,7 @@ ...@@ -548,6 +564,7 @@
.data64 = { 1, } .data64 = { 1, }
}, },
}, },
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
}, },
{ {
"jsgt32: BPF_X", "jsgt32: BPF_X",
...@@ -574,6 +591,7 @@ ...@@ -574,6 +591,7 @@
.data64 = { 0x7fffffff, } .data64 = { 0x7fffffff, }
}, },
}, },
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
}, },
{ {
"jsgt32: min/max deduction", "jsgt32: min/max deduction",
...@@ -614,6 +632,7 @@ ...@@ -614,6 +632,7 @@
.data64 = { 1, } .data64 = { 1, }
}, },
}, },
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
}, },
{ {
"jsle32: BPF_X", "jsle32: BPF_X",
...@@ -640,6 +659,7 @@ ...@@ -640,6 +659,7 @@
.data64 = { 0x7fffffff | 2ULL << 32, } .data64 = { 0x7fffffff | 2ULL << 32, }
}, },
}, },
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
}, },
{ {
"jsle32: min/max deduction", "jsle32: min/max deduction",
...@@ -680,6 +700,7 @@ ...@@ -680,6 +700,7 @@
.data64 = { 1, } .data64 = { 1, }
}, },
}, },
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
}, },
{ {
"jslt32: BPF_X", "jslt32: BPF_X",
...@@ -706,6 +727,7 @@ ...@@ -706,6 +727,7 @@
.data64 = { 0x7fffffff | 2ULL << 32, } .data64 = { 0x7fffffff | 2ULL << 32, }
}, },
}, },
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
}, },
{ {
"jslt32: min/max deduction", "jslt32: min/max deduction",
......
...@@ -53,6 +53,7 @@ ...@@ -53,6 +53,7 @@
.data64 = { ~0ULL, } .data64 = { ~0ULL, }
}, },
}, },
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
}, },
{ {
"jset: sign-extend", "jset: sign-extend",
...@@ -70,6 +71,7 @@ ...@@ -70,6 +71,7 @@
.result = ACCEPT, .result = ACCEPT,
.retval = 2, .retval = 2,
.data = { 1, 0, 0, 0, 0, 0, 0, 1, }, .data = { 1, 0, 0, 0, 0, 0, 0, 1, },
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
}, },
{ {
"jset: known const compare", "jset: known const compare",
......
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
.errstr_unpriv = "attempt to corrupt spilled", .errstr_unpriv = "attempt to corrupt spilled",
.errstr = "R0 invalid mem access 'inv", .errstr = "R0 invalid mem access 'inv",
.result = REJECT, .result = REJECT,
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
}, },
{ {
"check corrupted spill/fill, LSB", "check corrupted spill/fill, LSB",
......
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