Commit fd068ddc authored by Jakub Kicinski's avatar Jakub Kicinski Committed by David S. Miller

nfp: bpf: calculate code store ECC

In the initial PoC firmware I simply disabled ECC on the instruction
store.  Do the ECC calculation for generated instructions in the driver.
Signed-off-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: default avatarSimon Horman <simon.horman@netronome.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 18e53b6c
...@@ -1715,6 +1715,23 @@ static int nfp_bpf_optimize(struct nfp_prog *nfp_prog) ...@@ -1715,6 +1715,23 @@ static int nfp_bpf_optimize(struct nfp_prog *nfp_prog)
return 0; return 0;
} }
static int nfp_bpf_ustore_calc(struct nfp_prog *nfp_prog)
{
int i;
for (i = 0; i < nfp_prog->prog_len; i++) {
int err;
err = nfp_ustore_check_valid_no_ecc(nfp_prog->prog[i]);
if (err)
return err;
nfp_prog->prog[i] = nfp_ustore_calc_ecc_insn(nfp_prog->prog[i]);
}
return 0;
}
/** /**
* nfp_bpf_jit() - translate BPF code into NFP assembly * nfp_bpf_jit() - translate BPF code into NFP assembly
* @filter: kernel BPF filter struct * @filter: kernel BPF filter struct
...@@ -1766,8 +1783,11 @@ nfp_bpf_jit(struct bpf_prog *filter, void *prog_mem, ...@@ -1766,8 +1783,11 @@ nfp_bpf_jit(struct bpf_prog *filter, void *prog_mem,
pr_err("Translation failed with error %d (translated: %u)\n", pr_err("Translation failed with error %d (translated: %u)\n",
ret, nfp_prog->n_translated); ret, nfp_prog->n_translated);
ret = -EINVAL; ret = -EINVAL;
goto out;
} }
ret = nfp_bpf_ustore_calc(nfp_prog);
res->n_instr = nfp_prog->prog_len; res->n_instr = nfp_prog->prog_len;
res->dense_mode = false; res->dense_mode = false;
out: out:
......
...@@ -215,3 +215,40 @@ int swreg_to_restricted(swreg dst, swreg lreg, swreg rreg, ...@@ -215,3 +215,40 @@ int swreg_to_restricted(swreg dst, swreg lreg, swreg rreg,
return 0; return 0;
} }
#define NFP_USTORE_ECC_POLY_WORDS 7
#define NFP_USTORE_OP_BITS 45
static const u64 nfp_ustore_ecc_polynomials[NFP_USTORE_ECC_POLY_WORDS] = {
0x0ff800007fffULL,
0x11f801ff801fULL,
0x1e387e0781e1ULL,
0x17cb8e388e22ULL,
0x1af5b2c93244ULL,
0x1f56d5525488ULL,
0x0daf69a46910ULL,
};
static bool parity(u64 value)
{
return hweight64(value) & 1;
}
int nfp_ustore_check_valid_no_ecc(u64 insn)
{
if (insn & ~GENMASK_ULL(NFP_USTORE_OP_BITS, 0))
return -EINVAL;
return 0;
}
u64 nfp_ustore_calc_ecc_insn(u64 insn)
{
u8 ecc = 0;
int i;
for (i = 0; i < NFP_USTORE_ECC_POLY_WORDS; i++)
ecc |= parity(nfp_ustore_ecc_polynomials[i] & insn) << i;
return insn | (u64)ecc << NFP_USTORE_OP_BITS;
}
...@@ -362,4 +362,7 @@ int swreg_to_unrestricted(swreg dst, swreg lreg, swreg rreg, ...@@ -362,4 +362,7 @@ int swreg_to_unrestricted(swreg dst, swreg lreg, swreg rreg,
int swreg_to_restricted(swreg dst, swreg lreg, swreg rreg, int swreg_to_restricted(swreg dst, swreg lreg, swreg rreg,
struct nfp_insn_re_regs *reg, bool has_imm8); struct nfp_insn_re_regs *reg, bool has_imm8);
int nfp_ustore_check_valid_no_ecc(u64 insn);
u64 nfp_ustore_calc_ecc_insn(u64 insn);
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment