Merge branch 'mlx5-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mellanox...
[linux-2.6-microblaze.git] / kernel / bpf / disasm.c
index b44d8c4..3acc7e0 100644 (file)
@@ -80,6 +80,13 @@ const char *const bpf_alu_string[16] = {
        [BPF_END >> 4]  = "endian",
 };
 
+static const char *const bpf_atomic_alu_string[16] = {
+       [BPF_ADD >> 4]  = "add",
+       [BPF_AND >> 4]  = "and",
+       [BPF_OR >> 4]  = "or",
+       [BPF_XOR >> 4]  = "or",
+};
+
 static const char *const bpf_ldst_string[] = {
        [BPF_W >> 3]  = "u32",
        [BPF_H >> 3]  = "u16",
@@ -153,14 +160,44 @@ void print_bpf_insn(const struct bpf_insn_cbs *cbs,
                                bpf_ldst_string[BPF_SIZE(insn->code) >> 3],
                                insn->dst_reg,
                                insn->off, insn->src_reg);
-               else if (BPF_MODE(insn->code) == BPF_XADD)
-                       verbose(cbs->private_data, "(%02x) lock *(%s *)(r%d %+d) += r%d\n",
+               else if (BPF_MODE(insn->code) == BPF_ATOMIC &&
+                        (insn->imm == BPF_ADD || insn->imm == BPF_AND ||
+                         insn->imm == BPF_OR || insn->imm == BPF_XOR)) {
+                       verbose(cbs->private_data, "(%02x) lock *(%s *)(r%d %+d) %s r%d\n",
+                               insn->code,
+                               bpf_ldst_string[BPF_SIZE(insn->code) >> 3],
+                               insn->dst_reg, insn->off,
+                               bpf_alu_string[BPF_OP(insn->imm) >> 4],
+                               insn->src_reg);
+               } else if (BPF_MODE(insn->code) == BPF_ATOMIC &&
+                          (insn->imm == (BPF_ADD | BPF_FETCH) ||
+                           insn->imm == (BPF_AND | BPF_FETCH) ||
+                           insn->imm == (BPF_OR | BPF_FETCH) ||
+                           insn->imm == (BPF_XOR | BPF_FETCH))) {
+                       verbose(cbs->private_data, "(%02x) r%d = atomic%s_fetch_%s((%s *)(r%d %+d), r%d)\n",
+                               insn->code, insn->src_reg,
+                               BPF_SIZE(insn->code) == BPF_DW ? "64" : "",
+                               bpf_atomic_alu_string[BPF_OP(insn->imm) >> 4],
+                               bpf_ldst_string[BPF_SIZE(insn->code) >> 3],
+                               insn->dst_reg, insn->off, insn->src_reg);
+               } else if (BPF_MODE(insn->code) == BPF_ATOMIC &&
+                          insn->imm == BPF_CMPXCHG) {
+                       verbose(cbs->private_data, "(%02x) r0 = atomic%s_cmpxchg((%s *)(r%d %+d), r0, r%d)\n",
                                insn->code,
+                               BPF_SIZE(insn->code) == BPF_DW ? "64" : "",
                                bpf_ldst_string[BPF_SIZE(insn->code) >> 3],
                                insn->dst_reg, insn->off,
                                insn->src_reg);
-               else
+               } else if (BPF_MODE(insn->code) == BPF_ATOMIC &&
+                          insn->imm == BPF_XCHG) {
+                       verbose(cbs->private_data, "(%02x) r%d = atomic%s_xchg((%s *)(r%d %+d), r%d)\n",
+                               insn->code, insn->src_reg,
+                               BPF_SIZE(insn->code) == BPF_DW ? "64" : "",
+                               bpf_ldst_string[BPF_SIZE(insn->code) >> 3],
+                               insn->dst_reg, insn->off, insn->src_reg);
+               } else {
                        verbose(cbs->private_data, "BUG_%02x\n", insn->code);
+               }
        } else if (class == BPF_ST) {
                if (BPF_MODE(insn->code) != BPF_MEM) {
                        verbose(cbs->private_data, "BUG_st_%02x\n", insn->code);