Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

uprobe: uretprobe speed up #7072

Closed

Commits on May 21, 2024

  1. x86/shstk: Make return uprobe work with shadow stack

    Currently the application with enabled shadow stack will crash
    if it sets up return uprobe. The reason is the uretprobe kernel
    code changes the user space task's stack, but does not update
    shadow stack accordingly.
    
    Adding new functions to update values on shadow stack and using
    them in uprobe code to keep shadow stack in sync with uretprobe
    changes to user stack.
    
    Fixes: 8b1c23543436 ("x86/shstk: Add return uprobe support")
    Signed-off-by: Jiri Olsa <jolsa@kernel.org>
    Reviewed-by: Oleg Nesterov <oleg@redhat.com>
    olsajiri authored and Kernel Patches Daemon committed May 21, 2024
    Configuration menu
    Copy the full SHA
    8ace528 View commit details
    Browse the repository at this point in the history
  2. uprobe: Wire up uretprobe system call

    Wiring up uretprobe system call, which comes in following changes.
    We need to do the wiring before, because the uretprobe implementation
    needs the syscall number.
    
    Note at the moment uretprobe syscall is supported only for native
    64-bit process.
    
    Reviewed-by: Oleg Nesterov <oleg@redhat.com>
    Reviewed-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
    Acked-by: Andrii Nakryiko <andrii@kernel.org>
    Signed-off-by: Jiri Olsa <jolsa@kernel.org>
    olsajiri authored and Kernel Patches Daemon committed May 21, 2024
    Configuration menu
    Copy the full SHA
    5fea280 View commit details
    Browse the repository at this point in the history
  3. uprobe: Add uretprobe syscall to speed up return probe

    Adding uretprobe syscall instead of trap to speed up return probe.
    
    At the moment the uretprobe setup/path is:
    
      - install entry uprobe
    
      - when the uprobe is hit, it overwrites probed function's return address
        on stack with address of the trampoline that contains breakpoint
        instruction
    
      - the breakpoint trap code handles the uretprobe consumers execution and
        jumps back to original return address
    
    This patch replaces the above trampoline's breakpoint instruction with new
    ureprobe syscall call. This syscall does exactly the same job as the trap
    with some more extra work:
    
      - syscall trampoline must save original value for rax/r11/rcx registers
        on stack - rax is set to syscall number and r11/rcx are changed and
        used by syscall instruction
    
      - the syscall code reads the original values of those registers and
        restore those values in task's pt_regs area
    
      - only caller from trampoline exposed in '[uprobes]' is allowed,
        the process will receive SIGILL signal otherwise
    
    Even with some extra work, using the uretprobes syscall shows speed
    improvement (compared to using standard breakpoint):
    
      On Intel (11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz)
    
      current:
        uretprobe-nop  :    1.498 ± 0.000M/s
        uretprobe-push :    1.448 ± 0.001M/s
        uretprobe-ret  :    0.816 ± 0.001M/s
    
      with the fix:
        uretprobe-nop  :    1.969 ± 0.002M/s  < 31% speed up
        uretprobe-push :    1.910 ± 0.000M/s  < 31% speed up
        uretprobe-ret  :    0.934 ± 0.000M/s  < 14% speed up
    
      On Amd (AMD Ryzen 7 5700U)
    
      current:
        uretprobe-nop  :    0.778 ± 0.001M/s
        uretprobe-push :    0.744 ± 0.001M/s
        uretprobe-ret  :    0.540 ± 0.001M/s
    
      with the fix:
        uretprobe-nop  :    0.860 ± 0.001M/s  < 10% speed up
        uretprobe-push :    0.818 ± 0.001M/s  < 10% speed up
        uretprobe-ret  :    0.578 ± 0.000M/s  <  7% speed up
    
    The performance test spawns a thread that runs loop which triggers
    uprobe with attached bpf program that increments the counter that
    gets printed in results above.
    
    The uprobe (and uretprobe) kind is determined by which instruction
    is being patched with breakpoint instruction. That's also important
    for uretprobes, because uprobe is installed for each uretprobe.
    
    The performance test is part of bpf selftests:
      tools/testing/selftests/bpf/run_bench_uprobes.sh
    
    Note at the moment uretprobe syscall is supported only for native
    64-bit process, compat process still uses standard breakpoint.
    
    Note that when shadow stack is enabled the uretprobe syscall returns
    via iret, which is slower than return via sysret, but won't cause the
    shadow stack violation.
    
    Suggested-by: Andrii Nakryiko <andrii@kernel.org>
    Reviewed-by: Oleg Nesterov <oleg@redhat.com>
    Reviewed-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
    Acked-by: Andrii Nakryiko <andrii@kernel.org>
    Signed-off-by: Oleg Nesterov <oleg@redhat.com>
    Signed-off-by: Jiri Olsa <jolsa@kernel.org>
    olsajiri authored and Kernel Patches Daemon committed May 21, 2024
    Configuration menu
    Copy the full SHA
    692ec2e View commit details
    Browse the repository at this point in the history
  4. selftests/x86: Add return uprobe shadow stack test

    Adding return uprobe test for shadow stack and making sure it's
    working properly. Borrowed some of the code from bpf selftests.
    
    Signed-off-by: Jiri Olsa <jolsa@kernel.org>
    olsajiri authored and Kernel Patches Daemon committed May 21, 2024
    Configuration menu
    Copy the full SHA
    7daa81c View commit details
    Browse the repository at this point in the history
  5. selftests/bpf: Add uretprobe syscall test for regs integrity

    Add uretprobe syscall test that compares register values before
    and after the uretprobe is hit. It also compares the register
    values seen from attached bpf program.
    
    Acked-by: Andrii Nakryiko <andrii@kernel.org>
    Reviewed-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
    Signed-off-by: Jiri Olsa <jolsa@kernel.org>
    olsajiri authored and Kernel Patches Daemon committed May 21, 2024
    Configuration menu
    Copy the full SHA
    504e1c9 View commit details
    Browse the repository at this point in the history
  6. selftests/bpf: Add uretprobe syscall test for regs changes

    Adding test that creates uprobe consumer on uretprobe which changes some
    of the registers. Making sure the changed registers are propagated to the
    user space when the ureptobe syscall trampoline is used on x86_64.
    
    To be able to do this, adding support to bpf_testmod to create uprobe via
    new attribute file:
      /sys/kernel/bpf_testmod_uprobe
    
    This file is expecting file offset and creates related uprobe on current
    process exe file and removes existing uprobe if offset is 0. The can be
    only single uprobe at any time.
    
    The uprobe has specific consumer that changes registers used in ureprobe
    syscall trampoline and which are later checked in the test.
    
    Acked-by: Andrii Nakryiko <andrii@kernel.org>
    Reviewed-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
    Signed-off-by: Jiri Olsa <jolsa@kernel.org>
    olsajiri authored and Kernel Patches Daemon committed May 21, 2024
    Configuration menu
    Copy the full SHA
    3afdeff View commit details
    Browse the repository at this point in the history
  7. selftests/bpf: Add uretprobe syscall call from user space test

    Adding test to verify that when called from outside of the
    trampoline provided by kernel, the uretprobe syscall will cause
    calling process to receive SIGILL signal and the attached bpf
    program is not executed.
    
    Acked-by: Andrii Nakryiko <andrii@kernel.org>
    Reviewed-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
    Signed-off-by: Jiri Olsa <jolsa@kernel.org>
    olsajiri authored and Kernel Patches Daemon committed May 21, 2024
    Configuration menu
    Copy the full SHA
    6e37f2e View commit details
    Browse the repository at this point in the history
  8. selftests/bpf: Add uretprobe shadow stack test

    Adding uretprobe shadow stack test that runs all existing
    uretprobe tests with shadow stack enabled if it's available.
    
    Signed-off-by: Jiri Olsa <jolsa@kernel.org>
    olsajiri authored and Kernel Patches Daemon committed May 21, 2024
    Configuration menu
    Copy the full SHA
    ec6beae View commit details
    Browse the repository at this point in the history
  9. man2: Add uretprobe syscall page

    Adding man page for new uretprobe syscall.
    
    Signed-off-by: Jiri Olsa <jolsa@kernel.org>
    olsajiri authored and Kernel Patches Daemon committed May 21, 2024
    Configuration menu
    Copy the full SHA
    891bd81 View commit details
    Browse the repository at this point in the history