Skip to content

Commit 6e1077f

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf
Alexei Starovoitov says: ==================== pull-request: bpf 2019-02-16 The following pull-request contains BPF updates for your *net* tree. The main changes are: 1) fix lockdep false positive in bpf_get_stackid(), from Alexei. 2) several AF_XDP fixes, from Bjorn, Magnus, Davidlohr. 3) fix narrow load from struct bpf_sock, from Martin. 4) mips JIT fixes, from Paul. 5) gso handling fix in bpf helpers, from Willem. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 8681ef1 + 1910fae commit 6e1077f

File tree

7 files changed

+46
-30
lines changed

7 files changed

+46
-30
lines changed

arch/mips/net/ebpf_jit.c

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,6 @@ enum reg_val_type {
7979
REG_64BIT_32BIT,
8080
/* 32-bit compatible, need truncation for 64-bit ops. */
8181
REG_32BIT,
82-
/* 32-bit zero extended. */
83-
REG_32BIT_ZERO_EX,
8482
/* 32-bit no sign/zero extension needed. */
8583
REG_32BIT_POS
8684
};
@@ -343,12 +341,15 @@ static int build_int_epilogue(struct jit_ctx *ctx, int dest_reg)
343341
const struct bpf_prog *prog = ctx->skf;
344342
int stack_adjust = ctx->stack_size;
345343
int store_offset = stack_adjust - 8;
344+
enum reg_val_type td;
346345
int r0 = MIPS_R_V0;
347346

348-
if (dest_reg == MIPS_R_RA &&
349-
get_reg_val_type(ctx, prog->len, BPF_REG_0) == REG_32BIT_ZERO_EX)
347+
if (dest_reg == MIPS_R_RA) {
350348
/* Don't let zero extended value escape. */
351-
emit_instr(ctx, sll, r0, r0, 0);
349+
td = get_reg_val_type(ctx, prog->len, BPF_REG_0);
350+
if (td == REG_64BIT)
351+
emit_instr(ctx, sll, r0, r0, 0);
352+
}
352353

353354
if (ctx->flags & EBPF_SAVE_RA) {
354355
emit_instr(ctx, ld, MIPS_R_RA, store_offset, MIPS_R_SP);
@@ -692,7 +693,7 @@ static int build_one_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
692693
if (dst < 0)
693694
return dst;
694695
td = get_reg_val_type(ctx, this_idx, insn->dst_reg);
695-
if (td == REG_64BIT || td == REG_32BIT_ZERO_EX) {
696+
if (td == REG_64BIT) {
696697
/* sign extend */
697698
emit_instr(ctx, sll, dst, dst, 0);
698699
}
@@ -707,7 +708,7 @@ static int build_one_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
707708
if (dst < 0)
708709
return dst;
709710
td = get_reg_val_type(ctx, this_idx, insn->dst_reg);
710-
if (td == REG_64BIT || td == REG_32BIT_ZERO_EX) {
711+
if (td == REG_64BIT) {
711712
/* sign extend */
712713
emit_instr(ctx, sll, dst, dst, 0);
713714
}
@@ -721,7 +722,7 @@ static int build_one_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
721722
if (dst < 0)
722723
return dst;
723724
td = get_reg_val_type(ctx, this_idx, insn->dst_reg);
724-
if (td == REG_64BIT || td == REG_32BIT_ZERO_EX)
725+
if (td == REG_64BIT)
725726
/* sign extend */
726727
emit_instr(ctx, sll, dst, dst, 0);
727728
if (insn->imm == 1) {
@@ -860,13 +861,13 @@ static int build_one_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
860861
if (src < 0 || dst < 0)
861862
return -EINVAL;
862863
td = get_reg_val_type(ctx, this_idx, insn->dst_reg);
863-
if (td == REG_64BIT || td == REG_32BIT_ZERO_EX) {
864+
if (td == REG_64BIT) {
864865
/* sign extend */
865866
emit_instr(ctx, sll, dst, dst, 0);
866867
}
867868
did_move = false;
868869
ts = get_reg_val_type(ctx, this_idx, insn->src_reg);
869-
if (ts == REG_64BIT || ts == REG_32BIT_ZERO_EX) {
870+
if (ts == REG_64BIT) {
870871
int tmp_reg = MIPS_R_AT;
871872

872873
if (bpf_op == BPF_MOV) {
@@ -1254,8 +1255,7 @@ static int build_one_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
12541255
if (insn->imm == 64 && td == REG_32BIT)
12551256
emit_instr(ctx, dinsu, dst, MIPS_R_ZERO, 32, 32);
12561257

1257-
if (insn->imm != 64 &&
1258-
(td == REG_64BIT || td == REG_32BIT_ZERO_EX)) {
1258+
if (insn->imm != 64 && td == REG_64BIT) {
12591259
/* sign extend */
12601260
emit_instr(ctx, sll, dst, dst, 0);
12611261
}

include/linux/skbuff.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4212,6 +4212,12 @@ static inline bool skb_is_gso_sctp(const struct sk_buff *skb)
42124212
return skb_shinfo(skb)->gso_type & SKB_GSO_SCTP;
42134213
}
42144214

4215+
static inline bool skb_is_gso_tcp(const struct sk_buff *skb)
4216+
{
4217+
return skb_is_gso(skb) &&
4218+
skb_shinfo(skb)->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6);
4219+
}
4220+
42154221
static inline void skb_gso_reset(struct sk_buff *skb)
42164222
{
42174223
skb_shinfo(skb)->gso_size = 0;

kernel/bpf/stackmap.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ static void do_up_read(struct irq_work *entry)
4444
struct stack_map_irq_work *work;
4545

4646
work = container_of(entry, struct stack_map_irq_work, irq_work);
47-
up_read(work->sem);
47+
up_read_non_owner(work->sem);
4848
work->sem = NULL;
4949
}
5050

@@ -338,6 +338,12 @@ static void stack_map_get_build_id_offset(struct bpf_stack_build_id *id_offs,
338338
} else {
339339
work->sem = &current->mm->mmap_sem;
340340
irq_work_queue(&work->irq_work);
341+
/*
342+
* The irq_work will release the mmap_sem with
343+
* up_read_non_owner(). The rwsem_release() is called
344+
* here to release the lock from lockdep's perspective.
345+
*/
346+
rwsem_release(&current->mm->mmap_sem.dep_map, 1, _RET_IP_);
341347
}
342348
}
343349

kernel/bpf/verifier.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1617,12 +1617,13 @@ static int check_flow_keys_access(struct bpf_verifier_env *env, int off,
16171617
return 0;
16181618
}
16191619

1620-
static int check_sock_access(struct bpf_verifier_env *env, u32 regno, int off,
1621-
int size, enum bpf_access_type t)
1620+
static int check_sock_access(struct bpf_verifier_env *env, int insn_idx,
1621+
u32 regno, int off, int size,
1622+
enum bpf_access_type t)
16221623
{
16231624
struct bpf_reg_state *regs = cur_regs(env);
16241625
struct bpf_reg_state *reg = &regs[regno];
1625-
struct bpf_insn_access_aux info;
1626+
struct bpf_insn_access_aux info = {};
16261627

16271628
if (reg->smin_value < 0) {
16281629
verbose(env, "R%d min value is negative, either use unsigned index or do a if (index >=0) check.\n",
@@ -1636,6 +1637,8 @@ static int check_sock_access(struct bpf_verifier_env *env, u32 regno, int off,
16361637
return -EACCES;
16371638
}
16381639

1640+
env->insn_aux_data[insn_idx].ctx_field_size = info.ctx_field_size;
1641+
16391642
return 0;
16401643
}
16411644

@@ -2032,7 +2035,7 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn
20322035
verbose(env, "cannot write into socket\n");
20332036
return -EACCES;
20342037
}
2035-
err = check_sock_access(env, regno, off, size, t);
2038+
err = check_sock_access(env, insn_idx, regno, off, size, t);
20362039
if (!err && value_regno >= 0)
20372040
mark_reg_unknown(env, regs, value_regno);
20382041
} else {

net/core/filter.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2789,8 +2789,7 @@ static int bpf_skb_proto_4_to_6(struct sk_buff *skb)
27892789
u32 off = skb_mac_header_len(skb);
27902790
int ret;
27912791

2792-
/* SCTP uses GSO_BY_FRAGS, thus cannot adjust it. */
2793-
if (skb_is_gso(skb) && unlikely(skb_is_gso_sctp(skb)))
2792+
if (!skb_is_gso_tcp(skb))
27942793
return -ENOTSUPP;
27952794

27962795
ret = skb_cow(skb, len_diff);
@@ -2831,8 +2830,7 @@ static int bpf_skb_proto_6_to_4(struct sk_buff *skb)
28312830
u32 off = skb_mac_header_len(skb);
28322831
int ret;
28332832

2834-
/* SCTP uses GSO_BY_FRAGS, thus cannot adjust it. */
2835-
if (skb_is_gso(skb) && unlikely(skb_is_gso_sctp(skb)))
2833+
if (!skb_is_gso_tcp(skb))
28362834
return -ENOTSUPP;
28372835

28382836
ret = skb_unclone(skb, GFP_ATOMIC);
@@ -2957,8 +2955,7 @@ static int bpf_skb_net_grow(struct sk_buff *skb, u32 len_diff)
29572955
u32 off = skb_mac_header_len(skb) + bpf_skb_net_base_len(skb);
29582956
int ret;
29592957

2960-
/* SCTP uses GSO_BY_FRAGS, thus cannot adjust it. */
2961-
if (skb_is_gso(skb) && unlikely(skb_is_gso_sctp(skb)))
2958+
if (!skb_is_gso_tcp(skb))
29622959
return -ENOTSUPP;
29632960

29642961
ret = skb_cow(skb, len_diff);
@@ -2987,8 +2984,7 @@ static int bpf_skb_net_shrink(struct sk_buff *skb, u32 len_diff)
29872984
u32 off = skb_mac_header_len(skb) + bpf_skb_net_base_len(skb);
29882985
int ret;
29892986

2990-
/* SCTP uses GSO_BY_FRAGS, thus cannot adjust it. */
2991-
if (skb_is_gso(skb) && unlikely(skb_is_gso_sctp(skb)))
2987+
if (!skb_is_gso_tcp(skb))
29922988
return -ENOTSUPP;
29932989

29942990
ret = skb_unclone(skb, GFP_ATOMIC);

net/xdp/xdp_umem.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,10 @@ int xdp_umem_assign_dev(struct xdp_umem *umem, struct net_device *dev,
125125
return 0;
126126

127127
err_unreg_umem:
128-
xdp_clear_umem_at_qid(dev, queue_id);
129128
if (!force_zc)
130129
err = 0; /* fallback to copy mode */
130+
if (err)
131+
xdp_clear_umem_at_qid(dev, queue_id);
131132
out_rtnl_unlock:
132133
rtnl_unlock();
133134
return err;
@@ -259,10 +260,10 @@ static int xdp_umem_pin_pages(struct xdp_umem *umem)
259260
if (!umem->pgs)
260261
return -ENOMEM;
261262

262-
down_write(&current->mm->mmap_sem);
263-
npgs = get_user_pages(umem->address, umem->npgs,
264-
gup_flags, &umem->pgs[0], NULL);
265-
up_write(&current->mm->mmap_sem);
263+
down_read(&current->mm->mmap_sem);
264+
npgs = get_user_pages_longterm(umem->address, umem->npgs,
265+
gup_flags, &umem->pgs[0], NULL);
266+
up_read(&current->mm->mmap_sem);
266267

267268
if (npgs != umem->npgs) {
268269
if (npgs >= 0) {

net/xdp/xsk.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,8 @@ static int xsk_mmap(struct file *file, struct socket *sock,
669669
if (!umem)
670670
return -EINVAL;
671671

672+
/* Matches the smp_wmb() in XDP_UMEM_REG */
673+
smp_rmb();
672674
if (offset == XDP_UMEM_PGOFF_FILL_RING)
673675
q = READ_ONCE(umem->fq);
674676
else if (offset == XDP_UMEM_PGOFF_COMPLETION_RING)
@@ -678,6 +680,8 @@ static int xsk_mmap(struct file *file, struct socket *sock,
678680
if (!q)
679681
return -EINVAL;
680682

683+
/* Matches the smp_wmb() in xsk_init_queue */
684+
smp_rmb();
681685
qpg = virt_to_head_page(q->ring);
682686
if (size > (PAGE_SIZE << compound_order(qpg)))
683687
return -EINVAL;

0 commit comments

Comments
 (0)