bpf: introduce new mov32 variant for doing explicit zero extension [Linux 5.3]

This Linux kernel change "bpf: introduce new mov32 variant for doing explicit zero extension" is included in the Linux 5.3 release. This change is authored by Jiong Wang <jiong.wang [at] netronome.com> on Fri May 24 23:25:14 2019 +0100. The commit for this change in Linux stable tree is 7d13404 (patch).

bpf: introduce new mov32 variant for doing explicit zero extension

The encoding for this new variant is based on BPF_X format. "imm" field was
0 only, now it could be 1 which means doing zero extension unconditionally

  .code = BPF_ALU | BPF_MOV | BPF_X
  .dst_reg = DST
  .src_reg = SRC
  .imm  = 1

We use this new form for doing zero extension for which verifier will
guarantee SRC == DST.

Implications on JIT back-ends when doing code-gen for
BPF_ALU | BPF_MOV | BPF_X:
  1. No change if hardware already does zero extension unconditionally for
     sub-register write.
  2. Otherwise, when seeing imm == 1, just generate insns to clear high
     32-bit. No need to generate insns for the move because when imm == 1,
     dst_reg is the same as src_reg at the moment.

Interpreter doesn't need change as well. It is doing unconditionally zero
extension for mov32 already.

One helper macro BPF_ZEXT_REG is added to help creating zero extension
insn using this new mov32 variant.

One helper function insn_is_zext is added for checking one insn is an
zero extension on dst. This will be widely used by a few JIT back-ends in
later patches in this set.

Signed-off-by: Jiong Wang <jiong.wang@netronome.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

There are 14 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 include/linux/filter.h | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/include/linux/filter.h b/include/linux/filter.h
index 7148bab..bb10ffb 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -160,6 +160,20 @@
        .off   = 0,                 \
        .imm   = IMM })

+/* Special form of mov32, used for doing explicit zero extension on dst. */
+#define BPF_ZEXT_REG(DST)                  \
+   ((struct bpf_insn) {                    \
+       .code  = BPF_ALU | BPF_MOV | BPF_X,     \
+       .dst_reg = DST,                 \
+       .src_reg = DST,                 \
+       .off   = 0,                 \
+       .imm   = 1 })
+
+static inline bool insn_is_zext(const struct bpf_insn *insn)
+{
+   return insn->code == (BPF_ALU | BPF_MOV | BPF_X) && insn->imm == 1;
+}
+
 /* BPF_LD_IMM64 macro encodes single 'load 64-bit immediate' insn */
 #define BPF_LD_IMM64(DST, IMM)                 \
    BPF_LD_IMM64_RAW(DST, 0, IMM)

Leave a Reply

Your email address will not be published. Required fields are marked *