180544aebSJohn Birrell /*- 28a36da99SPedro F. Giffuni * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 38a36da99SPedro F. Giffuni * 480544aebSJohn Birrell * Copyright (c) 2007-2008 John Birrell <jb@FreeBSD.org> 580544aebSJohn Birrell * All rights reserved. 680544aebSJohn Birrell * 780544aebSJohn Birrell * Redistribution and use in source and binary forms, with or without 880544aebSJohn Birrell * modification, are permitted provided that the following conditions 980544aebSJohn Birrell * are met: 1080544aebSJohn Birrell * 1. Redistributions of source code must retain the above copyright 1180544aebSJohn Birrell * notice, this list of conditions and the following disclaimer. 1280544aebSJohn Birrell * 2. Redistributions in binary form must reproduce the above copyright 1380544aebSJohn Birrell * notice, this list of conditions and the following disclaimer in the 1480544aebSJohn Birrell * documentation and/or other materials provided with the distribution. 1580544aebSJohn Birrell * 1680544aebSJohn Birrell * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1780544aebSJohn Birrell * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1880544aebSJohn Birrell * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1980544aebSJohn Birrell * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2080544aebSJohn Birrell * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2180544aebSJohn Birrell * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2280544aebSJohn Birrell * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2380544aebSJohn Birrell * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2480544aebSJohn Birrell * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2580544aebSJohn Birrell * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2680544aebSJohn Birrell * SUCH DAMAGE. 2780544aebSJohn Birrell */ 2880544aebSJohn Birrell 2980544aebSJohn Birrell #include <sys/cdefs.h> 3080544aebSJohn Birrell __FBSDID("$FreeBSD$"); 3180544aebSJohn Birrell 3280544aebSJohn Birrell #include "opt_kdb.h" 3380544aebSJohn Birrell 3480544aebSJohn Birrell #include <sys/param.h> 3580544aebSJohn Birrell #include <sys/systm.h> 3680544aebSJohn Birrell #include <sys/eventhandler.h> 3780544aebSJohn Birrell #include <sys/kdb.h> 3880544aebSJohn Birrell #include <sys/kernel.h> 3980544aebSJohn Birrell #include <sys/malloc.h> 4080544aebSJohn Birrell #include <sys/proc.h> 4180544aebSJohn Birrell #include <sys/dtrace_bsd.h> 42de5b1952SAlexander Leidinger #include <sys/sysctl.h> 43f2789bd5SMark Johnston #include <sys/sysent.h> 4480544aebSJohn Birrell 4580544aebSJohn Birrell #define KDTRACE_PROC_SIZE 64 4680544aebSJohn Birrell #define KDTRACE_THREAD_SIZE 256 4780544aebSJohn Birrell 48de5b1952SAlexander Leidinger FEATURE(kdtrace_hooks, 49de5b1952SAlexander Leidinger "Kernel DTrace hooks which are required to load DTrace kernel modules"); 50de5b1952SAlexander Leidinger 51d745c852SEd Schouten static MALLOC_DEFINE(M_KDTRACE, "kdtrace", "DTrace hooks"); 5280544aebSJohn Birrell 53f2789bd5SMark Johnston /* Hooks used in the machine-dependent trap handlers. */ 54f2789bd5SMark Johnston dtrace_trap_func_t dtrace_trap_func; 55f2789bd5SMark Johnston dtrace_doubletrap_func_t dtrace_doubletrap_func; 56f2789bd5SMark Johnston dtrace_pid_probe_ptr_t dtrace_pid_probe_ptr; 57f2789bd5SMark Johnston dtrace_return_probe_ptr_t dtrace_return_probe_ptr; 58f2789bd5SMark Johnston 59*9d68f774SMateusz Guzik bool __read_frequently systrace_enabled; 60*9d68f774SMateusz Guzik systrace_probe_func_t systrace_probe_func; 61f2789bd5SMark Johnston 6280544aebSJohn Birrell /* Return the DTrace process data size compiled in the kernel hooks. */ 6380544aebSJohn Birrell size_t 6480544aebSJohn Birrell kdtrace_proc_size() 6580544aebSJohn Birrell { 669f3a1843SRui Paulo 6780544aebSJohn Birrell return (KDTRACE_PROC_SIZE); 6880544aebSJohn Birrell } 6980544aebSJohn Birrell 7080544aebSJohn Birrell static void 7180544aebSJohn Birrell kdtrace_proc_ctor(void *arg __unused, struct proc *p) 7280544aebSJohn Birrell { 7380544aebSJohn Birrell 74258f5a25SRui Paulo p->p_dtrace = malloc(KDTRACE_PROC_SIZE, M_KDTRACE, M_WAITOK|M_ZERO); 7580544aebSJohn Birrell } 7680544aebSJohn Birrell 7780544aebSJohn Birrell static void 7880544aebSJohn Birrell kdtrace_proc_dtor(void *arg __unused, struct proc *p) 7980544aebSJohn Birrell { 809f3a1843SRui Paulo 8180544aebSJohn Birrell if (p->p_dtrace != NULL) { 8280544aebSJohn Birrell free(p->p_dtrace, M_KDTRACE); 8380544aebSJohn Birrell p->p_dtrace = NULL; 8480544aebSJohn Birrell } 8580544aebSJohn Birrell } 8680544aebSJohn Birrell 8780544aebSJohn Birrell /* Return the DTrace thread data size compiled in the kernel hooks. */ 8880544aebSJohn Birrell size_t 8980544aebSJohn Birrell kdtrace_thread_size() 9080544aebSJohn Birrell { 91258f5a25SRui Paulo 9280544aebSJohn Birrell return (KDTRACE_THREAD_SIZE); 9380544aebSJohn Birrell } 9480544aebSJohn Birrell 9580544aebSJohn Birrell static void 9680544aebSJohn Birrell kdtrace_thread_ctor(void *arg __unused, struct thread *td) 9780544aebSJohn Birrell { 9880544aebSJohn Birrell 99258f5a25SRui Paulo td->td_dtrace = malloc(KDTRACE_THREAD_SIZE, M_KDTRACE, M_WAITOK|M_ZERO); 10080544aebSJohn Birrell } 10180544aebSJohn Birrell 10280544aebSJohn Birrell static void 10380544aebSJohn Birrell kdtrace_thread_dtor(void *arg __unused, struct thread *td) 10480544aebSJohn Birrell { 1059f3a1843SRui Paulo 10680544aebSJohn Birrell if (td->td_dtrace != NULL) { 10780544aebSJohn Birrell free(td->td_dtrace, M_KDTRACE); 10880544aebSJohn Birrell td->td_dtrace = NULL; 10980544aebSJohn Birrell } 11080544aebSJohn Birrell } 11180544aebSJohn Birrell 11280544aebSJohn Birrell /* 11380544aebSJohn Birrell * Initialise the kernel DTrace hooks. 11480544aebSJohn Birrell */ 11580544aebSJohn Birrell static void 11680544aebSJohn Birrell init_dtrace(void *dummy __unused) 11780544aebSJohn Birrell { 1189f3a1843SRui Paulo 1199f3a1843SRui Paulo EVENTHANDLER_REGISTER(process_ctor, kdtrace_proc_ctor, NULL, 1209f3a1843SRui Paulo EVENTHANDLER_PRI_ANY); 1219f3a1843SRui Paulo EVENTHANDLER_REGISTER(process_dtor, kdtrace_proc_dtor, NULL, 1229f3a1843SRui Paulo EVENTHANDLER_PRI_ANY); 1239f3a1843SRui Paulo EVENTHANDLER_REGISTER(thread_ctor, kdtrace_thread_ctor, NULL, 1249f3a1843SRui Paulo EVENTHANDLER_PRI_ANY); 1259f3a1843SRui Paulo EVENTHANDLER_REGISTER(thread_dtor, kdtrace_thread_dtor, NULL, 1269f3a1843SRui Paulo EVENTHANDLER_PRI_ANY); 12780544aebSJohn Birrell } 12880544aebSJohn Birrell 12980544aebSJohn Birrell SYSINIT(kdtrace, SI_SUB_KDTRACE, SI_ORDER_FIRST, init_dtrace, NULL); 130