]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
nfp: bpf: direct packet access - write
authorJakub Kicinski <jakub.kicinski@netronome.com>
Thu, 12 Oct 2017 17:34:17 +0000 (10:34 -0700)
committerDavid S. Miller <davem@davemloft.net>
Sat, 14 Oct 2017 18:13:28 +0000 (11:13 -0700)
This patch adds ability to write packet contents using pre-validated
packet pointers (direct packet access).

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Simon Horman <simon.horman@netronome.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/netronome/nfp/bpf/jit.c
drivers/net/ethernet/netronome/nfp/nfp_asm.c
drivers/net/ethernet/netronome/nfp/nfp_asm.h

index 975d63fbc1d534ac4aa3ec544140401e8fc3698e..139a4ebdc774b2c4db8cd43811a0874a4617142b 100644 (file)
@@ -607,6 +607,35 @@ static int construct_data_ld(struct nfp_prog *nfp_prog, u16 offset, u8 size)
        return data_ld(nfp_prog, tmp_reg, 0, size);
 }
 
+static int
+data_stx_host_order(struct nfp_prog *nfp_prog, u8 dst_gpr, swreg offset,
+                   u8 src_gpr, u8 size)
+{
+       unsigned int i;
+
+       for (i = 0; i * 4 < size; i++)
+               wrp_mov(nfp_prog, reg_xfer(i), reg_a(src_gpr + i));
+
+       emit_cmd(nfp_prog, CMD_TGT_WRITE8_SWAP, CMD_MODE_32b, 0,
+                reg_a(dst_gpr), offset, size - 1, true);
+
+       return 0;
+}
+
+static int
+data_st_host_order(struct nfp_prog *nfp_prog, u8 dst_gpr, swreg offset,
+                  u64 imm, u8 size)
+{
+       wrp_immed(nfp_prog, reg_xfer(0), imm);
+       if (size == 8)
+               wrp_immed(nfp_prog, reg_xfer(1), imm >> 32);
+
+       emit_cmd(nfp_prog, CMD_TGT_WRITE8_SWAP, CMD_MODE_32b, 0,
+                reg_a(dst_gpr), offset, size - 1, true);
+
+       return 0;
+}
+
 static void
 wrp_alu_imm(struct nfp_prog *nfp_prog, u8 dst, enum alu_op alu_op, u32 imm)
 {
@@ -1196,24 +1225,88 @@ static int mem_ldx8(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
        return mem_ldx(nfp_prog, meta, 8);
 }
 
-static int mem_stx4_skb(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
+static int
+mem_st_data(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta,
+           unsigned int size)
+{
+       u64 imm = meta->insn.imm; /* sign extend */
+       swreg off_reg;
+
+       off_reg = re_load_imm_any(nfp_prog, meta->insn.off, imm_b(nfp_prog));
+
+       return data_st_host_order(nfp_prog, meta->insn.dst_reg * 2, off_reg,
+                                 imm, size);
+}
+
+static int mem_st(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta,
+                 unsigned int size)
 {
+       if (meta->ptr.type == PTR_TO_PACKET)
+               return mem_st_data(nfp_prog, meta, size);
+
        return -EOPNOTSUPP;
 }
 
-static int mem_stx4_xdp(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
+static int mem_st1(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
+{
+       return mem_st(nfp_prog, meta, 1);
+}
+
+static int mem_st2(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
+{
+       return mem_st(nfp_prog, meta, 2);
+}
+
+static int mem_st4(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
+{
+       return mem_st(nfp_prog, meta, 4);
+}
+
+static int mem_st8(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
 {
+       return mem_st(nfp_prog, meta, 8);
+}
+
+static int
+mem_stx_data(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta,
+            unsigned int size)
+{
+       swreg off_reg;
+
+       off_reg = re_load_imm_any(nfp_prog, meta->insn.off, imm_b(nfp_prog));
+
+       return data_stx_host_order(nfp_prog, meta->insn.dst_reg * 2, off_reg,
+                                  meta->insn.src_reg * 2, size);
+}
+
+static int
+mem_stx(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta,
+       unsigned int size)
+{
+       if (meta->ptr.type == PTR_TO_PACKET)
+               return mem_stx_data(nfp_prog, meta, size);
+
        return -EOPNOTSUPP;
 }
 
+static int mem_stx1(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
+{
+       return mem_stx(nfp_prog, meta, 1);
+}
+
+static int mem_stx2(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
+{
+       return mem_stx(nfp_prog, meta, 2);
+}
+
 static int mem_stx4(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
 {
-       if (meta->ptr.type == PTR_TO_PACKET)
-               return -EOPNOTSUPP;
+       return mem_stx(nfp_prog, meta, 4);
+}
 
-       if (nfp_prog->act == NN_ACT_XDP)
-               return mem_stx4_xdp(nfp_prog, meta);
-       return mem_stx4_skb(nfp_prog, meta);
+static int mem_stx8(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
+{
+       return mem_stx(nfp_prog, meta, 8);
 }
 
 static int jump(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
@@ -1432,7 +1525,14 @@ static const instr_cb_t instr_cb[256] = {
        [BPF_LDX | BPF_MEM | BPF_H] =   mem_ldx2,
        [BPF_LDX | BPF_MEM | BPF_W] =   mem_ldx4,
        [BPF_LDX | BPF_MEM | BPF_DW] =  mem_ldx8,
+       [BPF_STX | BPF_MEM | BPF_B] =   mem_stx1,
+       [BPF_STX | BPF_MEM | BPF_H] =   mem_stx2,
        [BPF_STX | BPF_MEM | BPF_W] =   mem_stx4,
+       [BPF_STX | BPF_MEM | BPF_DW] =  mem_stx8,
+       [BPF_ST | BPF_MEM | BPF_B] =    mem_st1,
+       [BPF_ST | BPF_MEM | BPF_H] =    mem_st2,
+       [BPF_ST | BPF_MEM | BPF_W] =    mem_st4,
+       [BPF_ST | BPF_MEM | BPF_DW] =   mem_st8,
        [BPF_JMP | BPF_JA | BPF_K] =    jump,
        [BPF_JMP | BPF_JEQ | BPF_K] =   jeq_imm,
        [BPF_JMP | BPF_JGT | BPF_K] =   jgt_imm,
index 7cae99b3e00a5a952312cb9d97c5d8c189c5a6a8..830f6de25f475fbe086fc43c5911fb08591854bc 100644 (file)
@@ -40,7 +40,7 @@
 #include "nfp_asm.h"
 
 const struct cmd_tgt_act cmd_tgt_act[__CMD_TGT_MAP_SIZE] = {
-       [CMD_TGT_WRITE8] =              { 0x00, 0x42 },
+       [CMD_TGT_WRITE8_SWAP] =         { 0x02, 0x42 },
        [CMD_TGT_READ8] =               { 0x01, 0x43 },
        [CMD_TGT_READ32] =              { 0x00, 0x5c },
        [CMD_TGT_READ32_LE] =           { 0x01, 0x5c },
index e3df7a26724fd26b11a8fdfae581a9243f29db7e..c26aa7e4a83967df9bda2304d4108092c315467b 100644 (file)
@@ -217,7 +217,7 @@ struct cmd_tgt_act {
 
 enum cmd_tgt_map {
        CMD_TGT_READ8,
-       CMD_TGT_WRITE8,
+       CMD_TGT_WRITE8_SWAP,
        CMD_TGT_READ32,
        CMD_TGT_READ32_LE,
        CMD_TGT_READ32_SWAP,