diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index bb6249021ea4..29675804edd2 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -41,6 +41,8 @@ #include #include +#include + struct fault_info { int (*fn)(unsigned long far, unsigned int esr, struct pt_regs *regs); @@ -290,6 +292,7 @@ static void die_kernel_fault(const char *msg, unsigned long addr, pr_alert("Unable to handle kernel %s at virtual address %016lx\n", msg, addr); + trace_android_rvh_die_kernel_fault(regs, esr, addr, msg); mem_abort_decode(esr); show_pte(addr); @@ -724,6 +727,7 @@ static int do_sea(unsigned long far, unsigned int esr, struct pt_regs *regs) */ siaddr = untagged_addr(far); } + trace_android_rvh_do_sea(regs, esr, siaddr, inf->name); arm64_notify_die(inf->name, regs, inf->sig, inf->code, siaddr, esr); return 0; @@ -819,6 +823,7 @@ void do_mem_abort(unsigned long far, unsigned int esr, struct pt_regs *regs) if (!user_mode(regs)) { pr_alert("Unhandled fault at 0x%016lx\n", addr); + trace_android_rvh_do_mem_abort(regs, esr, addr, inf->name); mem_abort_decode(esr); show_pte(addr); } @@ -841,6 +846,8 @@ NOKPROBE_SYMBOL(do_el0_irq_bp_hardening); void do_sp_pc_abort(unsigned long addr, unsigned int esr, struct pt_regs *regs) { + trace_android_rvh_do_sp_pc_abort(regs, esr, addr, user_mode(regs)); + arm64_notify_die("SP/PC alignment exception", regs, SIGBUS, BUS_ADRALN, addr, esr); } diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index 6bf499fa6fcf..ab184f8bdbcb 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -34,6 +34,7 @@ #include #include #include +#include /* * Export tracepoints that act as a bare tracehook (ie: have no trace event @@ -145,3 +146,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_watchdog_timer_softlockup); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_try_to_freeze_todo); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_try_to_freeze_todo_unfrozen); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_dequeue_task_idle); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_die_kernel_fault); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_do_sea); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_do_mem_abort); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_do_sp_pc_abort); diff --git a/include/trace/hooks/fault.h b/include/trace/hooks/fault.h new file mode 100644 index 000000000000..1daf2d250f31 --- /dev/null +++ b/include/trace/hooks/fault.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM fault +#define TRACE_INCLUDE_PATH trace/hooks + +#if !defined(_TRACE_HOOK_FAULT_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_HOOK_FAULT_H +#include +#include +/* + * Following tracepoints are not exported in tracefs and provide a + * mechanism for vendor modules to hook and extend functionality + */ +struct pt_regs; +DECLARE_RESTRICTED_HOOK(android_rvh_die_kernel_fault, + TP_PROTO(struct pt_regs *regs, unsigned int esr, unsigned long addr, const char *msg), + TP_ARGS(regs, esr, addr, msg), 1); + +DECLARE_RESTRICTED_HOOK(android_rvh_do_sea, + TP_PROTO(struct pt_regs *regs, unsigned int esr, unsigned long addr, const char *msg), + TP_ARGS(regs, esr, addr, msg), 1); + +DECLARE_RESTRICTED_HOOK(android_rvh_do_mem_abort, + TP_PROTO(struct pt_regs *regs, unsigned int esr, unsigned long addr, const char *msg), + TP_ARGS(regs, esr, addr, msg), 1); + +DECLARE_RESTRICTED_HOOK(android_rvh_do_sp_pc_abort, + TP_PROTO(struct pt_regs *regs, unsigned int esr, unsigned long addr, bool user), + TP_ARGS(regs, esr, addr, user), + TP_CONDITION(!user)); + +/* macro versions of hooks are no longer required */ + +#endif /* _TRACE_HOOK_FAULT_H */ +/* This part must be outside protection */ +#include