Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf
authorDavid S. Miller <davem@davemloft.net>
Thu, 18 Jul 2019 21:04:45 +0000 (14:04 -0700)
committerDavid S. Miller <davem@davemloft.net>
Thu, 18 Jul 2019 21:04:45 +0000 (14:04 -0700)
Alexei Starovoitov says:

====================
pull-request: bpf 2019-07-18

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

The main changes are:

1) verifier precision propagation fix, from Andrii.

2) BTF size fix for typedefs, from Andrii.

3) a bunch of big endian fixes, from Ilya.

4) wide load from bpf_sock_addr fixes, from Stanislav.

5) a bunch of misc fixes from a number of developers.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
32 files changed:
MAINTAINERS
include/linux/filter.h
include/uapi/linux/bpf.h
kernel/bpf/btf.c
kernel/bpf/verifier.c
net/core/filter.c
net/xdp/xdp_umem.c
net/xdp/xsk.c
samples/bpf/Makefile
tools/bpf/bpftool/main.h
tools/include/uapi/linux/bpf.h
tools/lib/bpf/libbpf.c
tools/lib/bpf/xsk.c
tools/testing/selftests/bpf/Makefile
tools/testing/selftests/bpf/bpf_helpers.h
tools/testing/selftests/bpf/prog_tests/attach_probe.c
tools/testing/selftests/bpf/prog_tests/perf_buffer.c
tools/testing/selftests/bpf/prog_tests/send_signal.c
tools/testing/selftests/bpf/progs/loop1.c
tools/testing/selftests/bpf/progs/loop2.c
tools/testing/selftests/bpf/progs/loop3.c
tools/testing/selftests/bpf/progs/test_get_stack_rawtp.c
tools/testing/selftests/bpf/progs/test_stacktrace_build_id.c
tools/testing/selftests/bpf/progs/test_stacktrace_map.c
tools/testing/selftests/bpf/progs/test_xdp_noinline.c
tools/testing/selftests/bpf/test_btf.c
tools/testing/selftests/bpf/test_progs.h
tools/testing/selftests/bpf/test_verifier.c
tools/testing/selftests/bpf/verifier/array_access.c
tools/testing/selftests/bpf/verifier/value_ptr_arith.c
tools/testing/selftests/bpf/verifier/wide_access.c [new file with mode: 0644]
tools/testing/selftests/bpf/verifier/wide_store.c [deleted file]

index 64f659d8346cceb3d1bb236614712defbe100fac..2854d42288e906ec9ea36cc385503f44bf3d15b6 100644 (file)
@@ -3108,9 +3108,9 @@ S:        Maintained
 F:     arch/riscv/net/
 
 BPF JIT for S390
+M:     Ilya Leoshkevich <iii@linux.ibm.com>
 M:     Heiko Carstens <heiko.carstens@de.ibm.com>
 M:     Vasily Gorbik <gor@linux.ibm.com>
-M:     Christian Borntraeger <borntraeger@de.ibm.com>
 L:     netdev@vger.kernel.org
 L:     bpf@vger.kernel.org
 S:     Maintained
index 6d944369ca876005021a1f010605a661acdc258d..ff65d22cf336935c9406930496dc8a8f57a0cbd0 100644 (file)
@@ -747,7 +747,7 @@ bpf_ctx_narrow_access_ok(u32 off, u32 size, u32 size_default)
        return size <= size_default && (size & (size - 1)) == 0;
 }
 
-#define bpf_ctx_wide_store_ok(off, size, type, field)                  \
+#define bpf_ctx_wide_access_ok(off, size, type, field)                 \
        (size == sizeof(__u64) &&                                       \
        off >= offsetof(type, field) &&                                 \
        off + sizeof(__u64) <= offsetofend(type, field) &&              \
index 6f68438aa4edd98114b825f1aaf036115e5c728a..81be929b89fc5eec7be0368727223f7117066a2e 100644 (file)
@@ -3248,7 +3248,7 @@ struct bpf_sock_addr {
        __u32 user_ip4;         /* Allows 1,2,4-byte read and 4-byte write.
                                 * Stored in network byte order.
                                 */
-       __u32 user_ip6[4];      /* Allows 1,2,4-byte read and 4,8-byte write.
+       __u32 user_ip6[4];      /* Allows 1,2,4,8-byte read and 4,8-byte write.
                                 * Stored in network byte order.
                                 */
        __u32 user_port;        /* Allows 4-byte read and write.
@@ -3260,7 +3260,7 @@ struct bpf_sock_addr {
        __u32 msg_src_ip4;      /* Allows 1,2,4-byte read and 4-byte write.
                                 * Stored in network byte order.
                                 */
-       __u32 msg_src_ip6[4];   /* Allows 1,2,4-byte read and 4,8-byte write.
+       __u32 msg_src_ip6[4];   /* Allows 1,2,4,8-byte read and 4,8-byte write.
                                 * Stored in network byte order.
                                 */
        __bpf_md_ptr(struct bpf_sock *, sk);
index 546ebee39e2afbe1bd3903a3f2a6f602554c2a27..5fcc7a17eb5a4d538ffef61335481a262bc23720 100644 (file)
@@ -1073,11 +1073,18 @@ const struct btf_type *btf_type_id_size(const struct btf *btf,
                                 !btf_type_is_var(size_type)))
                        return NULL;
 
-               size = btf->resolved_sizes[size_type_id];
                size_type_id = btf->resolved_ids[size_type_id];
                size_type = btf_type_by_id(btf, size_type_id);
                if (btf_type_nosize_or_null(size_type))
                        return NULL;
+               else if (btf_type_has_size(size_type))
+                       size = size_type->size;
+               else if (btf_type_is_array(size_type))
+                       size = btf->resolved_sizes[size_type_id];
+               else if (btf_type_is_ptr(size_type))
+                       size = sizeof(void *);
+               else
+                       return NULL;
        }
 
        *type_id = size_type_id;
@@ -1602,7 +1609,6 @@ static int btf_modifier_resolve(struct btf_verifier_env *env,
        const struct btf_type *next_type;
        u32 next_type_id = t->type;
        struct btf *btf = env->btf;
-       u32 next_type_size = 0;
 
        next_type = btf_type_by_id(btf, next_type_id);
        if (!next_type || btf_type_is_resolve_source_only(next_type)) {
@@ -1620,7 +1626,7 @@ static int btf_modifier_resolve(struct btf_verifier_env *env,
         * save us a few type-following when we use it later (e.g. in
         * pretty print).
         */
-       if (!btf_type_id_size(btf, &next_type_id, &next_type_size)) {
+       if (!btf_type_id_size(btf, &next_type_id, NULL)) {
                if (env_type_is_resolved(env, next_type_id))
                        next_type = btf_type_id_resolve(btf, &next_type_id);
 
@@ -1633,7 +1639,7 @@ static int btf_modifier_resolve(struct btf_verifier_env *env,
                }
        }
 
-       env_stack_pop_resolved(env, next_type_id, next_type_size);
+       env_stack_pop_resolved(env, next_type_id, 0);
 
        return 0;
 }
@@ -1645,7 +1651,6 @@ static int btf_var_resolve(struct btf_verifier_env *env,
        const struct btf_type *t = v->t;
        u32 next_type_id = t->type;
        struct btf *btf = env->btf;
-       u32 next_type_size;
 
        next_type = btf_type_by_id(btf, next_type_id);
        if (!next_type || btf_type_is_resolve_source_only(next_type)) {
@@ -1675,12 +1680,12 @@ static int btf_var_resolve(struct btf_verifier_env *env,
         * forward types or similar that would resolve to size of
         * zero is allowed.
         */
-       if (!btf_type_id_size(btf, &next_type_id, &next_type_size)) {
+       if (!btf_type_id_size(btf, &next_type_id, NULL)) {
                btf_verifier_log_type(env, v->t, "Invalid type_id");
                return -EINVAL;
        }
 
-       env_stack_pop_resolved(env, next_type_id, next_type_size);
+       env_stack_pop_resolved(env, next_type_id, 0);
 
        return 0;
 }
index a2e763703c300b6348d230a0944d0537a210f62b..5900cbb966b17adb04538e887b2f2eff658ba823 100644 (file)
@@ -1519,9 +1519,9 @@ static int backtrack_insn(struct bpf_verifier_env *env, int idx,
                        return -EFAULT;
                }
                *stack_mask |= 1ull << spi;
-       } else if (class == BPF_STX) {
+       } else if (class == BPF_STX || class == BPF_ST) {
                if (*reg_mask & dreg)
-                       /* stx shouldn't be using _scalar_ dst_reg
+                       /* stx & st shouldn't be using _scalar_ dst_reg
                         * to access memory. It means backtracking
                         * encountered a case of pointer subtraction.
                         */
@@ -1540,7 +1540,8 @@ static int backtrack_insn(struct bpf_verifier_env *env, int idx,
                if (!(*stack_mask & (1ull << spi)))
                        return 0;
                *stack_mask &= ~(1ull << spi);
-               *reg_mask |= sreg;
+               if (class == BPF_STX)
+                       *reg_mask |= sreg;
        } else if (class == BPF_JMP || class == BPF_JMP32) {
                if (opcode == BPF_CALL) {
                        if (insn->src_reg == BPF_PSEUDO_CALL)
@@ -1569,10 +1570,6 @@ static int backtrack_insn(struct bpf_verifier_env *env, int idx,
                if (mode == BPF_IND || mode == BPF_ABS)
                        /* to be analyzed */
                        return -ENOTSUPP;
-       } else if (class == BPF_ST) {
-               if (*reg_mask & dreg)
-                       /* likely pointer subtraction */
-                       return -ENOTSUPP;
        }
        return 0;
 }
@@ -6106,11 +6103,13 @@ static int check_return_code(struct bpf_verifier_env *env)
                if (env->prog->expected_attach_type == BPF_CGROUP_UDP4_RECVMSG ||
                    env->prog->expected_attach_type == BPF_CGROUP_UDP6_RECVMSG)
                        range = tnum_range(1, 1);
+               break;
        case BPF_PROG_TYPE_CGROUP_SKB:
                if (env->prog->expected_attach_type == BPF_CGROUP_INET_EGRESS) {
                        range = tnum_range(0, 3);
                        enforce_attach_type_range = tnum_range(2, 3);
                }
+               break;
        case BPF_PROG_TYPE_CGROUP_SOCK:
        case BPF_PROG_TYPE_SOCK_OPS:
        case BPF_PROG_TYPE_CGROUP_DEVICE:
index 47f6386fb17afbd41c2685097b9eac75d92c634b..0f6854ccf8949f131f7e229d552f9f947dc205a2 100644 (file)
@@ -6884,20 +6884,30 @@ static bool sock_addr_is_valid_access(int off, int size,
        case bpf_ctx_range(struct bpf_sock_addr, msg_src_ip4):
        case bpf_ctx_range_till(struct bpf_sock_addr, msg_src_ip6[0],
                                msg_src_ip6[3]):
-               /* Only narrow read access allowed for now. */
                if (type == BPF_READ) {
                        bpf_ctx_record_field_size(info, size_default);
+
+                       if (bpf_ctx_wide_access_ok(off, size,
+                                                  struct bpf_sock_addr,
+                                                  user_ip6))
+                               return true;
+
+                       if (bpf_ctx_wide_access_ok(off, size,
+                                                  struct bpf_sock_addr,
+                                                  msg_src_ip6))
+                               return true;
+
                        if (!bpf_ctx_narrow_access_ok(off, size, size_default))
                                return false;
                } else {
-                       if (bpf_ctx_wide_store_ok(off, size,
-                                                 struct bpf_sock_addr,
-                                                 user_ip6))
+                       if (bpf_ctx_wide_access_ok(off, size,
+                                                  struct bpf_sock_addr,
+                                                  user_ip6))
                                return true;
 
-                       if (bpf_ctx_wide_store_ok(off, size,
-                                                 struct bpf_sock_addr,
-                                                 msg_src_ip6))
+                       if (bpf_ctx_wide_access_ok(off, size,
+                                                  struct bpf_sock_addr,
+                                                  msg_src_ip6))
                                return true;
 
                        if (size != size_default)
index 20c91f02d3d8056614112a3adbf9a27fedd5629f..83de74ca729a39bc22cd83ac3f1cb2e7b184db0f 100644 (file)
@@ -87,21 +87,20 @@ int xdp_umem_assign_dev(struct xdp_umem *umem, struct net_device *dev,
        struct netdev_bpf bpf;
        int err = 0;
 
+       ASSERT_RTNL();
+
        force_zc = flags & XDP_ZEROCOPY;
        force_copy = flags & XDP_COPY;
 
        if (force_zc && force_copy)
                return -EINVAL;
 
-       rtnl_lock();
-       if (xdp_get_umem_from_qid(dev, queue_id)) {
-               err = -EBUSY;
-               goto out_rtnl_unlock;
-       }
+       if (xdp_get_umem_from_qid(dev, queue_id))
+               return -EBUSY;
 
        err = xdp_reg_umem_at_qid(dev, umem, queue_id);
        if (err)
-               goto out_rtnl_unlock;
+               return err;
 
        umem->dev = dev;
        umem->queue_id = queue_id;
@@ -110,7 +109,7 @@ int xdp_umem_assign_dev(struct xdp_umem *umem, struct net_device *dev,
 
        if (force_copy)
                /* For copy-mode, we are done. */
-               goto out_rtnl_unlock;
+               return 0;
 
        if (!dev->netdev_ops->ndo_bpf ||
            !dev->netdev_ops->ndo_xsk_async_xmit) {
@@ -125,7 +124,6 @@ int xdp_umem_assign_dev(struct xdp_umem *umem, struct net_device *dev,
        err = dev->netdev_ops->ndo_bpf(dev, &bpf);
        if (err)
                goto err_unreg_umem;
-       rtnl_unlock();
 
        umem->zc = true;
        return 0;
@@ -135,8 +133,6 @@ err_unreg_umem:
                err = 0; /* fallback to copy mode */
        if (err)
                xdp_clear_umem_at_qid(dev, queue_id);
-out_rtnl_unlock:
-       rtnl_unlock();
        return err;
 }
 
index d4d6f10aa93646d280c23eb6f28b89582cbb922f..59b57d7086970b53b140bc500c881ab9cf1fb98b 100644 (file)
@@ -240,6 +240,9 @@ static int xsk_generic_xmit(struct sock *sk, struct msghdr *m,
 
        mutex_lock(&xs->mutex);
 
+       if (xs->queue_id >= xs->dev->real_num_tx_queues)
+               goto out;
+
        while (xskq_peek_desc(xs->tx, &desc)) {
                char *buffer;
                u64 addr;
@@ -250,12 +253,6 @@ static int xsk_generic_xmit(struct sock *sk, struct msghdr *m,
                        goto out;
                }
 
-               if (xskq_reserve_addr(xs->umem->cq))
-                       goto out;
-
-               if (xs->queue_id >= xs->dev->real_num_tx_queues)
-                       goto out;
-
                len = desc.len;
                skb = sock_alloc_send_skb(sk, len, 1, &err);
                if (unlikely(!skb)) {
@@ -267,7 +264,7 @@ static int xsk_generic_xmit(struct sock *sk, struct msghdr *m,
                addr = desc.addr;
                buffer = xdp_umem_get_data(xs->umem, addr);
                err = skb_store_bits(skb, 0, buffer, len);
-               if (unlikely(err)) {
+               if (unlikely(err) || xskq_reserve_addr(xs->umem->cq)) {
                        kfree_skb(skb);
                        goto out;
                }
@@ -433,6 +430,7 @@ static int xsk_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
        if (flags & ~(XDP_SHARED_UMEM | XDP_COPY | XDP_ZEROCOPY))
                return -EINVAL;
 
+       rtnl_lock();
        mutex_lock(&xs->mutex);
        if (xs->state != XSK_READY) {
                err = -EBUSY;
@@ -518,6 +516,7 @@ out_unlock:
                xs->state = XSK_BOUND;
 out_release:
        mutex_unlock(&xs->mutex);
+       rtnl_unlock();
        return err;
 }
 
index f90daadfbc89cd59f3df0824864b2f872e66a293..1d9be26b4edd79b2ad0f4661411790d9e71d45dd 100644 (file)
@@ -284,7 +284,7 @@ $(obj)/%.o: $(src)/%.c
        $(Q)$(CLANG) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) $(EXTRA_CFLAGS) -I$(obj) \
                -I$(srctree)/tools/testing/selftests/bpf/ \
                -D__KERNEL__ -D__BPF_TRACING__ -Wno-unused-value -Wno-pointer-sign \
-               -D__TARGET_ARCH_$(ARCH) -Wno-compare-distinct-pointer-types \
+               -D__TARGET_ARCH_$(SRCARCH) -Wno-compare-distinct-pointer-types \
                -Wno-gnu-variable-sized-type-not-at-end \
                -Wno-address-of-packed-member -Wno-tautological-compare \
                -Wno-unknown-warning-option $(CLANG_ARCH_ARGS) \
index 3ef0d9051e105f52d2cb21bc8176d1f1e8bbeef2..7031a4bf87a020716df5eb20fa0c641c423de9d7 100644 (file)
@@ -74,6 +74,7 @@ static const char * const prog_type_name[] = {
        [BPF_PROG_TYPE_SK_REUSEPORT]            = "sk_reuseport",
        [BPF_PROG_TYPE_FLOW_DISSECTOR]          = "flow_dissector",
        [BPF_PROG_TYPE_CGROUP_SYSCTL]           = "cgroup_sysctl",
+       [BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE] = "raw_tracepoint_writable",
        [BPF_PROG_TYPE_CGROUP_SOCKOPT]          = "cgroup_sockopt",
 };
 
index f506c68b26127cd5b6c54f2b04106e2f7368f2ee..1f61374fcf81ad276bdab6b147c39bef814a5f92 100644 (file)
@@ -3245,7 +3245,7 @@ struct bpf_sock_addr {
        __u32 user_ip4;         /* Allows 1,2,4-byte read and 4-byte write.
                                 * Stored in network byte order.
                                 */
-       __u32 user_ip6[4];      /* Allows 1,2,4-byte read and 4,8-byte write.
+       __u32 user_ip6[4];      /* Allows 1,2,4,8-byte read and 4,8-byte write.
                                 * Stored in network byte order.
                                 */
        __u32 user_port;        /* Allows 4-byte read and write.
@@ -3257,7 +3257,7 @@ struct bpf_sock_addr {
        __u32 msg_src_ip4;      /* Allows 1,2,4-byte read and 4-byte write.
                                 * Stored in network byte order.
                                 */
-       __u32 msg_src_ip6[4];   /* Allows 1,2,4-byte read and 4,8-byte write.
+       __u32 msg_src_ip6[4];   /* Allows 1,2,4,8-byte read and 4,8-byte write.
                                 * Stored in network byte order.
                                 */
        __bpf_md_ptr(struct bpf_sock *, sk);
index ed07789b3e62307d46a3cb7d5862170a850eb259..794dd5064ae8a01d9628c3baade0605a24fa4f44 100644 (file)
@@ -4126,8 +4126,8 @@ static int perf_event_open_probe(bool uprobe, bool retprobe, const char *name,
        }
        attr.size = sizeof(attr);
        attr.type = type;
-       attr.config1 = (uint64_t)(void *)name; /* kprobe_func or uprobe_path */
-       attr.config2 = offset;                 /* kprobe_addr or probe_offset */
+       attr.config1 = ptr_to_u64(name); /* kprobe_func or uprobe_path */
+       attr.config2 = offset;           /* kprobe_addr or probe_offset */
 
        /* pid filter is meaningful only for uprobes */
        pfd = syscall(__NR_perf_event_open, &attr,
index b33740221b7e7bd86c4f1286c8010fe587f79fc6..5007b5d4fd2c51186a554fb03893dcabd7bef381 100644 (file)
@@ -517,7 +517,8 @@ int xsk_socket__create(struct xsk_socket **xsk_ptr, const char *ifname,
                err = -errno;
                goto out_socket;
        }
-       strncpy(xsk->ifname, ifname, IFNAMSIZ);
+       strncpy(xsk->ifname, ifname, IFNAMSIZ - 1);
+       xsk->ifname[IFNAMSIZ - 1] = '\0';
 
        err = xsk_set_xdp_socket_config(&xsk->config, usr_config);
        if (err)
index 2620406a53ecc341c9e6704b043c33a008ea7d78..11c9c62c33620790f6ff72cba3369721f13fdc4e 100644 (file)
@@ -1,4 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
+include ../../../../scripts/Kbuild.include
+include ../../../scripts/Makefile.arch
 
 LIBDIR := ../../../lib
 BPFDIR := $(LIBDIR)/bpf
@@ -81,13 +83,14 @@ all: $(TEST_CUSTOM_PROGS)
 $(OUTPUT)/urandom_read: $(OUTPUT)/%: %.c
        $(CC) -o $@ $< -Wl,--build-id
 
-$(OUTPUT)/test_maps: map_tests/*.c
+$(OUTPUT)/test_stub.o: test_stub.c
+       $(CC) $(TEST_PROGS_CFLAGS) $(CFLAGS) -c -o $@ $<
 
 BPFOBJ := $(OUTPUT)/libbpf.a
 
-$(TEST_GEN_PROGS): test_stub.o $(BPFOBJ)
+$(TEST_GEN_PROGS): $(OUTPUT)/test_stub.o $(BPFOBJ)
 
-$(TEST_GEN_PROGS_EXTENDED): test_stub.o $(OUTPUT)/libbpf.a
+$(TEST_GEN_PROGS_EXTENDED): $(OUTPUT)/test_stub.o $(OUTPUT)/libbpf.a
 
 $(OUTPUT)/test_dev_cgroup: cgroup_helpers.c
 $(OUTPUT)/test_skb_cgroup_id_user: cgroup_helpers.c
@@ -138,7 +141,8 @@ CLANG_SYS_INCLUDES := $(shell $(CLANG) -v -E - </dev/null 2>&1 \
 
 CLANG_FLAGS = -I. -I./include/uapi -I../../../include/uapi \
              $(CLANG_SYS_INCLUDES) \
-             -Wno-compare-distinct-pointer-types
+             -Wno-compare-distinct-pointer-types \
+             -D__TARGET_ARCH_$(SRCARCH)
 
 $(OUTPUT)/test_l4lb_noinline.o: CLANG_FLAGS += -fno-inline
 $(OUTPUT)/test_xdp_noinline.o: CLANG_FLAGS += -fno-inline
@@ -172,6 +176,7 @@ endif
 endif
 
 TEST_PROGS_CFLAGS := -I. -I$(OUTPUT)
+TEST_MAPS_CFLAGS := -I. -I$(OUTPUT)
 TEST_VERIFIER_CFLAGS := -I. -I$(OUTPUT) -Iverifier
 
 ifneq ($(SUBREG_CODEGEN),)
@@ -180,12 +185,12 @@ TEST_CUSTOM_PROGS += $(ALU32_BUILD_DIR)/test_progs_32
 $(ALU32_BUILD_DIR):
        mkdir -p $@
 
-$(ALU32_BUILD_DIR)/urandom_read: $(OUTPUT)/urandom_read
+$(ALU32_BUILD_DIR)/urandom_read: $(OUTPUT)/urandom_read | $(ALU32_BUILD_DIR)
        cp $< $@
 
 $(ALU32_BUILD_DIR)/test_progs_32: test_progs.c $(OUTPUT)/libbpf.a\
-                                               $(ALU32_BUILD_DIR) \
-                                               $(ALU32_BUILD_DIR)/urandom_read
+                                               $(ALU32_BUILD_DIR)/urandom_read \
+                                               | $(ALU32_BUILD_DIR)
        $(CC) $(TEST_PROGS_CFLAGS) $(CFLAGS) \
                -o $(ALU32_BUILD_DIR)/test_progs_32 \
                test_progs.c test_stub.c trace_helpers.c prog_tests/*.c \
@@ -194,10 +199,10 @@ $(ALU32_BUILD_DIR)/test_progs_32: test_progs.c $(OUTPUT)/libbpf.a\
 $(ALU32_BUILD_DIR)/test_progs_32: $(PROG_TESTS_H)
 $(ALU32_BUILD_DIR)/test_progs_32: prog_tests/*.c
 
-$(ALU32_BUILD_DIR)/%.o: progs/%.c $(ALU32_BUILD_DIR) \
-                                       $(ALU32_BUILD_DIR)/test_progs_32
-       $(CLANG) $(CLANG_FLAGS) \
-                -O2 -target bpf -emit-llvm -c $< -o - |      \
+$(ALU32_BUILD_DIR)/%.o: progs/%.c $(ALU32_BUILD_DIR)/test_progs_32 \
+                                       | $(ALU32_BUILD_DIR)
+       ($(CLANG) $(CLANG_FLAGS) -O2 -target bpf -emit-llvm -c $< -o - || \
+               echo "clang failed") | \
        $(LLC) -march=bpf -mattr=+alu32 -mcpu=$(CPU) $(LLC_FLAGS) \
                -filetype=obj -o $@
 ifeq ($(DWARF2BTF),y)
@@ -208,32 +213,30 @@ endif
 # Have one program compiled without "-target bpf" to test whether libbpf loads
 # it successfully
 $(OUTPUT)/test_xdp.o: progs/test_xdp.c
-       $(CLANG) $(CLANG_FLAGS) \
-               -O2 -emit-llvm -c $< -o - | \
+       ($(CLANG) $(CLANG_FLAGS) -O2 -emit-llvm -c $< -o - || \
+               echo "clang failed") | \
        $(LLC) -march=bpf -mcpu=$(CPU) $(LLC_FLAGS) -filetype=obj -o $@
 ifeq ($(DWARF2BTF),y)
        $(BTF_PAHOLE) -J $@
 endif
 
 $(OUTPUT)/%.o: progs/%.c
-       $(CLANG) $(CLANG_FLAGS) \
-                -O2 -target bpf -emit-llvm -c $< -o - |      \
+       ($(CLANG) $(CLANG_FLAGS) -O2 -target bpf -emit-llvm -c $< -o - || \
+               echo "clang failed") | \
        $(LLC) -march=bpf -mcpu=$(CPU) $(LLC_FLAGS) -filetype=obj -o $@
 ifeq ($(DWARF2BTF),y)
        $(BTF_PAHOLE) -J $@
 endif
 
-PROG_TESTS_H := $(OUTPUT)/prog_tests/tests.h
-test_progs.c: $(PROG_TESTS_H)
-$(OUTPUT)/test_progs: CFLAGS += $(TEST_PROGS_CFLAGS)
-$(OUTPUT)/test_progs: prog_tests/*.c
-
 PROG_TESTS_DIR = $(OUTPUT)/prog_tests
 $(PROG_TESTS_DIR):
        mkdir -p $@
-
+PROG_TESTS_H := $(PROG_TESTS_DIR)/tests.h
 PROG_TESTS_FILES := $(wildcard prog_tests/*.c)
-$(PROG_TESTS_H): $(PROG_TESTS_DIR) $(PROG_TESTS_FILES)
+test_progs.c: $(PROG_TESTS_H)
+$(OUTPUT)/test_progs: CFLAGS += $(TEST_PROGS_CFLAGS)
+$(OUTPUT)/test_progs: test_progs.c $(PROG_TESTS_H) $(PROG_TESTS_FILES)
+$(PROG_TESTS_H): $(PROG_TESTS_FILES) | $(PROG_TESTS_DIR)
        $(shell ( cd prog_tests/; \
                  echo '/* Generated header, do not edit */'; \
                  echo '#ifdef DECLARE'; \
@@ -246,15 +249,15 @@ $(PROG_TESTS_H): $(PROG_TESTS_DIR) $(PROG_TESTS_FILES)
                  echo '#endif' \
                 ) > $(PROG_TESTS_H))
 
-TEST_MAPS_CFLAGS := -I. -I$(OUTPUT)
 MAP_TESTS_DIR = $(OUTPUT)/map_tests
 $(MAP_TESTS_DIR):
        mkdir -p $@
 MAP_TESTS_H := $(MAP_TESTS_DIR)/tests.h
+MAP_TESTS_FILES := $(wildcard map_tests/*.c)
 test_maps.c: $(MAP_TESTS_H)
 $(OUTPUT)/test_maps: CFLAGS += $(TEST_MAPS_CFLAGS)
-MAP_TESTS_FILES := $(wildcard map_tests/*.c)
-$(MAP_TESTS_H): $(MAP_TESTS_DIR) $(MAP_TESTS_FILES)
+$(OUTPUT)/test_maps: test_maps.c $(MAP_TESTS_H) $(MAP_TESTS_FILES)
+$(MAP_TESTS_H): $(MAP_TESTS_FILES) | $(MAP_TESTS_DIR)
        $(shell ( cd map_tests/; \
                  echo '/* Generated header, do not edit */'; \
                  echo '#ifdef DECLARE'; \
@@ -267,16 +270,15 @@ $(MAP_TESTS_H): $(MAP_TESTS_DIR) $(MAP_TESTS_FILES)
                  echo '#endif' \
                 ) > $(MAP_TESTS_H))
 
-VERIFIER_TESTS_H := $(OUTPUT)/verifier/tests.h
-test_verifier.c: $(VERIFIER_TESTS_H)
-$(OUTPUT)/test_verifier: CFLAGS += $(TEST_VERIFIER_CFLAGS)
-
 VERIFIER_TESTS_DIR = $(OUTPUT)/verifier
 $(VERIFIER_TESTS_DIR):
        mkdir -p $@
-
+VERIFIER_TESTS_H := $(VERIFIER_TESTS_DIR)/tests.h
 VERIFIER_TEST_FILES := $(wildcard verifier/*.c)
-$(OUTPUT)/verifier/tests.h: $(VERIFIER_TESTS_DIR) $(VERIFIER_TEST_FILES)
+test_verifier.c: $(VERIFIER_TESTS_H)
+$(OUTPUT)/test_verifier: CFLAGS += $(TEST_VERIFIER_CFLAGS)
+$(OUTPUT)/test_verifier: test_verifier.c $(VERIFIER_TESTS_H)
+$(VERIFIER_TESTS_H): $(VERIFIER_TEST_FILES) | $(VERIFIER_TESTS_DIR)
        $(shell ( cd verifier/; \
                  echo '/* Generated header, do not edit */'; \
                  echo '#ifdef FILL_ARRAY'; \
index 5a3d92c8bec8623176360b997a314daa51e3c8a5..f804f210244eadf0deb361879f74f6c268c1b34e 100644 (file)
@@ -315,8 +315,8 @@ static int (*bpf_skb_adjust_room)(void *ctx, __s32 len_diff, __u32 mode,
 #if defined(__TARGET_ARCH_x86)
        #define bpf_target_x86
        #define bpf_target_defined
-#elif defined(__TARGET_ARCH_s930x)
-       #define bpf_target_s930x
+#elif defined(__TARGET_ARCH_s390)
+       #define bpf_target_s390
        #define bpf_target_defined
 #elif defined(__TARGET_ARCH_arm)
        #define bpf_target_arm
@@ -341,8 +341,8 @@ static int (*bpf_skb_adjust_room)(void *ctx, __s32 len_diff, __u32 mode,
 #ifndef bpf_target_defined
 #if defined(__x86_64__)
        #define bpf_target_x86
-#elif defined(__s390x__)
-       #define bpf_target_s930x
+#elif defined(__s390__)
+       #define bpf_target_s390
 #elif defined(__arm__)
        #define bpf_target_arm
 #elif defined(__aarch64__)
@@ -358,6 +358,7 @@ static int (*bpf_skb_adjust_room)(void *ctx, __s32 len_diff, __u32 mode,
 
 #if defined(bpf_target_x86)
 
+#ifdef __KERNEL__
 #define PT_REGS_PARM1(x) ((x)->di)
 #define PT_REGS_PARM2(x) ((x)->si)
 #define PT_REGS_PARM3(x) ((x)->dx)
@@ -368,19 +369,49 @@ static int (*bpf_skb_adjust_room)(void *ctx, __s32 len_diff, __u32 mode,
 #define PT_REGS_RC(x) ((x)->ax)
 #define PT_REGS_SP(x) ((x)->sp)
 #define PT_REGS_IP(x) ((x)->ip)
+#else
+#ifdef __i386__
+/* i386 kernel is built with -mregparm=3 */
+#define PT_REGS_PARM1(x) ((x)->eax)
+#define PT_REGS_PARM2(x) ((x)->edx)
+#define PT_REGS_PARM3(x) ((x)->ecx)
+#define PT_REGS_PARM4(x) 0
+#define PT_REGS_PARM5(x) 0
+#define PT_REGS_RET(x) ((x)->esp)
+#define PT_REGS_FP(x) ((x)->ebp)
+#define PT_REGS_RC(x) ((x)->eax)
+#define PT_REGS_SP(x) ((x)->esp)
+#define PT_REGS_IP(x) ((x)->eip)
+#else
+#define PT_REGS_PARM1(x) ((x)->rdi)
+#define PT_REGS_PARM2(x) ((x)->rsi)
+#define PT_REGS_PARM3(x) ((x)->rdx)
+#define PT_REGS_PARM4(x) ((x)->rcx)
+#define PT_REGS_PARM5(x) ((x)->r8)
+#define PT_REGS_RET(x) ((x)->rsp)
+#define PT_REGS_FP(x) ((x)->rbp)
+#define PT_REGS_RC(x) ((x)->rax)
+#define PT_REGS_SP(x) ((x)->rsp)
+#define PT_REGS_IP(x) ((x)->rip)
+#endif
+#endif
 
-#elif defined(bpf_target_s390x)
+#elif defined(bpf_target_s390)
 
-#define PT_REGS_PARM1(x) ((x)->gprs[2])
-#define PT_REGS_PARM2(x) ((x)->gprs[3])
-#define PT_REGS_PARM3(x) ((x)->gprs[4])
-#define PT_REGS_PARM4(x) ((x)->gprs[5])
-#define PT_REGS_PARM5(x) ((x)->gprs[6])
-#define PT_REGS_RET(x) ((x)->gprs[14])
-#define PT_REGS_FP(x) ((x)->gprs[11]) /* Works only with CONFIG_FRAME_POINTER */
-#define PT_REGS_RC(x) ((x)->gprs[2])
-#define PT_REGS_SP(x) ((x)->gprs[15])
-#define PT_REGS_IP(x) ((x)->psw.addr)
+/* s390 provides user_pt_regs instead of struct pt_regs to userspace */
+struct pt_regs;
+#define PT_REGS_S390 const volatile user_pt_regs
+#define PT_REGS_PARM1(x) (((PT_REGS_S390 *)(x))->gprs[2])
+#define PT_REGS_PARM2(x) (((PT_REGS_S390 *)(x))->gprs[3])
+#define PT_REGS_PARM3(x) (((PT_REGS_S390 *)(x))->gprs[4])
+#define PT_REGS_PARM4(x) (((PT_REGS_S390 *)(x))->gprs[5])
+#define PT_REGS_PARM5(x) (((PT_REGS_S390 *)(x))->gprs[6])
+#define PT_REGS_RET(x) (((PT_REGS_S390 *)(x))->gprs[14])
+/* Works only with CONFIG_FRAME_POINTER */
+#define PT_REGS_FP(x) (((PT_REGS_S390 *)(x))->gprs[11])
+#define PT_REGS_RC(x) (((PT_REGS_S390 *)(x))->gprs[2])
+#define PT_REGS_SP(x) (((PT_REGS_S390 *)(x))->gprs[15])
+#define PT_REGS_IP(x) (((PT_REGS_S390 *)(x))->psw.addr)
 
 #elif defined(bpf_target_arm)
 
@@ -397,16 +428,20 @@ static int (*bpf_skb_adjust_room)(void *ctx, __s32 len_diff, __u32 mode,
 
 #elif defined(bpf_target_arm64)
 
-#define PT_REGS_PARM1(x) ((x)->regs[0])
-#define PT_REGS_PARM2(x) ((x)->regs[1])
-#define PT_REGS_PARM3(x) ((x)->regs[2])
-#define PT_REGS_PARM4(x) ((x)->regs[3])
-#define PT_REGS_PARM5(x) ((x)->regs[4])
-#define PT_REGS_RET(x) ((x)->regs[30])
-#define PT_REGS_FP(x) ((x)->regs[29]) /* Works only with CONFIG_FRAME_POINTER */
-#define PT_REGS_RC(x) ((x)->regs[0])
-#define PT_REGS_SP(x) ((x)->sp)
-#define PT_REGS_IP(x) ((x)->pc)
+/* arm64 provides struct user_pt_regs instead of struct pt_regs to userspace */
+struct pt_regs;
+#define PT_REGS_ARM64 const volatile struct user_pt_regs
+#define PT_REGS_PARM1(x) (((PT_REGS_ARM64 *)(x))->regs[0])
+#define PT_REGS_PARM2(x) (((PT_REGS_ARM64 *)(x))->regs[1])
+#define PT_REGS_PARM3(x) (((PT_REGS_ARM64 *)(x))->regs[2])
+#define PT_REGS_PARM4(x) (((PT_REGS_ARM64 *)(x))->regs[3])
+#define PT_REGS_PARM5(x) (((PT_REGS_ARM64 *)(x))->regs[4])
+#define PT_REGS_RET(x) (((PT_REGS_ARM64 *)(x))->regs[30])
+/* Works only with CONFIG_FRAME_POINTER */
+#define PT_REGS_FP(x) (((PT_REGS_ARM64 *)(x))->regs[29])
+#define PT_REGS_RC(x) (((PT_REGS_ARM64 *)(x))->regs[0])
+#define PT_REGS_SP(x) (((PT_REGS_ARM64 *)(x))->sp)
+#define PT_REGS_IP(x) (((PT_REGS_ARM64 *)(x))->pc)
 
 #elif defined(bpf_target_mips)
 
@@ -452,10 +487,10 @@ static int (*bpf_skb_adjust_room)(void *ctx, __s32 len_diff, __u32 mode,
 
 #endif
 
-#ifdef bpf_target_powerpc
+#if defined(bpf_target_powerpc)
 #define BPF_KPROBE_READ_RET_IP(ip, ctx)                ({ (ip) = (ctx)->link; })
 #define BPF_KRETPROBE_READ_RET_IP              BPF_KPROBE_READ_RET_IP
-#elif bpf_target_sparc
+#elif defined(bpf_target_sparc)
 #define BPF_KPROBE_READ_RET_IP(ip, ctx)                ({ (ip) = PT_REGS_RET(ctx); })
 #define BPF_KRETPROBE_READ_RET_IP              BPF_KPROBE_READ_RET_IP
 #else
index a4686395522cd3f3c9619efd0644fce0fd383eb3..5ecc267d98b06b5289d39d01b85630a7145347b1 100644 (file)
@@ -21,12 +21,6 @@ ssize_t get_base_addr() {
        return -EINVAL;
 }
 
-#ifdef __x86_64__
-#define SYS_KPROBE_NAME "__x64_sys_nanosleep"
-#else
-#define SYS_KPROBE_NAME "sys_nanosleep"
-#endif
-
 void test_attach_probe(void)
 {
        const char *kprobe_name = "kprobe/sys_nanosleep";
@@ -84,7 +78,7 @@ void test_attach_probe(void)
 
        kprobe_link = bpf_program__attach_kprobe(kprobe_prog,
                                                 false /* retprobe */,
-                                                SYS_KPROBE_NAME);
+                                                SYS_NANOSLEEP_KPROBE_NAME);
        if (CHECK(IS_ERR(kprobe_link), "attach_kprobe",
                  "err %ld\n", PTR_ERR(kprobe_link))) {
                kprobe_link = NULL;
@@ -92,7 +86,7 @@ void test_attach_probe(void)
        }
        kretprobe_link = bpf_program__attach_kprobe(kretprobe_prog,
                                                    true /* retprobe */,
-                                                   SYS_KPROBE_NAME);
+                                                   SYS_NANOSLEEP_KPROBE_NAME);
        if (CHECK(IS_ERR(kretprobe_link), "attach_kretprobe",
                  "err %ld\n", PTR_ERR(kretprobe_link))) {
                kretprobe_link = NULL;
index 3f1ef95865ff4fc8077abf2a15ed089b13764461..3003fddc0613f5c460c2876ad5ae57a25fecfe22 100644 (file)
@@ -5,12 +5,6 @@
 #include <sys/socket.h>
 #include <test_progs.h>
 
-#ifdef __x86_64__
-#define SYS_KPROBE_NAME "__x64_sys_nanosleep"
-#else
-#define SYS_KPROBE_NAME "sys_nanosleep"
-#endif
-
 static void on_sample(void *ctx, int cpu, void *data, __u32 size)
 {
        int cpu_data = *(int *)data, duration = 0;
@@ -56,7 +50,7 @@ void test_perf_buffer(void)
 
        /* attach kprobe */
        link = bpf_program__attach_kprobe(prog, false /* retprobe */,
-                                         SYS_KPROBE_NAME);
+                                         SYS_NANOSLEEP_KPROBE_NAME);
        if (CHECK(IS_ERR(link), "attach_kprobe", "err %ld\n", PTR_ERR(link)))
                goto out_close;
 
index 67cea1686305082eac0263ce16de8012c0f9c68c..54218ee3c004496ce1451c5a86434d149944422d 100644 (file)
@@ -173,6 +173,18 @@ static int test_send_signal_tracepoint(void)
        return test_send_signal_common(&attr, BPF_PROG_TYPE_TRACEPOINT, "tracepoint");
 }
 
+static int test_send_signal_perf(void)
+{
+       struct perf_event_attr attr = {
+               .sample_period = 1,
+               .type = PERF_TYPE_SOFTWARE,
+               .config = PERF_COUNT_SW_CPU_CLOCK,
+       };
+
+       return test_send_signal_common(&attr, BPF_PROG_TYPE_PERF_EVENT,
+                                      "perf_sw_event");
+}
+
 static int test_send_signal_nmi(void)
 {
        struct perf_event_attr attr = {
@@ -181,8 +193,26 @@ static int test_send_signal_nmi(void)
                .type = PERF_TYPE_HARDWARE,
                .config = PERF_COUNT_HW_CPU_CYCLES,
        };
+       int pmu_fd;
+
+       /* Some setups (e.g. virtual machines) might run with hardware
+        * perf events disabled. If this is the case, skip this test.
+        */
+       pmu_fd = syscall(__NR_perf_event_open, &attr, 0 /* pid */,
+                        -1 /* cpu */, -1 /* group_fd */, 0 /* flags */);
+       if (pmu_fd == -1) {
+               if (errno == ENOENT) {
+                       printf("%s:SKIP:no PERF_COUNT_HW_CPU_CYCLES\n",
+                               __func__);
+                       return 0;
+               }
+               /* Let the test fail with a more informative message */
+       } else {
+               close(pmu_fd);
+       }
 
-       return test_send_signal_common(&attr, BPF_PROG_TYPE_PERF_EVENT, "perf_event");
+       return test_send_signal_common(&attr, BPF_PROG_TYPE_PERF_EVENT,
+                                      "perf_hw_event");
 }
 
 void test_send_signal(void)
@@ -190,6 +220,7 @@ void test_send_signal(void)
        int ret = 0;
 
        ret |= test_send_signal_tracepoint();
+       ret |= test_send_signal_perf();
        ret |= test_send_signal_nmi();
        if (!ret)
                printf("test_send_signal:OK\n");
index dea395af9ea9f57bb61028d082b13deb1c2d968c..7cdb7f878310b2dba828432d421ac61e0c69dfae 100644 (file)
@@ -18,7 +18,7 @@ int nested_loops(volatile struct pt_regs* ctx)
        for (j = 0; j < 300; j++)
                for (i = 0; i < j; i++) {
                        if (j & 1)
-                               m = ctx->rax;
+                               m = PT_REGS_RC(ctx);
                        else
                                m = j;
                        sum += i * m;
index 0637bd8e8bcf5827144fca281b08d9dbc88bf76f..9b2f808a2863732f7a3648ed6a875c1a93b57425 100644 (file)
@@ -16,7 +16,7 @@ int while_true(volatile struct pt_regs* ctx)
        int i = 0;
 
        while (true) {
-               if (ctx->rax & 1)
+               if (PT_REGS_RC(ctx) & 1)
                        i += 3;
                else
                        i += 7;
index 30a0f6cba080b9b5c69d0d073d568182287de074..d727657d51e2ab95afe97465f2ba9a63ce7bc23c 100644 (file)
@@ -16,7 +16,7 @@ int while_true(volatile struct pt_regs* ctx)
        __u64 i = 0, sum = 0;
        do {
                i++;
-               sum += ctx->rax;
+               sum += PT_REGS_RC(ctx);
        } while (i < 0x100000000ULL);
        return sum;
 }
index d06b47a090972922eba7062cb3e75633e21efbd2..33254b771384e4d2c20a180c1c55b167ec37ca91 100644 (file)
@@ -47,11 +47,12 @@ struct {
  * issue and avoid complicated C programming massaging.
  * This is an acceptable workaround since there is one entry here.
  */
+typedef __u64 raw_stack_trace_t[2 * MAX_STACK_RAWTP];
 struct {
        __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
        __uint(max_entries, 1);
        __type(key, __u32);
-       __u64 (*value)[2 * MAX_STACK_RAWTP];
+       __type(value, raw_stack_trace_t);
 } rawdata_map SEC(".maps");
 
 SEC("tracepoint/raw_syscalls/sys_enter")
index bbfc8337b6f0e46eecf4281b20a82e7252f01690..f5638e26865d030804f60df8ea706ed81abdea76 100644 (file)
@@ -36,8 +36,7 @@ struct {
        __uint(type, BPF_MAP_TYPE_ARRAY);
        __uint(max_entries, 128);
        __type(key, __u32);
-       /* there seems to be a bug in kernel not handling typedef properly */
-       struct bpf_stack_build_id (*value)[PERF_MAX_STACK_DEPTH];
+       __type(value, stack_trace_t);
 } stack_amap SEC(".maps");
 
 /* taken from /sys/kernel/debug/tracing/events/random/urandom_read/format */
index 803c15dc109d21ee18e16fb40378847c2e2bfd86..fa0be3e10a1002c7834c6f6f9bfbaaea60ef8b27 100644 (file)
@@ -35,7 +35,7 @@ struct {
        __uint(type, BPF_MAP_TYPE_ARRAY);
        __uint(max_entries, 16384);
        __type(key, __u32);
-       __u64 (*value)[PERF_MAX_STACK_DEPTH];
+       __type(value, stack_trace_t);
 } stack_amap SEC(".maps");
 
 /* taken from /sys/kernel/debug/tracing/events/sched/sched_switch/format */
index dad8a7e33eaa7d3bd71f0ff3911feb92fac3128c..e88d7b9d65abf808eb839b60b72998ff4fc67256 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/tcp.h>
 #include <linux/udp.h>
 #include "bpf_helpers.h"
+#include "bpf_endian.h"
 
 static __u32 rol32(__u32 word, unsigned int shift)
 {
@@ -305,7 +306,7 @@ bool encap_v6(struct xdp_md *xdp, struct ctl_value *cval,
        ip6h->nexthdr = IPPROTO_IPV6;
        ip_suffix = pckt->flow.srcv6[3] ^ pckt->flow.port16[0];
        ip6h->payload_len =
-           __builtin_bswap16(pkt_bytes + sizeof(struct ipv6hdr));
+           bpf_htons(pkt_bytes + sizeof(struct ipv6hdr));
        ip6h->hop_limit = 4;
 
        ip6h->saddr.in6_u.u6_addr32[0] = 1;
@@ -322,7 +323,7 @@ bool encap_v4(struct xdp_md *xdp, struct ctl_value *cval,
              struct real_definition *dst, __u32 pkt_bytes)
 {
 
-       __u32 ip_suffix = __builtin_bswap16(pckt->flow.port16[0]);
+       __u32 ip_suffix = bpf_ntohs(pckt->flow.port16[0]);
        struct eth_hdr *new_eth;
        struct eth_hdr *old_eth;
        __u16 *next_iph_u16;
@@ -352,7 +353,7 @@ bool encap_v4(struct xdp_md *xdp, struct ctl_value *cval,
        iph->protocol = IPPROTO_IPIP;
        iph->check = 0;
        iph->tos = 1;
-       iph->tot_len = __builtin_bswap16(pkt_bytes + sizeof(struct iphdr));
+       iph->tot_len = bpf_htons(pkt_bytes + sizeof(struct iphdr));
        /* don't update iph->daddr, since it will overwrite old eth_proto
         * and multiple iterations of bpf_prog_run() will fail
         */
@@ -639,7 +640,7 @@ static int process_l3_headers_v6(struct packet_description *pckt,
        iph_len = sizeof(struct ipv6hdr);
        *protocol = ip6h->nexthdr;
        pckt->flow.proto = *protocol;
-       *pkt_bytes = __builtin_bswap16(ip6h->payload_len);
+       *pkt_bytes = bpf_ntohs(ip6h->payload_len);
        off += iph_len;
        if (*protocol == 45) {
                return XDP_DROP;
@@ -671,7 +672,7 @@ static int process_l3_headers_v4(struct packet_description *pckt,
                return XDP_DROP;
        *protocol = iph->protocol;
        pckt->flow.proto = *protocol;
-       *pkt_bytes = __builtin_bswap16(iph->tot_len);
+       *pkt_bytes = bpf_ntohs(iph->tot_len);
        off += 20;
        if (iph->frag_off & 65343)
                return XDP_DROP;
@@ -808,10 +809,10 @@ int balancer_ingress(struct xdp_md *ctx)
        nh_off = sizeof(struct eth_hdr);
        if (data + nh_off > data_end)
                return XDP_DROP;
-       eth_proto = eth->eth_proto;
-       if (eth_proto == 8)
+       eth_proto = bpf_ntohs(eth->eth_proto);
+       if (eth_proto == ETH_P_IP)
                return process_packet(data, nh_off, data_end, 0, ctx);
-       else if (eth_proto == 56710)
+       else if (eth_proto == ETH_P_IPV6)
                return process_packet(data, nh_off, data_end, 1, ctx);
        else
                return XDP_DROP;
index 8351cb5f4a2052ec14047db01d04ad15e61723ea..3d617e806054803e332d8530447c6de1ecfbbc95 100644 (file)
@@ -3417,6 +3417,94 @@ static struct btf_raw_test raw_tests[] = {
        .value_type_id = 1,
        .max_entries = 4,
 },
+/*
+ * typedef int arr_t[16];
+ * struct s {
+ *     arr_t *a;
+ * };
+ */
+{
+       .descr = "struct->ptr->typedef->array->int size resolution",
+       .raw_types = {
+               BTF_STRUCT_ENC(NAME_TBD, 1, 8),                 /* [1] */
+               BTF_MEMBER_ENC(NAME_TBD, 2, 0),
+               BTF_PTR_ENC(3),                                 /* [2] */
+               BTF_TYPEDEF_ENC(NAME_TBD, 4),                   /* [3] */
+               BTF_TYPE_ARRAY_ENC(5, 5, 16),                   /* [4] */
+               BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [5] */
+               BTF_END_RAW,
+       },
+       BTF_STR_SEC("\0s\0a\0arr_t"),
+       .map_type = BPF_MAP_TYPE_ARRAY,
+       .map_name = "ptr_mod_chain_size_resolve_map",
+       .key_size = sizeof(int),
+       .value_size = sizeof(int) * 16,
+       .key_type_id = 5 /* int */,
+       .value_type_id = 3 /* arr_t */,
+       .max_entries = 4,
+},
+/*
+ * typedef int arr_t[16][8][4];
+ * struct s {
+ *     arr_t *a;
+ * };
+ */
+{
+       .descr = "struct->ptr->typedef->multi-array->int size resolution",
+       .raw_types = {
+               BTF_STRUCT_ENC(NAME_TBD, 1, 8),                 /* [1] */
+               BTF_MEMBER_ENC(NAME_TBD, 2, 0),
+               BTF_PTR_ENC(3),                                 /* [2] */
+               BTF_TYPEDEF_ENC(NAME_TBD, 4),                   /* [3] */
+               BTF_TYPE_ARRAY_ENC(5, 7, 16),                   /* [4] */
+               BTF_TYPE_ARRAY_ENC(6, 7, 8),                    /* [5] */
+               BTF_TYPE_ARRAY_ENC(7, 7, 4),                    /* [6] */
+               BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [7] */
+               BTF_END_RAW,
+       },
+       BTF_STR_SEC("\0s\0a\0arr_t"),
+       .map_type = BPF_MAP_TYPE_ARRAY,
+       .map_name = "multi_arr_size_resolve_map",
+       .key_size = sizeof(int),
+       .value_size = sizeof(int) * 16 * 8 * 4,
+       .key_type_id = 7 /* int */,
+       .value_type_id = 3 /* arr_t */,
+       .max_entries = 4,
+},
+/*
+ * typedef int int_t;
+ * typedef int_t arr3_t[4];
+ * typedef arr3_t arr2_t[8];
+ * typedef arr2_t arr1_t[16];
+ * struct s {
+ *     arr1_t *a;
+ * };
+ */
+{
+       .descr = "typedef/multi-arr mix size resolution",
+       .raw_types = {
+               BTF_STRUCT_ENC(NAME_TBD, 1, 8),                 /* [1] */
+               BTF_MEMBER_ENC(NAME_TBD, 2, 0),
+               BTF_PTR_ENC(3),                                 /* [2] */
+               BTF_TYPEDEF_ENC(NAME_TBD, 4),                   /* [3] */
+               BTF_TYPE_ARRAY_ENC(5, 10, 16),                  /* [4] */
+               BTF_TYPEDEF_ENC(NAME_TBD, 6),                   /* [5] */
+               BTF_TYPE_ARRAY_ENC(7, 10, 8),                   /* [6] */
+               BTF_TYPEDEF_ENC(NAME_TBD, 8),                   /* [7] */
+               BTF_TYPE_ARRAY_ENC(9, 10, 4),                   /* [8] */
+               BTF_TYPEDEF_ENC(NAME_TBD, 10),                  /* [9] */
+               BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [10] */
+               BTF_END_RAW,
+       },
+       BTF_STR_SEC("\0s\0a\0arr1_t\0arr2_t\0arr3_t\0int_t"),
+       .map_type = BPF_MAP_TYPE_ARRAY,
+       .map_name = "typedef_arra_mix_size_resolve_map",
+       .key_size = sizeof(int),
+       .value_size = sizeof(int) * 16 * 8 * 4,
+       .key_type_id = 10 /* int */,
+       .value_type_id = 3 /* arr_t */,
+       .max_entries = 4,
+},
 
 }; /* struct btf_raw_test raw_tests[] */
 
index f095e1d4c657f4ee56a2198ce26561274d9b7115..49e0f7d85643f40d00272bc5cf2196cda95f4563 100644 (file)
@@ -92,3 +92,11 @@ int compare_map_keys(int map1_fd, int map2_fd);
 int compare_stack_ips(int smap_fd, int amap_fd, int stack_trace_len);
 int extract_build_id(char *build_id, size_t size);
 void *spin_lock_thread(void *arg);
+
+#ifdef __x86_64__
+#define SYS_NANOSLEEP_KPROBE_NAME "__x64_sys_nanosleep"
+#elif defined(__s390x__)
+#define SYS_NANOSLEEP_KPROBE_NAME "__s390x_sys_nanosleep"
+#else
+#define SYS_NANOSLEEP_KPROBE_NAME "sys_nanosleep"
+#endif
index b0773291012ad8bd1ae9ec310ea25b857d059ed4..84135d5f4b351043a212c9c2c24bde4fb0e04418 100644 (file)
@@ -86,7 +86,7 @@ struct bpf_test {
        int fixup_sk_storage_map[MAX_FIXUPS];
        const char *errstr;
        const char *errstr_unpriv;
-       uint32_t retval, retval_unpriv, insn_processed;
+       uint32_t insn_processed;
        int prog_len;
        enum {
                UNDEF,
@@ -95,16 +95,20 @@ struct bpf_test {
        } result, result_unpriv;
        enum bpf_prog_type prog_type;
        uint8_t flags;
-       __u8 data[TEST_DATA_LEN];
        void (*fill_helper)(struct bpf_test *self);
        uint8_t runs;
-       struct {
-               uint32_t retval, retval_unpriv;
-               union {
-                       __u8 data[TEST_DATA_LEN];
-                       __u64 data64[TEST_DATA_LEN / 8];
-               };
-       } retvals[MAX_TEST_RUNS];
+#define bpf_testdata_struct_t                                  \
+       struct {                                                \
+               uint32_t retval, retval_unpriv;                 \
+               union {                                         \
+                       __u8 data[TEST_DATA_LEN];               \
+                       __u64 data64[TEST_DATA_LEN / 8];        \
+               };                                              \
+       }
+       union {
+               bpf_testdata_struct_t;
+               bpf_testdata_struct_t retvals[MAX_TEST_RUNS];
+       };
        enum bpf_attach_type expected_attach_type;
 };
 
@@ -949,17 +953,8 @@ static void do_test_single(struct bpf_test *test, bool unpriv,
                uint32_t expected_val;
                int i;
 
-               if (!test->runs) {
-                       expected_val = unpriv && test->retval_unpriv ?
-                               test->retval_unpriv : test->retval;
-
-                       err = do_prog_test_run(fd_prog, unpriv, expected_val,
-                                              test->data, sizeof(test->data));
-                       if (err)
-                               run_errs++;
-                       else
-                               run_successes++;
-               }
+               if (!test->runs)
+                       test->runs = 1;
 
                for (i = 0; i < test->runs; i++) {
                        if (unpriv && test->retvals[i].retval_unpriv)
index bcb83196e459bed011b9df3b1dbb3404ac9a6088..f3c33e128709b885ee579f08f02ea09cea7bf211 100644 (file)
        BPF_LD_MAP_FD(BPF_REG_1, 0),
        BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
        BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
-       BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
+       BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 0),
        BPF_EXIT_INSN(),
        },
        .fixup_map_array_ro = { 3 },
index c3de1a2c9dc5a741e613f2ab80a7f1f27869d0de..a53d99cebd9ffff7db1c1065b74135a786b9f280 100644 (file)
        BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
        BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
        BPF_EXIT_INSN(),
-       BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
+       BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
        BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
        BPF_MOV64_IMM(BPF_REG_2, 0),
        BPF_MOV64_IMM(BPF_REG_3, 0x100000),
diff --git a/tools/testing/selftests/bpf/verifier/wide_access.c b/tools/testing/selftests/bpf/verifier/wide_access.c
new file mode 100644 (file)
index 0000000..ccade93
--- /dev/null
@@ -0,0 +1,73 @@
+#define BPF_SOCK_ADDR_STORE(field, off, res, err) \
+{ \
+       "wide store to bpf_sock_addr." #field "[" #off "]", \
+       .insns = { \
+       BPF_MOV64_IMM(BPF_REG_0, 1), \
+       BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, \
+                   offsetof(struct bpf_sock_addr, field[off])), \
+       BPF_EXIT_INSN(), \
+       }, \
+       .result = res, \
+       .prog_type = BPF_PROG_TYPE_CGROUP_SOCK_ADDR, \
+       .expected_attach_type = BPF_CGROUP_UDP6_SENDMSG, \
+       .errstr = err, \
+}
+
+/* user_ip6[0] is u64 aligned */
+BPF_SOCK_ADDR_STORE(user_ip6, 0, ACCEPT,
+                   NULL),
+BPF_SOCK_ADDR_STORE(user_ip6, 1, REJECT,
+                   "invalid bpf_context access off=12 size=8"),
+BPF_SOCK_ADDR_STORE(user_ip6, 2, ACCEPT,
+                   NULL),
+BPF_SOCK_ADDR_STORE(user_ip6, 3, REJECT,
+                   "invalid bpf_context access off=20 size=8"),
+
+/* msg_src_ip6[0] is _not_ u64 aligned */
+BPF_SOCK_ADDR_STORE(msg_src_ip6, 0, REJECT,
+                   "invalid bpf_context access off=44 size=8"),
+BPF_SOCK_ADDR_STORE(msg_src_ip6, 1, ACCEPT,
+                   NULL),
+BPF_SOCK_ADDR_STORE(msg_src_ip6, 2, REJECT,
+                   "invalid bpf_context access off=52 size=8"),
+BPF_SOCK_ADDR_STORE(msg_src_ip6, 3, REJECT,
+                   "invalid bpf_context access off=56 size=8"),
+
+#undef BPF_SOCK_ADDR_STORE
+
+#define BPF_SOCK_ADDR_LOAD(field, off, res, err) \
+{ \
+       "wide load from bpf_sock_addr." #field "[" #off "]", \
+       .insns = { \
+       BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, \
+                   offsetof(struct bpf_sock_addr, field[off])), \
+       BPF_MOV64_IMM(BPF_REG_0, 1), \
+       BPF_EXIT_INSN(), \
+       }, \
+       .result = res, \
+       .prog_type = BPF_PROG_TYPE_CGROUP_SOCK_ADDR, \
+       .expected_attach_type = BPF_CGROUP_UDP6_SENDMSG, \
+       .errstr = err, \
+}
+
+/* user_ip6[0] is u64 aligned */
+BPF_SOCK_ADDR_LOAD(user_ip6, 0, ACCEPT,
+                  NULL),
+BPF_SOCK_ADDR_LOAD(user_ip6, 1, REJECT,
+                  "invalid bpf_context access off=12 size=8"),
+BPF_SOCK_ADDR_LOAD(user_ip6, 2, ACCEPT,
+                  NULL),
+BPF_SOCK_ADDR_LOAD(user_ip6, 3, REJECT,
+                  "invalid bpf_context access off=20 size=8"),
+
+/* msg_src_ip6[0] is _not_ u64 aligned */
+BPF_SOCK_ADDR_LOAD(msg_src_ip6, 0, REJECT,
+                  "invalid bpf_context access off=44 size=8"),
+BPF_SOCK_ADDR_LOAD(msg_src_ip6, 1, ACCEPT,
+                  NULL),
+BPF_SOCK_ADDR_LOAD(msg_src_ip6, 2, REJECT,
+                  "invalid bpf_context access off=52 size=8"),
+BPF_SOCK_ADDR_LOAD(msg_src_ip6, 3, REJECT,
+                  "invalid bpf_context access off=56 size=8"),
+
+#undef BPF_SOCK_ADDR_LOAD
diff --git a/tools/testing/selftests/bpf/verifier/wide_store.c b/tools/testing/selftests/bpf/verifier/wide_store.c
deleted file mode 100644 (file)
index 8fe9960..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-#define BPF_SOCK_ADDR(field, off, res, err) \
-{ \
-       "wide store to bpf_sock_addr." #field "[" #off "]", \
-       .insns = { \
-       BPF_MOV64_IMM(BPF_REG_0, 1), \
-       BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, \
-                   offsetof(struct bpf_sock_addr, field[off])), \
-       BPF_EXIT_INSN(), \
-       }, \
-       .result = res, \
-       .prog_type = BPF_PROG_TYPE_CGROUP_SOCK_ADDR, \
-       .expected_attach_type = BPF_CGROUP_UDP6_SENDMSG, \
-       .errstr = err, \
-}
-
-/* user_ip6[0] is u64 aligned */
-BPF_SOCK_ADDR(user_ip6, 0, ACCEPT,
-             NULL),
-BPF_SOCK_ADDR(user_ip6, 1, REJECT,
-             "invalid bpf_context access off=12 size=8"),
-BPF_SOCK_ADDR(user_ip6, 2, ACCEPT,
-             NULL),
-BPF_SOCK_ADDR(user_ip6, 3, REJECT,
-             "invalid bpf_context access off=20 size=8"),
-
-/* msg_src_ip6[0] is _not_ u64 aligned */
-BPF_SOCK_ADDR(msg_src_ip6, 0, REJECT,
-             "invalid bpf_context access off=44 size=8"),
-BPF_SOCK_ADDR(msg_src_ip6, 1, ACCEPT,
-             NULL),
-BPF_SOCK_ADDR(msg_src_ip6, 2, REJECT,
-             "invalid bpf_context access off=52 size=8"),
-BPF_SOCK_ADDR(msg_src_ip6, 3, REJECT,
-             "invalid bpf_context access off=56 size=8"),
-
-#undef BPF_SOCK_ADDR