Skip to content

Commit

Permalink
LoongArch: BPF: Don't sign extend function return value
Browse files Browse the repository at this point in the history
[ Upstream commit 5d47ec2 ]

The `cls_redirect` test triggers a kernel panic like:

  # ./test_progs -t cls_redirect
  Can't find bpf_testmod.ko kernel module: -2
  WARNING! Selftests relying on bpf_testmod.ko will be skipped.
  [   30.938489] CPU 3 Unable to handle kernel paging request at virtual address fffffffffd814de0, era == ffff800002009fb8, ra == ffff800002009f9c
  [   30.939331] Oops[#1]:
  [   30.939513] CPU: 3 PID: 1260 Comm: test_progs Not tainted 6.7.0-rc2-loong-devel-g2f56bb0d2327 torvalds#35 a896aca3f4164f09cc346f89f2e09832e07be5f6
  [   30.939732] Hardware name: QEMU QEMU Virtual Machine, BIOS unknown 2/2/2022
  [   30.939901] pc ffff800002009fb8 ra ffff800002009f9c tp 9000000104da4000 sp 9000000104da7ab0
  [   30.940038] a0 fffffffffd814de0 a1 9000000104da7a68 a2 0000000000000000 a3 9000000104da7c10
  [   30.940183] a4 9000000104da7c14 a5 0000000000000002 a6 0000000000000021 a7 00005555904d7f90
  [   30.940321] t0 0000000000000110 t1 0000000000000000 t2 fffffffffd814de0 t3 0004c4b400000000
  [   30.940456] t4 ffffffffffffffff t5 00000000c3f63600 t6 0000000000000000 t7 0000000000000000
  [   30.940590] t8 000000000006d803 u0 0000000000000020 s9 9000000104da7b10 s0 900000010504c200
  [   30.940727] s1 fffffffffd814de0 s2 900000010504c200 s3 9000000104da7c10 s4 9000000104da7ad0
  [   30.940866] s5 0000000000000000 s6 90000000030e65bc s7 9000000104da7b44 s8 90000000044f6fc0
  [   30.941015]    ra: ffff800002009f9c bpf_prog_846803e5ae81417f_cls_redirect+0xa0/0x590
  [   30.941535]   ERA: ffff800002009fb8 bpf_prog_846803e5ae81417f_cls_redirect+0xbc/0x590
  [   30.941696]  CRMD: 000000b0 (PLV0 -IE -DA +PG DACF=CC DACM=CC -WE)
  [   30.942224]  PRMD: 00000004 (PPLV0 +PIE -PWE)
  [   30.942330]  EUEN: 00000003 (+FPE +SXE -ASXE -BTE)
  [   30.942453]  ECFG: 00071c1c (LIE=2-4,10-12 VS=7)
  [   30.942612] ESTAT: 00010000 [PIL] (IS= ECode=1 EsubCode=0)
  [   30.942764]  BADV: fffffffffd814de0
  [   30.942854]  PRID: 0014c010 (Loongson-64bit, Loongson-3A5000)
  [   30.942974] Modules linked in:
  [   30.943078] Process test_progs (pid: 1260, threadinfo=00000000ce303226, task=000000007d10bb76)
  [   30.943306] Stack : 900000010a064000 90000000044f6fc0 9000000104da7b48 0000000000000000
  [   30.943495]         0000000000000000 9000000104da7c14 9000000104da7c10 900000010504c200
  [   30.943626]         0000000000000001 ffff80001b88c000 9000000104da7b70 90000000030e6668
  [   30.943785]         0000000000000000 9000000104da7b58 ffff80001b88c048 9000000003d05000
  [   30.943936]         900000000303ac88 0000000000000000 0000000000000000 9000000104da7b70
  [   30.944091]         0000000000000000 0000000000000001 0000000731eeab00 0000000000000000
  [   30.944245]         ffff80001b88c000 0000000000000000 0000000000000000 54b99959429f83b8
  [   30.944402]         ffff80001b88c000 90000000044f6fc0 9000000101d70000 ffff80001b88c000
  [   30.944538]         000000000000005a 900000010504c200 900000010a064000 900000010a067000
  [   30.944697]         9000000104da7d88 0000000000000000 9000000003d05000 90000000030e794c
  [   30.944852]         ...
  [   30.944924] Call Trace:
  [   30.945120] [<ffff800002009fb8>] bpf_prog_846803e5ae81417f_cls_redirect+0xbc/0x590
  [   30.945650] [<90000000030e6668>] bpf_test_run+0x1ec/0x2f8
  [   30.945958] [<90000000030e794c>] bpf_prog_test_run_skb+0x31c/0x684
  [   30.946065] [<90000000026d4f68>] __sys_bpf+0x678/0x2724
  [   30.946159] [<90000000026d7288>] sys_bpf+0x20/0x2c
  [   30.946253] [<90000000032dd224>] do_syscall+0x7c/0x94
  [   30.946343] [<9000000002541c5c>] handle_syscall+0xbc/0x158
  [   30.946492]
  [   30.946549] Code: 0015030e  5c0009c0  5001d000 <28c00304> 02c00484  29c00304  00150009  2a42d2e4  0280200d
  [   30.946793]
  [   30.946971] ---[ end trace 0000000000000000 ]---
  [   32.093225] Kernel panic - not syncing: Fatal exception in interrupt
  [   32.093526] Kernel relocated by 0x2320000
  [   32.093630]  .text @ 0x9000000002520000
  [   32.093725]  .data @ 0x9000000003400000
  [   32.093792]  .bss  @ 0x9000000004413200
  [   34.971998] ---[ end Kernel panic - not syncing: Fatal exception in interrupt ]---

This is because we signed-extend function return values. When subprog
mode is enabled, we have:

  cls_redirect()
    -> get_global_metrics() returns pcpu ptr 0xfffffefffc00b480

The pointer returned is later signed-extended to 0xfffffffffc00b480 at
`BPF_JMP | BPF_EXIT`. During BPF prog run, this triggers unhandled page
fault and a kernel panic.

Drop the unnecessary signed-extension on return values like other
architectures do.

With this change, we have:

  # ./test_progs -t cls_redirect
  Can't find bpf_testmod.ko kernel module: -2
  WARNING! Selftests relying on bpf_testmod.ko will be skipped.
  torvalds#51/1    cls_redirect/cls_redirect_inlined:OK
  torvalds#51/2    cls_redirect/IPv4 TCP accept unknown (no hops, flags: SYN):OK
  torvalds#51/3    cls_redirect/IPv6 TCP accept unknown (no hops, flags: SYN):OK
  torvalds#51/4    cls_redirect/IPv4 TCP accept unknown (no hops, flags: ACK):OK
  torvalds#51/5    cls_redirect/IPv6 TCP accept unknown (no hops, flags: ACK):OK
  torvalds#51/6    cls_redirect/IPv4 TCP forward unknown (one hop, flags: ACK):OK
  torvalds#51/7    cls_redirect/IPv6 TCP forward unknown (one hop, flags: ACK):OK
  torvalds#51/8    cls_redirect/IPv4 TCP accept known (one hop, flags: ACK):OK
  torvalds#51/9    cls_redirect/IPv6 TCP accept known (one hop, flags: ACK):OK
  torvalds#51/10   cls_redirect/IPv4 UDP accept unknown (no hops, flags: none):OK
  torvalds#51/11   cls_redirect/IPv6 UDP accept unknown (no hops, flags: none):OK
  torvalds#51/12   cls_redirect/IPv4 UDP forward unknown (one hop, flags: none):OK
  torvalds#51/13   cls_redirect/IPv6 UDP forward unknown (one hop, flags: none):OK
  torvalds#51/14   cls_redirect/IPv4 UDP accept known (one hop, flags: none):OK
  torvalds#51/15   cls_redirect/IPv6 UDP accept known (one hop, flags: none):OK
  torvalds#51/16   cls_redirect/cls_redirect_subprogs:OK
  torvalds#51/17   cls_redirect/IPv4 TCP accept unknown (no hops, flags: SYN):OK
  torvalds#51/18   cls_redirect/IPv6 TCP accept unknown (no hops, flags: SYN):OK
  torvalds#51/19   cls_redirect/IPv4 TCP accept unknown (no hops, flags: ACK):OK
  torvalds#51/20   cls_redirect/IPv6 TCP accept unknown (no hops, flags: ACK):OK
  torvalds#51/21   cls_redirect/IPv4 TCP forward unknown (one hop, flags: ACK):OK
  torvalds#51/22   cls_redirect/IPv6 TCP forward unknown (one hop, flags: ACK):OK
  torvalds#51/23   cls_redirect/IPv4 TCP accept known (one hop, flags: ACK):OK
  torvalds#51/24   cls_redirect/IPv6 TCP accept known (one hop, flags: ACK):OK
  torvalds#51/25   cls_redirect/IPv4 UDP accept unknown (no hops, flags: none):OK
  torvalds#51/26   cls_redirect/IPv6 UDP accept unknown (no hops, flags: none):OK
  torvalds#51/27   cls_redirect/IPv4 UDP forward unknown (one hop, flags: none):OK
  torvalds#51/28   cls_redirect/IPv6 UDP forward unknown (one hop, flags: none):OK
  torvalds#51/29   cls_redirect/IPv4 UDP accept known (one hop, flags: none):OK
  torvalds#51/30   cls_redirect/IPv6 UDP accept known (one hop, flags: none):OK
  torvalds#51/31   cls_redirect/cls_redirect_dynptr:OK
  torvalds#51/32   cls_redirect/IPv4 TCP accept unknown (no hops, flags: SYN):OK
  torvalds#51/33   cls_redirect/IPv6 TCP accept unknown (no hops, flags: SYN):OK
  torvalds#51/34   cls_redirect/IPv4 TCP accept unknown (no hops, flags: ACK):OK
  torvalds#51/35   cls_redirect/IPv6 TCP accept unknown (no hops, flags: ACK):OK
  torvalds#51/36   cls_redirect/IPv4 TCP forward unknown (one hop, flags: ACK):OK
  torvalds#51/37   cls_redirect/IPv6 TCP forward unknown (one hop, flags: ACK):OK
  torvalds#51/38   cls_redirect/IPv4 TCP accept known (one hop, flags: ACK):OK
  torvalds#51/39   cls_redirect/IPv6 TCP accept known (one hop, flags: ACK):OK
  torvalds#51/40   cls_redirect/IPv4 UDP accept unknown (no hops, flags: none):OK
  torvalds#51/41   cls_redirect/IPv6 UDP accept unknown (no hops, flags: none):OK
  torvalds#51/42   cls_redirect/IPv4 UDP forward unknown (one hop, flags: none):OK
  torvalds#51/43   cls_redirect/IPv6 UDP forward unknown (one hop, flags: none):OK
  torvalds#51/44   cls_redirect/IPv4 UDP accept known (one hop, flags: none):OK
  torvalds#51/45   cls_redirect/IPv6 UDP accept known (one hop, flags: none):OK
  torvalds#51      cls_redirect:OK
  Summary: 1/45 PASSED, 0 SKIPPED, 0 FAILED

Fixes: 5dc6155 ("LoongArch: Add BPF JIT support")
Signed-off-by: Hengqi Chen <hengqi.chen@gmail.com>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
chenhengqi authored and gregkh committed Dec 13, 2023
1 parent 3275410 commit 4b11737
Showing 1 changed file with 0 additions and 2 deletions.
2 changes: 0 additions & 2 deletions arch/loongarch/net/bpf_jit.c
Original file line number Diff line number Diff line change
Expand Up @@ -855,8 +855,6 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext

/* function return */
case BPF_JMP | BPF_EXIT:
emit_sext_32(ctx, regmap[BPF_REG_0], true);

if (i == ctx->prog->len - 1)
break;

Expand Down

0 comments on commit 4b11737

Please sign in to comment.