summaryrefslogtreecommitdiff
path: root/samples
diff options
context:
space:
mode:
authorAlexei Starovoitov <ast@plumgrid.com>2015-05-20 02:59:04 +0300
committerDavid S. Miller <davem@davemloft.net>2015-05-22 00:07:59 +0300
commitb52f00e6a7154308a08d0a2edab621f277801a2c (patch)
treebc237fc42afe6082173e9eee6e1a8bddaf7917fa /samples
parent04fd61ab36ec065e194ab5e74ae34a5240d992bb (diff)
downloadlinux-b52f00e6a7154308a08d0a2edab621f277801a2c.tar.xz
x86: bpf_jit: implement bpf_tail_call() helper
bpf_tail_call() arguments: ctx - context pointer jmp_table - one of BPF_MAP_TYPE_PROG_ARRAY maps used as the jump table index - index in the jump table In this implementation x64 JIT bypasses stack unwind and jumps into the callee program after prologue, so the callee program reuses the same stack. The logic can be roughly expressed in C like: u32 tail_call_cnt; void *jumptable[2] = { &&label1, &&label2 }; int bpf_prog1(void *ctx) { label1: ... } int bpf_prog2(void *ctx) { label2: ... } int bpf_prog1(void *ctx) { ... if (tail_call_cnt++ < MAX_TAIL_CALL_CNT) goto *jumptable[index]; ... and pass my 'ctx' to callee ... ... fall through if no entry in jumptable ... } Note that 'skip current program epilogue and next program prologue' is an optimization. Other JITs don't have to do it the same way. >From safety point of view it's valid as well, since programs always initialize the stack before use, so any residue in the stack left by the current program is not going be read. The same verifier checks are done for the calls from the kernel into all bpf programs. Signed-off-by: Alexei Starovoitov <ast@plumgrid.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'samples')
0 files changed, 0 insertions, 0 deletions