mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-30 08:02:30 +00:00
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: 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
18e53b6cb9
commit
fd068ddc88
3 changed files with 60 additions and 0 deletions
|
@ -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,
|
||||||
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,
|
||||||
|
|
||||||
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,
|
||||||
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
|
||||||
|
|
Loading…
Reference in a new issue