mirror of
https://github.com/armbian/linux-cix.git
synced 2026-01-06 12:30:45 -08:00
Merge tag 'trace-v5.16' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace
Pull tracing updates from Steven Rostedt: - kprobes: Restructured stack unwinder to show properly on x86 when a stack dump happens from a kretprobe callback. - Fix to bootconfig parsing - Have tracefs allow owner and group permissions by default (only denying others). There's been pressure to allow non root to tracefs in a controlled fashion, and using groups is probably the safest. - Bootconfig memory managament updates. - Bootconfig clean up to have the tools directory be less dependent on changes in the kernel tree. - Allow perf to be traced by function tracer. - Rewrite of function graph tracer to be a callback from the function tracer instead of having its own trampoline (this change will happen on an arch by arch basis, and currently only x86_64 implements it). - Allow multiple direct trampolines (bpf hooks to functions) be batched together in one synchronization. - Allow histogram triggers to add variables that can perform calculations against the event's fields. - Use the linker to determine architecture callbacks from the ftrace trampoline to allow for proper parameter prototypes and prevent warnings from the compiler. - Extend histogram triggers to key off of variables. - Have trace recursion use bit magic to determine preempt context over if branches. - Have trace recursion disable preemption as all use cases do anyway. - Added testing for verification of tracing utilities. - Various small clean ups and fixes. * tag 'trace-v5.16' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace: (101 commits) tracing/histogram: Fix semicolon.cocci warnings tracing/histogram: Fix documentation inline emphasis warning tracing: Increase PERF_MAX_TRACE_SIZE to handle Sentinel1 and docker together tracing: Show size of requested perf buffer bootconfig: Initialize ret in xbc_parse_tree() ftrace: do CPU checking after preemption disabled ftrace: disable preemption when recursion locked tracing/histogram: Document expression arithmetic and constants tracing/histogram: Optimize division by a power of 2 tracing/histogram: Covert expr to const if both operands are constants tracing/histogram: Simplify handling of .sym-offset in expressions tracing: Fix operator precedence for hist triggers expression tracing: Add division and multiplication support for hist triggers tracing: Add support for creating hist trigger variables from literal selftests/ftrace: Stop tracing while reading the trace file by default MAINTAINERS: Update KPROBES and TRACING entries test_kprobes: Move it from kernel/ to lib/ docs, kprobes: Remove invalid URL and add new reference samples/kretprobes: Fix return value if register_kretprobe() failed lib/bootconfig: Fix the xbc_get_info kerneldoc ...
This commit is contained in:
@@ -1763,6 +1763,20 @@ using the same key and variable from yet another event::
|
||||
|
||||
# echo 'hist:key=pid:wakeupswitch_lat=$wakeup_lat+$switchtime_lat ...' >> event3/trigger
|
||||
|
||||
Expressions support the use of addition, subtraction, multiplication and
|
||||
division operators (+-\*/).
|
||||
|
||||
Note that division by zero always returns -1.
|
||||
|
||||
Numeric constants can also be used directly in an expression::
|
||||
|
||||
# echo 'hist:keys=next_pid:timestamp_secs=common_timestamp/1000000 ...' >> event/trigger
|
||||
|
||||
or assigned to a variable and referenced in a subsequent expression::
|
||||
|
||||
# echo 'hist:keys=next_pid:us_per_sec=1000000 ...' >> event/trigger
|
||||
# echo 'hist:keys=next_pid:timestamp_secs=common_timestamp/$us_per_sec ...' >> event/trigger
|
||||
|
||||
2.2.2 Synthetic Events
|
||||
----------------------
|
||||
|
||||
|
||||
@@ -784,6 +784,6 @@ References
|
||||
|
||||
For additional information on Kprobes, refer to the following URLs:
|
||||
|
||||
- https://www.ibm.com/developerworks/library/l-kprobes/index.html
|
||||
- https://lwn.net/Articles/132196/
|
||||
- https://www.kernel.org/doc/ols/2006/ols2006v2-pages-109-124.pdf
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ Timerlat tracer
|
||||
###############
|
||||
|
||||
The timerlat tracer aims to help the preemptive kernel developers to
|
||||
find souces of wakeup latencies of real-time threads. Like cyclictest,
|
||||
find sources of wakeup latencies of real-time threads. Like cyclictest,
|
||||
the tracer sets a periodic timer that wakes up a thread. The thread then
|
||||
computes a *wakeup latency* value as the difference between the *current
|
||||
time* and the *absolute time* that the timer was set to expire. The main
|
||||
@@ -50,14 +50,14 @@ The second is the *timer latency* observed by the thread. The ACTIVATION
|
||||
ID field serves to relate the *irq* execution to its respective *thread*
|
||||
execution.
|
||||
|
||||
The *irq*/*thread* splitting is important to clarify at which context
|
||||
The *irq*/*thread* splitting is important to clarify in which context
|
||||
the unexpected high value is coming from. The *irq* context can be
|
||||
delayed by hardware related actions, such as SMIs, NMIs, IRQs
|
||||
or by a thread masking interrupts. Once the timer happens, the delay
|
||||
delayed by hardware-related actions, such as SMIs, NMIs, IRQs,
|
||||
or by thread masking interrupts. Once the timer happens, the delay
|
||||
can also be influenced by blocking caused by threads. For example, by
|
||||
postponing the scheduler execution via preempt_disable(), by the
|
||||
scheduler execution, or by masking interrupts. Threads can
|
||||
also be delayed by the interference from other threads and IRQs.
|
||||
postponing the scheduler execution via preempt_disable(), scheduler
|
||||
execution, or masking interrupts. Threads can also be delayed by the
|
||||
interference from other threads and IRQs.
|
||||
|
||||
Tracer options
|
||||
---------------------
|
||||
@@ -68,14 +68,14 @@ directory. The timerlat configs are:
|
||||
|
||||
- cpus: CPUs at which a timerlat thread will execute.
|
||||
- timerlat_period_us: the period of the timerlat thread.
|
||||
- osnoise/stop_tracing_us: stop the system tracing if a
|
||||
- stop_tracing_us: stop the system tracing if a
|
||||
timer latency at the *irq* context higher than the configured
|
||||
value happens. Writing 0 disables this option.
|
||||
- stop_tracing_total_us: stop the system tracing if a
|
||||
timer latency at the *thread* context higher than the configured
|
||||
timer latency at the *thread* context is higher than the configured
|
||||
value happens. Writing 0 disables this option.
|
||||
- print_stack: save the stack of the IRQ ocurrence, and print
|
||||
it afte the *thread context* event".
|
||||
- print_stack: save the stack of the IRQ occurrence, and print
|
||||
it after the *thread context* event".
|
||||
|
||||
timerlat and osnoise
|
||||
----------------------------
|
||||
@@ -95,7 +95,7 @@ For example::
|
||||
timerlat/5-1035 [005] ....... 548.771104: #402268 context thread timer_latency 39960 ns
|
||||
|
||||
In this case, the root cause of the timer latency does not point to a
|
||||
single cause, but to multiple ones. Firstly, the timer IRQ was delayed
|
||||
single cause but to multiple ones. Firstly, the timer IRQ was delayed
|
||||
for 13 us, which may point to a long IRQ disabled section (see IRQ
|
||||
stacktrace section). Then the timer interrupt that wakes up the timerlat
|
||||
thread took 7597 ns, and the qxl:21 device IRQ took 7139 ns. Finally,
|
||||
|
||||
@@ -10482,10 +10482,13 @@ M: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
|
||||
M: "David S. Miller" <davem@davemloft.net>
|
||||
M: Masami Hiramatsu <mhiramat@kernel.org>
|
||||
S: Maintained
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace.git
|
||||
F: Documentation/trace/kprobes.rst
|
||||
F: include/asm-generic/kprobes.h
|
||||
F: include/linux/kprobes.h
|
||||
F: kernel/kprobes.c
|
||||
F: lib/test_kprobes.c
|
||||
F: samples/kprobes
|
||||
|
||||
KS0108 LCD CONTROLLER DRIVER
|
||||
M: Miguel Ojeda <ojeda@kernel.org>
|
||||
@@ -19026,7 +19029,7 @@ TRACING
|
||||
M: Steven Rostedt <rostedt@goodmis.org>
|
||||
M: Ingo Molnar <mingo@redhat.com>
|
||||
S: Maintained
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git perf/core
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace.git
|
||||
F: Documentation/trace/ftrace.rst
|
||||
F: arch/*/*/*/ftrace.h
|
||||
F: arch/*/kernel/ftrace.c
|
||||
|
||||
@@ -191,6 +191,14 @@ config HAVE_OPTPROBES
|
||||
config HAVE_KPROBES_ON_FTRACE
|
||||
bool
|
||||
|
||||
config ARCH_CORRECT_STACKTRACE_ON_KRETPROBE
|
||||
bool
|
||||
help
|
||||
Since kretprobes modifies return address on the stack, the
|
||||
stacktrace may see the kretprobe trampoline address instead
|
||||
of correct one. If the architecture stacktrace code and
|
||||
unwinder can adjust such entries, select this configuration.
|
||||
|
||||
config HAVE_FUNCTION_ERROR_INJECTION
|
||||
bool
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ struct kprobe_ctlblk {
|
||||
};
|
||||
|
||||
int kprobe_fault_handler(struct pt_regs *regs, unsigned long cause);
|
||||
void kretprobe_trampoline(void);
|
||||
void __kretprobe_trampoline(void);
|
||||
void trap_is_kprobe(unsigned long address, struct pt_regs *regs);
|
||||
#else
|
||||
#define trap_is_kprobe(address, regs)
|
||||
|
||||
@@ -149,6 +149,11 @@ static inline long regs_return_value(struct pt_regs *regs)
|
||||
return (long)regs->r0;
|
||||
}
|
||||
|
||||
static inline void instruction_pointer_set(struct pt_regs *regs,
|
||||
unsigned long val)
|
||||
{
|
||||
instruction_pointer(regs) = val;
|
||||
}
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#endif /* __ASM_PTRACE_H */
|
||||
|
||||
@@ -363,8 +363,9 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
|
||||
|
||||
static void __used kretprobe_trampoline_holder(void)
|
||||
{
|
||||
__asm__ __volatile__(".global kretprobe_trampoline\n"
|
||||
"kretprobe_trampoline:\n" "nop\n");
|
||||
__asm__ __volatile__(".global __kretprobe_trampoline\n"
|
||||
"__kretprobe_trampoline:\n"
|
||||
"nop\n");
|
||||
}
|
||||
|
||||
void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
|
||||
@@ -375,13 +376,13 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
|
||||
ri->fp = NULL;
|
||||
|
||||
/* Replace the return addr with trampoline addr */
|
||||
regs->blink = (unsigned long)&kretprobe_trampoline;
|
||||
regs->blink = (unsigned long)&__kretprobe_trampoline;
|
||||
}
|
||||
|
||||
static int __kprobes trampoline_probe_handler(struct kprobe *p,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
regs->ret = __kretprobe_trampoline_handler(regs, &kretprobe_trampoline, NULL);
|
||||
regs->ret = __kretprobe_trampoline_handler(regs, NULL);
|
||||
|
||||
/* By returning a non zero value, we are telling the kprobe handler
|
||||
* that we don't want the post_handler to run
|
||||
@@ -390,7 +391,7 @@ static int __kprobes trampoline_probe_handler(struct kprobe *p,
|
||||
}
|
||||
|
||||
static struct kprobe trampoline_p = {
|
||||
.addr = (kprobe_opcode_t *) &kretprobe_trampoline,
|
||||
.addr = (kprobe_opcode_t *) &__kretprobe_trampoline,
|
||||
.pre_handler = trampoline_probe_handler
|
||||
};
|
||||
|
||||
@@ -402,7 +403,7 @@ int __init arch_init_kprobes(void)
|
||||
|
||||
int __kprobes arch_trampoline_kprobe(struct kprobe *p)
|
||||
{
|
||||
if (p->addr == (kprobe_opcode_t *) &kretprobe_trampoline)
|
||||
if (p->addr == (kprobe_opcode_t *) &__kretprobe_trampoline)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -3,6 +3,7 @@ config ARM
|
||||
bool
|
||||
default y
|
||||
select ARCH_32BIT_OFF_T
|
||||
select ARCH_CORRECT_STACKTRACE_ON_KRETPROBE if HAVE_KRETPROBES && FRAME_POINTER && !ARM_UNWIND
|
||||
select ARCH_HAS_BINFMT_FLAT
|
||||
select ARCH_HAS_DEBUG_VIRTUAL if MMU
|
||||
select ARCH_HAS_DMA_WRITE_COMBINE if !ARM_DMA_MEM_BUFFERABLE
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#define __ASM_STACKTRACE_H
|
||||
|
||||
#include <asm/ptrace.h>
|
||||
#include <linux/llist.h>
|
||||
|
||||
struct stackframe {
|
||||
/*
|
||||
@@ -13,6 +14,10 @@ struct stackframe {
|
||||
unsigned long sp;
|
||||
unsigned long lr;
|
||||
unsigned long pc;
|
||||
#ifdef CONFIG_KRETPROBES
|
||||
struct llist_node *kr_cur;
|
||||
struct task_struct *tsk;
|
||||
#endif
|
||||
};
|
||||
|
||||
static __always_inline
|
||||
@@ -22,6 +27,10 @@ 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
|
||||
frame->kr_cur = NULL;
|
||||
frame->tsk = current;
|
||||
#endif
|
||||
}
|
||||
|
||||
extern int unwind_frame(struct stackframe *frame);
|
||||
|
||||
@@ -193,11 +193,6 @@ int ftrace_make_nop(struct module *mod,
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int __init ftrace_dyn_arch_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_DYNAMIC_FTRACE */
|
||||
|
||||
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
|
||||
|
||||
@@ -42,6 +42,10 @@ void *return_address(unsigned int level)
|
||||
frame.sp = current_stack_pointer;
|
||||
frame.lr = (unsigned long)__builtin_return_address(0);
|
||||
frame.pc = (unsigned long)return_address;
|
||||
#ifdef CONFIG_KRETPROBES
|
||||
frame.kr_cur = NULL;
|
||||
frame.tsk = current;
|
||||
#endif
|
||||
|
||||
walk_stackframe(&frame, save_return_addr, &data);
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
#include <linux/export.h>
|
||||
#include <linux/kprobes.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/sched/debug.h>
|
||||
#include <linux/stacktrace.h>
|
||||
@@ -54,8 +55,7 @@ int notrace unwind_frame(struct stackframe *frame)
|
||||
|
||||
frame->sp = frame->fp;
|
||||
frame->fp = *(unsigned long *)(fp);
|
||||
frame->pc = frame->lr;
|
||||
frame->lr = *(unsigned long *)(fp + 4);
|
||||
frame->pc = *(unsigned long *)(fp + 4);
|
||||
#else
|
||||
/* check current frame pointer is within bounds */
|
||||
if (fp < low + 12 || fp > high - 4)
|
||||
@@ -66,6 +66,11 @@ 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);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -157,6 +162,10 @@ static noinline void __save_stack_trace(struct task_struct *tsk,
|
||||
frame.lr = (unsigned long)__builtin_return_address(0);
|
||||
frame.pc = (unsigned long)__save_stack_trace;
|
||||
}
|
||||
#ifdef CONFIG_KRETPROBES
|
||||
frame.kr_cur = NULL;
|
||||
frame.tsk = tsk;
|
||||
#endif
|
||||
|
||||
walk_stackframe(&frame, save_trace, &data);
|
||||
}
|
||||
@@ -174,6 +183,10 @@ 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
|
||||
frame.kr_cur = NULL;
|
||||
frame.tsk = current;
|
||||
#endif
|
||||
|
||||
walk_stackframe(&frame, save_trace, &data);
|
||||
}
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
* Copyright (C) 2007 Marvell Ltd.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "kprobes: " fmt
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/kprobes.h>
|
||||
#include <linux/module.h>
|
||||
@@ -278,7 +280,7 @@ void __kprobes kprobe_handler(struct pt_regs *regs)
|
||||
break;
|
||||
case KPROBE_REENTER:
|
||||
/* A nested probe was hit in FIQ, it is a BUG */
|
||||
pr_warn("Unrecoverable kprobe detected.\n");
|
||||
pr_warn("Failed to recover from reentered kprobes.\n");
|
||||
dump_kprobe(p);
|
||||
fallthrough;
|
||||
default:
|
||||
@@ -366,19 +368,41 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
|
||||
/*
|
||||
* 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 to the user return-handler. This is
|
||||
* not a complete pt_regs structure, but that should be plenty sufficient
|
||||
* for kretprobe handlers which should normally be interested in r0 only
|
||||
* anyway.
|
||||
* 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)
|
||||
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
|
||||
@@ -387,11 +411,10 @@ void __naked __kprobes kretprobe_trampoline(void)
|
||||
: : : "memory");
|
||||
}
|
||||
|
||||
/* Called from kretprobe_trampoline */
|
||||
/* Called from __kretprobe_trampoline */
|
||||
static __used __kprobes void *trampoline_handler(struct pt_regs *regs)
|
||||
{
|
||||
return (void *)kretprobe_trampoline_handler(regs, &kretprobe_trampoline,
|
||||
(void *)regs->ARM_fp);
|
||||
return (void *)kretprobe_trampoline_handler(regs, (void *)regs->ARM_fp);
|
||||
}
|
||||
|
||||
void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
|
||||
@@ -401,7 +424,7 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
|
||||
ri->fp = (void *)regs->ARM_fp;
|
||||
|
||||
/* Replace the return addr with trampoline addr. */
|
||||
regs->ARM_lr = (unsigned long)&kretprobe_trampoline;
|
||||
regs->ARM_lr = (unsigned long)&__kretprobe_trampoline;
|
||||
}
|
||||
|
||||
int __kprobes arch_trampoline_kprobe(struct kprobe *p)
|
||||
|
||||
@@ -347,10 +347,11 @@ void arch_unoptimize_kprobes(struct list_head *oplist,
|
||||
}
|
||||
|
||||
int arch_within_optimized_kprobe(struct optimized_kprobe *op,
|
||||
unsigned long addr)
|
||||
kprobe_opcode_t *addr)
|
||||
{
|
||||
return ((unsigned long)op->kp.addr <= addr &&
|
||||
(unsigned long)op->kp.addr + RELATIVEJUMP_SIZE > addr);
|
||||
return (op->kp.addr <= addr &&
|
||||
op->kp.addr + (RELATIVEJUMP_SIZE / sizeof(kprobe_opcode_t)) > addr);
|
||||
|
||||
}
|
||||
|
||||
void arch_remove_optimized_kprobe(struct optimized_kprobe *op)
|
||||
|
||||
@@ -11,6 +11,7 @@ config ARM64
|
||||
select ACPI_PPTT if ACPI
|
||||
select ARCH_HAS_DEBUG_WX
|
||||
select ARCH_BINFMT_ELF_STATE
|
||||
select ARCH_CORRECT_STACKTRACE_ON_KRETPROBE
|
||||
select ARCH_ENABLE_HUGEPAGE_MIGRATION if HUGETLB_PAGE && MIGRATION
|
||||
select ARCH_ENABLE_MEMORY_HOTPLUG
|
||||
select ARCH_ENABLE_MEMORY_HOTREMOVE
|
||||
|
||||
@@ -39,7 +39,7 @@ 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 __kretprobe_trampoline(void);
|
||||
void __kprobes *trampoline_probe_handler(struct pt_regs *regs);
|
||||
|
||||
#endif /* CONFIG_KPROBES */
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <linux/sched.h>
|
||||
#include <linux/sched/task_stack.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/llist.h>
|
||||
|
||||
#include <asm/memory.h>
|
||||
#include <asm/ptrace.h>
|
||||
@@ -59,6 +60,9 @@ struct stackframe {
|
||||
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
|
||||
int graph;
|
||||
#endif
|
||||
#ifdef CONFIG_KRETPROBES
|
||||
struct llist_node *kr_cur;
|
||||
#endif
|
||||
};
|
||||
|
||||
extern int unwind_frame(struct task_struct *tsk, struct stackframe *frame);
|
||||
|
||||
@@ -236,11 +236,6 @@ void arch_ftrace_update_code(int command)
|
||||
command |= FTRACE_MAY_SLEEP;
|
||||
ftrace_modify_all_code(command);
|
||||
}
|
||||
|
||||
int __init ftrace_dyn_arch_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_DYNAMIC_FTRACE */
|
||||
|
||||
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
* Copyright (C) 2013 Linaro Limited.
|
||||
* Author: Sandeepa Prabhu <sandeepa.prabhu@linaro.org>
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "kprobes: " fmt
|
||||
|
||||
#include <linux/extable.h>
|
||||
#include <linux/kasan.h>
|
||||
#include <linux/kernel.h>
|
||||
@@ -218,7 +221,7 @@ static int __kprobes reenter_kprobe(struct kprobe *p,
|
||||
break;
|
||||
case KPROBE_HIT_SS:
|
||||
case KPROBE_REENTER:
|
||||
pr_warn("Unrecoverable kprobe detected.\n");
|
||||
pr_warn("Failed to recover from reentered kprobes.\n");
|
||||
dump_kprobe(p);
|
||||
BUG();
|
||||
break;
|
||||
@@ -398,18 +401,17 @@ int __init arch_populate_kprobe_blacklist(void)
|
||||
|
||||
void __kprobes __used *trampoline_probe_handler(struct pt_regs *regs)
|
||||
{
|
||||
return (void *)kretprobe_trampoline_handler(regs, &kretprobe_trampoline,
|
||||
(void *)kernel_stack_pointer(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 *)kernel_stack_pointer(regs);
|
||||
ri->fp = (void *)regs->regs[29];
|
||||
|
||||
/* replace return addr (x30) with trampoline */
|
||||
regs->regs[30] = (long)&kretprobe_trampoline;
|
||||
regs->regs[30] = (long)&__kretprobe_trampoline;
|
||||
}
|
||||
|
||||
int __kprobes arch_trampoline_kprobe(struct kprobe *p)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user