Skip to content

Commit 25eb0ea

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf
Daniel Borkmann says: ==================== pull-request: bpf 2018-04-25 The following pull-request contains BPF updates for your *net* tree. The main changes are: 1) Fix to clear the percpu metadata_dst that could otherwise carry stale ip_tunnel_info, from William. 2) Fix that reduces the number of passes in x64 JIT with regards to dead code sanitation to avoid risk of prog rejection, from Gianluca. 3) Several fixes of sockmap programs, besides others, fixing a double page_put() in error path, missing refcount hold for pinned sockmap, adding required -target bpf for clang in sample Makefile, from John. 4) Fix to disable preemption in __BPF_PROG_RUN_ARRAY() paths, from Roman. 5) Fix tools/bpf/ Makefile with regards to a lex/yacc build error seen on older gcc-5, from John. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 91a8252 + 9c299a3 commit 25eb0ea

File tree

9 files changed

+82
-12
lines changed

9 files changed

+82
-12
lines changed

Documentation/bpf/bpf_devel_QA.txt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,14 @@ A: Although LLVM IR generation and optimization try to stay architecture
557557
pulls in some header files containing file scope host assembly codes.
558558
- You can add "-fno-jump-tables" to work around the switch table issue.
559559

560-
Otherwise, you can use bpf target.
560+
Otherwise, you can use bpf target. Additionally, you _must_ use bpf target
561+
when:
562+
563+
- Your program uses data structures with pointer or long / unsigned long
564+
types that interface with BPF helpers or context data structures. Access
565+
into these structures is verified by the BPF verifier and may result
566+
in verification failures if the native architecture is not aligned with
567+
the BPF architecture, e.g. 64-bit. An example of this is
568+
BPF_PROG_TYPE_SK_MSG require '-target bpf'
561569

562570
Happy BPF hacking!

arch/x86/net/bpf_jit_comp.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1027,7 +1027,17 @@ xadd: if (is_imm8(insn->off))
10271027
break;
10281028

10291029
case BPF_JMP | BPF_JA:
1030-
jmp_offset = addrs[i + insn->off] - addrs[i];
1030+
if (insn->off == -1)
1031+
/* -1 jmp instructions will always jump
1032+
* backwards two bytes. Explicitly handling
1033+
* this case avoids wasting too many passes
1034+
* when there are long sequences of replaced
1035+
* dead code.
1036+
*/
1037+
jmp_offset = -2;
1038+
else
1039+
jmp_offset = addrs[i + insn->off] - addrs[i];
1040+
10311041
if (!jmp_offset)
10321042
/* optimize out nop jumps */
10331043
break;

include/linux/bpf.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ struct bpf_map_ops {
3131
void (*map_release)(struct bpf_map *map, struct file *map_file);
3232
void (*map_free)(struct bpf_map *map);
3333
int (*map_get_next_key)(struct bpf_map *map, void *key, void *next_key);
34+
void (*map_release_uref)(struct bpf_map *map);
3435

3536
/* funcs callable from userspace and from eBPF programs */
3637
void *(*map_lookup_elem)(struct bpf_map *map, void *key);
@@ -351,6 +352,7 @@ int bpf_prog_array_copy(struct bpf_prog_array __rcu *old_array,
351352
struct bpf_prog **_prog, *__prog; \
352353
struct bpf_prog_array *_array; \
353354
u32 _ret = 1; \
355+
preempt_disable(); \
354356
rcu_read_lock(); \
355357
_array = rcu_dereference(array); \
356358
if (unlikely(check_non_null && !_array))\
@@ -362,6 +364,7 @@ int bpf_prog_array_copy(struct bpf_prog_array __rcu *old_array,
362364
} \
363365
_out: \
364366
rcu_read_unlock(); \
367+
preempt_enable_no_resched(); \
365368
_ret; \
366369
})
367370

@@ -434,7 +437,6 @@ int bpf_stackmap_copy(struct bpf_map *map, void *key, void *value);
434437
int bpf_fd_array_map_update_elem(struct bpf_map *map, struct file *map_file,
435438
void *key, void *value, u64 map_flags);
436439
int bpf_fd_array_map_lookup_elem(struct bpf_map *map, void *key, u32 *value);
437-
void bpf_fd_array_map_clear(struct bpf_map *map);
438440
int bpf_fd_htab_map_update_elem(struct bpf_map *map, struct file *map_file,
439441
void *key, void *value, u64 map_flags);
440442
int bpf_fd_htab_map_lookup_elem(struct bpf_map *map, void *key, u32 *value);

kernel/bpf/arraymap.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,7 @@ static u32 prog_fd_array_sys_lookup_elem(void *ptr)
476476
}
477477

478478
/* decrement refcnt of all bpf_progs that are stored in this map */
479-
void bpf_fd_array_map_clear(struct bpf_map *map)
479+
static void bpf_fd_array_map_clear(struct bpf_map *map)
480480
{
481481
struct bpf_array *array = container_of(map, struct bpf_array, map);
482482
int i;
@@ -495,6 +495,7 @@ const struct bpf_map_ops prog_array_map_ops = {
495495
.map_fd_get_ptr = prog_fd_array_get_ptr,
496496
.map_fd_put_ptr = prog_fd_array_put_ptr,
497497
.map_fd_sys_lookup_elem = prog_fd_array_sys_lookup_elem,
498+
.map_release_uref = bpf_fd_array_map_clear,
498499
};
499500

500501
static struct bpf_event_entry *bpf_event_entry_gen(struct file *perf_file,

kernel/bpf/sockmap.c

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#include <net/tcp.h>
4444
#include <linux/ptr_ring.h>
4545
#include <net/inet_common.h>
46+
#include <linux/sched/signal.h>
4647

4748
#define SOCK_CREATE_FLAG_MASK \
4849
(BPF_F_NUMA_NODE | BPF_F_RDONLY | BPF_F_WRONLY)
@@ -523,8 +524,6 @@ static int bpf_tcp_ingress(struct sock *sk, int apply_bytes,
523524
i = md->sg_start;
524525

525526
do {
526-
r->sg_data[i] = md->sg_data[i];
527-
528527
size = (apply && apply_bytes < md->sg_data[i].length) ?
529528
apply_bytes : md->sg_data[i].length;
530529

@@ -535,6 +534,7 @@ static int bpf_tcp_ingress(struct sock *sk, int apply_bytes,
535534
}
536535

537536
sk_mem_charge(sk, size);
537+
r->sg_data[i] = md->sg_data[i];
538538
r->sg_data[i].length = size;
539539
md->sg_data[i].length -= size;
540540
md->sg_data[i].offset += size;
@@ -732,6 +732,26 @@ static int bpf_exec_tx_verdict(struct smap_psock *psock,
732732
return err;
733733
}
734734

735+
static int bpf_wait_data(struct sock *sk,
736+
struct smap_psock *psk, int flags,
737+
long timeo, int *err)
738+
{
739+
int rc;
740+
741+
DEFINE_WAIT_FUNC(wait, woken_wake_function);
742+
743+
add_wait_queue(sk_sleep(sk), &wait);
744+
sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
745+
rc = sk_wait_event(sk, &timeo,
746+
!list_empty(&psk->ingress) ||
747+
!skb_queue_empty(&sk->sk_receive_queue),
748+
&wait);
749+
sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);
750+
remove_wait_queue(sk_sleep(sk), &wait);
751+
752+
return rc;
753+
}
754+
735755
static int bpf_tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
736756
int nonblock, int flags, int *addr_len)
737757
{
@@ -755,6 +775,7 @@ static int bpf_tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
755775
return tcp_recvmsg(sk, msg, len, nonblock, flags, addr_len);
756776

757777
lock_sock(sk);
778+
bytes_ready:
758779
while (copied != len) {
759780
struct scatterlist *sg;
760781
struct sk_msg_buff *md;
@@ -809,6 +830,28 @@ static int bpf_tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
809830
}
810831
}
811832

833+
if (!copied) {
834+
long timeo;
835+
int data;
836+
int err = 0;
837+
838+
timeo = sock_rcvtimeo(sk, nonblock);
839+
data = bpf_wait_data(sk, psock, flags, timeo, &err);
840+
841+
if (data) {
842+
if (!skb_queue_empty(&sk->sk_receive_queue)) {
843+
release_sock(sk);
844+
smap_release_sock(psock, sk);
845+
copied = tcp_recvmsg(sk, msg, len, nonblock, flags, addr_len);
846+
return copied;
847+
}
848+
goto bytes_ready;
849+
}
850+
851+
if (err)
852+
copied = err;
853+
}
854+
812855
release_sock(sk);
813856
smap_release_sock(psock, sk);
814857
return copied;
@@ -1831,7 +1874,7 @@ static int sock_map_update_elem(struct bpf_map *map,
18311874
return err;
18321875
}
18331876

1834-
static void sock_map_release(struct bpf_map *map, struct file *map_file)
1877+
static void sock_map_release(struct bpf_map *map)
18351878
{
18361879
struct bpf_stab *stab = container_of(map, struct bpf_stab, map);
18371880
struct bpf_prog *orig;
@@ -1855,7 +1898,7 @@ const struct bpf_map_ops sock_map_ops = {
18551898
.map_get_next_key = sock_map_get_next_key,
18561899
.map_update_elem = sock_map_update_elem,
18571900
.map_delete_elem = sock_map_delete_elem,
1858-
.map_release = sock_map_release,
1901+
.map_release_uref = sock_map_release,
18591902
};
18601903

18611904
BPF_CALL_4(bpf_sock_map_update, struct bpf_sock_ops_kern *, bpf_sock,

kernel/bpf/syscall.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -257,8 +257,8 @@ static void bpf_map_free_deferred(struct work_struct *work)
257257
static void bpf_map_put_uref(struct bpf_map *map)
258258
{
259259
if (atomic_dec_and_test(&map->usercnt)) {
260-
if (map->map_type == BPF_MAP_TYPE_PROG_ARRAY)
261-
bpf_fd_array_map_clear(map);
260+
if (map->ops->map_release_uref)
261+
map->ops->map_release_uref(map);
262262
}
263263
}
264264

net/core/filter.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3240,6 +3240,7 @@ BPF_CALL_4(bpf_skb_set_tunnel_key, struct sk_buff *, skb,
32403240
skb_dst_set(skb, (struct dst_entry *) md);
32413241

32423242
info = &md->u.tun_info;
3243+
memset(info, 0, sizeof(*info));
32433244
info->mode = IP_TUNNEL_INFO_TX;
32443245

32453246
info->key.tun_flags = TUNNEL_KEY | TUNNEL_CSUM | TUNNEL_NOCACHE;

samples/sockmap/Makefile

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,14 @@ $(src)/*.c: verify_target_bpf
6565
# asm/sysreg.h - inline assembly used by it is incompatible with llvm.
6666
# But, there is no easy way to fix it, so just exclude it since it is
6767
# useless for BPF samples.
68+
#
69+
# -target bpf option required with SK_MSG programs, this is to ensure
70+
# reading 'void *' data types for data and data_end are __u64 reads.
6871
$(obj)/%.o: $(src)/%.c
6972
$(CLANG) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) $(EXTRA_CFLAGS) -I$(obj) \
7073
-D__KERNEL__ -D__ASM_SYSREG_H -Wno-unused-value -Wno-pointer-sign \
7174
-Wno-compare-distinct-pointer-types \
7275
-Wno-gnu-variable-sized-type-not-at-end \
7376
-Wno-address-of-packed-member -Wno-tautological-compare \
74-
-Wno-unknown-warning-option \
75-
-O2 -emit-llvm -c $< -o -| $(LLC) -march=bpf -filetype=obj -o $@
77+
-Wno-unknown-warning-option -O2 -target bpf \
78+
-emit-llvm -c $< -o -| $(LLC) -march=bpf -filetype=obj -o $@

tools/bpf/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ $(OUTPUT)bpf_asm: $(OUTPUT)bpf_asm.o $(OUTPUT)bpf_exp.yacc.o $(OUTPUT)bpf_exp.le
7676
$(QUIET_LINK)$(CC) $(CFLAGS) -o $@ $^
7777

7878
$(OUTPUT)bpf_exp.lex.c: $(OUTPUT)bpf_exp.yacc.c
79+
$(OUTPUT)bpf_exp.yacc.o: $(OUTPUT)bpf_exp.yacc.c
80+
$(OUTPUT)bpf_exp.lex.o: $(OUTPUT)bpf_exp.lex.c
7981

8082
clean: bpftool_clean
8183
$(call QUIET_CLEAN, bpf-progs)

0 commit comments

Comments
 (0)