1. 19 Dec, 2019 7 commits
    • Daniel Borkmann's avatar
      bpf: Fix record_func_key to perform backtracking on r3 · cc52d914
      Daniel Borkmann authored
      While testing Cilium with /unreleased/ Linus' tree under BPF-based NodePort
      implementation, I noticed a strange BPF SNAT engine behavior from time to
      time. In some cases it would do the correct SNAT/DNAT service translation,
      but at a random point in time it would just stop and perform an unexpected
      translation after SYN, SYN/ACK and stack would send a RST back. While initially
      assuming that there is some sort of a race condition in BPF code, adding
      trace_printk()s for debugging purposes at some point seemed to have resolved
      the issue auto-magically.
      
      Digging deeper on this Heisenbug and reducing the trace_printk() calls to
      an absolute minimum, it turns out that a single call would suffice to
      trigger / not trigger the seen RST issue, even though the logic of the
      program itself remains unchanged. Turns out the single call changed verifier
      pruning behavior to get everything to work. Reconstructing a minimal test
      case, the incorrect JIT dump looked as follows:
      
        # bpftool p d j i 11346
        0xffffffffc0cba96c:
        [...]
          21:   movzbq 0x30(%rdi),%rax
          26:   cmp    $0xd,%rax
          2a:   je     0x000000000000003a
          2c:   xor    %edx,%edx
          2e:   movabs $0xffff89cc74e85800,%rsi
          38:   jmp    0x0000000000000049
          3a:   mov    $0x2,%edx
          3f:   movabs $0xffff89cc74e85800,%rsi
          49:   mov    -0x224(%rbp),%eax
          4f:   cmp    $0x20,%eax
          52:   ja     0x0000000000000062
          54:   add    $0x1,%eax
          57:   mov    %eax,-0x224(%rbp)
          5d:   jmpq   0xffffffffffff6911
          62:   mov    $0x1,%eax
        [...]
      
      Hence, unexpectedly, JIT emitted a direct jump even though retpoline based
      one would have been needed since in line 2c and 3a we have different slot
      keys in BPF reg r3. Verifier log of the test case reveals what happened:
      
        0: (b7) r0 = 14
        1: (73) *(u8 *)(r1 +48) = r0
        2: (71) r0 = *(u8 *)(r1 +48)
        3: (15) if r0 == 0xd goto pc+4
         R0_w=inv(id=0,umax_value=255,var_off=(0x0; 0xff)) R1=ctx(id=0,off=0,imm=0) R10=fp0
        4: (b7) r3 = 0
        5: (18) r2 = 0xffff89cc74d54a00
        7: (05) goto pc+3
        11: (85) call bpf_tail_call#12
        12: (b7) r0 = 1
        13: (95) exit
        from 3 to 8: R0_w=inv13 R1=ctx(id=0,off=0,imm=0) R10=fp0
        8: (b7) r3 = 2
        9: (18) r2 = 0xffff89cc74d54a00
        11: safe
        processed 13 insns (limit 1000000) [...]
      
      Second branch is pruned by verifier since considered safe, but issue is that
      record_func_key() couldn't have seen the index in line 3a and therefore
      decided that emitting a direct jump at this location was okay.
      
      Fix this by reusing our backtracking logic for precise scalar verification
      in order to prevent pruning on the slot key. This means verifier will track
      content of r3 all the way backwards and only prune if both scalars were
      unknown in state equivalence check and therefore poisoned in the first place
      in record_func_key(). The range is [x,x] in record_func_key() case since
      the slot always would have to be constant immediate. Correct verification
      after fix:
      
        0: (b7) r0 = 14
        1: (73) *(u8 *)(r1 +48) = r0
        2: (71) r0 = *(u8 *)(r1 +48)
        3: (15) if r0 == 0xd goto pc+4
         R0_w=invP(id=0,umax_value=255,var_off=(0x0; 0xff)) R1=ctx(id=0,off=0,imm=0) R10=fp0
        4: (b7) r3 = 0
        5: (18) r2 = 0x0
        7: (05) goto pc+3
        11: (85) call bpf_tail_call#12
        12: (b7) r0 = 1
        13: (95) exit
        from 3 to 8: R0_w=invP13 R1=ctx(id=0,off=0,imm=0) R10=fp0
        8: (b7) r3 = 2
        9: (18) r2 = 0x0
        11: (85) call bpf_tail_call#12
        12: (b7) r0 = 1
        13: (95) exit
        processed 15 insns (limit 1000000) [...]
      
      And correct corresponding JIT dump:
      
        # bpftool p d j i 11
        0xffffffffc0dc34c4:
        [...]
          21:	  movzbq 0x30(%rdi),%rax
          26:	  cmp    $0xd,%rax
          2a:	  je     0x000000000000003a
          2c:	  xor    %edx,%edx
          2e:	  movabs $0xffff9928b4c02200,%rsi
          38:	  jmp    0x0000000000000049
          3a:	  mov    $0x2,%edx
          3f:	  movabs $0xffff9928b4c02200,%rsi
          49:	  cmp    $0x4,%rdx
          4d:	  jae    0x0000000000000093
          4f:	  and    $0x3,%edx
          52:	  mov    %edx,%edx
          54:	  cmp    %edx,0x24(%rsi)
          57:	  jbe    0x0000000000000093
          59:	  mov    -0x224(%rbp),%eax
          5f:	  cmp    $0x20,%eax
          62:	  ja     0x0000000000000093
          64:	  add    $0x1,%eax
          67:	  mov    %eax,-0x224(%rbp)
          6d:	  mov    0x110(%rsi,%rdx,8),%rax
          75:	  test   %rax,%rax
          78:	  je     0x0000000000000093
          7a:	  mov    0x30(%rax),%rax
          7e:	  add    $0x19,%rax
          82:   callq  0x000000000000008e
          87:   pause
          89:   lfence
          8c:   jmp    0x0000000000000087
          8e:   mov    %rax,(%rsp)
          92:   retq
          93:   mov    $0x1,%eax
        [...]
      
      Also explicitly adding explicit env->allow_ptr_leaks to fixup_bpf_calls() since
      backtracking is enabled under former (direct jumps as well, but use different
      test). In case of only tracking different map pointers as in c93552c4 ("bpf:
      properly enforce index mask to prevent out-of-bounds speculation"), pruning
      cannot make such short-cuts, neither if there are paths with scalar and non-scalar
      types as r3. mark_chain_precision() is only needed after we know that
      register_is_const(). If it was not the case, we already poison the key on first
      path and non-const key in later paths are not matching the scalar range in regsafe()
      either. Cilium NodePort testing passes fine as well now. Note, released kernels
      not affected.
      
      Fixes: d2e4c1e6 ("bpf: Constant map key tracking for prog array pokes")
      Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Link: https://lore.kernel.org/bpf/ac43ffdeb7386c5bd688761ed266f3722bb39823.1576789878.git.daniel@iogearbox.net
      cc52d914
    • Alexander Lobakin's avatar
      net, sysctl: Fix compiler warning when only cBPF is present · 1148f9ad
      Alexander Lobakin authored
      proc_dointvec_minmax_bpf_restricted() has been firstly introduced
      in commit 2e4a3098 ("bpf: restrict access to core bpf sysctls")
      under CONFIG_HAVE_EBPF_JIT. Then, this ifdef has been removed in
      ede95a63 ("bpf: add bpf_jit_limit knob to restrict unpriv
      allocations"), because a new sysctl, bpf_jit_limit, made use of it.
      Finally, this parameter has become long instead of integer with
      fdadd049 ("bpf: fix bpf_jit_limit knob for PAGE_SIZE >= 64K")
      and thus, a new proc_dolongvec_minmax_bpf_restricted() has been
      added.
      
      With this last change, we got back to that
      proc_dointvec_minmax_bpf_restricted() is used only under
      CONFIG_HAVE_EBPF_JIT, but the corresponding ifdef has not been
      brought back.
      
      So, in configurations like CONFIG_BPF_JIT=y && CONFIG_HAVE_EBPF_JIT=n
      since v4.20 we have:
      
        CC      net/core/sysctl_net_core.o
      net/core/sysctl_net_core.c:292:1: warning: ‘proc_dointvec_minmax_bpf_restricted’ defined but not used [-Wunused-function]
        292 | proc_dointvec_minmax_bpf_restricted(struct ctl_table *table, int write,
            | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      
      Suppress this by guarding it with CONFIG_HAVE_EBPF_JIT again.
      
      Fixes: fdadd049 ("bpf: fix bpf_jit_limit knob for PAGE_SIZE >= 64K")
      Signed-off-by: default avatarAlexander Lobakin <alobakin@dlink.ru>
      Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
      Link: https://lore.kernel.org/bpf/20191218091821.7080-1-alobakin@dlink.ru
      1148f9ad
    • Daniel Borkmann's avatar
      Merge branch 'bpf-fix-xsk-wakeup' · ca8d0fa7
      Daniel Borkmann authored
      Maxim Mikityanskiy says:
      
      ====================
      This series addresses the issue described in the commit message of the
      first patch: lack of synchronization between XSK wakeup and destroying
      the resources used by XSK wakeup. The idea is similar to napi_synchronize.
      The series contains fixes for the drivers that implement XSK.
      
      v2 incorporates changes suggested by Björn:
      
      1. Call synchronize_rcu in Intel drivers only if the XDP program is
         being unloaded.
      2. Don't forget rcu_read_lock when wakeup is called from xsk_poll.
      3. Use xs->zc as the condition to call ndo_xsk_wakeup.
      ====================
      Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
      ca8d0fa7
    • Maxim Mikityanskiy's avatar
      net/ixgbe: Fix concurrency issues between config flow and XSK · c0fdccfd
      Maxim Mikityanskiy authored
      Use synchronize_rcu to wait until the XSK wakeup function finishes
      before destroying the resources it uses:
      
      1. ixgbe_down already calls synchronize_rcu after setting __IXGBE_DOWN.
      
      2. After switching the XDP program, call synchronize_rcu to let
      ixgbe_xsk_wakeup exit before the XDP program is freed.
      
      3. Changing the number of channels brings the interface down.
      
      4. Disabling UMEM sets __IXGBE_TX_DISABLED before closing hardware
      resources and resetting xsk_umem. Check that bit in ixgbe_xsk_wakeup to
      avoid using the XDP ring when it's already destroyed. synchronize_rcu is
      called from ixgbe_txrx_ring_disable.
      Signed-off-by: default avatarMaxim Mikityanskiy <maximmi@mellanox.com>
      Signed-off-by: default avatarBjörn Töpel <bjorn.topel@intel.com>
      Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
      Link: https://lore.kernel.org/bpf/20191217162023.16011-5-maximmi@mellanox.com
      c0fdccfd
    • Maxim Mikityanskiy's avatar
      net/i40e: Fix concurrency issues between config flow and XSK · b3873a5b
      Maxim Mikityanskiy authored
      Use synchronize_rcu to wait until the XSK wakeup function finishes
      before destroying the resources it uses:
      
      1. i40e_down already calls synchronize_rcu. On i40e_down either
      __I40E_VSI_DOWN or __I40E_CONFIG_BUSY is set. Check the latter in
      i40e_xsk_wakeup (the former is already checked there).
      
      2. After switching the XDP program, call synchronize_rcu to let
      i40e_xsk_wakeup exit before the XDP program is freed.
      
      3. Changing the number of channels brings the interface down (see
      i40e_prep_for_reset and i40e_pf_quiesce_all_vsi).
      
      4. Disabling UMEM sets __I40E_CONFIG_BUSY, too.
      Signed-off-by: default avatarMaxim Mikityanskiy <maximmi@mellanox.com>
      Signed-off-by: default avatarBjörn Töpel <bjorn.topel@intel.com>
      Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
      Link: https://lore.kernel.org/bpf/20191217162023.16011-4-maximmi@mellanox.com
      b3873a5b
    • Maxim Mikityanskiy's avatar
      net/mlx5e: Fix concurrency issues between config flow and XSK · 9cf88808
      Maxim Mikityanskiy authored
      After disabling resources necessary for XSK (the XDP program, channels,
      XSK queues), use synchronize_rcu to wait until the XSK wakeup function
      finishes, before freeing the resources.
      
      Suspend XSK wakeups during switching channels. If the XDP program is
      being removed, synchronize_rcu before closing the old channels to allow
      XSK wakeup to complete.
      Signed-off-by: default avatarMaxim Mikityanskiy <maximmi@mellanox.com>
      Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
      Link: https://lore.kernel.org/bpf/20191217162023.16011-3-maximmi@mellanox.com
      9cf88808
    • Maxim Mikityanskiy's avatar
      xsk: Add rcu_read_lock around the XSK wakeup · 06870682
      Maxim Mikityanskiy authored
      The XSK wakeup callback in drivers makes some sanity checks before
      triggering NAPI. However, some configuration changes may occur during
      this function that affect the result of those checks. For example, the
      interface can go down, and all the resources will be destroyed after the
      checks in the wakeup function, but before it attempts to use these
      resources. Wrap this callback in rcu_read_lock to allow driver to
      synchronize_rcu before actually destroying the resources.
      
      xsk_wakeup is a new function that encapsulates calling ndo_xsk_wakeup
      wrapped into the RCU lock. After this commit, xsk_poll starts using
      xsk_wakeup and checks xs->zc instead of ndo_xsk_wakeup != NULL to decide
      ndo_xsk_wakeup should be called. It also fixes a bug introduced with the
      need_wakeup feature: a non-zero-copy socket may be used with a driver
      supporting zero-copy, and in this case ndo_xsk_wakeup should not be
      called, so the xs->zc check is the correct one.
      
      Fixes: 77cd0d7b ("xsk: add support for need_wakeup flag in AF_XDP rings")
      Signed-off-by: default avatarMaxim Mikityanskiy <maximmi@mellanox.com>
      Signed-off-by: default avatarBjörn Töpel <bjorn.topel@intel.com>
      Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
      Link: https://lore.kernel.org/bpf/20191217162023.16011-2-maximmi@mellanox.com
      06870682
  2. 17 Dec, 2019 1 commit
  3. 16 Dec, 2019 1 commit
  4. 13 Dec, 2019 1 commit
  5. 12 Dec, 2019 3 commits
  6. 11 Dec, 2019 22 commits
  7. 10 Dec, 2019 1 commit
  8. 09 Dec, 2019 4 commits
    • Davide Caratti's avatar
      tc-testing: unbreak full listing of tdc testcases · 991a3459
      Davide Caratti authored
      the following command currently fails:
      
       [root@fedora tc-testing]# ./tdc.py -l
       The following test case IDs are not unique:
       {'6f5e'}
       Please correct them before continuing.
      
      this happens because there are two tests having the same id:
      
       [root@fedora tc-testing]# grep -r 6f5e tc-tests/*
       tc-tests/actions/pedit.json:        "id": "6f5e",
       tc-tests/filters/basic.json:        "id": "6f5e",
      
      fix it replacing the latest duplicate id with a brand new one:
      
       [root@fedora tc-testing]# sed -i 's/6f5e//1' tc-tests/filters/basic.json
       [root@fedora tc-testing]# ./tdc.py -i
      
      Fixes: 4717b053 ("tc-testing: Introduced tdc tests for basic filter")
      Signed-off-by: default avatarDavide Caratti <dcaratti@redhat.com>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      991a3459
    • Chuhong Yuan's avatar
      fjes: fix missed check in fjes_acpi_add · a288f105
      Chuhong Yuan authored
      fjes_acpi_add() misses a check for platform_device_register_simple().
      Add a check to fix it.
      
      Fixes: 658d439b ("fjes: Introduce FUJITSU Extended Socket Network Device driver")
      Signed-off-by: default avatarChuhong Yuan <hslester96@gmail.com>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      a288f105
    • Mao Wenan's avatar
      af_packet: set defaule value for tmo · b43d1f9f
      Mao Wenan authored
      There is softlockup when using TPACKET_V3:
      ...
      NMI watchdog: BUG: soft lockup - CPU#2 stuck for 60010ms!
      (__irq_svc) from [<c0558a0c>] (_raw_spin_unlock_irqrestore+0x44/0x54)
      (_raw_spin_unlock_irqrestore) from [<c027b7e8>] (mod_timer+0x210/0x25c)
      (mod_timer) from [<c0549c30>]
      (prb_retire_rx_blk_timer_expired+0x68/0x11c)
      (prb_retire_rx_blk_timer_expired) from [<c027a7ac>]
      (call_timer_fn+0x90/0x17c)
      (call_timer_fn) from [<c027ab6c>] (run_timer_softirq+0x2d4/0x2fc)
      (run_timer_softirq) from [<c021eaf4>] (__do_softirq+0x218/0x318)
      (__do_softirq) from [<c021eea0>] (irq_exit+0x88/0xac)
      (irq_exit) from [<c0240130>] (msa_irq_exit+0x11c/0x1d4)
      (msa_irq_exit) from [<c0209cf0>] (handle_IPI+0x650/0x7f4)
      (handle_IPI) from [<c02015bc>] (gic_handle_irq+0x108/0x118)
      (gic_handle_irq) from [<c0558ee4>] (__irq_usr+0x44/0x5c)
      ...
      
      If __ethtool_get_link_ksettings() is failed in
      prb_calc_retire_blk_tmo(), msec and tmo will be zero, so tov_in_jiffies
      is zero and the timer expire for retire_blk_timer is turn to
      mod_timer(&pkc->retire_blk_timer, jiffies + 0),
      which will trigger cpu usage of softirq is 100%.
      
      Fixes: f6fb8f10 ("af-packet: TPACKET_V3 flexible buffer implementation.")
      Tested-by: default avatarXiao Jiangfeng <xiaojiangfeng@huawei.com>
      Signed-off-by: default avatarMao Wenan <maowenan@huawei.com>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      b43d1f9f
    • Grygorii Strashko's avatar
      net: ethernet: ti: davinci_cpdma: fix warning "device driver frees DMA memory with different size" · 8a2b2220
      Grygorii Strashko authored
      The TI CPSW(s) driver produces warning with DMA API debug options enabled:
      
      WARNING: CPU: 0 PID: 1033 at kernel/dma/debug.c:1025 check_unmap+0x4a8/0x968
      DMA-API: cpsw 48484000.ethernet: device driver frees DMA memory with different size
       [device address=0x00000000abc6aa02] [map size=64 bytes] [unmap size=42 bytes]
      CPU: 0 PID: 1033 Comm: ping Not tainted 5.3.0-dirty #41
      Hardware name: Generic DRA72X (Flattened Device Tree)
      [<c0112c60>] (unwind_backtrace) from [<c010d270>] (show_stack+0x10/0x14)
      [<c010d270>] (show_stack) from [<c09bc564>] (dump_stack+0xd8/0x110)
      [<c09bc564>] (dump_stack) from [<c013b93c>] (__warn+0xe0/0x10c)
      [<c013b93c>] (__warn) from [<c013b9ac>] (warn_slowpath_fmt+0x44/0x6c)
      [<c013b9ac>] (warn_slowpath_fmt) from [<c01e0368>] (check_unmap+0x4a8/0x968)
      [<c01e0368>] (check_unmap) from [<c01e08a8>] (debug_dma_unmap_page+0x80/0x90)
      [<c01e08a8>] (debug_dma_unmap_page) from [<c0752414>] (__cpdma_chan_free+0x114/0x16c)
      [<c0752414>] (__cpdma_chan_free) from [<c07525c4>] (__cpdma_chan_process+0x158/0x17c)
      [<c07525c4>] (__cpdma_chan_process) from [<c0753690>] (cpdma_chan_process+0x3c/0x5c)
      [<c0753690>] (cpdma_chan_process) from [<c0758660>] (cpsw_tx_mq_poll+0x48/0x94)
      [<c0758660>] (cpsw_tx_mq_poll) from [<c0803018>] (net_rx_action+0x108/0x4e4)
      [<c0803018>] (net_rx_action) from [<c010230c>] (__do_softirq+0xec/0x598)
      [<c010230c>] (__do_softirq) from [<c0143914>] (do_softirq.part.4+0x68/0x74)
      [<c0143914>] (do_softirq.part.4) from [<c0143a44>] (__local_bh_enable_ip+0x124/0x17c)
      [<c0143a44>] (__local_bh_enable_ip) from [<c0871590>] (ip_finish_output2+0x294/0xb7c)
      [<c0871590>] (ip_finish_output2) from [<c0875440>] (ip_output+0x210/0x364)
      [<c0875440>] (ip_output) from [<c0875e2c>] (ip_send_skb+0x1c/0xf8)
      [<c0875e2c>] (ip_send_skb) from [<c08a7fd4>] (raw_sendmsg+0x9a8/0xc74)
      [<c08a7fd4>] (raw_sendmsg) from [<c07d6b90>] (sock_sendmsg+0x14/0x24)
      [<c07d6b90>] (sock_sendmsg) from [<c07d8260>] (__sys_sendto+0xbc/0x100)
      [<c07d8260>] (__sys_sendto) from [<c01011ac>] (__sys_trace_return+0x0/0x14)
      Exception stack(0xea9a7fa8 to 0xea9a7ff0)
      ...
      
      The reason is that cpdma_chan_submit_si() now stores original buffer length
      (sw_len) in CPDMA descriptor instead of adjusted buffer length (hw_len)
      used to map the buffer.
      
      Hence, fix an issue by passing correct buffer length in CPDMA descriptor.
      
      Cc: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>
      Fixes: 6670acac ("net: ethernet: ti: davinci_cpdma: add dma mapped submit")
      Signed-off-by: default avatarGrygorii Strashko <grygorii.strashko@ti.com>
      Reviewed-by: default avatarIvan Khoronzhuk <ivan.khoronzhuk@linaro.org>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      8a2b2220