Loading arch/arm64/kernel/traps.c +5 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ #include <asm/exception.h> #include <asm/system_misc.h> #include <asm/sysreg.h> #include <trace/events/exception.h> static const char *handler[]= { "Synchronous Abort", Loading Loading @@ -458,6 +459,8 @@ void arm64_notify_segfault(struct pt_regs *regs, unsigned long addr) asmlinkage void __exception do_undefinstr(struct pt_regs *regs) { void __user *pc = (void __user *)instruction_pointer(regs); /* check for AArch32 breakpoint instructions */ if (!aarch32_break_handler(regs)) return; Loading @@ -465,6 +468,8 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs) if (call_undef_hook(regs) == 0) return; trace_undef_instr(regs, pc); force_signal_inject(SIGILL, ILL_ILLOPC, regs, 0); } Loading arch/arm64/mm/fault.c +3 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ #include <asm/pgtable.h> #include <asm/tlbflush.h> #include <soc/qcom/scm.h> #include <trace/events/exception.h> struct fault_info { int (*fn)(unsigned long addr, unsigned int esr, Loading Loading @@ -212,6 +213,8 @@ static void __do_user_fault(struct task_struct *tsk, unsigned long addr, struct siginfo si; const struct fault_info *inf; trace_user_fault(tsk, addr, esr); if (unhandled_signal(tsk, sig) && show_unhandled_signals_ratelimited()) { inf = esr_to_fault_info(esr); pr_info("%s[%d]: unhandled %s (%d) at 0x%08lx, esr 0x%03x\n", Loading drivers/hwtracing/coresight/Kconfig +8 −0 Original line number Diff line number Diff line Loading @@ -148,6 +148,14 @@ config CORESIGHT_CTI hardware component to another. It can also be used to pass software generated events. config CORESIGHT_EVENT tristate "CoreSight Event driver" help This driver provides support for registering with various events and performing CoreSight actions like aborting trace on their occurrence. These events can be controlled by using module parameters. config CORESIGHT_CSR bool "CoreSight Slave Register driver" help Loading drivers/hwtracing/coresight/Makefile +1 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ obj-$(CONFIG_CORESIGHT_STM) += coresight-stm.o obj-$(CONFIG_CORESIGHT_OST) += coresight-ost.o obj-$(CONFIG_CORESIGHT_TPDA) += coresight-tpda.o obj-$(CONFIG_CORESIGHT_TPDM) += coresight-tpdm.o obj-$(CONFIG_CORESIGHT_EVENT) += coresight-event.o obj-$(CONFIG_CORESIGHT_CTI) += coresight-cti.o obj-$(CONFIG_CORESIGHT_CSR) += coresight-csr.o obj-$(CONFIG_CORESIGHT_HWEVENT) += coresight-hwevent.o Loading drivers/hwtracing/coresight/coresight-event.c 0 → 100644 +169 −0 Original line number Diff line number Diff line /* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * only version 2 as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #include <linux/module.h> #include <linux/kernel.h> #include <linux/slab.h> #include <linux/init.h> #include <linux/sched.h> #include <linux/coresight.h> #include <trace/events/exception.h> static int event_abort_enable; static int event_abort_set(const char *val, struct kernel_param *kp); module_param_call(event_abort_enable, event_abort_set, param_get_int, &event_abort_enable, 0644); static int event_abort_early_panic = 1; static int event_abort_on_panic_set(const char *val, struct kernel_param *kp); module_param_call(event_abort_early_panic, event_abort_on_panic_set, param_get_int, &event_abort_early_panic, 0644); static void event_abort_user_fault(void *ignore, struct task_struct *task, unsigned long addr, unsigned int fsr) { coresight_abort(); pr_debug("coresight_event: task_name: %s, addr: %lu, fsr:%u", (char *)task->comm, addr, fsr); } static void event_abort_undef_instr(void *ignore, struct pt_regs *regs, void __user *pc) { if (user_mode(regs)) { coresight_abort(); pr_debug("coresight_event: pc: %pK", pc); } } static void event_abort_unhandled_abort(void *ignore, struct pt_regs *regs, unsigned long addr, unsigned int fsr) { if (user_mode(regs)) { coresight_abort(); pr_debug("coresight_event: addr: %lu, fsr:%u", addr, fsr); } } static void event_abort_kernel_panic(void *ignore, long state) { coresight_abort(); } static int event_abort_register(void) { int ret; ret = register_trace_user_fault(event_abort_user_fault, NULL); if (ret) goto err_usr_fault; ret = register_trace_undef_instr(event_abort_undef_instr, NULL); if (ret) goto err_undef_instr; ret = register_trace_unhandled_abort(event_abort_unhandled_abort, NULL); if (ret) goto err_unhandled_abort; return 0; err_unhandled_abort: unregister_trace_undef_instr(event_abort_undef_instr, NULL); err_undef_instr: unregister_trace_user_fault(event_abort_user_fault, NULL); err_usr_fault: return ret; } static void event_abort_unregister(void) { unregister_trace_user_fault(event_abort_user_fault, NULL); unregister_trace_undef_instr(event_abort_undef_instr, NULL); unregister_trace_unhandled_abort(event_abort_unhandled_abort, NULL); } static int event_abort_set(const char *val, struct kernel_param *kp) { int ret; ret = param_set_int(val, kp); if (ret) { pr_err("coresight_event: error setting value %d\n", ret); return ret; } if (event_abort_enable) ret = event_abort_register(); else event_abort_unregister(); return ret; } static int event_abort_on_panic_set(const char *val, struct kernel_param *kp) { int ret; ret = param_set_int(val, kp); if (ret) { pr_err("coresight_event: error setting val on panic %d\n", ret); return ret; } if (event_abort_early_panic) { unregister_trace_kernel_panic_late(event_abort_kernel_panic, NULL); ret = register_trace_kernel_panic(event_abort_kernel_panic, NULL); if (ret) goto err; } else { unregister_trace_kernel_panic(event_abort_kernel_panic, NULL); ret = register_trace_kernel_panic_late(event_abort_kernel_panic, NULL); if (ret) goto err; } return 0; err: pr_err("coresight_event: error registering panic event %d\n", ret); return ret; } static int __init event_init(void) { int ret; ret = register_trace_kernel_panic(event_abort_kernel_panic, NULL); if (ret) { /* We do not want to fail module init. This module can still * be used to register other abort events. */ pr_err("coresight_event: error registering on panic %d\n", ret); } return 0; } module_init(event_init); static void __exit event_exit(void) { unregister_trace_kernel_panic(event_abort_kernel_panic, NULL); } module_exit(event_exit); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("Coresight Event driver to abort tracing"); Loading
arch/arm64/kernel/traps.c +5 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ #include <asm/exception.h> #include <asm/system_misc.h> #include <asm/sysreg.h> #include <trace/events/exception.h> static const char *handler[]= { "Synchronous Abort", Loading Loading @@ -458,6 +459,8 @@ void arm64_notify_segfault(struct pt_regs *regs, unsigned long addr) asmlinkage void __exception do_undefinstr(struct pt_regs *regs) { void __user *pc = (void __user *)instruction_pointer(regs); /* check for AArch32 breakpoint instructions */ if (!aarch32_break_handler(regs)) return; Loading @@ -465,6 +468,8 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs) if (call_undef_hook(regs) == 0) return; trace_undef_instr(regs, pc); force_signal_inject(SIGILL, ILL_ILLOPC, regs, 0); } Loading
arch/arm64/mm/fault.c +3 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ #include <asm/pgtable.h> #include <asm/tlbflush.h> #include <soc/qcom/scm.h> #include <trace/events/exception.h> struct fault_info { int (*fn)(unsigned long addr, unsigned int esr, Loading Loading @@ -212,6 +213,8 @@ static void __do_user_fault(struct task_struct *tsk, unsigned long addr, struct siginfo si; const struct fault_info *inf; trace_user_fault(tsk, addr, esr); if (unhandled_signal(tsk, sig) && show_unhandled_signals_ratelimited()) { inf = esr_to_fault_info(esr); pr_info("%s[%d]: unhandled %s (%d) at 0x%08lx, esr 0x%03x\n", Loading
drivers/hwtracing/coresight/Kconfig +8 −0 Original line number Diff line number Diff line Loading @@ -148,6 +148,14 @@ config CORESIGHT_CTI hardware component to another. It can also be used to pass software generated events. config CORESIGHT_EVENT tristate "CoreSight Event driver" help This driver provides support for registering with various events and performing CoreSight actions like aborting trace on their occurrence. These events can be controlled by using module parameters. config CORESIGHT_CSR bool "CoreSight Slave Register driver" help Loading
drivers/hwtracing/coresight/Makefile +1 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ obj-$(CONFIG_CORESIGHT_STM) += coresight-stm.o obj-$(CONFIG_CORESIGHT_OST) += coresight-ost.o obj-$(CONFIG_CORESIGHT_TPDA) += coresight-tpda.o obj-$(CONFIG_CORESIGHT_TPDM) += coresight-tpdm.o obj-$(CONFIG_CORESIGHT_EVENT) += coresight-event.o obj-$(CONFIG_CORESIGHT_CTI) += coresight-cti.o obj-$(CONFIG_CORESIGHT_CSR) += coresight-csr.o obj-$(CONFIG_CORESIGHT_HWEVENT) += coresight-hwevent.o Loading
drivers/hwtracing/coresight/coresight-event.c 0 → 100644 +169 −0 Original line number Diff line number Diff line /* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * only version 2 as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #include <linux/module.h> #include <linux/kernel.h> #include <linux/slab.h> #include <linux/init.h> #include <linux/sched.h> #include <linux/coresight.h> #include <trace/events/exception.h> static int event_abort_enable; static int event_abort_set(const char *val, struct kernel_param *kp); module_param_call(event_abort_enable, event_abort_set, param_get_int, &event_abort_enable, 0644); static int event_abort_early_panic = 1; static int event_abort_on_panic_set(const char *val, struct kernel_param *kp); module_param_call(event_abort_early_panic, event_abort_on_panic_set, param_get_int, &event_abort_early_panic, 0644); static void event_abort_user_fault(void *ignore, struct task_struct *task, unsigned long addr, unsigned int fsr) { coresight_abort(); pr_debug("coresight_event: task_name: %s, addr: %lu, fsr:%u", (char *)task->comm, addr, fsr); } static void event_abort_undef_instr(void *ignore, struct pt_regs *regs, void __user *pc) { if (user_mode(regs)) { coresight_abort(); pr_debug("coresight_event: pc: %pK", pc); } } static void event_abort_unhandled_abort(void *ignore, struct pt_regs *regs, unsigned long addr, unsigned int fsr) { if (user_mode(regs)) { coresight_abort(); pr_debug("coresight_event: addr: %lu, fsr:%u", addr, fsr); } } static void event_abort_kernel_panic(void *ignore, long state) { coresight_abort(); } static int event_abort_register(void) { int ret; ret = register_trace_user_fault(event_abort_user_fault, NULL); if (ret) goto err_usr_fault; ret = register_trace_undef_instr(event_abort_undef_instr, NULL); if (ret) goto err_undef_instr; ret = register_trace_unhandled_abort(event_abort_unhandled_abort, NULL); if (ret) goto err_unhandled_abort; return 0; err_unhandled_abort: unregister_trace_undef_instr(event_abort_undef_instr, NULL); err_undef_instr: unregister_trace_user_fault(event_abort_user_fault, NULL); err_usr_fault: return ret; } static void event_abort_unregister(void) { unregister_trace_user_fault(event_abort_user_fault, NULL); unregister_trace_undef_instr(event_abort_undef_instr, NULL); unregister_trace_unhandled_abort(event_abort_unhandled_abort, NULL); } static int event_abort_set(const char *val, struct kernel_param *kp) { int ret; ret = param_set_int(val, kp); if (ret) { pr_err("coresight_event: error setting value %d\n", ret); return ret; } if (event_abort_enable) ret = event_abort_register(); else event_abort_unregister(); return ret; } static int event_abort_on_panic_set(const char *val, struct kernel_param *kp) { int ret; ret = param_set_int(val, kp); if (ret) { pr_err("coresight_event: error setting val on panic %d\n", ret); return ret; } if (event_abort_early_panic) { unregister_trace_kernel_panic_late(event_abort_kernel_panic, NULL); ret = register_trace_kernel_panic(event_abort_kernel_panic, NULL); if (ret) goto err; } else { unregister_trace_kernel_panic(event_abort_kernel_panic, NULL); ret = register_trace_kernel_panic_late(event_abort_kernel_panic, NULL); if (ret) goto err; } return 0; err: pr_err("coresight_event: error registering panic event %d\n", ret); return ret; } static int __init event_init(void) { int ret; ret = register_trace_kernel_panic(event_abort_kernel_panic, NULL); if (ret) { /* We do not want to fail module init. This module can still * be used to register other abort events. */ pr_err("coresight_event: error registering on panic %d\n", ret); } return 0; } module_init(event_init); static void __exit event_exit(void) { unregister_trace_kernel_panic(event_abort_kernel_panic, NULL); } module_exit(event_exit); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("Coresight Event driver to abort tracing");