* [PATCH bpf 0/4] kprobes: rethook, ARM, arm64: Replace kretprobe trampoline with rethook @ 2022-04-05 9:33 ` Masami Hiramatsu 0 siblings, 0 replies; 16+ messages in thread From: Masami Hiramatsu @ 2022-04-05 9:33 UTC (permalink / raw) To: Alexei Starovoitov, Alexei Starovoitov Cc: Daniel Borkmann, Shubham Bansal, Andrii Nakryiko, Masami Hiramatsu, bpf, kernel-team, Jiri Olsa, Steven Rostedt, Naveen N . Rao, Anil S Keshavamurthy, David S . Miller, linux-kernel, Mark Rutland, Will Deacon, Ard Biesheuvel, Russell King, Catalin Marinas, linux-arm-kernel Hello, Here is a series for replacing kretprobe trampoline with rethook on ARM/arm64. This series are applicable to bpf tree (not arm tree) because the basement patch is still only on that tree. Actually, this series includes a trivial bugfix for the arm unwinder to initialize an internal data structure([1/4]). This is not critical for stack trace, but required for rethook to find LR register on the stack. This also have an update for the rethook interface, which allows us to check the rethook_hook() failure ([2/4]). This is also required for the rethook on arm because unwinder is able to fail. The rest of patches are replacing kretprobe trampoline with rethook on ARM ([3/4]) and arm64 ([4/4]). Background: This rethook came from Jiri's request of multiple kprobe for bpf[1]. He tried to solve an issue that starting bpf with multiple kprobe will take a long time because bpf-kprobe will wait for RCU grace period for sync rcu events. Jiri wanted to attach a single bpf handler to multiple kprobes and he tried to introduce multiple-probe interface to kprobe. So I asked him to use ftrace and kretprobe-like hook if it is only for the function entry and exit, instead of adding ad-hoc interface to kprobes. For this purpose, I introduced the fprobe (kprobe like interface for ftrace) with the rethook (this is a generic return hook feature for fprobe exit handler)[2]. [1] https://lore.kernel.org/all/20220104080943.113249-1-jolsa@kernel.org/T/#u [2] https://lore.kernel.org/all/164191321766.806991.7930388561276940676.stgit@devnote2/T/#u The rethook is basically same as the kretprobe trampoline. I just made it decoupled from kprobes. Eventually, the all arch dependent kretprobe trampolines will be replaced with the rethook trampoline instead of cloning the code. When I port the rethook for all arch which supports kretprobe, the legacy kretprobe specific code (which is for CONFIG_KRETPROBE_ON_RETHOOK=n) will be removed eventually. BTW, the arm Clang support for rethook is for kretprobes only. fprobe and ftrace seems not working with Clang yet. Thank you, --- Masami Hiramatsu (4): ARM: unwind: Initialize the lr_addr field of unwind_ctrl_block rethook,fprobe,kprobes: Check a failure in the rethook_hook() ARM: rethook: Replace kretprobe trampoline with rethook arm64: rethook: Replace kretprobe trampoline with rethook arch/arm/Kconfig | 1 arch/arm/include/asm/stacktrace.h | 5 + arch/arm/kernel/stacktrace.c | 13 +-- arch/arm/kernel/unwind.c | 1 arch/arm/probes/Makefile | 1 arch/arm/probes/kprobes/core.c | 62 ------------ arch/arm/probes/rethook.c | 127 +++++++++++++++++++++++++ arch/arm64/Kconfig | 1 arch/arm64/include/asm/kprobes.h | 2 arch/arm64/include/asm/stacktrace.h | 2 arch/arm64/kernel/Makefile | 1 arch/arm64/kernel/probes/Makefile | 1 arch/arm64/kernel/probes/kprobes.c | 15 --- arch/arm64/kernel/probes/kprobes_trampoline.S | 86 ----------------- arch/arm64/kernel/rethook.c | 26 +++++ arch/arm64/kernel/rethook_trampoline.S | 87 +++++++++++++++++ arch/arm64/kernel/stacktrace.c | 9 +- arch/x86/kernel/rethook.c | 4 + include/linux/rethook.h | 4 - kernel/kprobes.c | 8 +- kernel/trace/fprobe.c | 5 + kernel/trace/rethook.c | 12 ++ 22 files changed, 285 insertions(+), 188 deletions(-) create mode 100644 arch/arm/probes/rethook.c delete mode 100644 arch/arm64/kernel/probes/kprobes_trampoline.S create mode 100644 arch/arm64/kernel/rethook.c create mode 100644 arch/arm64/kernel/rethook_trampoline.S -- Masami Hiramatsu (Linaro) <mhiramat@kernel.org> _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH bpf 0/4] kprobes: rethook,ARM,arm64: Replace kretprobe trampoline with rethook @ 2022-04-05 9:33 ` Masami Hiramatsu 0 siblings, 0 replies; 16+ messages in thread From: Masami Hiramatsu @ 2022-04-05 9:33 UTC (permalink / raw) To: Alexei Starovoitov, Alexei Starovoitov Cc: Daniel Borkmann, Shubham Bansal, Andrii Nakryiko, Masami Hiramatsu, bpf, kernel-team, Jiri Olsa, Steven Rostedt, Naveen N . Rao, Anil S Keshavamurthy, David S . Miller, linux-kernel, Mark Rutland, Will Deacon, Ard Biesheuvel, Russell King, Catalin Marinas, linux-arm-kernel Hello, Here is a series for replacing kretprobe trampoline with rethook on ARM/arm64. This series are applicable to bpf tree (not arm tree) because the basement patch is still only on that tree. Actually, this series includes a trivial bugfix for the arm unwinder to initialize an internal data structure([1/4]). This is not critical for stack trace, but required for rethook to find LR register on the stack. This also have an update for the rethook interface, which allows us to check the rethook_hook() failure ([2/4]). This is also required for the rethook on arm because unwinder is able to fail. The rest of patches are replacing kretprobe trampoline with rethook on ARM ([3/4]) and arm64 ([4/4]). Background: This rethook came from Jiri's request of multiple kprobe for bpf[1]. He tried to solve an issue that starting bpf with multiple kprobe will take a long time because bpf-kprobe will wait for RCU grace period for sync rcu events. Jiri wanted to attach a single bpf handler to multiple kprobes and he tried to introduce multiple-probe interface to kprobe. So I asked him to use ftrace and kretprobe-like hook if it is only for the function entry and exit, instead of adding ad-hoc interface to kprobes. For this purpose, I introduced the fprobe (kprobe like interface for ftrace) with the rethook (this is a generic return hook feature for fprobe exit handler)[2]. [1] https://lore.kernel.org/all/20220104080943.113249-1-jolsa@kernel.org/T/#u [2] https://lore.kernel.org/all/164191321766.806991.7930388561276940676.stgit@devnote2/T/#u The rethook is basically same as the kretprobe trampoline. I just made it decoupled from kprobes. Eventually, the all arch dependent kretprobe trampolines will be replaced with the rethook trampoline instead of cloning the code. When I port the rethook for all arch which supports kretprobe, the legacy kretprobe specific code (which is for CONFIG_KRETPROBE_ON_RETHOOK=n) will be removed eventually. BTW, the arm Clang support for rethook is for kretprobes only. fprobe and ftrace seems not working with Clang yet. Thank you, --- Masami Hiramatsu (4): ARM: unwind: Initialize the lr_addr field of unwind_ctrl_block rethook,fprobe,kprobes: Check a failure in the rethook_hook() ARM: rethook: Replace kretprobe trampoline with rethook arm64: rethook: Replace kretprobe trampoline with rethook arch/arm/Kconfig | 1 arch/arm/include/asm/stacktrace.h | 5 + arch/arm/kernel/stacktrace.c | 13 +-- arch/arm/kernel/unwind.c | 1 arch/arm/probes/Makefile | 1 arch/arm/probes/kprobes/core.c | 62 ------------ arch/arm/probes/rethook.c | 127 +++++++++++++++++++++++++ arch/arm64/Kconfig | 1 arch/arm64/include/asm/kprobes.h | 2 arch/arm64/include/asm/stacktrace.h | 2 arch/arm64/kernel/Makefile | 1 arch/arm64/kernel/probes/Makefile | 1 arch/arm64/kernel/probes/kprobes.c | 15 --- arch/arm64/kernel/probes/kprobes_trampoline.S | 86 ----------------- arch/arm64/kernel/rethook.c | 26 +++++ arch/arm64/kernel/rethook_trampoline.S | 87 +++++++++++++++++ arch/arm64/kernel/stacktrace.c | 9 +- arch/x86/kernel/rethook.c | 4 + include/linux/rethook.h | 4 - kernel/kprobes.c | 8 +- kernel/trace/fprobe.c | 5 + kernel/trace/rethook.c | 12 ++ 22 files changed, 285 insertions(+), 188 deletions(-) create mode 100644 arch/arm/probes/rethook.c delete mode 100644 arch/arm64/kernel/probes/kprobes_trampoline.S create mode 100644 arch/arm64/kernel/rethook.c create mode 100644 arch/arm64/kernel/rethook_trampoline.S -- Masami Hiramatsu (Linaro) <mhiramat@kernel.org> ^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH bpf 1/4] ARM: unwind: Initialize the lr_addr field of unwind_ctrl_block 2022-04-05 9:33 ` [PATCH bpf 0/4] kprobes: rethook,ARM,arm64: " Masami Hiramatsu @ 2022-04-05 9:33 ` Masami Hiramatsu -1 siblings, 0 replies; 16+ messages in thread From: Masami Hiramatsu @ 2022-04-05 9:33 UTC (permalink / raw) To: Alexei Starovoitov, Alexei Starovoitov Cc: Daniel Borkmann, Shubham Bansal, Andrii Nakryiko, Masami Hiramatsu, bpf, kernel-team, Jiri Olsa, Steven Rostedt, Naveen N . Rao, Anil S Keshavamurthy, David S . Miller, linux-kernel, Mark Rutland, Will Deacon, Ard Biesheuvel, Russell King, Catalin Marinas, linux-arm-kernel Since the unwind_ctrl_block::lr_addr is finally passed to stackframe::lr_addr, that value will be exposed unconditionally. Thus it should be initialized. Without this fix, when unwind_frame() doesn't update the unwind_ctrl_block::lr_addr (e.g. 'lr' register is not saved in the target function), stackframe::lr_addr will contain a wrong value. Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org> --- arch/arm/kernel/unwind.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c index a37ea6c772cd..93e767682cf4 100644 --- a/arch/arm/kernel/unwind.c +++ b/arch/arm/kernel/unwind.c @@ -404,6 +404,7 @@ int unwind_frame(struct stackframe *frame) ctrl.vrs[SP] = frame->sp; ctrl.vrs[LR] = frame->lr; ctrl.vrs[PC] = 0; + ctrl.lr_addr = 0; if (idx->insn == 1) /* can't unwind */ _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH bpf 1/4] ARM: unwind: Initialize the lr_addr field of unwind_ctrl_block @ 2022-04-05 9:33 ` Masami Hiramatsu 0 siblings, 0 replies; 16+ messages in thread From: Masami Hiramatsu @ 2022-04-05 9:33 UTC (permalink / raw) To: Alexei Starovoitov, Alexei Starovoitov Cc: Daniel Borkmann, Shubham Bansal, Andrii Nakryiko, Masami Hiramatsu, bpf, kernel-team, Jiri Olsa, Steven Rostedt, Naveen N . Rao, Anil S Keshavamurthy, David S . Miller, linux-kernel, Mark Rutland, Will Deacon, Ard Biesheuvel, Russell King, Catalin Marinas, linux-arm-kernel Since the unwind_ctrl_block::lr_addr is finally passed to stackframe::lr_addr, that value will be exposed unconditionally. Thus it should be initialized. Without this fix, when unwind_frame() doesn't update the unwind_ctrl_block::lr_addr (e.g. 'lr' register is not saved in the target function), stackframe::lr_addr will contain a wrong value. Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org> --- arch/arm/kernel/unwind.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c index a37ea6c772cd..93e767682cf4 100644 --- a/arch/arm/kernel/unwind.c +++ b/arch/arm/kernel/unwind.c @@ -404,6 +404,7 @@ int unwind_frame(struct stackframe *frame) ctrl.vrs[SP] = frame->sp; ctrl.vrs[LR] = frame->lr; ctrl.vrs[PC] = 0; + ctrl.lr_addr = 0; if (idx->insn == 1) /* can't unwind */ ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH bpf 1/4] ARM: unwind: Initialize the lr_addr field of unwind_ctrl_block 2022-04-05 9:33 ` Masami Hiramatsu @ 2022-04-06 18:53 ` kernel test robot -1 siblings, 0 replies; 16+ messages in thread From: kernel test robot @ 2022-04-06 18:53 UTC (permalink / raw) To: Masami Hiramatsu, Alexei Starovoitov Cc: kbuild-all, Daniel Borkmann, Shubham Bansal, Andrii Nakryiko, Masami Hiramatsu, bpf, kernel-team, Jiri Olsa, Steven Rostedt, Naveen N . Rao, Anil S Keshavamurthy, David S . Miller, linux-kernel, Mark Rutland, Will Deacon, Ard Biesheuvel, Russell King, Catalin Marinas, linux-arm-kernel Hi Masami, I love your patch! Perhaps something to improve: [auto build test WARNING on bpf/master] url: https://github.com/intel-lab-lkp/linux/commits/Masami-Hiramatsu/kprobes-rethook-ARM-arm64-Replace-kretprobe-trampoline-with-rethook/20220405-195153 base: https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git master config: arm-randconfig-s032-20220406 (https://download.01.org/0day-ci/archive/20220407/202204070204.g3wpjuJi-lkp@intel.com/config) compiler: arm-linux-gnueabi-gcc (GCC) 11.2.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # apt-get install sparse # sparse version: v0.6.4-dirty # https://github.com/intel-lab-lkp/linux/commit/99971b0c57ce1501eda858656ed06758bbd4e376 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Masami-Hiramatsu/kprobes-rethook-ARM-arm64-Replace-kretprobe-trampoline-with-rethook/20220405-195153 git checkout 99971b0c57ce1501eda858656ed06758bbd4e376 # save the config file to linux build tree mkdir build_dir COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=arm SHELL=/bin/bash arch/arm/kernel/ If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> sparse warnings: (new ones prefixed by >>) >> arch/arm/kernel/unwind.c:407:24: sparse: sparse: Using plain integer as NULL pointer vim +407 arch/arm/kernel/unwind.c 377 378 /* 379 * Unwind a single frame starting with *sp for the symbol at *pc. It 380 * updates the *pc and *sp with the new values. 381 */ 382 int unwind_frame(struct stackframe *frame) 383 { 384 const struct unwind_idx *idx; 385 struct unwind_ctrl_block ctrl; 386 unsigned long sp_low; 387 388 /* store the highest address on the stack to avoid crossing it*/ 389 sp_low = frame->sp; 390 ctrl.sp_high = ALIGN(sp_low - THREAD_SIZE, THREAD_ALIGN) 391 + THREAD_SIZE; 392 393 pr_debug("%s(pc = %08lx lr = %08lx sp = %08lx)\n", __func__, 394 frame->pc, frame->lr, frame->sp); 395 396 idx = unwind_find_idx(frame->pc); 397 if (!idx) { 398 if (frame->pc && kernel_text_address(frame->pc)) 399 pr_warn("unwind: Index not found %08lx\n", frame->pc); 400 return -URC_FAILURE; 401 } 402 403 ctrl.vrs[FP] = frame->fp; 404 ctrl.vrs[SP] = frame->sp; 405 ctrl.vrs[LR] = frame->lr; 406 ctrl.vrs[PC] = 0; > 407 ctrl.lr_addr = 0; 408 409 if (idx->insn == 1) 410 /* can't unwind */ 411 return -URC_FAILURE; 412 else if (frame->pc == prel31_to_addr(&idx->addr_offset)) { 413 /* 414 * Unwinding is tricky when we're halfway through the prologue, 415 * since the stack frame that the unwinder expects may not be 416 * fully set up yet. However, one thing we do know for sure is 417 * that if we are unwinding from the very first instruction of 418 * a function, we are still effectively in the stack frame of 419 * the caller, and the unwind info has no relevance yet. 420 */ 421 if (frame->pc == frame->lr) 422 return -URC_FAILURE; 423 frame->pc = frame->lr; 424 return URC_OK; 425 } else if ((idx->insn & 0x80000000) == 0) 426 /* prel31 to the unwind table */ 427 ctrl.insn = (unsigned long *)prel31_to_addr(&idx->insn); 428 else if ((idx->insn & 0xff000000) == 0x80000000) 429 /* only personality routine 0 supported in the index */ 430 ctrl.insn = &idx->insn; 431 else { 432 pr_warn("unwind: Unsupported personality routine %08lx in the index at %p\n", 433 idx->insn, idx); 434 return -URC_FAILURE; 435 } 436 437 /* check the personality routine */ 438 if ((*ctrl.insn & 0xff000000) == 0x80000000) { 439 ctrl.byte = 2; 440 ctrl.entries = 1; 441 } else if ((*ctrl.insn & 0xff000000) == 0x81000000) { 442 ctrl.byte = 1; 443 ctrl.entries = 1 + ((*ctrl.insn & 0x00ff0000) >> 16); 444 } else { 445 pr_warn("unwind: Unsupported personality routine %08lx at %p\n", 446 *ctrl.insn, ctrl.insn); 447 return -URC_FAILURE; 448 } 449 450 ctrl.check_each_pop = 0; 451 452 if (prel31_to_addr(&idx->addr_offset) == (u32)&call_with_stack) { 453 /* 454 * call_with_stack() is the only place where we permit SP to 455 * jump from one stack to another, and since we know it is 456 * guaranteed to happen, set up the SP bounds accordingly. 457 */ 458 sp_low = frame->fp; 459 ctrl.sp_high = ALIGN(frame->fp, THREAD_SIZE); 460 } 461 462 while (ctrl.entries > 0) { 463 int urc; 464 if ((ctrl.sp_high - ctrl.vrs[SP]) < sizeof(ctrl.vrs)) 465 ctrl.check_each_pop = 1; 466 urc = unwind_exec_insn(&ctrl); 467 if (urc < 0) 468 return urc; 469 if (ctrl.vrs[SP] < sp_low || ctrl.vrs[SP] > ctrl.sp_high) 470 return -URC_FAILURE; 471 } 472 473 if (ctrl.vrs[PC] == 0) 474 ctrl.vrs[PC] = ctrl.vrs[LR]; 475 476 /* check for infinite loop */ 477 if (frame->pc == ctrl.vrs[PC] && frame->sp == ctrl.vrs[SP]) 478 return -URC_FAILURE; 479 480 frame->fp = ctrl.vrs[FP]; 481 frame->sp = ctrl.vrs[SP]; 482 frame->lr = ctrl.vrs[LR]; 483 frame->pc = ctrl.vrs[PC]; 484 frame->lr_addr = ctrl.lr_addr; 485 486 return URC_OK; 487 } 488 -- 0-DAY CI Kernel Test Service https://01.org/lkp _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH bpf 1/4] ARM: unwind: Initialize the lr_addr field of unwind_ctrl_block @ 2022-04-06 18:53 ` kernel test robot 0 siblings, 0 replies; 16+ messages in thread From: kernel test robot @ 2022-04-06 18:53 UTC (permalink / raw) To: Masami Hiramatsu, Alexei Starovoitov Cc: kbuild-all, Daniel Borkmann, Shubham Bansal, Andrii Nakryiko, Masami Hiramatsu, bpf, kernel-team, Jiri Olsa, Steven Rostedt, Naveen N . Rao, Anil S Keshavamurthy, David S . Miller, linux-kernel, Mark Rutland, Will Deacon, Ard Biesheuvel, Russell King, Catalin Marinas, linux-arm-kernel Hi Masami, I love your patch! Perhaps something to improve: [auto build test WARNING on bpf/master] url: https://github.com/intel-lab-lkp/linux/commits/Masami-Hiramatsu/kprobes-rethook-ARM-arm64-Replace-kretprobe-trampoline-with-rethook/20220405-195153 base: https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git master config: arm-randconfig-s032-20220406 (https://download.01.org/0day-ci/archive/20220407/202204070204.g3wpjuJi-lkp@intel.com/config) compiler: arm-linux-gnueabi-gcc (GCC) 11.2.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # apt-get install sparse # sparse version: v0.6.4-dirty # https://github.com/intel-lab-lkp/linux/commit/99971b0c57ce1501eda858656ed06758bbd4e376 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Masami-Hiramatsu/kprobes-rethook-ARM-arm64-Replace-kretprobe-trampoline-with-rethook/20220405-195153 git checkout 99971b0c57ce1501eda858656ed06758bbd4e376 # save the config file to linux build tree mkdir build_dir COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=arm SHELL=/bin/bash arch/arm/kernel/ If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> sparse warnings: (new ones prefixed by >>) >> arch/arm/kernel/unwind.c:407:24: sparse: sparse: Using plain integer as NULL pointer vim +407 arch/arm/kernel/unwind.c 377 378 /* 379 * Unwind a single frame starting with *sp for the symbol at *pc. It 380 * updates the *pc and *sp with the new values. 381 */ 382 int unwind_frame(struct stackframe *frame) 383 { 384 const struct unwind_idx *idx; 385 struct unwind_ctrl_block ctrl; 386 unsigned long sp_low; 387 388 /* store the highest address on the stack to avoid crossing it*/ 389 sp_low = frame->sp; 390 ctrl.sp_high = ALIGN(sp_low - THREAD_SIZE, THREAD_ALIGN) 391 + THREAD_SIZE; 392 393 pr_debug("%s(pc = %08lx lr = %08lx sp = %08lx)\n", __func__, 394 frame->pc, frame->lr, frame->sp); 395 396 idx = unwind_find_idx(frame->pc); 397 if (!idx) { 398 if (frame->pc && kernel_text_address(frame->pc)) 399 pr_warn("unwind: Index not found %08lx\n", frame->pc); 400 return -URC_FAILURE; 401 } 402 403 ctrl.vrs[FP] = frame->fp; 404 ctrl.vrs[SP] = frame->sp; 405 ctrl.vrs[LR] = frame->lr; 406 ctrl.vrs[PC] = 0; > 407 ctrl.lr_addr = 0; 408 409 if (idx->insn == 1) 410 /* can't unwind */ 411 return -URC_FAILURE; 412 else if (frame->pc == prel31_to_addr(&idx->addr_offset)) { 413 /* 414 * Unwinding is tricky when we're halfway through the prologue, 415 * since the stack frame that the unwinder expects may not be 416 * fully set up yet. However, one thing we do know for sure is 417 * that if we are unwinding from the very first instruction of 418 * a function, we are still effectively in the stack frame of 419 * the caller, and the unwind info has no relevance yet. 420 */ 421 if (frame->pc == frame->lr) 422 return -URC_FAILURE; 423 frame->pc = frame->lr; 424 return URC_OK; 425 } else if ((idx->insn & 0x80000000) == 0) 426 /* prel31 to the unwind table */ 427 ctrl.insn = (unsigned long *)prel31_to_addr(&idx->insn); 428 else if ((idx->insn & 0xff000000) == 0x80000000) 429 /* only personality routine 0 supported in the index */ 430 ctrl.insn = &idx->insn; 431 else { 432 pr_warn("unwind: Unsupported personality routine %08lx in the index at %p\n", 433 idx->insn, idx); 434 return -URC_FAILURE; 435 } 436 437 /* check the personality routine */ 438 if ((*ctrl.insn & 0xff000000) == 0x80000000) { 439 ctrl.byte = 2; 440 ctrl.entries = 1; 441 } else if ((*ctrl.insn & 0xff000000) == 0x81000000) { 442 ctrl.byte = 1; 443 ctrl.entries = 1 + ((*ctrl.insn & 0x00ff0000) >> 16); 444 } else { 445 pr_warn("unwind: Unsupported personality routine %08lx at %p\n", 446 *ctrl.insn, ctrl.insn); 447 return -URC_FAILURE; 448 } 449 450 ctrl.check_each_pop = 0; 451 452 if (prel31_to_addr(&idx->addr_offset) == (u32)&call_with_stack) { 453 /* 454 * call_with_stack() is the only place where we permit SP to 455 * jump from one stack to another, and since we know it is 456 * guaranteed to happen, set up the SP bounds accordingly. 457 */ 458 sp_low = frame->fp; 459 ctrl.sp_high = ALIGN(frame->fp, THREAD_SIZE); 460 } 461 462 while (ctrl.entries > 0) { 463 int urc; 464 if ((ctrl.sp_high - ctrl.vrs[SP]) < sizeof(ctrl.vrs)) 465 ctrl.check_each_pop = 1; 466 urc = unwind_exec_insn(&ctrl); 467 if (urc < 0) 468 return urc; 469 if (ctrl.vrs[SP] < sp_low || ctrl.vrs[SP] > ctrl.sp_high) 470 return -URC_FAILURE; 471 } 472 473 if (ctrl.vrs[PC] == 0) 474 ctrl.vrs[PC] = ctrl.vrs[LR]; 475 476 /* check for infinite loop */ 477 if (frame->pc == ctrl.vrs[PC] && frame->sp == ctrl.vrs[SP]) 478 return -URC_FAILURE; 479 480 frame->fp = ctrl.vrs[FP]; 481 frame->sp = ctrl.vrs[SP]; 482 frame->lr = ctrl.vrs[LR]; 483 frame->pc = ctrl.vrs[PC]; 484 frame->lr_addr = ctrl.lr_addr; 485 486 return URC_OK; 487 } 488 -- 0-DAY CI Kernel Test Service https://01.org/lkp ^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH bpf 2/4] rethook, fprobe, kprobes: Check a failure in the rethook_hook() 2022-04-05 9:33 ` [PATCH bpf 0/4] kprobes: rethook,ARM,arm64: " Masami Hiramatsu @ 2022-04-05 9:33 ` Masami Hiramatsu -1 siblings, 0 replies; 16+ messages in thread From: Masami Hiramatsu @ 2022-04-05 9:33 UTC (permalink / raw) To: Alexei Starovoitov, Alexei Starovoitov Cc: Daniel Borkmann, Shubham Bansal, Andrii Nakryiko, Masami Hiramatsu, bpf, kernel-team, Jiri Olsa, Steven Rostedt, Naveen N . Rao, Anil S Keshavamurthy, David S . Miller, linux-kernel, Mark Rutland, Will Deacon, Ard Biesheuvel, Russell King, Catalin Marinas, linux-arm-kernel Since there are possible to fail to hook the function return (depends on archtecutre implememtation), rethook_hook() should return the error in that case and caller must check it. Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org> --- arch/x86/kernel/rethook.c | 4 +++- include/linux/rethook.h | 4 ++-- kernel/kprobes.c | 8 +++++--- kernel/trace/fprobe.c | 5 ++++- kernel/trace/rethook.c | 12 ++++++++++-- 5 files changed, 24 insertions(+), 9 deletions(-) diff --git a/arch/x86/kernel/rethook.c b/arch/x86/kernel/rethook.c index 8a1c0111ae79..c92b4875e3b9 100644 --- a/arch/x86/kernel/rethook.c +++ b/arch/x86/kernel/rethook.c @@ -114,7 +114,7 @@ void arch_rethook_fixup_return(struct pt_regs *regs, } NOKPROBE_SYMBOL(arch_rethook_fixup_return); -void arch_rethook_prepare(struct rethook_node *rh, struct pt_regs *regs, bool mcount) +int arch_rethook_prepare(struct rethook_node *rh, struct pt_regs *regs, bool mcount) { unsigned long *stack = (unsigned long *)regs->sp; @@ -123,5 +123,7 @@ void arch_rethook_prepare(struct rethook_node *rh, struct pt_regs *regs, bool mc /* Replace the return addr with trampoline addr */ stack[0] = (unsigned long) arch_rethook_trampoline; + + return 0; } NOKPROBE_SYMBOL(arch_rethook_prepare); diff --git a/include/linux/rethook.h b/include/linux/rethook.h index c8ac1e5afcd1..07b9c6663b8e 100644 --- a/include/linux/rethook.h +++ b/include/linux/rethook.h @@ -63,12 +63,12 @@ void rethook_free(struct rethook *rh); void rethook_add_node(struct rethook *rh, struct rethook_node *node); struct rethook_node *rethook_try_get(struct rethook *rh); void rethook_recycle(struct rethook_node *node); -void rethook_hook(struct rethook_node *node, struct pt_regs *regs, bool mcount); +int rethook_hook(struct rethook_node *node, struct pt_regs *regs, bool mcount); unsigned long rethook_find_ret_addr(struct task_struct *tsk, unsigned long frame, struct llist_node **cur); /* Arch dependent code must implement arch_* and trampoline code */ -void arch_rethook_prepare(struct rethook_node *node, struct pt_regs *regs, bool mcount); +int arch_rethook_prepare(struct rethook_node *node, struct pt_regs *regs, bool mcount); void arch_rethook_trampoline(void); /** diff --git a/kernel/kprobes.c b/kernel/kprobes.c index dbe57df2e199..7fd7f1195bde 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c @@ -2109,10 +2109,12 @@ static int pre_handler_kretprobe(struct kprobe *p, struct pt_regs *regs) ri = container_of(rhn, struct kretprobe_instance, node); - if (rp->entry_handler && rp->entry_handler(ri, regs)) + if (rp->entry_handler && rp->entry_handler(ri, regs)) { rethook_recycle(rhn); - else - rethook_hook(rhn, regs, kprobe_ftrace(p)); + } else if (rethook_hook(rhn, regs, kprobe_ftrace(p)) < 0) { + rethook_recycle(rhn); + rp->nmissed++; + } return 0; } diff --git a/kernel/trace/fprobe.c b/kernel/trace/fprobe.c index 89d9f994ebb0..d3b13294d545 100644 --- a/kernel/trace/fprobe.c +++ b/kernel/trace/fprobe.c @@ -48,7 +48,10 @@ static void fprobe_handler(unsigned long ip, unsigned long parent_ip, } fpr = container_of(rh, struct fprobe_rethook_node, node); fpr->entry_ip = ip; - rethook_hook(rh, ftrace_get_regs(fregs), true); + if (rethook_hook(rh, ftrace_get_regs(fregs), true) < 0) { + rethook_recycle(rh); + fp->nmissed++; + } } out: diff --git a/kernel/trace/rethook.c b/kernel/trace/rethook.c index b56833700d23..e7db83438e45 100644 --- a/kernel/trace/rethook.c +++ b/kernel/trace/rethook.c @@ -174,11 +174,19 @@ NOKPROBE_SYMBOL(rethook_try_get); * from ftrace (mcount) callback, @mcount must be set true. If this is called * from the real function entry (e.g. kprobes) @mcount must be set false. * This is because the way to hook the function return depends on the context. + * This returns 0 if succeeded to hook the function return, or -errno if + * failed. */ -void rethook_hook(struct rethook_node *node, struct pt_regs *regs, bool mcount) +int rethook_hook(struct rethook_node *node, struct pt_regs *regs, bool mcount) { - arch_rethook_prepare(node, regs, mcount); + int ret; + + ret = arch_rethook_prepare(node, regs, mcount); + if (ret < 0) + return ret; + __llist_add(&node->llist, ¤t->rethooks); + return 0; } NOKPROBE_SYMBOL(rethook_hook); _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH bpf 2/4] rethook,fprobe,kprobes: Check a failure in the rethook_hook() @ 2022-04-05 9:33 ` Masami Hiramatsu 0 siblings, 0 replies; 16+ messages in thread From: Masami Hiramatsu @ 2022-04-05 9:33 UTC (permalink / raw) To: Alexei Starovoitov, Alexei Starovoitov Cc: Daniel Borkmann, Shubham Bansal, Andrii Nakryiko, Masami Hiramatsu, bpf, kernel-team, Jiri Olsa, Steven Rostedt, Naveen N . Rao, Anil S Keshavamurthy, David S . Miller, linux-kernel, Mark Rutland, Will Deacon, Ard Biesheuvel, Russell King, Catalin Marinas, linux-arm-kernel Since there are possible to fail to hook the function return (depends on archtecutre implememtation), rethook_hook() should return the error in that case and caller must check it. Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org> --- arch/x86/kernel/rethook.c | 4 +++- include/linux/rethook.h | 4 ++-- kernel/kprobes.c | 8 +++++--- kernel/trace/fprobe.c | 5 ++++- kernel/trace/rethook.c | 12 ++++++++++-- 5 files changed, 24 insertions(+), 9 deletions(-) diff --git a/arch/x86/kernel/rethook.c b/arch/x86/kernel/rethook.c index 8a1c0111ae79..c92b4875e3b9 100644 --- a/arch/x86/kernel/rethook.c +++ b/arch/x86/kernel/rethook.c @@ -114,7 +114,7 @@ void arch_rethook_fixup_return(struct pt_regs *regs, } NOKPROBE_SYMBOL(arch_rethook_fixup_return); -void arch_rethook_prepare(struct rethook_node *rh, struct pt_regs *regs, bool mcount) +int arch_rethook_prepare(struct rethook_node *rh, struct pt_regs *regs, bool mcount) { unsigned long *stack = (unsigned long *)regs->sp; @@ -123,5 +123,7 @@ void arch_rethook_prepare(struct rethook_node *rh, struct pt_regs *regs, bool mc /* Replace the return addr with trampoline addr */ stack[0] = (unsigned long) arch_rethook_trampoline; + + return 0; } NOKPROBE_SYMBOL(arch_rethook_prepare); diff --git a/include/linux/rethook.h b/include/linux/rethook.h index c8ac1e5afcd1..07b9c6663b8e 100644 --- a/include/linux/rethook.h +++ b/include/linux/rethook.h @@ -63,12 +63,12 @@ void rethook_free(struct rethook *rh); void rethook_add_node(struct rethook *rh, struct rethook_node *node); struct rethook_node *rethook_try_get(struct rethook *rh); void rethook_recycle(struct rethook_node *node); -void rethook_hook(struct rethook_node *node, struct pt_regs *regs, bool mcount); +int rethook_hook(struct rethook_node *node, struct pt_regs *regs, bool mcount); unsigned long rethook_find_ret_addr(struct task_struct *tsk, unsigned long frame, struct llist_node **cur); /* Arch dependent code must implement arch_* and trampoline code */ -void arch_rethook_prepare(struct rethook_node *node, struct pt_regs *regs, bool mcount); +int arch_rethook_prepare(struct rethook_node *node, struct pt_regs *regs, bool mcount); void arch_rethook_trampoline(void); /** diff --git a/kernel/kprobes.c b/kernel/kprobes.c index dbe57df2e199..7fd7f1195bde 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c @@ -2109,10 +2109,12 @@ static int pre_handler_kretprobe(struct kprobe *p, struct pt_regs *regs) ri = container_of(rhn, struct kretprobe_instance, node); - if (rp->entry_handler && rp->entry_handler(ri, regs)) + if (rp->entry_handler && rp->entry_handler(ri, regs)) { rethook_recycle(rhn); - else - rethook_hook(rhn, regs, kprobe_ftrace(p)); + } else if (rethook_hook(rhn, regs, kprobe_ftrace(p)) < 0) { + rethook_recycle(rhn); + rp->nmissed++; + } return 0; } diff --git a/kernel/trace/fprobe.c b/kernel/trace/fprobe.c index 89d9f994ebb0..d3b13294d545 100644 --- a/kernel/trace/fprobe.c +++ b/kernel/trace/fprobe.c @@ -48,7 +48,10 @@ static void fprobe_handler(unsigned long ip, unsigned long parent_ip, } fpr = container_of(rh, struct fprobe_rethook_node, node); fpr->entry_ip = ip; - rethook_hook(rh, ftrace_get_regs(fregs), true); + if (rethook_hook(rh, ftrace_get_regs(fregs), true) < 0) { + rethook_recycle(rh); + fp->nmissed++; + } } out: diff --git a/kernel/trace/rethook.c b/kernel/trace/rethook.c index b56833700d23..e7db83438e45 100644 --- a/kernel/trace/rethook.c +++ b/kernel/trace/rethook.c @@ -174,11 +174,19 @@ NOKPROBE_SYMBOL(rethook_try_get); * from ftrace (mcount) callback, @mcount must be set true. If this is called * from the real function entry (e.g. kprobes) @mcount must be set false. * This is because the way to hook the function return depends on the context. + * This returns 0 if succeeded to hook the function return, or -errno if + * failed. */ -void rethook_hook(struct rethook_node *node, struct pt_regs *regs, bool mcount) +int rethook_hook(struct rethook_node *node, struct pt_regs *regs, bool mcount) { - arch_rethook_prepare(node, regs, mcount); + int ret; + + ret = arch_rethook_prepare(node, regs, mcount); + if (ret < 0) + return ret; + __llist_add(&node->llist, ¤t->rethooks); + return 0; } NOKPROBE_SYMBOL(rethook_hook); ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH bpf 3/4] ARM: rethook: Replace kretprobe trampoline with rethook 2022-04-05 9:33 ` [PATCH bpf 0/4] kprobes: rethook,ARM,arm64: " Masami Hiramatsu @ 2022-04-05 9:34 ` Masami Hiramatsu -1 siblings, 0 replies; 16+ messages in thread From: Masami Hiramatsu @ 2022-04-05 9:34 UTC (permalink / raw) To: Alexei Starovoitov, Alexei Starovoitov Cc: Daniel Borkmann, Shubham Bansal, Andrii Nakryiko, Masami Hiramatsu, bpf, kernel-team, Jiri Olsa, Steven Rostedt, Naveen N . Rao, Anil S Keshavamurthy, David S . Miller, linux-kernel, Mark Rutland, Will Deacon, Ard Biesheuvel, Russell King, Catalin Marinas, linux-arm-kernel Replace the kretprob's trampoline code with the rethook on arm. This also enables rethook support on arm. Most of the code has been copied from kretprobe on arm. The significant difference is that the rethook on mcount (ftrace) support is added. If the rethook is called from the kprobes for kretprobe, there is no problem to replace the LR register with trampoline address because the LR register will be saved after kprobe probed. However, the mcount call will be placed right after making a stack frame for the function. This means we have to decode the stackframe to find where the LR register is saved. With the CONFIG_FRAME_POINTER, the frame pointer (FP register) is used. Without that, rethook has to unwind one stack frame to find it. Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org> --- arch/arm/Kconfig | 1 arch/arm/include/asm/stacktrace.h | 5 + arch/arm/kernel/stacktrace.c | 13 ++-- arch/arm/probes/Makefile | 1 arch/arm/probes/kprobes/core.c | 62 ------------------ arch/arm/probes/rethook.c | 127 +++++++++++++++++++++++++++++++++++++ 6 files changed, 139 insertions(+), 70 deletions(-) create mode 100644 arch/arm/probes/rethook.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c1251856ef77..cb56c848930a 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -110,6 +110,7 @@ config ARM select HAVE_MOD_ARCH_SPECIFIC select HAVE_NMI select HAVE_OPTPROBES if !THUMB2_KERNEL + select HAVE_RETHOOK select HAVE_PERF_EVENTS select HAVE_PERF_REGS select HAVE_PERF_USER_STACK_DUMP diff --git a/arch/arm/include/asm/stacktrace.h b/arch/arm/include/asm/stacktrace.h index 3e78f921b8b2..76a70b25863e 100644 --- a/arch/arm/include/asm/stacktrace.h +++ b/arch/arm/include/asm/stacktrace.h @@ -17,7 +17,8 @@ struct stackframe { /* address of the LR value on the stack */ unsigned long *lr_addr; -#ifdef CONFIG_KRETPROBES + +#if defined(CONFIG_RETHOOK) struct llist_node *kr_cur; struct task_struct *tsk; #endif @@ -30,7 +31,7 @@ void arm_get_current_stackframe(struct pt_regs *regs, struct stackframe *frame) frame->sp = regs->ARM_sp; frame->lr = regs->ARM_lr; frame->pc = regs->ARM_pc; -#ifdef CONFIG_KRETPROBES +#if defined(CONFIG_RETHOOK) frame->kr_cur = NULL; frame->tsk = current; #endif diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c index b5efecb3d730..6df085ecdf41 100644 --- a/arch/arm/kernel/stacktrace.c +++ b/arch/arm/kernel/stacktrace.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only #include <linux/export.h> #include <linux/kprobes.h> +#include <linux/rethook.h> #include <linux/sched.h> #include <linux/sched/debug.h> #include <linux/stacktrace.h> @@ -66,10 +67,10 @@ int notrace unwind_frame(struct stackframe *frame) frame->sp = *(unsigned long *)(fp - 8); frame->pc = *(unsigned long *)(fp - 4); #endif -#ifdef CONFIG_KRETPROBES - if (is_kretprobe_trampoline(frame->pc)) - frame->pc = kretprobe_find_ret_addr(frame->tsk, - (void *)frame->fp, &frame->kr_cur); +#ifdef CONFIG_RETHOOK + if (is_rethook_trampoline(frame->pc)) + frame->pc = rethook_find_ret_addr(frame->tsk, frame->fp, + &frame->kr_cur); #endif return 0; @@ -163,7 +164,7 @@ static noinline void __save_stack_trace(struct task_struct *tsk, here: frame.pc = (unsigned long)&&here; } -#ifdef CONFIG_KRETPROBES +#ifdef CONFIG_RETHOOK frame.kr_cur = NULL; frame.tsk = tsk; #endif @@ -184,7 +185,7 @@ void save_stack_trace_regs(struct pt_regs *regs, struct stack_trace *trace) frame.sp = regs->ARM_sp; frame.lr = regs->ARM_lr; frame.pc = regs->ARM_pc; -#ifdef CONFIG_KRETPROBES +#ifdef CONFIG_RETHOOK frame.kr_cur = NULL; frame.tsk = current; #endif diff --git a/arch/arm/probes/Makefile b/arch/arm/probes/Makefile index 8b0ea5ace100..10c083a22223 100644 --- a/arch/arm/probes/Makefile +++ b/arch/arm/probes/Makefile @@ -6,3 +6,4 @@ obj-$(CONFIG_KPROBES) += decode-thumb.o else obj-$(CONFIG_KPROBES) += decode-arm.o endif +obj-$(CONFIG_RETHOOK) += rethook.o diff --git a/arch/arm/probes/kprobes/core.c b/arch/arm/probes/kprobes/core.c index 9090c3a74dcc..2f01f8267cc3 100644 --- a/arch/arm/probes/kprobes/core.c +++ b/arch/arm/probes/kprobes/core.c @@ -365,68 +365,6 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, return NOTIFY_DONE; } -/* - * When a retprobed function returns, trampoline_handler() is called, - * calling the kretprobe's handler. We construct a struct pt_regs to - * give a view of registers r0-r11, sp, lr, and pc to the user - * return-handler. This is not a complete pt_regs structure, but that - * should be enough for stacktrace from the return handler with or - * without pt_regs. - */ -void __naked __kprobes __kretprobe_trampoline(void) -{ - __asm__ __volatile__ ( -#ifdef CONFIG_FRAME_POINTER - "ldr lr, =__kretprobe_trampoline \n\t" - /* __kretprobe_trampoline makes a framepointer on pt_regs. */ -#ifdef CONFIG_CC_IS_CLANG - "stmdb sp, {sp, lr, pc} \n\t" - "sub sp, sp, #12 \n\t" - /* In clang case, pt_regs->ip = lr. */ - "stmdb sp!, {r0 - r11, lr} \n\t" - /* fp points regs->r11 (fp) */ - "add fp, sp, #44 \n\t" -#else /* !CONFIG_CC_IS_CLANG */ - /* In gcc case, pt_regs->ip = fp. */ - "stmdb sp, {fp, sp, lr, pc} \n\t" - "sub sp, sp, #16 \n\t" - "stmdb sp!, {r0 - r11} \n\t" - /* fp points regs->r15 (pc) */ - "add fp, sp, #60 \n\t" -#endif /* CONFIG_CC_IS_CLANG */ -#else /* !CONFIG_FRAME_POINTER */ - "sub sp, sp, #16 \n\t" - "stmdb sp!, {r0 - r11} \n\t" -#endif /* CONFIG_FRAME_POINTER */ - "mov r0, sp \n\t" - "bl trampoline_handler \n\t" - "mov lr, r0 \n\t" - "ldmia sp!, {r0 - r11} \n\t" - "add sp, sp, #16 \n\t" -#ifdef CONFIG_THUMB2_KERNEL - "bx lr \n\t" -#else - "mov pc, lr \n\t" -#endif - : : : "memory"); -} - -/* Called from __kretprobe_trampoline */ -static __used __kprobes void *trampoline_handler(struct pt_regs *regs) -{ - return (void *)kretprobe_trampoline_handler(regs, (void *)regs->ARM_fp); -} - -void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, - struct pt_regs *regs) -{ - ri->ret_addr = (kprobe_opcode_t *)regs->ARM_lr; - ri->fp = (void *)regs->ARM_fp; - - /* Replace the return addr with trampoline addr. */ - regs->ARM_lr = (unsigned long)&__kretprobe_trampoline; -} - int __kprobes arch_trampoline_kprobe(struct kprobe *p) { return 0; diff --git a/arch/arm/probes/rethook.c b/arch/arm/probes/rethook.c new file mode 100644 index 000000000000..598a2b579b91 --- /dev/null +++ b/arch/arm/probes/rethook.c @@ -0,0 +1,127 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * arm implementation of rethook. Mostly copied from arch/arm/probes/kprobes/core.c + */ + +#include <linux/kprobes.h> +#include <linux/rethook.h> + +#include <asm/stacktrace.h> + +/* Called from arch_rethook_trampoline */ +static __used notrace unsigned long arch_rethook_trampoline_callback(struct pt_regs *regs) +{ + return rethook_trampoline_handler(regs, regs->ARM_fp); +} +NOKPROBE_SYMBOL(arch_rethook_trampoline_callback); + +/* + * When a rethook'ed function returns, it returns to arch_rethook_trampoline + * which calls rethook callback. We construct a struct pt_regs to + * give a view of registers r0-r11, sp, lr, and pc to the user + * return-handler. This is not a complete pt_regs structure, but that + * should be enough for stacktrace from the return handler with or + * without pt_regs. + */ +asm( + ".text\n" + ".global arch_rethook_trampoline\n" + ".type arch_rethook_trampoline, %function\n" + "arch_rethook_trampoline:\n" +#ifdef CONFIG_FRAME_POINTER + "adr lr, . \n\t" + /* this makes a framepointer on pt_regs. */ +#ifdef CONFIG_CC_IS_CLANG + "stmdb sp, {sp, lr, pc} \n\t" + "sub sp, sp, #12 \n\t" + /* In clang case, pt_regs->ip = lr. */ + "stmdb sp!, {r0 - r11, lr} \n\t" + /* fp points regs->r11 (fp) */ + "add fp, sp, #44 \n\t" +#else /* !CONFIG_CC_IS_CLANG */ + /* In gcc case, pt_regs->ip = fp. */ + "stmdb sp, {fp, sp, lr, pc} \n\t" + "sub sp, sp, #16 \n\t" + "stmdb sp!, {r0 - r11} \n\t" + /* fp points regs->r15 (pc) */ + "add fp, sp, #60 \n\t" +#endif /* CONFIG_CC_IS_CLANG */ +#else /* !CONFIG_FRAME_POINTER */ + "sub sp, sp, #16 \n\t" + "stmdb sp!, {r0 - r11} \n\t" +#endif /* CONFIG_FRAME_POINTER */ + "mov r0, sp \n\t" + "bl arch_rethook_trampoline_callback \n\t" + "mov lr, r0 \n\t" + "ldmia sp!, {r0 - r11} \n\t" + "add sp, sp, #16 \n\t" +#ifdef CONFIG_THUMB2_KERNEL + "bx lr \n\t" +#else + "mov pc, lr \n\t" +#endif + ".size arch_rethook_trampoline, .-arch_rethook_trampoline\n" +); +NOKPROBE_SYMBOL(arch_rethook_trampoline); + +/* + * At the entry of function with mcount, if the FRAME_POINTER is enabled, + * the stack and registers are prepared for the mcount function as below. + * + * mov ip, sp + * push {fp, ip, lr, pc} + * sub fp, ip, #4 ; FP[0] = PC, FP[-4] = LR, and FP[-12] = call-site FP. + * push {lr} + * bl <__gnu_mcount_nc> ; call ftrace + * + * And when returning from the function, call-site FP, SP and PC are restored + * from stack as below; + * + * ldm sp, {fp, sp, pc} + * + * Thus, if the arch_rethook_prepare() is called from real function entry, + * it must change the LR and save FP in pt_regs. But if it is called via + * mcount context (ftrace), it must change the LR on stack, which is next + * to the PC (= FP[-4]), and save the FP value at FP[-12]. + * + * If the FRAME_POINTER is disabled, we have to use arm unwinder to find where + * the LR is stored. + */ +int notrace arch_rethook_prepare(struct rethook_node *rh, struct pt_regs *regs, bool mcount) +{ + unsigned long *lr_addr; + int ret; + + if (mcount) { + /* Clang + mcount case is not supported yet. */ + if (IS_ENABLED(CONFIG_CC_IS_CLANG)) + return -EOPNOTSUPP; + if (IS_ENABLED(CONFIG_FRAME_POINTER)) { + lr_addr = (unsigned long *)(regs->ARM_fp - 4); + rh->frame = *(unsigned long *)(regs->ARM_fp - 12); + } else { + struct stackframe frame; + + arm_get_current_stackframe(regs, &frame); + ret = unwind_frame(&frame); + if (ret < 0) + return -EINVAL; + + if (frame.lr_addr) + lr_addr = frame.lr_addr; + else + lr_addr = ®s->ARM_lr; + rh->frame = regs->ARM_fp; + } + } else { + lr_addr = ®s->ARM_lr; + rh->frame = regs->ARM_fp; + } + + /* Replace the return addr with trampoline addr. */ + rh->ret_addr = *lr_addr; + *lr_addr = (unsigned long)arch_rethook_trampoline; + + return 0; +} +NOKPROBE_SYMBOL(arch_rethook_prepare); _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH bpf 3/4] ARM: rethook: Replace kretprobe trampoline with rethook @ 2022-04-05 9:34 ` Masami Hiramatsu 0 siblings, 0 replies; 16+ messages in thread From: Masami Hiramatsu @ 2022-04-05 9:34 UTC (permalink / raw) To: Alexei Starovoitov, Alexei Starovoitov Cc: Daniel Borkmann, Shubham Bansal, Andrii Nakryiko, Masami Hiramatsu, bpf, kernel-team, Jiri Olsa, Steven Rostedt, Naveen N . Rao, Anil S Keshavamurthy, David S . Miller, linux-kernel, Mark Rutland, Will Deacon, Ard Biesheuvel, Russell King, Catalin Marinas, linux-arm-kernel Replace the kretprob's trampoline code with the rethook on arm. This also enables rethook support on arm. Most of the code has been copied from kretprobe on arm. The significant difference is that the rethook on mcount (ftrace) support is added. If the rethook is called from the kprobes for kretprobe, there is no problem to replace the LR register with trampoline address because the LR register will be saved after kprobe probed. However, the mcount call will be placed right after making a stack frame for the function. This means we have to decode the stackframe to find where the LR register is saved. With the CONFIG_FRAME_POINTER, the frame pointer (FP register) is used. Without that, rethook has to unwind one stack frame to find it. Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org> --- arch/arm/Kconfig | 1 arch/arm/include/asm/stacktrace.h | 5 + arch/arm/kernel/stacktrace.c | 13 ++-- arch/arm/probes/Makefile | 1 arch/arm/probes/kprobes/core.c | 62 ------------------ arch/arm/probes/rethook.c | 127 +++++++++++++++++++++++++++++++++++++ 6 files changed, 139 insertions(+), 70 deletions(-) create mode 100644 arch/arm/probes/rethook.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c1251856ef77..cb56c848930a 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -110,6 +110,7 @@ config ARM select HAVE_MOD_ARCH_SPECIFIC select HAVE_NMI select HAVE_OPTPROBES if !THUMB2_KERNEL + select HAVE_RETHOOK select HAVE_PERF_EVENTS select HAVE_PERF_REGS select HAVE_PERF_USER_STACK_DUMP diff --git a/arch/arm/include/asm/stacktrace.h b/arch/arm/include/asm/stacktrace.h index 3e78f921b8b2..76a70b25863e 100644 --- a/arch/arm/include/asm/stacktrace.h +++ b/arch/arm/include/asm/stacktrace.h @@ -17,7 +17,8 @@ struct stackframe { /* address of the LR value on the stack */ unsigned long *lr_addr; -#ifdef CONFIG_KRETPROBES + +#if defined(CONFIG_RETHOOK) struct llist_node *kr_cur; struct task_struct *tsk; #endif @@ -30,7 +31,7 @@ void arm_get_current_stackframe(struct pt_regs *regs, struct stackframe *frame) frame->sp = regs->ARM_sp; frame->lr = regs->ARM_lr; frame->pc = regs->ARM_pc; -#ifdef CONFIG_KRETPROBES +#if defined(CONFIG_RETHOOK) frame->kr_cur = NULL; frame->tsk = current; #endif diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c index b5efecb3d730..6df085ecdf41 100644 --- a/arch/arm/kernel/stacktrace.c +++ b/arch/arm/kernel/stacktrace.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only #include <linux/export.h> #include <linux/kprobes.h> +#include <linux/rethook.h> #include <linux/sched.h> #include <linux/sched/debug.h> #include <linux/stacktrace.h> @@ -66,10 +67,10 @@ int notrace unwind_frame(struct stackframe *frame) frame->sp = *(unsigned long *)(fp - 8); frame->pc = *(unsigned long *)(fp - 4); #endif -#ifdef CONFIG_KRETPROBES - if (is_kretprobe_trampoline(frame->pc)) - frame->pc = kretprobe_find_ret_addr(frame->tsk, - (void *)frame->fp, &frame->kr_cur); +#ifdef CONFIG_RETHOOK + if (is_rethook_trampoline(frame->pc)) + frame->pc = rethook_find_ret_addr(frame->tsk, frame->fp, + &frame->kr_cur); #endif return 0; @@ -163,7 +164,7 @@ static noinline void __save_stack_trace(struct task_struct *tsk, here: frame.pc = (unsigned long)&&here; } -#ifdef CONFIG_KRETPROBES +#ifdef CONFIG_RETHOOK frame.kr_cur = NULL; frame.tsk = tsk; #endif @@ -184,7 +185,7 @@ void save_stack_trace_regs(struct pt_regs *regs, struct stack_trace *trace) frame.sp = regs->ARM_sp; frame.lr = regs->ARM_lr; frame.pc = regs->ARM_pc; -#ifdef CONFIG_KRETPROBES +#ifdef CONFIG_RETHOOK frame.kr_cur = NULL; frame.tsk = current; #endif diff --git a/arch/arm/probes/Makefile b/arch/arm/probes/Makefile index 8b0ea5ace100..10c083a22223 100644 --- a/arch/arm/probes/Makefile +++ b/arch/arm/probes/Makefile @@ -6,3 +6,4 @@ obj-$(CONFIG_KPROBES) += decode-thumb.o else obj-$(CONFIG_KPROBES) += decode-arm.o endif +obj-$(CONFIG_RETHOOK) += rethook.o diff --git a/arch/arm/probes/kprobes/core.c b/arch/arm/probes/kprobes/core.c index 9090c3a74dcc..2f01f8267cc3 100644 --- a/arch/arm/probes/kprobes/core.c +++ b/arch/arm/probes/kprobes/core.c @@ -365,68 +365,6 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, return NOTIFY_DONE; } -/* - * When a retprobed function returns, trampoline_handler() is called, - * calling the kretprobe's handler. We construct a struct pt_regs to - * give a view of registers r0-r11, sp, lr, and pc to the user - * return-handler. This is not a complete pt_regs structure, but that - * should be enough for stacktrace from the return handler with or - * without pt_regs. - */ -void __naked __kprobes __kretprobe_trampoline(void) -{ - __asm__ __volatile__ ( -#ifdef CONFIG_FRAME_POINTER - "ldr lr, =__kretprobe_trampoline \n\t" - /* __kretprobe_trampoline makes a framepointer on pt_regs. */ -#ifdef CONFIG_CC_IS_CLANG - "stmdb sp, {sp, lr, pc} \n\t" - "sub sp, sp, #12 \n\t" - /* In clang case, pt_regs->ip = lr. */ - "stmdb sp!, {r0 - r11, lr} \n\t" - /* fp points regs->r11 (fp) */ - "add fp, sp, #44 \n\t" -#else /* !CONFIG_CC_IS_CLANG */ - /* In gcc case, pt_regs->ip = fp. */ - "stmdb sp, {fp, sp, lr, pc} \n\t" - "sub sp, sp, #16 \n\t" - "stmdb sp!, {r0 - r11} \n\t" - /* fp points regs->r15 (pc) */ - "add fp, sp, #60 \n\t" -#endif /* CONFIG_CC_IS_CLANG */ -#else /* !CONFIG_FRAME_POINTER */ - "sub sp, sp, #16 \n\t" - "stmdb sp!, {r0 - r11} \n\t" -#endif /* CONFIG_FRAME_POINTER */ - "mov r0, sp \n\t" - "bl trampoline_handler \n\t" - "mov lr, r0 \n\t" - "ldmia sp!, {r0 - r11} \n\t" - "add sp, sp, #16 \n\t" -#ifdef CONFIG_THUMB2_KERNEL - "bx lr \n\t" -#else - "mov pc, lr \n\t" -#endif - : : : "memory"); -} - -/* Called from __kretprobe_trampoline */ -static __used __kprobes void *trampoline_handler(struct pt_regs *regs) -{ - return (void *)kretprobe_trampoline_handler(regs, (void *)regs->ARM_fp); -} - -void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, - struct pt_regs *regs) -{ - ri->ret_addr = (kprobe_opcode_t *)regs->ARM_lr; - ri->fp = (void *)regs->ARM_fp; - - /* Replace the return addr with trampoline addr. */ - regs->ARM_lr = (unsigned long)&__kretprobe_trampoline; -} - int __kprobes arch_trampoline_kprobe(struct kprobe *p) { return 0; diff --git a/arch/arm/probes/rethook.c b/arch/arm/probes/rethook.c new file mode 100644 index 000000000000..598a2b579b91 --- /dev/null +++ b/arch/arm/probes/rethook.c @@ -0,0 +1,127 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * arm implementation of rethook. Mostly copied from arch/arm/probes/kprobes/core.c + */ + +#include <linux/kprobes.h> +#include <linux/rethook.h> + +#include <asm/stacktrace.h> + +/* Called from arch_rethook_trampoline */ +static __used notrace unsigned long arch_rethook_trampoline_callback(struct pt_regs *regs) +{ + return rethook_trampoline_handler(regs, regs->ARM_fp); +} +NOKPROBE_SYMBOL(arch_rethook_trampoline_callback); + +/* + * When a rethook'ed function returns, it returns to arch_rethook_trampoline + * which calls rethook callback. We construct a struct pt_regs to + * give a view of registers r0-r11, sp, lr, and pc to the user + * return-handler. This is not a complete pt_regs structure, but that + * should be enough for stacktrace from the return handler with or + * without pt_regs. + */ +asm( + ".text\n" + ".global arch_rethook_trampoline\n" + ".type arch_rethook_trampoline, %function\n" + "arch_rethook_trampoline:\n" +#ifdef CONFIG_FRAME_POINTER + "adr lr, . \n\t" + /* this makes a framepointer on pt_regs. */ +#ifdef CONFIG_CC_IS_CLANG + "stmdb sp, {sp, lr, pc} \n\t" + "sub sp, sp, #12 \n\t" + /* In clang case, pt_regs->ip = lr. */ + "stmdb sp!, {r0 - r11, lr} \n\t" + /* fp points regs->r11 (fp) */ + "add fp, sp, #44 \n\t" +#else /* !CONFIG_CC_IS_CLANG */ + /* In gcc case, pt_regs->ip = fp. */ + "stmdb sp, {fp, sp, lr, pc} \n\t" + "sub sp, sp, #16 \n\t" + "stmdb sp!, {r0 - r11} \n\t" + /* fp points regs->r15 (pc) */ + "add fp, sp, #60 \n\t" +#endif /* CONFIG_CC_IS_CLANG */ +#else /* !CONFIG_FRAME_POINTER */ + "sub sp, sp, #16 \n\t" + "stmdb sp!, {r0 - r11} \n\t" +#endif /* CONFIG_FRAME_POINTER */ + "mov r0, sp \n\t" + "bl arch_rethook_trampoline_callback \n\t" + "mov lr, r0 \n\t" + "ldmia sp!, {r0 - r11} \n\t" + "add sp, sp, #16 \n\t" +#ifdef CONFIG_THUMB2_KERNEL + "bx lr \n\t" +#else + "mov pc, lr \n\t" +#endif + ".size arch_rethook_trampoline, .-arch_rethook_trampoline\n" +); +NOKPROBE_SYMBOL(arch_rethook_trampoline); + +/* + * At the entry of function with mcount, if the FRAME_POINTER is enabled, + * the stack and registers are prepared for the mcount function as below. + * + * mov ip, sp + * push {fp, ip, lr, pc} + * sub fp, ip, #4 ; FP[0] = PC, FP[-4] = LR, and FP[-12] = call-site FP. + * push {lr} + * bl <__gnu_mcount_nc> ; call ftrace + * + * And when returning from the function, call-site FP, SP and PC are restored + * from stack as below; + * + * ldm sp, {fp, sp, pc} + * + * Thus, if the arch_rethook_prepare() is called from real function entry, + * it must change the LR and save FP in pt_regs. But if it is called via + * mcount context (ftrace), it must change the LR on stack, which is next + * to the PC (= FP[-4]), and save the FP value at FP[-12]. + * + * If the FRAME_POINTER is disabled, we have to use arm unwinder to find where + * the LR is stored. + */ +int notrace arch_rethook_prepare(struct rethook_node *rh, struct pt_regs *regs, bool mcount) +{ + unsigned long *lr_addr; + int ret; + + if (mcount) { + /* Clang + mcount case is not supported yet. */ + if (IS_ENABLED(CONFIG_CC_IS_CLANG)) + return -EOPNOTSUPP; + if (IS_ENABLED(CONFIG_FRAME_POINTER)) { + lr_addr = (unsigned long *)(regs->ARM_fp - 4); + rh->frame = *(unsigned long *)(regs->ARM_fp - 12); + } else { + struct stackframe frame; + + arm_get_current_stackframe(regs, &frame); + ret = unwind_frame(&frame); + if (ret < 0) + return -EINVAL; + + if (frame.lr_addr) + lr_addr = frame.lr_addr; + else + lr_addr = ®s->ARM_lr; + rh->frame = regs->ARM_fp; + } + } else { + lr_addr = ®s->ARM_lr; + rh->frame = regs->ARM_fp; + } + + /* Replace the return addr with trampoline addr. */ + rh->ret_addr = *lr_addr; + *lr_addr = (unsigned long)arch_rethook_trampoline; + + return 0; +} +NOKPROBE_SYMBOL(arch_rethook_prepare); ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH bpf 4/4] arm64: rethook: Replace kretprobe trampoline with rethook 2022-04-05 9:33 ` [PATCH bpf 0/4] kprobes: rethook,ARM,arm64: " Masami Hiramatsu @ 2022-04-05 9:34 ` Masami Hiramatsu -1 siblings, 0 replies; 16+ messages in thread From: Masami Hiramatsu @ 2022-04-05 9:34 UTC (permalink / raw) To: Alexei Starovoitov, Alexei Starovoitov Cc: Daniel Borkmann, Shubham Bansal, Andrii Nakryiko, Masami Hiramatsu, bpf, kernel-team, Jiri Olsa, Steven Rostedt, Naveen N . Rao, Anil S Keshavamurthy, David S . Miller, linux-kernel, Mark Rutland, Will Deacon, Ard Biesheuvel, Russell King, Catalin Marinas, linux-arm-kernel Replace the kretprobe's trampoline code with the rethook on arm64. The rethook on arm64 is almost renamed from kretprobe trampoline code. The mechanism is completely same. Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org> --- arch/arm64/Kconfig | 1 arch/arm64/include/asm/kprobes.h | 2 - arch/arm64/include/asm/stacktrace.h | 2 - arch/arm64/kernel/Makefile | 1 arch/arm64/kernel/probes/Makefile | 1 arch/arm64/kernel/probes/kprobes.c | 15 ---- arch/arm64/kernel/probes/kprobes_trampoline.S | 86 ------------------------- arch/arm64/kernel/rethook.c | 26 +++++++ arch/arm64/kernel/rethook_trampoline.S | 87 +++++++++++++++++++++++++ arch/arm64/kernel/stacktrace.c | 9 +-- 10 files changed, 121 insertions(+), 109 deletions(-) delete mode 100644 arch/arm64/kernel/probes/kprobes_trampoline.S create mode 100644 arch/arm64/kernel/rethook.c create mode 100644 arch/arm64/kernel/rethook_trampoline.S diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 57c4c995965f..7d2945930283 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -204,6 +204,7 @@ config ARM64 select HAVE_SYSCALL_TRACEPOINTS select HAVE_KPROBES select HAVE_KRETPROBES + select HAVE_RETHOOK select HAVE_GENERIC_VDSO select IOMMU_DMA if IOMMU_SUPPORT select IRQ_DOMAIN diff --git a/arch/arm64/include/asm/kprobes.h b/arch/arm64/include/asm/kprobes.h index 05cd82eeca13..4ac558058377 100644 --- a/arch/arm64/include/asm/kprobes.h +++ b/arch/arm64/include/asm/kprobes.h @@ -39,8 +39,6 @@ void arch_remove_kprobe(struct kprobe *); int kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr); int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val, void *data); -void __kretprobe_trampoline(void); -void __kprobes *trampoline_probe_handler(struct pt_regs *regs); #endif /* CONFIG_KPROBES */ #endif /* _ARM_KPROBES_H */ diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h index e77cdef9ca29..f781874f1609 100644 --- a/arch/arm64/include/asm/stacktrace.h +++ b/arch/arm64/include/asm/stacktrace.h @@ -58,7 +58,7 @@ struct stackframe { DECLARE_BITMAP(stacks_done, __NR_STACK_TYPES); unsigned long prev_fp; enum stack_type prev_type; -#ifdef CONFIG_KRETPROBES +#if defined(CONFIG_RETHOOK) struct llist_node *kr_cur; #endif }; diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index 986837d7ec82..62e033b1b095 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile @@ -60,6 +60,7 @@ obj-$(CONFIG_ACPI_NUMA) += acpi_numa.o obj-$(CONFIG_ARM64_ACPI_PARKING_PROTOCOL) += acpi_parking_protocol.o obj-$(CONFIG_PARAVIRT) += paravirt.o obj-$(CONFIG_RANDOMIZE_BASE) += kaslr.o +obj-$(CONFIG_RETHOOK) += rethook.o rethook_trampoline.o obj-$(CONFIG_HIBERNATION) += hibernate.o hibernate-asm.o obj-$(CONFIG_ELF_CORE) += elfcore.o obj-$(CONFIG_KEXEC_CORE) += machine_kexec.o relocate_kernel.o \ diff --git a/arch/arm64/kernel/probes/Makefile b/arch/arm64/kernel/probes/Makefile index 8e4be92e25b1..1fa58cda64ff 100644 --- a/arch/arm64/kernel/probes/Makefile +++ b/arch/arm64/kernel/probes/Makefile @@ -1,6 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_KPROBES) += kprobes.o decode-insn.o \ - kprobes_trampoline.o \ simulate-insn.o obj-$(CONFIG_UPROBES) += uprobes.o decode-insn.o \ simulate-insn.o diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c index d9dfa82c1f18..4a3cc266e77e 100644 --- a/arch/arm64/kernel/probes/kprobes.c +++ b/arch/arm64/kernel/probes/kprobes.c @@ -399,21 +399,6 @@ int __init arch_populate_kprobe_blacklist(void) return ret; } -void __kprobes __used *trampoline_probe_handler(struct pt_regs *regs) -{ - return (void *)kretprobe_trampoline_handler(regs, (void *)regs->regs[29]); -} - -void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, - struct pt_regs *regs) -{ - ri->ret_addr = (kprobe_opcode_t *)regs->regs[30]; - ri->fp = (void *)regs->regs[29]; - - /* replace return addr (x30) with trampoline */ - regs->regs[30] = (long)&__kretprobe_trampoline; -} - int __kprobes arch_trampoline_kprobe(struct kprobe *p) { return 0; diff --git a/arch/arm64/kernel/probes/kprobes_trampoline.S b/arch/arm64/kernel/probes/kprobes_trampoline.S deleted file mode 100644 index 9a6499bed58b..000000000000 --- a/arch/arm64/kernel/probes/kprobes_trampoline.S +++ /dev/null @@ -1,86 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * trampoline entry and return code for kretprobes. - */ - -#include <linux/linkage.h> -#include <asm/asm-offsets.h> -#include <asm/assembler.h> - - .text - - .macro save_all_base_regs - stp x0, x1, [sp, #S_X0] - stp x2, x3, [sp, #S_X2] - stp x4, x5, [sp, #S_X4] - stp x6, x7, [sp, #S_X6] - stp x8, x9, [sp, #S_X8] - stp x10, x11, [sp, #S_X10] - stp x12, x13, [sp, #S_X12] - stp x14, x15, [sp, #S_X14] - stp x16, x17, [sp, #S_X16] - stp x18, x19, [sp, #S_X18] - stp x20, x21, [sp, #S_X20] - stp x22, x23, [sp, #S_X22] - stp x24, x25, [sp, #S_X24] - stp x26, x27, [sp, #S_X26] - stp x28, x29, [sp, #S_X28] - add x0, sp, #PT_REGS_SIZE - stp lr, x0, [sp, #S_LR] - /* - * Construct a useful saved PSTATE - */ - mrs x0, nzcv - mrs x1, daif - orr x0, x0, x1 - mrs x1, CurrentEL - orr x0, x0, x1 - mrs x1, SPSel - orr x0, x0, x1 - stp xzr, x0, [sp, #S_PC] - .endm - - .macro restore_all_base_regs - ldr x0, [sp, #S_PSTATE] - and x0, x0, #(PSR_N_BIT | PSR_Z_BIT | PSR_C_BIT | PSR_V_BIT) - msr nzcv, x0 - ldp x0, x1, [sp, #S_X0] - ldp x2, x3, [sp, #S_X2] - ldp x4, x5, [sp, #S_X4] - ldp x6, x7, [sp, #S_X6] - ldp x8, x9, [sp, #S_X8] - ldp x10, x11, [sp, #S_X10] - ldp x12, x13, [sp, #S_X12] - ldp x14, x15, [sp, #S_X14] - ldp x16, x17, [sp, #S_X16] - ldp x18, x19, [sp, #S_X18] - ldp x20, x21, [sp, #S_X20] - ldp x22, x23, [sp, #S_X22] - ldp x24, x25, [sp, #S_X24] - ldp x26, x27, [sp, #S_X26] - ldp x28, x29, [sp, #S_X28] - .endm - -SYM_CODE_START(__kretprobe_trampoline) - sub sp, sp, #PT_REGS_SIZE - - save_all_base_regs - - /* Setup a frame pointer. */ - add x29, sp, #S_FP - - mov x0, sp - bl trampoline_probe_handler - /* - * Replace trampoline address in lr with actual orig_ret_addr return - * address. - */ - mov lr, x0 - - /* The frame pointer (x29) is restored with other registers. */ - restore_all_base_regs - - add sp, sp, #PT_REGS_SIZE - ret - -SYM_CODE_END(__kretprobe_trampoline) diff --git a/arch/arm64/kernel/rethook.c b/arch/arm64/kernel/rethook.c new file mode 100644 index 000000000000..78bb6b968de5 --- /dev/null +++ b/arch/arm64/kernel/rethook.c @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Generic return hook for arm64. + * Most of the code is copied from arch/arm64/kernel/probes/kprobes.c + */ + +#include <linux/kprobes.h> +#include <linux/rethook.h> + +/* This is called from arch_rethook_trampoline() */ +unsigned long __used arch_rethook_trampoline_callback(struct pt_regs *regs) +{ + return rethook_trampoline_handler(regs, regs->regs[29]); +} +NOKPROBE_SYMBOL(arch_rethook_trampoline_callback); + +int arch_rethook_prepare(struct rethook_node *rhn, struct pt_regs *regs, bool mcount) +{ + rhn->ret_addr = regs->regs[30]; + rhn->frame = regs->regs[29]; + + /* replace return addr (x30) with trampoline */ + regs->regs[30] = (u64)arch_rethook_trampoline; + return 0; +} +NOKPROBE_SYMBOL(arch_rethook_prepare); diff --git a/arch/arm64/kernel/rethook_trampoline.S b/arch/arm64/kernel/rethook_trampoline.S new file mode 100644 index 000000000000..146d4553674c --- /dev/null +++ b/arch/arm64/kernel/rethook_trampoline.S @@ -0,0 +1,87 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * trampoline entry and return code for rethook. + * Renamed from arch/arm64/kernel/probes/kprobes_trampoline.S + */ + +#include <linux/linkage.h> +#include <asm/asm-offsets.h> +#include <asm/assembler.h> + + .text + + .macro save_all_base_regs + stp x0, x1, [sp, #S_X0] + stp x2, x3, [sp, #S_X2] + stp x4, x5, [sp, #S_X4] + stp x6, x7, [sp, #S_X6] + stp x8, x9, [sp, #S_X8] + stp x10, x11, [sp, #S_X10] + stp x12, x13, [sp, #S_X12] + stp x14, x15, [sp, #S_X14] + stp x16, x17, [sp, #S_X16] + stp x18, x19, [sp, #S_X18] + stp x20, x21, [sp, #S_X20] + stp x22, x23, [sp, #S_X22] + stp x24, x25, [sp, #S_X24] + stp x26, x27, [sp, #S_X26] + stp x28, x29, [sp, #S_X28] + add x0, sp, #PT_REGS_SIZE + stp lr, x0, [sp, #S_LR] + /* + * Construct a useful saved PSTATE + */ + mrs x0, nzcv + mrs x1, daif + orr x0, x0, x1 + mrs x1, CurrentEL + orr x0, x0, x1 + mrs x1, SPSel + orr x0, x0, x1 + stp xzr, x0, [sp, #S_PC] + .endm + + .macro restore_all_base_regs + ldr x0, [sp, #S_PSTATE] + and x0, x0, #(PSR_N_BIT | PSR_Z_BIT | PSR_C_BIT | PSR_V_BIT) + msr nzcv, x0 + ldp x0, x1, [sp, #S_X0] + ldp x2, x3, [sp, #S_X2] + ldp x4, x5, [sp, #S_X4] + ldp x6, x7, [sp, #S_X6] + ldp x8, x9, [sp, #S_X8] + ldp x10, x11, [sp, #S_X10] + ldp x12, x13, [sp, #S_X12] + ldp x14, x15, [sp, #S_X14] + ldp x16, x17, [sp, #S_X16] + ldp x18, x19, [sp, #S_X18] + ldp x20, x21, [sp, #S_X20] + ldp x22, x23, [sp, #S_X22] + ldp x24, x25, [sp, #S_X24] + ldp x26, x27, [sp, #S_X26] + ldp x28, x29, [sp, #S_X28] + .endm + +SYM_CODE_START(arch_rethook_trampoline) + sub sp, sp, #PT_REGS_SIZE + + save_all_base_regs + + /* Setup a frame pointer. */ + add x29, sp, #S_FP + + mov x0, sp + bl arch_rethook_trampoline_callback + /* + * Replace trampoline address in lr with actual orig_ret_addr return + * address. + */ + mov lr, x0 + + /* The frame pointer (x29) is restored with other registers. */ + restore_all_base_regs + + add sp, sp, #PT_REGS_SIZE + ret + +SYM_CODE_END(arch_rethook_trampoline) diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c index e4103e085681..5b717af4b555 100644 --- a/arch/arm64/kernel/stacktrace.c +++ b/arch/arm64/kernel/stacktrace.c @@ -8,6 +8,7 @@ #include <linux/export.h> #include <linux/ftrace.h> #include <linux/kprobes.h> +#include <linux/rethook.h> #include <linux/sched.h> #include <linux/sched/debug.h> #include <linux/sched/task_stack.h> @@ -38,7 +39,7 @@ static notrace void start_backtrace(struct stackframe *frame, unsigned long fp, { frame->fp = fp; frame->pc = pc; -#ifdef CONFIG_KRETPROBES +#if defined(CONFIG_RETHOOK) frame->kr_cur = NULL; #endif @@ -134,9 +135,9 @@ static int notrace unwind_frame(struct task_struct *tsk, frame->pc = orig_pc; } #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ -#ifdef CONFIG_KRETPROBES - if (is_kretprobe_trampoline(frame->pc)) - frame->pc = kretprobe_find_ret_addr(tsk, (void *)frame->fp, &frame->kr_cur); +#ifdef CONFIG_RETHOOK + if (is_rethook_trampoline(frame->pc)) + frame->pc = rethook_find_ret_addr(tsk, frame->fp, &frame->kr_cur); #endif return 0; _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH bpf 4/4] arm64: rethook: Replace kretprobe trampoline with rethook @ 2022-04-05 9:34 ` Masami Hiramatsu 0 siblings, 0 replies; 16+ messages in thread From: Masami Hiramatsu @ 2022-04-05 9:34 UTC (permalink / raw) To: Alexei Starovoitov, Alexei Starovoitov Cc: Daniel Borkmann, Shubham Bansal, Andrii Nakryiko, Masami Hiramatsu, bpf, kernel-team, Jiri Olsa, Steven Rostedt, Naveen N . Rao, Anil S Keshavamurthy, David S . Miller, linux-kernel, Mark Rutland, Will Deacon, Ard Biesheuvel, Russell King, Catalin Marinas, linux-arm-kernel Replace the kretprobe's trampoline code with the rethook on arm64. The rethook on arm64 is almost renamed from kretprobe trampoline code. The mechanism is completely same. Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org> --- arch/arm64/Kconfig | 1 arch/arm64/include/asm/kprobes.h | 2 - arch/arm64/include/asm/stacktrace.h | 2 - arch/arm64/kernel/Makefile | 1 arch/arm64/kernel/probes/Makefile | 1 arch/arm64/kernel/probes/kprobes.c | 15 ---- arch/arm64/kernel/probes/kprobes_trampoline.S | 86 ------------------------- arch/arm64/kernel/rethook.c | 26 +++++++ arch/arm64/kernel/rethook_trampoline.S | 87 +++++++++++++++++++++++++ arch/arm64/kernel/stacktrace.c | 9 +-- 10 files changed, 121 insertions(+), 109 deletions(-) delete mode 100644 arch/arm64/kernel/probes/kprobes_trampoline.S create mode 100644 arch/arm64/kernel/rethook.c create mode 100644 arch/arm64/kernel/rethook_trampoline.S diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 57c4c995965f..7d2945930283 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -204,6 +204,7 @@ config ARM64 select HAVE_SYSCALL_TRACEPOINTS select HAVE_KPROBES select HAVE_KRETPROBES + select HAVE_RETHOOK select HAVE_GENERIC_VDSO select IOMMU_DMA if IOMMU_SUPPORT select IRQ_DOMAIN diff --git a/arch/arm64/include/asm/kprobes.h b/arch/arm64/include/asm/kprobes.h index 05cd82eeca13..4ac558058377 100644 --- a/arch/arm64/include/asm/kprobes.h +++ b/arch/arm64/include/asm/kprobes.h @@ -39,8 +39,6 @@ void arch_remove_kprobe(struct kprobe *); int kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr); int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val, void *data); -void __kretprobe_trampoline(void); -void __kprobes *trampoline_probe_handler(struct pt_regs *regs); #endif /* CONFIG_KPROBES */ #endif /* _ARM_KPROBES_H */ diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h index e77cdef9ca29..f781874f1609 100644 --- a/arch/arm64/include/asm/stacktrace.h +++ b/arch/arm64/include/asm/stacktrace.h @@ -58,7 +58,7 @@ struct stackframe { DECLARE_BITMAP(stacks_done, __NR_STACK_TYPES); unsigned long prev_fp; enum stack_type prev_type; -#ifdef CONFIG_KRETPROBES +#if defined(CONFIG_RETHOOK) struct llist_node *kr_cur; #endif }; diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index 986837d7ec82..62e033b1b095 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile @@ -60,6 +60,7 @@ obj-$(CONFIG_ACPI_NUMA) += acpi_numa.o obj-$(CONFIG_ARM64_ACPI_PARKING_PROTOCOL) += acpi_parking_protocol.o obj-$(CONFIG_PARAVIRT) += paravirt.o obj-$(CONFIG_RANDOMIZE_BASE) += kaslr.o +obj-$(CONFIG_RETHOOK) += rethook.o rethook_trampoline.o obj-$(CONFIG_HIBERNATION) += hibernate.o hibernate-asm.o obj-$(CONFIG_ELF_CORE) += elfcore.o obj-$(CONFIG_KEXEC_CORE) += machine_kexec.o relocate_kernel.o \ diff --git a/arch/arm64/kernel/probes/Makefile b/arch/arm64/kernel/probes/Makefile index 8e4be92e25b1..1fa58cda64ff 100644 --- a/arch/arm64/kernel/probes/Makefile +++ b/arch/arm64/kernel/probes/Makefile @@ -1,6 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_KPROBES) += kprobes.o decode-insn.o \ - kprobes_trampoline.o \ simulate-insn.o obj-$(CONFIG_UPROBES) += uprobes.o decode-insn.o \ simulate-insn.o diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c index d9dfa82c1f18..4a3cc266e77e 100644 --- a/arch/arm64/kernel/probes/kprobes.c +++ b/arch/arm64/kernel/probes/kprobes.c @@ -399,21 +399,6 @@ int __init arch_populate_kprobe_blacklist(void) return ret; } -void __kprobes __used *trampoline_probe_handler(struct pt_regs *regs) -{ - return (void *)kretprobe_trampoline_handler(regs, (void *)regs->regs[29]); -} - -void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, - struct pt_regs *regs) -{ - ri->ret_addr = (kprobe_opcode_t *)regs->regs[30]; - ri->fp = (void *)regs->regs[29]; - - /* replace return addr (x30) with trampoline */ - regs->regs[30] = (long)&__kretprobe_trampoline; -} - int __kprobes arch_trampoline_kprobe(struct kprobe *p) { return 0; diff --git a/arch/arm64/kernel/probes/kprobes_trampoline.S b/arch/arm64/kernel/probes/kprobes_trampoline.S deleted file mode 100644 index 9a6499bed58b..000000000000 --- a/arch/arm64/kernel/probes/kprobes_trampoline.S +++ /dev/null @@ -1,86 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * trampoline entry and return code for kretprobes. - */ - -#include <linux/linkage.h> -#include <asm/asm-offsets.h> -#include <asm/assembler.h> - - .text - - .macro save_all_base_regs - stp x0, x1, [sp, #S_X0] - stp x2, x3, [sp, #S_X2] - stp x4, x5, [sp, #S_X4] - stp x6, x7, [sp, #S_X6] - stp x8, x9, [sp, #S_X8] - stp x10, x11, [sp, #S_X10] - stp x12, x13, [sp, #S_X12] - stp x14, x15, [sp, #S_X14] - stp x16, x17, [sp, #S_X16] - stp x18, x19, [sp, #S_X18] - stp x20, x21, [sp, #S_X20] - stp x22, x23, [sp, #S_X22] - stp x24, x25, [sp, #S_X24] - stp x26, x27, [sp, #S_X26] - stp x28, x29, [sp, #S_X28] - add x0, sp, #PT_REGS_SIZE - stp lr, x0, [sp, #S_LR] - /* - * Construct a useful saved PSTATE - */ - mrs x0, nzcv - mrs x1, daif - orr x0, x0, x1 - mrs x1, CurrentEL - orr x0, x0, x1 - mrs x1, SPSel - orr x0, x0, x1 - stp xzr, x0, [sp, #S_PC] - .endm - - .macro restore_all_base_regs - ldr x0, [sp, #S_PSTATE] - and x0, x0, #(PSR_N_BIT | PSR_Z_BIT | PSR_C_BIT | PSR_V_BIT) - msr nzcv, x0 - ldp x0, x1, [sp, #S_X0] - ldp x2, x3, [sp, #S_X2] - ldp x4, x5, [sp, #S_X4] - ldp x6, x7, [sp, #S_X6] - ldp x8, x9, [sp, #S_X8] - ldp x10, x11, [sp, #S_X10] - ldp x12, x13, [sp, #S_X12] - ldp x14, x15, [sp, #S_X14] - ldp x16, x17, [sp, #S_X16] - ldp x18, x19, [sp, #S_X18] - ldp x20, x21, [sp, #S_X20] - ldp x22, x23, [sp, #S_X22] - ldp x24, x25, [sp, #S_X24] - ldp x26, x27, [sp, #S_X26] - ldp x28, x29, [sp, #S_X28] - .endm - -SYM_CODE_START(__kretprobe_trampoline) - sub sp, sp, #PT_REGS_SIZE - - save_all_base_regs - - /* Setup a frame pointer. */ - add x29, sp, #S_FP - - mov x0, sp - bl trampoline_probe_handler - /* - * Replace trampoline address in lr with actual orig_ret_addr return - * address. - */ - mov lr, x0 - - /* The frame pointer (x29) is restored with other registers. */ - restore_all_base_regs - - add sp, sp, #PT_REGS_SIZE - ret - -SYM_CODE_END(__kretprobe_trampoline) diff --git a/arch/arm64/kernel/rethook.c b/arch/arm64/kernel/rethook.c new file mode 100644 index 000000000000..78bb6b968de5 --- /dev/null +++ b/arch/arm64/kernel/rethook.c @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Generic return hook for arm64. + * Most of the code is copied from arch/arm64/kernel/probes/kprobes.c + */ + +#include <linux/kprobes.h> +#include <linux/rethook.h> + +/* This is called from arch_rethook_trampoline() */ +unsigned long __used arch_rethook_trampoline_callback(struct pt_regs *regs) +{ + return rethook_trampoline_handler(regs, regs->regs[29]); +} +NOKPROBE_SYMBOL(arch_rethook_trampoline_callback); + +int arch_rethook_prepare(struct rethook_node *rhn, struct pt_regs *regs, bool mcount) +{ + rhn->ret_addr = regs->regs[30]; + rhn->frame = regs->regs[29]; + + /* replace return addr (x30) with trampoline */ + regs->regs[30] = (u64)arch_rethook_trampoline; + return 0; +} +NOKPROBE_SYMBOL(arch_rethook_prepare); diff --git a/arch/arm64/kernel/rethook_trampoline.S b/arch/arm64/kernel/rethook_trampoline.S new file mode 100644 index 000000000000..146d4553674c --- /dev/null +++ b/arch/arm64/kernel/rethook_trampoline.S @@ -0,0 +1,87 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * trampoline entry and return code for rethook. + * Renamed from arch/arm64/kernel/probes/kprobes_trampoline.S + */ + +#include <linux/linkage.h> +#include <asm/asm-offsets.h> +#include <asm/assembler.h> + + .text + + .macro save_all_base_regs + stp x0, x1, [sp, #S_X0] + stp x2, x3, [sp, #S_X2] + stp x4, x5, [sp, #S_X4] + stp x6, x7, [sp, #S_X6] + stp x8, x9, [sp, #S_X8] + stp x10, x11, [sp, #S_X10] + stp x12, x13, [sp, #S_X12] + stp x14, x15, [sp, #S_X14] + stp x16, x17, [sp, #S_X16] + stp x18, x19, [sp, #S_X18] + stp x20, x21, [sp, #S_X20] + stp x22, x23, [sp, #S_X22] + stp x24, x25, [sp, #S_X24] + stp x26, x27, [sp, #S_X26] + stp x28, x29, [sp, #S_X28] + add x0, sp, #PT_REGS_SIZE + stp lr, x0, [sp, #S_LR] + /* + * Construct a useful saved PSTATE + */ + mrs x0, nzcv + mrs x1, daif + orr x0, x0, x1 + mrs x1, CurrentEL + orr x0, x0, x1 + mrs x1, SPSel + orr x0, x0, x1 + stp xzr, x0, [sp, #S_PC] + .endm + + .macro restore_all_base_regs + ldr x0, [sp, #S_PSTATE] + and x0, x0, #(PSR_N_BIT | PSR_Z_BIT | PSR_C_BIT | PSR_V_BIT) + msr nzcv, x0 + ldp x0, x1, [sp, #S_X0] + ldp x2, x3, [sp, #S_X2] + ldp x4, x5, [sp, #S_X4] + ldp x6, x7, [sp, #S_X6] + ldp x8, x9, [sp, #S_X8] + ldp x10, x11, [sp, #S_X10] + ldp x12, x13, [sp, #S_X12] + ldp x14, x15, [sp, #S_X14] + ldp x16, x17, [sp, #S_X16] + ldp x18, x19, [sp, #S_X18] + ldp x20, x21, [sp, #S_X20] + ldp x22, x23, [sp, #S_X22] + ldp x24, x25, [sp, #S_X24] + ldp x26, x27, [sp, #S_X26] + ldp x28, x29, [sp, #S_X28] + .endm + +SYM_CODE_START(arch_rethook_trampoline) + sub sp, sp, #PT_REGS_SIZE + + save_all_base_regs + + /* Setup a frame pointer. */ + add x29, sp, #S_FP + + mov x0, sp + bl arch_rethook_trampoline_callback + /* + * Replace trampoline address in lr with actual orig_ret_addr return + * address. + */ + mov lr, x0 + + /* The frame pointer (x29) is restored with other registers. */ + restore_all_base_regs + + add sp, sp, #PT_REGS_SIZE + ret + +SYM_CODE_END(arch_rethook_trampoline) diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c index e4103e085681..5b717af4b555 100644 --- a/arch/arm64/kernel/stacktrace.c +++ b/arch/arm64/kernel/stacktrace.c @@ -8,6 +8,7 @@ #include <linux/export.h> #include <linux/ftrace.h> #include <linux/kprobes.h> +#include <linux/rethook.h> #include <linux/sched.h> #include <linux/sched/debug.h> #include <linux/sched/task_stack.h> @@ -38,7 +39,7 @@ static notrace void start_backtrace(struct stackframe *frame, unsigned long fp, { frame->fp = fp; frame->pc = pc; -#ifdef CONFIG_KRETPROBES +#if defined(CONFIG_RETHOOK) frame->kr_cur = NULL; #endif @@ -134,9 +135,9 @@ static int notrace unwind_frame(struct task_struct *tsk, frame->pc = orig_pc; } #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ -#ifdef CONFIG_KRETPROBES - if (is_kretprobe_trampoline(frame->pc)) - frame->pc = kretprobe_find_ret_addr(tsk, (void *)frame->fp, &frame->kr_cur); +#ifdef CONFIG_RETHOOK + if (is_rethook_trampoline(frame->pc)) + frame->pc = rethook_find_ret_addr(tsk, frame->fp, &frame->kr_cur); #endif return 0; ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH bpf 4/4] arm64: rethook: Replace kretprobe trampoline with rethook 2022-04-05 9:34 ` Masami Hiramatsu @ 2022-04-05 17:40 ` kernel test robot -1 siblings, 0 replies; 16+ messages in thread From: kernel test robot @ 2022-04-05 17:40 UTC (permalink / raw) To: Masami Hiramatsu, Alexei Starovoitov Cc: kbuild-all, Daniel Borkmann, Shubham Bansal, Andrii Nakryiko, Masami Hiramatsu, bpf, kernel-team, Jiri Olsa, Steven Rostedt, Naveen N . Rao, Anil S Keshavamurthy, David S . Miller, linux-kernel, Mark Rutland, Will Deacon, Ard Biesheuvel, Russell King, Catalin Marinas, linux-arm-kernel Hi Masami, I love your patch! Perhaps something to improve: [auto build test WARNING on bpf/master] url: https://github.com/intel-lab-lkp/linux/commits/Masami-Hiramatsu/kprobes-rethook-ARM-arm64-Replace-kretprobe-trampoline-with-rethook/20220405-195153 base: https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git master config: arm64-allyesconfig (https://download.01.org/0day-ci/archive/20220406/202204060119.lme7uoGl-lkp@intel.com/config) compiler: aarch64-linux-gcc (GCC) 11.2.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/intel-lab-lkp/linux/commit/74084aa7903f112b1c3df1f864d49b15d8aba270 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Masami-Hiramatsu/kprobes-rethook-ARM-arm64-Replace-kretprobe-trampoline-with-rethook/20220405-195153 git checkout 74084aa7903f112b1c3df1f864d49b15d8aba270 # save the config file to linux build tree mkdir build_dir COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=arm64 SHELL=/bin/bash arch/arm64/kernel/ If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All warnings (new ones prefixed by >>): >> arch/arm64/kernel/rethook.c:11:22: warning: no previous prototype for 'arch_rethook_trampoline_callback' [-Wmissing-prototypes] 11 | unsigned long __used arch_rethook_trampoline_callback(struct pt_regs *regs) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ vim +/arch_rethook_trampoline_callback +11 arch/arm64/kernel/rethook.c 9 10 /* This is called from arch_rethook_trampoline() */ > 11 unsigned long __used arch_rethook_trampoline_callback(struct pt_regs *regs) 12 { 13 return rethook_trampoline_handler(regs, regs->regs[29]); 14 } 15 NOKPROBE_SYMBOL(arch_rethook_trampoline_callback); 16 -- 0-DAY CI Kernel Test Service https://01.org/lkp _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH bpf 4/4] arm64: rethook: Replace kretprobe trampoline with rethook @ 2022-04-05 17:40 ` kernel test robot 0 siblings, 0 replies; 16+ messages in thread From: kernel test robot @ 2022-04-05 17:40 UTC (permalink / raw) To: Masami Hiramatsu, Alexei Starovoitov Cc: kbuild-all, Daniel Borkmann, Shubham Bansal, Andrii Nakryiko, Masami Hiramatsu, bpf, kernel-team, Jiri Olsa, Steven Rostedt, Naveen N . Rao, Anil S Keshavamurthy, David S . Miller, linux-kernel, Mark Rutland, Will Deacon, Ard Biesheuvel, Russell King, Catalin Marinas, linux-arm-kernel Hi Masami, I love your patch! Perhaps something to improve: [auto build test WARNING on bpf/master] url: https://github.com/intel-lab-lkp/linux/commits/Masami-Hiramatsu/kprobes-rethook-ARM-arm64-Replace-kretprobe-trampoline-with-rethook/20220405-195153 base: https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git master config: arm64-allyesconfig (https://download.01.org/0day-ci/archive/20220406/202204060119.lme7uoGl-lkp@intel.com/config) compiler: aarch64-linux-gcc (GCC) 11.2.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/intel-lab-lkp/linux/commit/74084aa7903f112b1c3df1f864d49b15d8aba270 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Masami-Hiramatsu/kprobes-rethook-ARM-arm64-Replace-kretprobe-trampoline-with-rethook/20220405-195153 git checkout 74084aa7903f112b1c3df1f864d49b15d8aba270 # save the config file to linux build tree mkdir build_dir COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=arm64 SHELL=/bin/bash arch/arm64/kernel/ If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All warnings (new ones prefixed by >>): >> arch/arm64/kernel/rethook.c:11:22: warning: no previous prototype for 'arch_rethook_trampoline_callback' [-Wmissing-prototypes] 11 | unsigned long __used arch_rethook_trampoline_callback(struct pt_regs *regs) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ vim +/arch_rethook_trampoline_callback +11 arch/arm64/kernel/rethook.c 9 10 /* This is called from arch_rethook_trampoline() */ > 11 unsigned long __used arch_rethook_trampoline_callback(struct pt_regs *regs) 12 { 13 return rethook_trampoline_handler(regs, regs->regs[29]); 14 } 15 NOKPROBE_SYMBOL(arch_rethook_trampoline_callback); 16 -- 0-DAY CI Kernel Test Service https://01.org/lkp ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH bpf 4/4] arm64: rethook: Replace kretprobe trampoline with rethook 2022-04-05 9:34 ` Masami Hiramatsu @ 2022-04-05 21:25 ` kernel test robot -1 siblings, 0 replies; 16+ messages in thread From: kernel test robot @ 2022-04-05 21:25 UTC (permalink / raw) To: Masami Hiramatsu, Alexei Starovoitov Cc: llvm, kbuild-all, Daniel Borkmann, Shubham Bansal, Andrii Nakryiko, Masami Hiramatsu, bpf, kernel-team, Jiri Olsa, Steven Rostedt, Naveen N . Rao, Anil S Keshavamurthy, David S . Miller, linux-kernel, Mark Rutland, Will Deacon, Ard Biesheuvel, Russell King, Catalin Marinas, linux-arm-kernel Hi Masami, I love your patch! Perhaps something to improve: [auto build test WARNING on bpf/master] url: https://github.com/intel-lab-lkp/linux/commits/Masami-Hiramatsu/kprobes-rethook-ARM-arm64-Replace-kretprobe-trampoline-with-rethook/20220405-195153 base: https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git master config: arm64-randconfig-r022-20220405 (https://download.01.org/0day-ci/archive/20220406/202204060512.Pzw5bnTd-lkp@intel.com/config) compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project c4a1b07d0979e7ff20d7d541af666d822d66b566) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # install arm64 cross compiling tool for clang build # apt-get install binutils-aarch64-linux-gnu # https://github.com/intel-lab-lkp/linux/commit/74084aa7903f112b1c3df1f864d49b15d8aba270 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Masami-Hiramatsu/kprobes-rethook-ARM-arm64-Replace-kretprobe-trampoline-with-rethook/20220405-195153 git checkout 74084aa7903f112b1c3df1f864d49b15d8aba270 # save the config file to linux build tree mkdir build_dir COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=arm64 SHELL=/bin/bash arch/arm64/kernel/ If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All warnings (new ones prefixed by >>): >> arch/arm64/kernel/rethook.c:11:22: warning: no previous prototype for function 'arch_rethook_trampoline_callback' [-Wmissing-prototypes] unsigned long __used arch_rethook_trampoline_callback(struct pt_regs *regs) ^ arch/arm64/kernel/rethook.c:11:1: note: declare 'static' if the function is not intended to be used outside of this translation unit unsigned long __used arch_rethook_trampoline_callback(struct pt_regs *regs) ^ static 1 warning generated. vim +/arch_rethook_trampoline_callback +11 arch/arm64/kernel/rethook.c 9 10 /* This is called from arch_rethook_trampoline() */ > 11 unsigned long __used arch_rethook_trampoline_callback(struct pt_regs *regs) 12 { 13 return rethook_trampoline_handler(regs, regs->regs[29]); 14 } 15 NOKPROBE_SYMBOL(arch_rethook_trampoline_callback); 16 -- 0-DAY CI Kernel Test Service https://01.org/lkp ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH bpf 4/4] arm64: rethook: Replace kretprobe trampoline with rethook @ 2022-04-05 21:25 ` kernel test robot 0 siblings, 0 replies; 16+ messages in thread From: kernel test robot @ 2022-04-05 21:25 UTC (permalink / raw) To: Masami Hiramatsu, Alexei Starovoitov Cc: llvm, kbuild-all, Daniel Borkmann, Shubham Bansal, Andrii Nakryiko, Masami Hiramatsu, bpf, kernel-team, Jiri Olsa, Steven Rostedt, Naveen N . Rao, Anil S Keshavamurthy, David S . Miller, linux-kernel, Mark Rutland, Will Deacon, Ard Biesheuvel, Russell King, Catalin Marinas, linux-arm-kernel Hi Masami, I love your patch! Perhaps something to improve: [auto build test WARNING on bpf/master] url: https://github.com/intel-lab-lkp/linux/commits/Masami-Hiramatsu/kprobes-rethook-ARM-arm64-Replace-kretprobe-trampoline-with-rethook/20220405-195153 base: https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git master config: arm64-randconfig-r022-20220405 (https://download.01.org/0day-ci/archive/20220406/202204060512.Pzw5bnTd-lkp@intel.com/config) compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project c4a1b07d0979e7ff20d7d541af666d822d66b566) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # install arm64 cross compiling tool for clang build # apt-get install binutils-aarch64-linux-gnu # https://github.com/intel-lab-lkp/linux/commit/74084aa7903f112b1c3df1f864d49b15d8aba270 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Masami-Hiramatsu/kprobes-rethook-ARM-arm64-Replace-kretprobe-trampoline-with-rethook/20220405-195153 git checkout 74084aa7903f112b1c3df1f864d49b15d8aba270 # save the config file to linux build tree mkdir build_dir COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=arm64 SHELL=/bin/bash arch/arm64/kernel/ If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All warnings (new ones prefixed by >>): >> arch/arm64/kernel/rethook.c:11:22: warning: no previous prototype for function 'arch_rethook_trampoline_callback' [-Wmissing-prototypes] unsigned long __used arch_rethook_trampoline_callback(struct pt_regs *regs) ^ arch/arm64/kernel/rethook.c:11:1: note: declare 'static' if the function is not intended to be used outside of this translation unit unsigned long __used arch_rethook_trampoline_callback(struct pt_regs *regs) ^ static 1 warning generated. vim +/arch_rethook_trampoline_callback +11 arch/arm64/kernel/rethook.c 9 10 /* This is called from arch_rethook_trampoline() */ > 11 unsigned long __used arch_rethook_trampoline_callback(struct pt_regs *regs) 12 { 13 return rethook_trampoline_handler(regs, regs->regs[29]); 14 } 15 NOKPROBE_SYMBOL(arch_rethook_trampoline_callback); 16 -- 0-DAY CI Kernel Test Service https://01.org/lkp _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2022-04-06 20:29 UTC | newest] Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2022-04-05 9:33 [PATCH bpf 0/4] kprobes: rethook, ARM, arm64: Replace kretprobe trampoline with rethook Masami Hiramatsu 2022-04-05 9:33 ` [PATCH bpf 0/4] kprobes: rethook,ARM,arm64: " Masami Hiramatsu 2022-04-05 9:33 ` [PATCH bpf 1/4] ARM: unwind: Initialize the lr_addr field of unwind_ctrl_block Masami Hiramatsu 2022-04-05 9:33 ` Masami Hiramatsu 2022-04-06 18:53 ` kernel test robot 2022-04-06 18:53 ` kernel test robot 2022-04-05 9:33 ` [PATCH bpf 2/4] rethook, fprobe, kprobes: Check a failure in the rethook_hook() Masami Hiramatsu 2022-04-05 9:33 ` [PATCH bpf 2/4] rethook,fprobe,kprobes: " Masami Hiramatsu 2022-04-05 9:34 ` [PATCH bpf 3/4] ARM: rethook: Replace kretprobe trampoline with rethook Masami Hiramatsu 2022-04-05 9:34 ` Masami Hiramatsu 2022-04-05 9:34 ` [PATCH bpf 4/4] arm64: " Masami Hiramatsu 2022-04-05 9:34 ` Masami Hiramatsu 2022-04-05 17:40 ` kernel test robot 2022-04-05 17:40 ` kernel test robot 2022-04-05 21:25 ` kernel test robot 2022-04-05 21:25 ` kernel test robot
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.