riscv, bpf: Fix missing exception handling and redundant zext for LDX_B/H/W
authorPu Lehui <pulehui@huawei.com>
Thu, 24 Aug 2023 09:49:55 +0000 (09:49 +0000)
committerAlexei Starovoitov <ast@kernel.org>
Thu, 24 Aug 2023 16:13:08 +0000 (09:13 -0700)
For LDX_B/H/W, when zext has been inserted by verifier, it'll return 1,
and no exception handling will continue. Also, when the offset is 12-bit
value, the redundant zext inserted by the verifier is not removed. Fix
both scenarios by moving down the removal of redundant zext.

Signed-off-by: Pu Lehui <pulehui@huawei.com>
Link: https://lore.kernel.org/r/20230824095001.3408573-2-pulehui@huaweicloud.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
arch/riscv/net/bpf_jit_comp64.c

index 0ca4f5c..f2644e7 100644 (file)
@@ -1512,8 +1512,6 @@ out_be:
                        insns_start = ctx->ninsns;
                        emit(rv_lbu(rd, 0, RV_REG_T1), ctx);
                        insn_len = ctx->ninsns - insns_start;
-                       if (insn_is_zext(&insn[1]))
-                               return 1;
                        break;
                case BPF_H:
                        if (is_12b_int(off)) {
@@ -1528,8 +1526,6 @@ out_be:
                        insns_start = ctx->ninsns;
                        emit(rv_lhu(rd, 0, RV_REG_T1), ctx);
                        insn_len = ctx->ninsns - insns_start;
-                       if (insn_is_zext(&insn[1]))
-                               return 1;
                        break;
                case BPF_W:
                        if (is_12b_int(off)) {
@@ -1544,8 +1540,6 @@ out_be:
                        insns_start = ctx->ninsns;
                        emit(rv_lwu(rd, 0, RV_REG_T1), ctx);
                        insn_len = ctx->ninsns - insns_start;
-                       if (insn_is_zext(&insn[1]))
-                               return 1;
                        break;
                case BPF_DW:
                        if (is_12b_int(off)) {
@@ -1566,6 +1560,9 @@ out_be:
                ret = add_exception_handler(insn, ctx, rd, insn_len);
                if (ret)
                        return ret;
+
+               if (BPF_SIZE(code) != BPF_DW && insn_is_zext(&insn[1]))
+                       return 1;
                break;
        }
        /* speculation barrier */