mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-28 11:49:32 +00:00
nfp: bpf: direct packet access - write
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>
This commit is contained in:
parent
2ca71441f5
commit
e663fe3863
3 changed files with 109 additions and 9 deletions
|
@ -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,
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue