Skip to content

Commit

Permalink
nfp: bpf: direct packet access - write
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jakub Kicinski authored and David S. Miller committed Oct 14, 2017
1 parent 2ca7144 commit e663fe3
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 9 deletions.
114 changes: 107 additions & 7 deletions drivers/net/ethernet/netronome/nfp/bpf/jit.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/netronome/nfp/nfp_asm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 },
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/netronome/nfp/nfp_asm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit e663fe3

Please sign in to comment.