Merge tag 'dt-5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc
[linux-2.6-microblaze.git] / arch / x86 / net / bpf_jit_comp.c
index 16d76f8..0fe6aac 100644 (file)
@@ -1961,6 +1961,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.
@@ -1974,6 +1977,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) {