diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index 1c83433a97e8..d801a286e13f 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -26,6 +26,7 @@ #include #include #include +#include /* * Export tracepoints that act as a bare tracehook (ie: have no trace event @@ -92,3 +93,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_update_cpus_allowed); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_set_skip_swapcache_flags); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_set_gfp_zone_flags); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_set_readahead_gfp_mask); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_preempt_disable); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_preempt_enable); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_irqs_disable); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_irqs_enable); diff --git a/include/trace/hooks/preemptirq.h b/include/trace/hooks/preemptirq.h new file mode 100644 index 000000000000..be96261280a6 --- /dev/null +++ b/include/trace/hooks/preemptirq.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM preemptirq + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH trace/hooks + +#if !defined(_TRACE_HOOK_PREEMPTIRQ_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_HOOK_PREEMPTIRQ_H + +#include +#include + +#if defined(CONFIG_TRACEPOINTS) && defined(CONFIG_ANDROID_VENDOR_HOOKS) + +DECLARE_RESTRICTED_HOOK(android_rvh_preempt_disable, + TP_PROTO(unsigned long ip, unsigned long parent_ip), + TP_ARGS(ip, parent_ip), 1); + +DECLARE_RESTRICTED_HOOK(android_rvh_preempt_enable, + TP_PROTO(unsigned long ip, unsigned long parent_ip), + TP_ARGS(ip, parent_ip), 1); + +DECLARE_RESTRICTED_HOOK(android_rvh_irqs_disable, + TP_PROTO(unsigned long ip, unsigned long parent_ip), + TP_ARGS(ip, parent_ip), 1); + +DECLARE_RESTRICTED_HOOK(android_rvh_irqs_enable, + TP_PROTO(unsigned long ip, unsigned long parent_ip), + TP_ARGS(ip, parent_ip), 1); + +#else + +#define trace_android_rvh_preempt_disable(ip, parent_ip) +#define trace_android_rvh_preempt_enable(ip, parent_ip) +#define trace_android_rvh_irqs_disable(ip, parent_ip) +#define trace_android_rvh_irqs_enable(ip, parent_ip) + +#endif + +#endif /* _TRACE_HOOK_PREEMPTIRQ_H */ +/* This part must be outside protection */ +#include diff --git a/kernel/trace/trace_preemptirq.c b/kernel/trace/trace_preemptirq.c index f4938040c228..c881e5a5efb8 100644 --- a/kernel/trace/trace_preemptirq.c +++ b/kernel/trace/trace_preemptirq.c @@ -14,6 +14,8 @@ #define CREATE_TRACE_POINTS #include +#undef CREATE_TRACE_POINTS +#include #ifdef CONFIG_TRACE_IRQFLAGS /* Per-cpu variable to prevent redundant calls when IRQs already off */ @@ -28,8 +30,11 @@ static DEFINE_PER_CPU(int, tracing_irq_cpu); void trace_hardirqs_on_prepare(void) { if (this_cpu_read(tracing_irq_cpu)) { - if (!in_nmi()) + if (!in_nmi()) { trace_irq_enable(CALLER_ADDR0, CALLER_ADDR1); + trace_android_rvh_irqs_enable(CALLER_ADDR0, + CALLER_ADDR1); + } tracer_hardirqs_on(CALLER_ADDR0, CALLER_ADDR1); this_cpu_write(tracing_irq_cpu, 0); } @@ -40,8 +45,11 @@ NOKPROBE_SYMBOL(trace_hardirqs_on_prepare); void trace_hardirqs_on(void) { if (this_cpu_read(tracing_irq_cpu)) { - if (!in_nmi()) + if (!in_nmi()) { trace_irq_enable_rcuidle(CALLER_ADDR0, CALLER_ADDR1); + trace_android_rvh_irqs_enable(CALLER_ADDR0, + CALLER_ADDR1); + } tracer_hardirqs_on(CALLER_ADDR0, CALLER_ADDR1); this_cpu_write(tracing_irq_cpu, 0); } @@ -63,8 +71,11 @@ void trace_hardirqs_off_finish(void) if (!this_cpu_read(tracing_irq_cpu)) { this_cpu_write(tracing_irq_cpu, 1); tracer_hardirqs_off(CALLER_ADDR0, CALLER_ADDR1); - if (!in_nmi()) + if (!in_nmi()) { trace_irq_disable(CALLER_ADDR0, CALLER_ADDR1); + trace_android_rvh_irqs_disable(CALLER_ADDR0, + CALLER_ADDR1); + } } } @@ -78,8 +89,11 @@ void trace_hardirqs_off(void) if (!this_cpu_read(tracing_irq_cpu)) { this_cpu_write(tracing_irq_cpu, 1); tracer_hardirqs_off(CALLER_ADDR0, CALLER_ADDR1); - if (!in_nmi()) + if (!in_nmi()) { trace_irq_disable_rcuidle(CALLER_ADDR0, CALLER_ADDR1); + trace_android_rvh_irqs_disable(CALLER_ADDR0, + CALLER_ADDR1); + } } } EXPORT_SYMBOL(trace_hardirqs_off); @@ -88,8 +102,11 @@ NOKPROBE_SYMBOL(trace_hardirqs_off); __visible void trace_hardirqs_on_caller(unsigned long caller_addr) { if (this_cpu_read(tracing_irq_cpu)) { - if (!in_nmi()) + if (!in_nmi()) { trace_irq_enable_rcuidle(CALLER_ADDR0, caller_addr); + trace_android_rvh_irqs_enable(CALLER_ADDR0, + caller_addr); + } tracer_hardirqs_on(CALLER_ADDR0, caller_addr); this_cpu_write(tracing_irq_cpu, 0); } @@ -107,8 +124,11 @@ __visible void trace_hardirqs_off_caller(unsigned long caller_addr) if (!this_cpu_read(tracing_irq_cpu)) { this_cpu_write(tracing_irq_cpu, 1); tracer_hardirqs_off(CALLER_ADDR0, caller_addr); - if (!in_nmi()) + if (!in_nmi()) { trace_irq_disable_rcuidle(CALLER_ADDR0, caller_addr); + trace_android_rvh_irqs_enable(CALLER_ADDR0, + caller_addr); + } } } EXPORT_SYMBOL(trace_hardirqs_off_caller); @@ -119,15 +139,19 @@ NOKPROBE_SYMBOL(trace_hardirqs_off_caller); void trace_preempt_on(unsigned long a0, unsigned long a1) { - if (!in_nmi()) + if (!in_nmi()) { trace_preempt_enable_rcuidle(a0, a1); + trace_android_rvh_preempt_enable(a0, a1); + } tracer_preempt_on(a0, a1); } void trace_preempt_off(unsigned long a0, unsigned long a1) { - if (!in_nmi()) + if (!in_nmi()) { trace_preempt_disable_rcuidle(a0, a1); + trace_android_rvh_preempt_disable(a0, a1); + } tracer_preempt_off(a0, a1); } #endif