Commit 7671b026 authored by Jakub Kicinski's avatar Jakub Kicinski

Merge https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf

Daniel Borkmann says:

====================
pull-request: bpf 2021-10-07

We've added 7 non-merge commits during the last 8 day(s) which contain
a total of 8 files changed, 38 insertions(+), 21 deletions(-).

The main changes are:

1) Fix ARM BPF JIT to preserve caller-saved regs for DIV/MOD JIT-internal
   helper call, from Johan Almbladh.

2) Fix integer overflow in BPF stack map element size calculation when
   used with preallocation, from Tatsuhiko Yasumatsu.

3) Fix an AF_UNIX regression due to added BPF sockmap support related
   to shutdown handling, from Jiang Wang.

4) Fix a segfault in libbpf when generating light skeletons from objects
   without BTF, from Kumar Kartikeya Dwivedi.

5) Fix a libbpf memory leak in strset to free the actual struct strset
   itself, from Andrii Nakryiko.

6) Dual-license bpf_insn.h similarly as we did for libbpf and bpftool,
   with ACKs from all contributors, from Luca Boccassi.
====================

Link: https://lore.kernel.org/r/20211007135010.21143-1-daniel@iogearbox.netSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 578f3932 d0c6416b
...@@ -36,6 +36,10 @@ ...@@ -36,6 +36,10 @@
* +-----+ * +-----+
* |RSVD | JIT scratchpad * |RSVD | JIT scratchpad
* current ARM_SP => +-----+ <= (BPF_FP - STACK_SIZE + SCRATCH_SIZE) * current ARM_SP => +-----+ <= (BPF_FP - STACK_SIZE + SCRATCH_SIZE)
* | ... | caller-saved registers
* +-----+
* | ... | arguments passed on stack
* ARM_SP during call => +-----|
* | | * | |
* | ... | Function call stack * | ... | Function call stack
* | | * | |
...@@ -63,6 +67,12 @@ ...@@ -63,6 +67,12 @@
* *
* When popping registers off the stack at the end of a BPF function, we * When popping registers off the stack at the end of a BPF function, we
* reference them via the current ARM_FP register. * reference them via the current ARM_FP register.
*
* Some eBPF operations are implemented via a call to a helper function.
* Such calls are "invisible" in the eBPF code, so it is up to the calling
* program to preserve any caller-saved ARM registers during the call. The
* JIT emits code to push and pop those registers onto the stack, immediately
* above the callee stack frame.
*/ */
#define CALLEE_MASK (1 << ARM_R4 | 1 << ARM_R5 | 1 << ARM_R6 | \ #define CALLEE_MASK (1 << ARM_R4 | 1 << ARM_R5 | 1 << ARM_R6 | \
1 << ARM_R7 | 1 << ARM_R8 | 1 << ARM_R9 | \ 1 << ARM_R7 | 1 << ARM_R8 | 1 << ARM_R9 | \
...@@ -70,6 +80,8 @@ ...@@ -70,6 +80,8 @@
#define CALLEE_PUSH_MASK (CALLEE_MASK | 1 << ARM_LR) #define CALLEE_PUSH_MASK (CALLEE_MASK | 1 << ARM_LR)
#define CALLEE_POP_MASK (CALLEE_MASK | 1 << ARM_PC) #define CALLEE_POP_MASK (CALLEE_MASK | 1 << ARM_PC)
#define CALLER_MASK (1 << ARM_R0 | 1 << ARM_R1 | 1 << ARM_R2 | 1 << ARM_R3)
enum { enum {
/* Stack layout - these are offsets from (top of stack - 4) */ /* Stack layout - these are offsets from (top of stack - 4) */
BPF_R2_HI, BPF_R2_HI,
...@@ -464,6 +476,7 @@ static inline int epilogue_offset(const struct jit_ctx *ctx) ...@@ -464,6 +476,7 @@ static inline int epilogue_offset(const struct jit_ctx *ctx)
static inline void emit_udivmod(u8 rd, u8 rm, u8 rn, struct jit_ctx *ctx, u8 op) static inline void emit_udivmod(u8 rd, u8 rm, u8 rn, struct jit_ctx *ctx, u8 op)
{ {
const int exclude_mask = BIT(ARM_R0) | BIT(ARM_R1);
const s8 *tmp = bpf2a32[TMP_REG_1]; const s8 *tmp = bpf2a32[TMP_REG_1];
#if __LINUX_ARM_ARCH__ == 7 #if __LINUX_ARM_ARCH__ == 7
...@@ -495,11 +508,17 @@ static inline void emit_udivmod(u8 rd, u8 rm, u8 rn, struct jit_ctx *ctx, u8 op) ...@@ -495,11 +508,17 @@ static inline void emit_udivmod(u8 rd, u8 rm, u8 rn, struct jit_ctx *ctx, u8 op)
emit(ARM_MOV_R(ARM_R0, rm), ctx); emit(ARM_MOV_R(ARM_R0, rm), ctx);
} }
/* Push caller-saved registers on stack */
emit(ARM_PUSH(CALLER_MASK & ~exclude_mask), ctx);
/* Call appropriate function */ /* Call appropriate function */
emit_mov_i(ARM_IP, op == BPF_DIV ? emit_mov_i(ARM_IP, op == BPF_DIV ?
(u32)jit_udiv32 : (u32)jit_mod32, ctx); (u32)jit_udiv32 : (u32)jit_mod32, ctx);
emit_blx_r(ARM_IP, ctx); emit_blx_r(ARM_IP, ctx);
/* Restore caller-saved registers from stack */
emit(ARM_POP(CALLER_MASK & ~exclude_mask), ctx);
/* Save return value */ /* Save return value */
if (rd != ARM_R0) if (rd != ARM_R0)
emit(ARM_MOV_R(rd, ARM_R0), ctx); emit(ARM_MOV_R(rd, ARM_R0), ctx);
......
...@@ -63,7 +63,8 @@ static inline int stack_map_data_size(struct bpf_map *map) ...@@ -63,7 +63,8 @@ static inline int stack_map_data_size(struct bpf_map *map)
static int prealloc_elems_and_freelist(struct bpf_stack_map *smap) static int prealloc_elems_and_freelist(struct bpf_stack_map *smap)
{ {
u32 elem_size = sizeof(struct stack_map_bucket) + smap->map.value_size; u64 elem_size = sizeof(struct stack_map_bucket) +
(u64)smap->map.value_size;
int err; int err;
smap->elems = bpf_map_area_alloc(elem_size * smap->map.max_entries, smap->elems = bpf_map_area_alloc(elem_size * smap->map.max_entries,
......
...@@ -2882,6 +2882,9 @@ static int unix_shutdown(struct socket *sock, int mode) ...@@ -2882,6 +2882,9 @@ static int unix_shutdown(struct socket *sock, int mode)
unix_state_lock(sk); unix_state_lock(sk);
sk->sk_shutdown |= mode; sk->sk_shutdown |= mode;
if ((sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) &&
mode == SHUTDOWN_MASK)
sk->sk_state = TCP_CLOSE;
other = unix_peer(sk); other = unix_peer(sk);
if (other) if (other)
sock_hold(other); sock_hold(other);
...@@ -2904,13 +2907,11 @@ static int unix_shutdown(struct socket *sock, int mode) ...@@ -2904,13 +2907,11 @@ static int unix_shutdown(struct socket *sock, int mode)
other->sk_shutdown |= peer_mode; other->sk_shutdown |= peer_mode;
unix_state_unlock(other); unix_state_unlock(other);
other->sk_state_change(other); other->sk_state_change(other);
if (peer_mode == SHUTDOWN_MASK) { if (peer_mode == SHUTDOWN_MASK)
sk_wake_async(other, SOCK_WAKE_WAITD, POLL_HUP); sk_wake_async(other, SOCK_WAKE_WAITD, POLL_HUP);
other->sk_state = TCP_CLOSE; else if (peer_mode & RCV_SHUTDOWN)
} else if (peer_mode & RCV_SHUTDOWN) {
sk_wake_async(other, SOCK_WAKE_WAITD, POLL_IN); sk_wake_async(other, SOCK_WAKE_WAITD, POLL_IN);
} }
}
if (other) if (other)
sock_put(other); sock_put(other);
......
...@@ -322,17 +322,11 @@ $(obj)/hbm_edt_kern.o: $(src)/hbm.h $(src)/hbm_kern.h ...@@ -322,17 +322,11 @@ $(obj)/hbm_edt_kern.o: $(src)/hbm.h $(src)/hbm_kern.h
-include $(BPF_SAMPLES_PATH)/Makefile.target -include $(BPF_SAMPLES_PATH)/Makefile.target
VMLINUX_BTF_PATHS ?= $(if $(O),$(O)/vmlinux) \ VMLINUX_BTF_PATHS ?= $(abspath $(if $(O),$(O)/vmlinux)) \
$(if $(KBUILD_OUTPUT),$(KBUILD_OUTPUT)/vmlinux) \ $(abspath $(if $(KBUILD_OUTPUT),$(KBUILD_OUTPUT)/vmlinux)) \
../../../../vmlinux \ $(abspath ./vmlinux)
/sys/kernel/btf/vmlinux \
/boot/vmlinux-$(shell uname -r)
VMLINUX_BTF ?= $(abspath $(firstword $(wildcard $(VMLINUX_BTF_PATHS)))) VMLINUX_BTF ?= $(abspath $(firstword $(wildcard $(VMLINUX_BTF_PATHS))))
ifeq ($(VMLINUX_BTF),)
$(error Cannot find a vmlinux for VMLINUX_BTF at any of "$(VMLINUX_BTF_PATHS)")
endif
$(obj)/vmlinux.h: $(VMLINUX_BTF) $(BPFTOOL) $(obj)/vmlinux.h: $(VMLINUX_BTF) $(BPFTOOL)
ifeq ($(VMLINUX_H),) ifeq ($(VMLINUX_H),)
$(Q)$(BPFTOOL) btf dump file $(VMLINUX_BTF) format c > $@ $(Q)$(BPFTOOL) btf dump file $(VMLINUX_BTF) format c > $@
...@@ -340,6 +334,11 @@ else ...@@ -340,6 +334,11 @@ else
$(Q)cp "$(VMLINUX_H)" $@ $(Q)cp "$(VMLINUX_H)" $@
endif endif
ifeq ($(VMLINUX_BTF),)
$(error Cannot find a vmlinux for VMLINUX_BTF at any of "$(VMLINUX_BTF_PATHS)",\
build the kernel or set VMLINUX_BTF variable)
endif
clean-files += vmlinux.h clean-files += vmlinux.h
# Get Clang's default includes on this system, as opposed to those seen by # Get Clang's default includes on this system, as opposed to those seen by
......
/* SPDX-License-Identifier: GPL-2.0 */ /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
/* eBPF instruction mini library */ /* eBPF instruction mini library */
#ifndef __BPF_INSN_H #ifndef __BPF_INSN_H
#define __BPF_INSN_H #define __BPF_INSN_H
......
...@@ -5,11 +5,6 @@ ...@@ -5,11 +5,6 @@
#include "xdp_sample.bpf.h" #include "xdp_sample.bpf.h"
#include "xdp_sample_shared.h" #include "xdp_sample_shared.h"
enum {
BPF_F_BROADCAST = (1ULL << 3),
BPF_F_EXCLUDE_INGRESS = (1ULL << 4),
};
struct { struct {
__uint(type, BPF_MAP_TYPE_DEVMAP_HASH); __uint(type, BPF_MAP_TYPE_DEVMAP_HASH);
__uint(key_size, sizeof(int)); __uint(key_size, sizeof(int));
......
...@@ -6894,6 +6894,7 @@ int bpf_object__load_xattr(struct bpf_object_load_attr *attr) ...@@ -6894,6 +6894,7 @@ int bpf_object__load_xattr(struct bpf_object_load_attr *attr)
if (obj->gen_loader) { if (obj->gen_loader) {
/* reset FDs */ /* reset FDs */
if (obj->btf)
btf__set_fd(obj->btf, -1); btf__set_fd(obj->btf, -1);
for (i = 0; i < obj->nr_maps; i++) for (i = 0; i < obj->nr_maps; i++)
obj->maps[i].fd = -1; obj->maps[i].fd = -1;
......
...@@ -88,6 +88,7 @@ void strset__free(struct strset *set) ...@@ -88,6 +88,7 @@ void strset__free(struct strset *set)
hashmap__free(set->strs_hash); hashmap__free(set->strs_hash);
free(set->strs_data); free(set->strs_data);
free(set);
} }
size_t strset__data_size(const struct strset *set) size_t strset__data_size(const struct strset *set)
......
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