bpf, x86: Store caller's ip in trampoline stack
authorJiri Olsa <jolsa@redhat.com>
Wed, 14 Jul 2021 09:43:53 +0000 (11:43 +0200)
committerAlexei Starovoitov <ast@kernel.org>
Fri, 16 Jul 2021 00:16:06 +0000 (17:16 -0700)
Storing caller's ip in trampoline's stack. Trampoline programs
can reach the IP in (ctx - 8) address, so there's no change in
program's arguments interface.

The IP address is takes from [fp + 8], which is return address
from the initial 'call fentry' call to trampoline.

This IP address will be returned via bpf_get_func_ip helper
helper, which is added in following patches.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/bpf/20210714094400.396467-2-jolsa@kernel.org
arch/x86/net/bpf_jit_comp.c
include/linux/bpf.h

index e835164..c320b3c 100644 (file)
@@ -1951,6 +1951,9 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i
        if (flags & BPF_TRAMP_F_CALL_ORIG)
                stack_size += 8; /* room for return value of orig_call */
 
+       if (flags & BPF_TRAMP_F_IP_ARG)
+               stack_size += 8; /* room for IP address argument */
+
        if (flags & BPF_TRAMP_F_SKIP_FRAME)
                /* skip patched call instruction and point orig_call to actual
                 * body of the kernel function.
@@ -1964,6 +1967,22 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i
        EMIT4(0x48, 0x83, 0xEC, stack_size); /* sub rsp, stack_size */
        EMIT1(0x53);             /* push rbx */
 
+       if (flags & BPF_TRAMP_F_IP_ARG) {
+               /* Store IP address of the traced function:
+                * mov rax, QWORD PTR [rbp + 8]
+                * sub rax, X86_PATCH_SIZE
+                * mov QWORD PTR [rbp - stack_size], rax
+                */
+               emit_ldx(&prog, BPF_DW, BPF_REG_0, BPF_REG_FP, 8);
+               EMIT4(0x48, 0x83, 0xe8, X86_PATCH_SIZE);
+               emit_stx(&prog, BPF_DW, BPF_REG_FP, BPF_REG_0, -stack_size);
+
+               /* Continue with stack_size for regs storage, stack will
+                * be correctly restored with 'leave' instruction.
+                */
+               stack_size -= 8;
+       }
+
        save_regs(m, &prog, nr_args, stack_size);
 
        if (flags & BPF_TRAMP_F_CALL_ORIG) {
index a9a4a48..94d77dc 100644 (file)
@@ -579,6 +579,11 @@ struct btf_func_model {
  */
 #define BPF_TRAMP_F_SKIP_FRAME         BIT(2)
 
+/* Store IP address of the caller on the trampoline stack,
+ * so it's available for trampoline's programs.
+ */
+#define BPF_TRAMP_F_IP_ARG             BIT(3)
+
 /* Each call __bpf_prog_enter + call bpf_func + call __bpf_prog_exit is ~50
  * bytes on x86.  Pick a number to fit into BPF_IMAGE_SIZE / 2
  */