]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
nfp: bpf: calculate code store ECC
authorJakub Kicinski <jakub.kicinski@netronome.com>
Mon, 9 Oct 2017 04:04:14 +0000 (21:04 -0700)
committerDavid S. Miller <davem@davemloft.net>
Mon, 9 Oct 2017 16:51:03 +0000 (09:51 -0700)
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>
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 9b6c98ccebfe93499dd6f0f4eb36811aeaeea828..f4aedc89bfc8e1536e6e782d19db2916711c909c 100644 (file)
@@ -1715,6 +1715,23 @@ static int nfp_bpf_optimize(struct nfp_prog *nfp_prog)
        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
  * @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",
                       ret, nfp_prog->n_translated);
                ret = -EINVAL;
+               goto out;
        }
 
+       ret = nfp_bpf_ustore_calc(nfp_prog);
+
        res->n_instr = nfp_prog->prog_len;
        res->dense_mode = false;
 out:
index 1decc638ea6f74ee3a59475353d36c758c8f1ac9..de76e7444fc2305f056a3cebb555c0d20ad15006 100644 (file)
@@ -215,3 +215,40 @@ int swreg_to_restricted(swreg dst, swreg lreg, swreg rreg,
 
        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;
+}
index 40a51a45afd79444606cb8199fb4fffc3cb14c86..d95087e5fb7320fba559aea0cf39386521393fad 100644 (file)
@@ -362,4 +362,7 @@ int swreg_to_unrestricted(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);
 
+int nfp_ustore_check_valid_no_ecc(u64 insn);
+u64 nfp_ustore_calc_ecc_insn(u64 insn);
+
 #endif