summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/netronome/nfp/bpf/verifier.c
diff options
context:
space:
mode:
authorJakub Kicinski2017-10-23 20:58:11 +0200
committerDavid S. Miller2017-10-24 10:38:37 +0200
commitd3488480635f453410fd27cea3fc370cedc7e28a (patch)
tree0cff71e73b2b9affc46425378aa80a88c21b0a3a /drivers/net/ethernet/netronome/nfp/bpf/verifier.c
parentnfp: bpf: optimize the RMW for stack accesses (diff)
downloadkernel-qcow2-linux-d3488480635f453410fd27cea3fc370cedc7e28a.tar.gz
kernel-qcow2-linux-d3488480635f453410fd27cea3fc370cedc7e28a.tar.xz
kernel-qcow2-linux-d3488480635f453410fd27cea3fc370cedc7e28a.zip
nfp: bpf: allow stack accesses via modified stack registers
As long as the verifier tells us the stack offset exactly we can render the LMEM reads quite easily. Simply make sure that the offset is constant for a given instruction and add it to the instruction's offset. Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com> Reviewed-by: Quentin Monnet <quentin.monnet@netronome.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/netronome/nfp/bpf/verifier.c')
-rw-r--r--drivers/net/ethernet/netronome/nfp/bpf/verifier.c24
1 files changed, 17 insertions, 7 deletions
diff --git a/drivers/net/ethernet/netronome/nfp/bpf/verifier.c b/drivers/net/ethernet/netronome/nfp/bpf/verifier.c
index 376d9938b823..633db3e1a11e 100644
--- a/drivers/net/ethernet/netronome/nfp/bpf/verifier.c
+++ b/drivers/net/ethernet/netronome/nfp/bpf/verifier.c
@@ -111,19 +111,29 @@ nfp_bpf_check_exit(struct nfp_prog *nfp_prog,
return 0;
}
-static int nfp_bpf_check_stack_access(const struct bpf_reg_state *reg)
+static int
+nfp_bpf_check_stack_access(struct nfp_insn_meta *meta,
+ const struct bpf_reg_state *reg)
{
+ s32 old_off, new_off;
+
if (!tnum_is_const(reg->var_off)) {
pr_info("variable ptr stack access\n");
return -EINVAL;
}
- if (reg->var_off.value || reg->off) {
- pr_info("stack access via modified register\n");
- return -EINVAL;
- }
+ if (meta->ptr.type == NOT_INIT)
+ return 0;
- return 0;
+ old_off = meta->ptr.off + meta->ptr.var_off.value;
+ new_off = reg->off + reg->var_off.value;
+
+ if (old_off == new_off)
+ return 0;
+
+ pr_info("stack access changed location was:%d is:%d\n",
+ old_off, new_off);
+ return -EINVAL;
}
static int
@@ -141,7 +151,7 @@ nfp_bpf_check_ptr(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta,
}
if (reg->type == PTR_TO_STACK) {
- err = nfp_bpf_check_stack_access(reg);
+ err = nfp_bpf_check_stack_access(meta, reg);
if (err)
return err;
}