@@ -847,6 +847,42 @@ static void nfp_bpf_opt_reg_init(struct nfp_prog *nfp_prog)
}
}
+/* Try to rename registers so that program uses only low ones */
+static int nfp_bpf_opt_reg_rename(struct nfp_prog *nfp_prog)
+{
+ bool reg_used[__MAX_BPF_REG] = {};
+ u8 tgt_reg[__MAX_BPF_REG] = {};
+ struct nfp_insn_meta *meta;
+ unsigned int i, j;
+
+ list_for_each_entry(meta, &nfp_prog->insns, l) {
+ if (meta->skip)
+ continue;
+
+ reg_used[meta->insn.src_reg] = true;
+ reg_used[meta->insn.dst_reg] = true;
+ }
+
+ if (reg_used[BPF_REG_10]) {
+ pr_err("Detected use of stack ptr\n");
+ return -EINVAL;
+ }
+
+ for (i = 0, j = 0; i < ARRAY_SIZE(tgt_reg); i++) {
+ if (!reg_used[i])
+ continue;
+
+ tgt_reg[i] = j++;
+ }
+
+ list_for_each_entry(meta, &nfp_prog->insns, l) {
+ meta->insn.src_reg = tgt_reg[meta->insn.src_reg];
+ meta->insn.dst_reg = tgt_reg[meta->insn.dst_reg];
+ }
+
+ return 0;
+}
+
/* Remove masking after load since our load guarantees this is not needed */
static void nfp_bpf_opt_ld_mask(struct nfp_prog *nfp_prog)
{
@@ -921,11 +957,20 @@ static void nfp_bpf_opt_ld_shift(struct nfp_prog *nfp_prog)
}
}
-static void nfp_bpf_optimize(struct nfp_prog *nfp_prog)
+static int nfp_bpf_optimize(struct nfp_prog *nfp_prog)
{
+ int ret;
+
nfp_bpf_opt_reg_init(nfp_prog);
+
+ ret = nfp_bpf_opt_reg_rename(nfp_prog);
+ if (ret)
+ return ret;
+
nfp_bpf_opt_ld_mask(nfp_prog);
nfp_bpf_opt_ld_shift(nfp_prog);
+
+ return 0;
}
/**
@@ -961,7 +1006,9 @@ nfp_bpf_jit(struct bpf_prog *filter, void *prog_mem, unsigned int prog_start,
if (ret)
goto out;
- nfp_bpf_optimize(nfp_prog);
+ ret = nfp_bpf_optimize(nfp_prog);
+ if (ret)
+ goto out;
nfp_prog->prog = prog_mem;
nfp_prog->__prog_alloc_len = prog_sz;