1179090Sjb/*-
2179090Sjb * Copyright (c) 2007-2008 John Birrell <jb@FreeBSD.org>
3179090Sjb * All rights reserved.
4179090Sjb *
5179090Sjb * Redistribution and use in source and binary forms, with or without
6179090Sjb * modification, are permitted provided that the following conditions
7179090Sjb * are met:
8179090Sjb * 1. Redistributions of source code must retain the above copyright
9179090Sjb *    notice, this list of conditions and the following disclaimer.
10179090Sjb * 2. Redistributions in binary form must reproduce the above copyright
11179090Sjb *    notice, this list of conditions and the following disclaimer in the
12179090Sjb *    documentation and/or other materials provided with the distribution.
13179090Sjb *
14179090Sjb * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15179090Sjb * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16179090Sjb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17179090Sjb * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18179090Sjb * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19179090Sjb * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20179090Sjb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21179090Sjb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22179090Sjb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23179090Sjb * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24179090Sjb * SUCH DAMAGE.
25179090Sjb */
26179090Sjb
27179090Sjb#include <sys/cdefs.h>
28179090Sjb__FBSDID("$FreeBSD: releng/10.2/sys/kern/kern_dtrace.c 269752 2014-08-09 14:05:01Z markj $");
29179090Sjb
30179090Sjb#include "opt_kdb.h"
31179090Sjb
32179090Sjb#include <sys/param.h>
33179090Sjb#include <sys/systm.h>
34179090Sjb#include <sys/eventhandler.h>
35179090Sjb#include <sys/kdb.h>
36179090Sjb#include <sys/kernel.h>
37179090Sjb#include <sys/malloc.h>
38179090Sjb#include <sys/proc.h>
39179090Sjb#include <sys/dtrace_bsd.h>
40219028Snetchild#include <sys/sysctl.h>
41269752Smarkj#include <sys/sysent.h>
42179090Sjb
43179090Sjb#define KDTRACE_PROC_SIZE	64
44179090Sjb#define	KDTRACE_THREAD_SIZE	256
45179090Sjb
46219028SnetchildFEATURE(kdtrace_hooks,
47219028Snetchild    "Kernel DTrace hooks which are required to load DTrace kernel modules");
48219028Snetchild
49227293Sedstatic MALLOC_DEFINE(M_KDTRACE, "kdtrace", "DTrace hooks");
50179090Sjb
51269752Smarkj/* Hooks used in the machine-dependent trap handlers. */
52269752Smarkjdtrace_trap_func_t		dtrace_trap_func;
53269752Smarkjdtrace_doubletrap_func_t	dtrace_doubletrap_func;
54269752Smarkjdtrace_pid_probe_ptr_t		dtrace_pid_probe_ptr;
55269752Smarkjdtrace_return_probe_ptr_t	dtrace_return_probe_ptr;
56269752Smarkj
57269752Smarkjsystrace_probe_func_t		systrace_probe_func;
58269752Smarkj
59179090Sjb/* Return the DTrace process data size compiled in the kernel hooks. */
60179090Sjbsize_t
61179090Sjbkdtrace_proc_size()
62179090Sjb{
63211613Srpaulo
64211613Srpaulo	return (KDTRACE_PROC_SIZE);
65179090Sjb}
66179090Sjb
67179090Sjbstatic void
68179090Sjbkdtrace_proc_ctor(void *arg __unused, struct proc *p)
69179090Sjb{
70179090Sjb
71211614Srpaulo	p->p_dtrace = malloc(KDTRACE_PROC_SIZE, M_KDTRACE, M_WAITOK|M_ZERO);
72179090Sjb}
73179090Sjb
74179090Sjbstatic void
75179090Sjbkdtrace_proc_dtor(void *arg __unused, struct proc *p)
76179090Sjb{
77211613Srpaulo
78179090Sjb	if (p->p_dtrace != NULL) {
79179090Sjb		free(p->p_dtrace, M_KDTRACE);
80179090Sjb		p->p_dtrace = NULL;
81179090Sjb	}
82179090Sjb}
83179090Sjb
84179090Sjb/* Return the DTrace thread data size compiled in the kernel hooks. */
85179090Sjbsize_t
86179090Sjbkdtrace_thread_size()
87179090Sjb{
88211614Srpaulo
89211613Srpaulo	return (KDTRACE_THREAD_SIZE);
90179090Sjb}
91179090Sjb
92179090Sjbstatic void
93179090Sjbkdtrace_thread_ctor(void *arg __unused, struct thread *td)
94179090Sjb{
95179090Sjb
96211614Srpaulo	td->td_dtrace = malloc(KDTRACE_THREAD_SIZE, M_KDTRACE, M_WAITOK|M_ZERO);
97179090Sjb}
98179090Sjb
99179090Sjbstatic void
100179090Sjbkdtrace_thread_dtor(void *arg __unused, struct thread *td)
101179090Sjb{
102211613Srpaulo
103179090Sjb	if (td->td_dtrace != NULL) {
104179090Sjb		free(td->td_dtrace, M_KDTRACE);
105179090Sjb		td->td_dtrace = NULL;
106179090Sjb	}
107179090Sjb}
108179090Sjb
109179090Sjb/*
110179090Sjb *  Initialise the kernel DTrace hooks.
111179090Sjb */
112179090Sjbstatic void
113179090Sjbinit_dtrace(void *dummy __unused)
114179090Sjb{
115211613Srpaulo
116211613Srpaulo	EVENTHANDLER_REGISTER(process_ctor, kdtrace_proc_ctor, NULL,
117211613Srpaulo	    EVENTHANDLER_PRI_ANY);
118211613Srpaulo	EVENTHANDLER_REGISTER(process_dtor, kdtrace_proc_dtor, NULL,
119211613Srpaulo	    EVENTHANDLER_PRI_ANY);
120211613Srpaulo	EVENTHANDLER_REGISTER(thread_ctor, kdtrace_thread_ctor, NULL,
121211613Srpaulo	    EVENTHANDLER_PRI_ANY);
122211613Srpaulo	EVENTHANDLER_REGISTER(thread_dtor, kdtrace_thread_dtor, NULL,
123211613Srpaulo	    EVENTHANDLER_PRI_ANY);
124179090Sjb}
125179090Sjb
126179090SjbSYSINIT(kdtrace, SI_SUB_KDTRACE, SI_ORDER_FIRST, init_dtrace, NULL);
127