1. 16 Sep, 2023 11 commits
    • Kumar Kartikeya Dwivedi's avatar
      bpf: Use bpf_is_subprog to check for subprogs · 9af27da6
      Kumar Kartikeya Dwivedi authored
      We would like to know whether a bpf_prog corresponds to the main prog or
      one of the subprogs. The current JIT implementations simply check this
      using the func_idx in bpf_prog->aux->func_idx. When the index is 0, it
      belongs to the main program, otherwise it corresponds to some
      subprogram.
      
      This will also be necessary to halt exception propagation while walking
      the stack when an exception is thrown, so we add a simple helper
      function to check this, named bpf_is_subprog, and convert existing JIT
      implementations to also make use of it.
      Signed-off-by: default avatarKumar Kartikeya Dwivedi <memxor@gmail.com>
      Link: https://lore.kernel.org/r/20230912233214.1518551-2-memxor@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      9af27da6
    • Alexei Starovoitov's avatar
      Merge branch 'arm32-bpf-add-support-for-cpuv4-insns' · c4ab64e6
      Alexei Starovoitov authored
      Puranjay Mohan says:
      
      ====================
      arm32, bpf: add support for cpuv4 insns
      
      Changes in V2 -> V3
      - Added comments at places where there could be confustion.
      - In the patch for DIV64, fix the if-else case that would never run.
      - In the same patch use a single instruction to POP caller saved regs.
      - Add a patch to change maintainership of ARM32 BPF JIT.
      
      Changes in V1 -> V2:
      - Fix coding style issues.
      - Don't use tmp variable for src in emit_ldsx_r() as it is redundant.
      - Optimize emit_ldsx_r() when offset can fit in immediate.
      
      Add the support for cpuv4 instructions for ARM32 BPF JIT. 64-bit division
      was not supported earlier so this series adds 64-bit DIV, SDIV, MOD, SMOD
      instructions as well.
      
      This series needs any one of the patches from [1] to disable zero-extension
      for BPF_MEMSX to support ldsx.
      
      The relevant selftests have passed expect ldsx_insn which needs fentry:
      
      Tested on BeagleBone Black (ARMv7-A):
      
      [root@alarm del]# echo 1 > /proc/sys/net/core/bpf_jit_enable
      [root@alarm del]# ./test_progs -a verifier_sdiv,verifier_movsx,verifier_ldsx,verifier_gotol,verifier_bswap
      #337/1   verifier_bswap/BSWAP, 16:OK
      #337/2   verifier_bswap/BSWAP, 16 @unpriv:OK
      #337/3   verifier_bswap/BSWAP, 32:OK
      #337/4   verifier_bswap/BSWAP, 32 @unpriv:OK
      #337/5   verifier_bswap/BSWAP, 64:OK
      #337/6   verifier_bswap/BSWAP, 64 @unpriv:OK
      #337     verifier_bswap:OK
      #351/1   verifier_gotol/gotol, small_imm:OK
      #351/2   verifier_gotol/gotol, small_imm @unpriv:OK
      #351     verifier_gotol:OK
      #359/1   verifier_ldsx/LDSX, S8:OK
      #359/2   verifier_ldsx/LDSX, S8 @unpriv:OK
      #359/3   verifier_ldsx/LDSX, S16:OK
      #359/4   verifier_ldsx/LDSX, S16 @unpriv:OK
      #359/5   verifier_ldsx/LDSX, S32:OK
      #359/6   verifier_ldsx/LDSX, S32 @unpriv:OK
      #359/7   verifier_ldsx/LDSX, S8 range checking, privileged:OK
      #359/8   verifier_ldsx/LDSX, S16 range checking:OK
      #359/9   verifier_ldsx/LDSX, S16 range checking @unpriv:OK
      #359/10  verifier_ldsx/LDSX, S32 range checking:OK
      #359/11  verifier_ldsx/LDSX, S32 range checking @unpriv:OK
      #359     verifier_ldsx:OK
      #370/1   verifier_movsx/MOV32SX, S8:OK
      #370/2   verifier_movsx/MOV32SX, S8 @unpriv:OK
      #370/3   verifier_movsx/MOV32SX, S16:OK
      #370/4   verifier_movsx/MOV32SX, S16 @unpriv:OK
      #370/5   verifier_movsx/MOV64SX, S8:OK
      #370/6   verifier_movsx/MOV64SX, S8 @unpriv:OK
      #370/7   verifier_movsx/MOV64SX, S16:OK
      #370/8   verifier_movsx/MOV64SX, S16 @unpriv:OK
      #370/9   verifier_movsx/MOV64SX, S32:OK
      #370/10  verifier_movsx/MOV64SX, S32 @unpriv:OK
      #370/11  verifier_movsx/MOV32SX, S8, range_check:OK
      #370/12  verifier_movsx/MOV32SX, S8, range_check @unpriv:OK
      #370/13  verifier_movsx/MOV32SX, S16, range_check:OK
      #370/14  verifier_movsx/MOV32SX, S16, range_check @unpriv:OK
      #370/15  verifier_movsx/MOV32SX, S16, range_check 2:OK
      #370/16  verifier_movsx/MOV32SX, S16, range_check 2 @unpriv:OK
      #370/17  verifier_movsx/MOV64SX, S8, range_check:OK
      #370/18  verifier_movsx/MOV64SX, S8, range_check @unpriv:OK
      #370/19  verifier_movsx/MOV64SX, S16, range_check:OK
      #370/20  verifier_movsx/MOV64SX, S16, range_check @unpriv:OK
      #370/21  verifier_movsx/MOV64SX, S32, range_check:OK
      #370/22  verifier_movsx/MOV64SX, S32, range_check @unpriv:OK
      #370/23  verifier_movsx/MOV64SX, S16, R10 Sign Extension:OK
      #370/24  verifier_movsx/MOV64SX, S16, R10 Sign Extension @unpriv:OK
      #370     verifier_movsx:OK
      #382/1   verifier_sdiv/SDIV32, non-zero imm divisor, check 1:OK
      #382/2   verifier_sdiv/SDIV32, non-zero imm divisor, check 1 @unpriv:OK
      #382/3   verifier_sdiv/SDIV32, non-zero imm divisor, check 2:OK
      #382/4   verifier_sdiv/SDIV32, non-zero imm divisor, check 2 @unpriv:OK
      #382/5   verifier_sdiv/SDIV32, non-zero imm divisor, check 3:OK
      #382/6   verifier_sdiv/SDIV32, non-zero imm divisor, check 3 @unpriv:OK
      #382/7   verifier_sdiv/SDIV32, non-zero imm divisor, check 4:OK
      #382/8   verifier_sdiv/SDIV32, non-zero imm divisor, check 4 @unpriv:OK
      #382/9   verifier_sdiv/SDIV32, non-zero imm divisor, check 5:OK
      #382/10  verifier_sdiv/SDIV32, non-zero imm divisor, check 5 @unpriv:OK
      #382/11  verifier_sdiv/SDIV32, non-zero imm divisor, check 6:OK
      #382/12  verifier_sdiv/SDIV32, non-zero imm divisor, check 6 @unpriv:OK
      #382/13  verifier_sdiv/SDIV32, non-zero imm divisor, check 7:OK
      #382/14  verifier_sdiv/SDIV32, non-zero imm divisor, check 7 @unpriv:OK
      #382/15  verifier_sdiv/SDIV32, non-zero imm divisor, check 8:OK
      #382/16  verifier_sdiv/SDIV32, non-zero imm divisor, check 8 @unpriv:OK
      #382/17  verifier_sdiv/SDIV32, non-zero reg divisor, check 1:OK
      #382/18  verifier_sdiv/SDIV32, non-zero reg divisor, check 1 @unpriv:OK
      #382/19  verifier_sdiv/SDIV32, non-zero reg divisor, check 2:OK
      #382/20  verifier_sdiv/SDIV32, non-zero reg divisor, check 2 @unpriv:OK
      #382/21  verifier_sdiv/SDIV32, non-zero reg divisor, check 3:OK
      #382/22  verifier_sdiv/SDIV32, non-zero reg divisor, check 3 @unpriv:OK
      #382/23  verifier_sdiv/SDIV32, non-zero reg divisor, check 4:OK
      #382/24  verifier_sdiv/SDIV32, non-zero reg divisor, check 4 @unpriv:OK
      #382/25  verifier_sdiv/SDIV32, non-zero reg divisor, check 5:OK
      #382/26  verifier_sdiv/SDIV32, non-zero reg divisor, check 5 @unpriv:OK
      #382/27  verifier_sdiv/SDIV32, non-zero reg divisor, check 6:OK
      #382/28  verifier_sdiv/SDIV32, non-zero reg divisor, check 6 @unpriv:OK
      #382/29  verifier_sdiv/SDIV32, non-zero reg divisor, check 7:OK
      #382/30  verifier_sdiv/SDIV32, non-zero reg divisor, check 7 @unpriv:OK
      #382/31  verifier_sdiv/SDIV32, non-zero reg divisor, check 8:OK
      #382/32  verifier_sdiv/SDIV32, non-zero reg divisor, check 8 @unpriv:OK
      #382/33  verifier_sdiv/SDIV64, non-zero imm divisor, check 1:OK
      #382/34  verifier_sdiv/SDIV64, non-zero imm divisor, check 1 @unpriv:OK
      #382/35  verifier_sdiv/SDIV64, non-zero imm divisor, check 2:OK
      #382/36  verifier_sdiv/SDIV64, non-zero imm divisor, check 2 @unpriv:OK
      #382/37  verifier_sdiv/SDIV64, non-zero imm divisor, check 3:OK
      #382/38  verifier_sdiv/SDIV64, non-zero imm divisor, check 3 @unpriv:OK
      #382/39  verifier_sdiv/SDIV64, non-zero imm divisor, check 4:OK
      #382/40  verifier_sdiv/SDIV64, non-zero imm divisor, check 4 @unpriv:OK
      #382/41  verifier_sdiv/SDIV64, non-zero imm divisor, check 5:OK
      #382/42  verifier_sdiv/SDIV64, non-zero imm divisor, check 5 @unpriv:OK
      #382/43  verifier_sdiv/SDIV64, non-zero imm divisor, check 6:OK
      #382/44  verifier_sdiv/SDIV64, non-zero imm divisor, check 6 @unpriv:OK
      #382/45  verifier_sdiv/SDIV64, non-zero reg divisor, check 1:OK
      #382/46  verifier_sdiv/SDIV64, non-zero reg divisor, check 1 @unpriv:OK
      #382/47  verifier_sdiv/SDIV64, non-zero reg divisor, check 2:OK
      #382/48  verifier_sdiv/SDIV64, non-zero reg divisor, check 2 @unpriv:OK
      #382/49  verifier_sdiv/SDIV64, non-zero reg divisor, check 3:OK
      #382/50  verifier_sdiv/SDIV64, non-zero reg divisor, check 3 @unpriv:OK
      #382/51  verifier_sdiv/SDIV64, non-zero reg divisor, check 4:OK
      #382/52  verifier_sdiv/SDIV64, non-zero reg divisor, check 4 @unpriv:OK
      #382/53  verifier_sdiv/SDIV64, non-zero reg divisor, check 5:OK
      #382/54  verifier_sdiv/SDIV64, non-zero reg divisor, check 5 @unpriv:OK
      #382/55  verifier_sdiv/SDIV64, non-zero reg divisor, check 6:OK
      #382/56  verifier_sdiv/SDIV64, non-zero reg divisor, check 6 @unpriv:OK
      #382/57  verifier_sdiv/SMOD32, non-zero imm divisor, check 1:OK
      #382/58  verifier_sdiv/SMOD32, non-zero imm divisor, check 1 @unpriv:OK
      #382/59  verifier_sdiv/SMOD32, non-zero imm divisor, check 2:OK
      #382/60  verifier_sdiv/SMOD32, non-zero imm divisor, check 2 @unpriv:OK
      #382/61  verifier_sdiv/SMOD32, non-zero imm divisor, check 3:OK
      #382/62  verifier_sdiv/SMOD32, non-zero imm divisor, check 3 @unpriv:OK
      #382/63  verifier_sdiv/SMOD32, non-zero imm divisor, check 4:OK
      #382/64  verifier_sdiv/SMOD32, non-zero imm divisor, check 4 @unpriv:OK
      #382/65  verifier_sdiv/SMOD32, non-zero imm divisor, check 5:OK
      #382/66  verifier_sdiv/SMOD32, non-zero imm divisor, check 5 @unpriv:OK
      #382/67  verifier_sdiv/SMOD32, non-zero imm divisor, check 6:OK
      #382/68  verifier_sdiv/SMOD32, non-zero imm divisor, check 6 @unpriv:OK
      #382/69  verifier_sdiv/SMOD32, non-zero reg divisor, check 1:OK
      #382/70  verifier_sdiv/SMOD32, non-zero reg divisor, check 1 @unpriv:OK
      #382/71  verifier_sdiv/SMOD32, non-zero reg divisor, check 2:OK
      #382/72  verifier_sdiv/SMOD32, non-zero reg divisor, check 2 @unpriv:OK
      #382/73  verifier_sdiv/SMOD32, non-zero reg divisor, check 3:OK
      #382/74  verifier_sdiv/SMOD32, non-zero reg divisor, check 3 @unpriv:OK
      #382/75  verifier_sdiv/SMOD32, non-zero reg divisor, check 4:OK
      #382/76  verifier_sdiv/SMOD32, non-zero reg divisor, check 4 @unpriv:OK
      #382/77  verifier_sdiv/SMOD32, non-zero reg divisor, check 5:OK
      #382/78  verifier_sdiv/SMOD32, non-zero reg divisor, check 5 @unpriv:OK
      #382/79  verifier_sdiv/SMOD32, non-zero reg divisor, check 6:OK
      #382/80  verifier_sdiv/SMOD32, non-zero reg divisor, check 6 @unpriv:OK
      #382/81  verifier_sdiv/SMOD64, non-zero imm divisor, check 1:OK
      #382/82  verifier_sdiv/SMOD64, non-zero imm divisor, check 1 @unpriv:OK
      #382/83  verifier_sdiv/SMOD64, non-zero imm divisor, check 2:OK
      #382/84  verifier_sdiv/SMOD64, non-zero imm divisor, check 2 @unpriv:OK
      #382/85  verifier_sdiv/SMOD64, non-zero imm divisor, check 3:OK
      #382/86  verifier_sdiv/SMOD64, non-zero imm divisor, check 3 @unpriv:OK
      #382/87  verifier_sdiv/SMOD64, non-zero imm divisor, check 4:OK
      #382/88  verifier_sdiv/SMOD64, non-zero imm divisor, check 4 @unpriv:OK
      #382/89  verifier_sdiv/SMOD64, non-zero imm divisor, check 5:OK
      #382/90  verifier_sdiv/SMOD64, non-zero imm divisor, check 5 @unpriv:OK
      #382/91  verifier_sdiv/SMOD64, non-zero imm divisor, check 6:OK
      #382/92  verifier_sdiv/SMOD64, non-zero imm divisor, check 6 @unpriv:OK
      #382/93  verifier_sdiv/SMOD64, non-zero imm divisor, check 7:OK
      #382/94  verifier_sdiv/SMOD64, non-zero imm divisor, check 7 @unpriv:OK
      #382/95  verifier_sdiv/SMOD64, non-zero imm divisor, check 8:OK
      #382/96  verifier_sdiv/SMOD64, non-zero imm divisor, check 8 @unpriv:OK
      #382/97  verifier_sdiv/SMOD64, non-zero reg divisor, check 1:OK
      #382/98  verifier_sdiv/SMOD64, non-zero reg divisor, check 1 @unpriv:OK
      #382/99  verifier_sdiv/SMOD64, non-zero reg divisor, check 2:OK
      #382/100 verifier_sdiv/SMOD64, non-zero reg divisor, check 2 @unpriv:OK
      #382/101 verifier_sdiv/SMOD64, non-zero reg divisor, check 3:OK
      #382/102 verifier_sdiv/SMOD64, non-zero reg divisor, check 3 @unpriv:OK
      #382/103 verifier_sdiv/SMOD64, non-zero reg divisor, check 4:OK
      #382/104 verifier_sdiv/SMOD64, non-zero reg divisor, check 4 @unpriv:OK
      #382/105 verifier_sdiv/SMOD64, non-zero reg divisor, check 5:OK
      #382/106 verifier_sdiv/SMOD64, non-zero reg divisor, check 5 @unpriv:OK
      #382/107 verifier_sdiv/SMOD64, non-zero reg divisor, check 6:OK
      #382/108 verifier_sdiv/SMOD64, non-zero reg divisor, check 6 @unpriv:OK
      #382/109 verifier_sdiv/SMOD64, non-zero reg divisor, check 7:OK
      #382/110 verifier_sdiv/SMOD64, non-zero reg divisor, check 7 @unpriv:OK
      #382/111 verifier_sdiv/SMOD64, non-zero reg divisor, check 8:OK
      #382/112 verifier_sdiv/SMOD64, non-zero reg divisor, check 8 @unpriv:OK
      #382/113 verifier_sdiv/SDIV32, zero divisor:OK
      #382/114 verifier_sdiv/SDIV32, zero divisor @unpriv:OK
      #382/115 verifier_sdiv/SDIV64, zero divisor:OK
      #382/116 verifier_sdiv/SDIV64, zero divisor @unpriv:OK
      #382/117 verifier_sdiv/SMOD32, zero divisor:OK
      #382/118 verifier_sdiv/SMOD32, zero divisor @unpriv:OK
      #382/119 verifier_sdiv/SMOD64, zero divisor:OK
      #382/120 verifier_sdiv/SMOD64, zero divisor @unpriv:OK
      #382     verifier_sdiv:OK
      Summary: 5/163 PASSED, 0 SKIPPED, 0 FAILED
      
      As the selftests don't compile for 32-bit architectures without
      modifications due to long being 32-bit,
      I have added new tests to lib/test_bpf.c for cpuv4 insns, all are passing:
      
      test_bpf: Summary: 1052 PASSED, 0 FAILED, [891/1040 JIT'ed]
      test_bpf: test_tail_calls: Summary: 10 PASSED, 0 FAILED, [10/10 JIT'ed]
      test_bpf: test_skb_segment: Summary: 2 PASSED, 0 FAILED
      
      [1] https://lore.kernel.org/all/mb61p5y4u3ptd.fsf@amazon.com/
      ====================
      
      Link: https://lore.kernel.org/r/20230907230550.1417590-1-puranjay12@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      c4ab64e6
    • Puranjay Mohan's avatar
      MAINTAINERS: Add myself for ARM32 BPF JIT maintainer. · 9b31b4f1
      Puranjay Mohan authored
      As Shubham has been inactive since 2017, Add myself for ARM32 BPF JIT.
      Signed-off-by: default avatarPuranjay Mohan <puranjay12@gmail.com>
      Link: https://lore.kernel.org/r/20230907230550.1417590-10-puranjay12@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      9b31b4f1
    • Puranjay Mohan's avatar
      bpf/tests: add tests for cpuv4 instructions · daabb2b0
      Puranjay Mohan authored
      The BPF JITs now support cpuv4 instructions. Add tests for these new
      instructions to the test suite:
      
      1. Sign extended Load
      2. Sign extended Mov
      3. Unconditional byte swap
      4. Unconditional jump with 32-bit offset
      5. Signed division and modulo
      Signed-off-by: default avatarPuranjay Mohan <puranjay12@gmail.com>
      Link: https://lore.kernel.org/r/20230907230550.1417590-9-puranjay12@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      daabb2b0
    • Puranjay Mohan's avatar
      selftest, bpf: enable cpu v4 tests for arm32 · 59ff6d63
      Puranjay Mohan authored
      Now that all the cpuv4 instructions are supported by the arm32 JIT,
      enable the selftests for arm32.
      Signed-off-by: default avatarPuranjay Mohan <puranjay12@gmail.com>
      Link: https://lore.kernel.org/r/20230907230550.1417590-8-puranjay12@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      59ff6d63
    • Puranjay Mohan's avatar
      arm32, bpf: add support for 64 bit division instruction · 71086041
      Puranjay Mohan authored
      ARM32 doesn't have instructions to do 64-bit/64-bit divisions. So, to
      implement the following instructions:
      BPF_ALU64 | BPF_DIV
      BPF_ALU64 | BPF_MOD
      BPF_ALU64 | BPF_SDIV
      BPF_ALU64 | BPF_SMOD
      
      We implement the above instructions by doing function calls to div64_u64()
      and div64_u64_rem() for unsigned division/mod and calls to div64_s64()
      for signed division/mod.
      Signed-off-by: default avatarPuranjay Mohan <puranjay12@gmail.com>
      Reviewed-by: default avatarRussell King (Oracle) <rmk+kernel@armlinux.org.uk>
      Link: https://lore.kernel.org/r/20230907230550.1417590-7-puranjay12@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      71086041
    • Puranjay Mohan's avatar
      arm32, bpf: add support for 32-bit signed division · 5097faa5
      Puranjay Mohan authored
      The cpuv4 added a new BPF_SDIV instruction that does signed division.
      The encoding is similar to BPF_DIV but BPF_SDIV sets offset=1.
      
      ARM32 already supports 32-bit BPF_DIV which can be easily extended to
      support BPF_SDIV as ARM32 has the SDIV instruction. When the CPU is not
      ARM-v7, we implement that SDIV/SMOD with the function call similar to
      the implementation of DIV/MOD.
      Signed-off-by: default avatarPuranjay Mohan <puranjay12@gmail.com>
      Reviewed-by: default avatarRussell King (Oracle) <rmk+kernel@armlinux.org.uk>
      Link: https://lore.kernel.org/r/20230907230550.1417590-6-puranjay12@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      5097faa5
    • Puranjay Mohan's avatar
      arm32, bpf: add support for unconditional bswap instruction · 1cfb7eae
      Puranjay Mohan authored
      The cpuv4 added a new unconditional bswap instruction with following
      behaviour:
      
      BPF_ALU64 | BPF_TO_LE | BPF_END with imm = 16/32/64 means:
      dst = bswap16(dst)
      dst = bswap32(dst)
      dst = bswap64(dst)
      
      As we already support converting to big-endian from little-endian we can
      use the same for unconditional bswap. just treat the unconditional scenario
      the same as big-endian conversion.
      Signed-off-by: default avatarPuranjay Mohan <puranjay12@gmail.com>
      Reviewed-by: default avatarRussell King (Oracle) <rmk+kernel@armlinux.org.uk>
      Link: https://lore.kernel.org/r/20230907230550.1417590-5-puranjay12@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      1cfb7eae
    • Puranjay Mohan's avatar
      arm32, bpf: add support for sign-extension mov instruction · fc832653
      Puranjay Mohan authored
      The cpuv4 added a new BPF_MOVSX instruction that sign extends the src
      before moving it to the destination.
      
      BPF_ALU | BPF_MOVSX sign extends 8-bit and 16-bit operands into 32-bit
      operands, and zeroes the remaining upper 32 bits.
      
      BPF_ALU64 | BPF_MOVSX sign extends 8-bit, 16-bit, and 32-bit  operands
      into 64-bit operands.
      
      The offset field of the instruction is used to tell the number of bit to
      use for sign-extension. BPF_MOV and BPF_MOVSX have the same code but the
      former sets offset to 0 and the later one sets the offset to 8, 16 or 32
      
      The behaviour of this instruction is dst = (s8,s16,s32)src
      
      On ARM32 the implementation uses LSH and ARSH to extend the 8/16 bits to
      a 32-bit register and then it is sign extended to the upper 32-bit
      register using ARSH. For 32-bit we just move it to the destination
      register and use ARSH to extend it to the upper 32-bit register.
      Signed-off-by: default avatarPuranjay Mohan <puranjay12@gmail.com>
      Reviewed-by: default avatarRussell King (Oracle) <rmk+kernel@armlinux.org.uk>
      Link: https://lore.kernel.org/r/20230907230550.1417590-4-puranjay12@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      fc832653
    • Puranjay Mohan's avatar
      arm32, bpf: add support for sign-extension load instruction · f9e6981b
      Puranjay Mohan authored
      The cpuv4 added the support of an instruction that is similar to load
      but also sign-extends the result after the load.
      
      BPF_MEMSX | <size> | BPF_LDX means dst = *(signed size *) (src + offset)
      here <size> can be one of BPF_B, BPF_H, BPF_W.
      
      ARM32 has instructions to load a byte or a half word with sign
      extension into a 32bit register. As the JIT uses two 32 bit registers
      to simulate a 64-bit BPF register, an extra instruction is emitted to
      sign-extent the result up to the second register.
      Signed-off-by: default avatarPuranjay Mohan <puranjay12@gmail.com>
      Reviewed-by: default avatarRussell King (Oracle) <rmk+kernel@armlinux.org.uk>
      Link: https://lore.kernel.org/r/20230907230550.1417590-3-puranjay12@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      f9e6981b
    • Puranjay Mohan's avatar
      arm32, bpf: add support for 32-bit offset jmp instruction · 471f3d4e
      Puranjay Mohan authored
      The cpuv4 adds unconditional jump with 32-bit offset where the immediate
      field of the instruction is to be used to calculate the jump offset.
      
      BPF_JA | BPF_K | BPF_JMP32 => gotol +imm => PC += imm.
      Signed-off-by: default avatarPuranjay Mohan <puranjay12@gmail.com>
      Reviewed-by: default avatarRussell King (Oracle) <rmk+kernel@armlinux.org.uk>
      Link: https://lore.kernel.org/r/20230907230550.1417590-2-puranjay12@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      471f3d4e
  2. 15 Sep, 2023 6 commits
  3. 14 Sep, 2023 13 commits
  4. 13 Sep, 2023 1 commit
  5. 12 Sep, 2023 4 commits
    • Alexei Starovoitov's avatar
      Merge branch 'bpf-x64-fix-tailcall-infinite-loop' · 5bbb9e1f
      Alexei Starovoitov authored
      Leon Hwang says:
      
      ====================
      bpf, x64: Fix tailcall infinite loop
      
      This patch series fixes a tailcall infinite loop on x64.
      
      From commit ebf7d1f5 ("bpf, x64: rework pro/epilogue and tailcall
      handling in JIT"), the tailcall on x64 works better than before.
      
      From commit e411901c ("bpf: allow for tailcalls in BPF subprograms
      for x64 JIT"), tailcall is able to run in BPF subprograms on x64.
      
      From commit 5b92a28a ("bpf: Support attaching tracing BPF program
      to other BPF programs"), BPF program is able to trace other BPF programs.
      
      How about combining them all together?
      
      1. FENTRY/FEXIT on a BPF subprogram.
      2. A tailcall runs in the BPF subprogram.
      3. The tailcall calls the subprogram's caller.
      
      As a result, a tailcall infinite loop comes up. And the loop would halt
      the machine.
      
      As we know, in tail call context, the tail_call_cnt propagates by stack
      and rax register between BPF subprograms. So do in trampolines.
      
      How did I discover the bug?
      
      From commit 7f6e4312 ("bpf: Limit caller's stack depth 256 for
      subprogs with tailcalls"), the total stack size limits to around 8KiB.
      Then, I write some bpf progs to validate the stack consuming, that are
      tailcalls running in bpf2bpf and FENTRY/FEXIT tracing on bpf2bpf.
      
      At that time, accidently, I made a tailcall loop. And then the loop halted
      my VM. Without the loop, the bpf progs would consume over 8KiB stack size.
      But the _stack-overflow_ did not halt my VM.
      
      With bpf_printk(), I confirmed that the tailcall count limit did not work
      expectedly. Next, read the code and fix it.
      
      Thank Ilya Leoshkevich, this bug on s390x has been fixed.
      
      Hopefully, this bug on arm64 will be fixed in near future.
      ====================
      
      Link: https://lore.kernel.org/r/20230912150442.2009-1-hffilwlqm@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      5bbb9e1f
    • Leon Hwang's avatar
      selftests/bpf: Add testcases for tailcall infinite loop fixing · e13b5f2f
      Leon Hwang authored
      Add 4 test cases to confirm the tailcall infinite loop bug has been fixed.
      
      Like tailcall_bpf2bpf cases, do fentry/fexit on the bpf2bpf, and then
      check the final count result.
      
      tools/testing/selftests/bpf/test_progs -t tailcalls
      226/13  tailcalls/tailcall_bpf2bpf_fentry:OK
      226/14  tailcalls/tailcall_bpf2bpf_fexit:OK
      226/15  tailcalls/tailcall_bpf2bpf_fentry_fexit:OK
      226/16  tailcalls/tailcall_bpf2bpf_fentry_entry:OK
      226     tailcalls:OK
      Summary: 1/16 PASSED, 0 SKIPPED, 0 FAILED
      Signed-off-by: default avatarLeon Hwang <hffilwlqm@gmail.com>
      Link: https://lore.kernel.org/r/20230912150442.2009-4-hffilwlqm@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      e13b5f2f
    • Leon Hwang's avatar
      bpf, x64: Fix tailcall infinite loop · 2b5dcb31
      Leon Hwang authored
      From commit ebf7d1f5 ("bpf, x64: rework pro/epilogue and tailcall
      handling in JIT"), the tailcall on x64 works better than before.
      
      From commit e411901c ("bpf: allow for tailcalls in BPF subprograms
      for x64 JIT"), tailcall is able to run in BPF subprograms on x64.
      
      From commit 5b92a28a ("bpf: Support attaching tracing BPF program
      to other BPF programs"), BPF program is able to trace other BPF programs.
      
      How about combining them all together?
      
      1. FENTRY/FEXIT on a BPF subprogram.
      2. A tailcall runs in the BPF subprogram.
      3. The tailcall calls the subprogram's caller.
      
      As a result, a tailcall infinite loop comes up. And the loop would halt
      the machine.
      
      As we know, in tail call context, the tail_call_cnt propagates by stack
      and rax register between BPF subprograms. So do in trampolines.
      
      Fixes: ebf7d1f5 ("bpf, x64: rework pro/epilogue and tailcall handling in JIT")
      Fixes: e411901c ("bpf: allow for tailcalls in BPF subprograms for x64 JIT")
      Reviewed-by: default avatarMaciej Fijalkowski <maciej.fijalkowski@intel.com>
      Signed-off-by: default avatarLeon Hwang <hffilwlqm@gmail.com>
      Link: https://lore.kernel.org/r/20230912150442.2009-3-hffilwlqm@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      2b5dcb31
    • Leon Hwang's avatar
      bpf, x64: Comment tail_call_cnt initialisation · 2bee9770
      Leon Hwang authored
      Without understanding emit_prologue(), it is really hard to figure out
      where does tail_call_cnt come from, even though searching tail_call_cnt
      in the whole kernel repo.
      
      By adding these comments, it is a little bit easier to understand
      tail_call_cnt initialisation.
      Signed-off-by: default avatarLeon Hwang <hffilwlqm@gmail.com>
      Link: https://lore.kernel.org/r/20230912150442.2009-2-hffilwlqm@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      2bee9770
  6. 11 Sep, 2023 1 commit
  7. 09 Sep, 2023 2 commits
  8. 08 Sep, 2023 2 commits