svn commit: r268600 - in head/sys: amd64/amd64 cddl/dev/dtrace/amd64 cddl/dev/dtrace/i386 cddl/dev/dtrace/mips cddl/dev/dtrace/powerpc i386/i386 mips/mips powerpc/aim sys
Mark Johnston
markj at FreeBSD.org
Mon Jul 14 04:38:19 UTC 2014
Author: markj
Date: Mon Jul 14 04:38:17 2014
New Revision: 268600
URL: http://svnweb.freebsd.org/changeset/base/268600
Log:
Invoke the DTrace trap handler before calling trap() on amd64. This matches
the upstream implementation and helps ensure that a trap induced by tracing
fbt::trap:entry is handled without recursively generating another trap.
This makes it possible to run most (but not all) of the DTrace tests under
common/safety/ without triggering a kernel panic.
Submitted by: Anton Rang <anton.rang at isilon.com> (original version)
Phabric: D95
Modified:
head/sys/amd64/amd64/exception.S
head/sys/amd64/amd64/trap.c
head/sys/cddl/dev/dtrace/amd64/dtrace_subr.c
head/sys/cddl/dev/dtrace/i386/dtrace_subr.c
head/sys/cddl/dev/dtrace/mips/dtrace_subr.c
head/sys/cddl/dev/dtrace/powerpc/dtrace_subr.c
head/sys/i386/i386/trap.c
head/sys/mips/mips/trap.c
head/sys/powerpc/aim/trap.c
head/sys/sys/dtrace_bsd.h
Modified: head/sys/amd64/amd64/exception.S
==============================================================================
--- head/sys/amd64/amd64/exception.S Mon Jul 14 00:16:49 2014 (r268599)
+++ head/sys/amd64/amd64/exception.S Mon Jul 14 04:38:17 2014 (r268600)
@@ -228,7 +228,24 @@ alltraps_pushregs_no_rdi:
.type calltrap, at function
calltrap:
movq %rsp,%rdi
+#ifdef KDTRACE_HOOKS
+ /*
+ * Give DTrace a chance to vet this trap and skip the call to trap() if
+ * it turns out that it was caused by a DTrace probe.
+ */
+ movq dtrace_trap_func,%rax
+ testq %rax,%rax
+ je skiphook
+ call *%rax
+ testq %rax,%rax
+ jne skiptrap
+ movq %rsp,%rdi
+skiphook:
+#endif
call trap
+#ifdef KDTRACE_HOOKS
+skiptrap:
+#endif
MEXITCOUNT
jmp doreti /* Handle any pending ASTs */
Modified: head/sys/amd64/amd64/trap.c
==============================================================================
--- head/sys/amd64/amd64/trap.c Mon Jul 14 00:16:49 2014 (r268599)
+++ head/sys/amd64/amd64/trap.c Mon Jul 14 04:38:17 2014 (r268600)
@@ -218,18 +218,6 @@ trap(struct trapframe *frame)
goto out;
}
-#ifdef KDTRACE_HOOKS
- /*
- * A trap can occur while DTrace executes a probe. Before
- * executing the probe, DTrace blocks re-scheduling and sets
- * a flag in its per-cpu flags to indicate that it doesn't
- * want to fault. On returning from the probe, the no-fault
- * flag is cleared and finally re-scheduling is enabled.
- */
- if (dtrace_trap_func != NULL && (*dtrace_trap_func)(frame, type))
- goto out;
-#endif
-
if ((frame->tf_rflags & PSL_I) == 0) {
/*
* Buggy application or kernel code has disabled
Modified: head/sys/cddl/dev/dtrace/amd64/dtrace_subr.c
==============================================================================
--- head/sys/cddl/dev/dtrace/amd64/dtrace_subr.c Mon Jul 14 00:16:49 2014 (r268599)
+++ head/sys/cddl/dev/dtrace/amd64/dtrace_subr.c Mon Jul 14 04:38:17 2014 (r268600)
@@ -462,29 +462,27 @@ dtrace_gethrestime(void)
return (current_time.tv_sec * 1000000000ULL + current_time.tv_nsec);
}
-/* Function to handle DTrace traps during probes. See amd64/amd64/trap.c */
+/*
+ * Function to handle DTrace traps during probes. See amd64/amd64/exception.S.
+ */
int
-dtrace_trap(struct trapframe *frame, u_int type)
+dtrace_trap(struct trapframe *frame)
{
/*
* A trap can occur while DTrace executes a probe. Before
* executing the probe, DTrace blocks re-scheduling and sets
- * a flag in it's per-cpu flags to indicate that it doesn't
+ * a flag in its per-cpu flags to indicate that it doesn't
* want to fault. On returning from the probe, the no-fault
* flag is cleared and finally re-scheduling is enabled.
*
* Check if DTrace has enabled 'no-fault' mode:
- *
*/
if ((cpu_core[curcpu].cpuc_dtrace_flags & CPU_DTRACE_NOFAULT) != 0) {
/*
* There are only a couple of trap types that are expected.
* All the rest will be handled in the usual way.
*/
- switch (type) {
- /* Privilieged instruction fault. */
- case T_PRIVINFLT:
- break;
+ switch (frame->tf_trapno) {
/* General protection fault. */
case T_PROTFLT:
/* Flag an illegal operation. */
Modified: head/sys/cddl/dev/dtrace/i386/dtrace_subr.c
==============================================================================
--- head/sys/cddl/dev/dtrace/i386/dtrace_subr.c Mon Jul 14 00:16:49 2014 (r268599)
+++ head/sys/cddl/dev/dtrace/i386/dtrace_subr.c Mon Jul 14 04:38:17 2014 (r268600)
@@ -473,24 +473,23 @@ dtrace_gethrestime(void)
/* Function to handle DTrace traps during probes. See i386/i386/trap.c */
int
-dtrace_trap(struct trapframe *frame, u_int type)
+dtrace_trap(struct trapframe *frame)
{
/*
* A trap can occur while DTrace executes a probe. Before
* executing the probe, DTrace blocks re-scheduling and sets
- * a flag in it's per-cpu flags to indicate that it doesn't
+ * a flag in its per-cpu flags to indicate that it doesn't
* want to fault. On returning from the probe, the no-fault
* flag is cleared and finally re-scheduling is enabled.
*
* Check if DTrace has enabled 'no-fault' mode:
- *
*/
if ((cpu_core[curcpu].cpuc_dtrace_flags & CPU_DTRACE_NOFAULT) != 0) {
/*
* There are only a couple of trap types that are expected.
* All the rest will be handled in the usual way.
*/
- switch (type) {
+ switch (frame->tf_trapno) {
/* General protection fault. */
case T_PROTFLT:
/* Flag an illegal operation. */
Modified: head/sys/cddl/dev/dtrace/mips/dtrace_subr.c
==============================================================================
--- head/sys/cddl/dev/dtrace/mips/dtrace_subr.c Mon Jul 14 00:16:49 2014 (r268599)
+++ head/sys/cddl/dev/dtrace/mips/dtrace_subr.c Mon Jul 14 04:38:17 2014 (r268600)
@@ -137,17 +137,20 @@ dtrace_gethrestime(void)
/* Function to handle DTrace traps during probes. See amd64/amd64/trap.c */
int
-dtrace_trap(struct trapframe *frame, u_int type)
+dtrace_trap(struct trapframe *frame)
{
+ u_int type;
+
+ type = (trapframe->cause & MIPS_CR_EXC_CODE) >> MIPS_CR_EXC_CODE_SHIFT;
+
/*
* A trap can occur while DTrace executes a probe. Before
* executing the probe, DTrace blocks re-scheduling and sets
- * a flag in it's per-cpu flags to indicate that it doesn't
+ * a flag in its per-cpu flags to indicate that it doesn't
* want to fault. On returning from the probe, the no-fault
* flag is cleared and finally re-scheduling is enabled.
*
* Check if DTrace has enabled 'no-fault' mode:
- *
*/
if ((cpu_core[curcpu].cpuc_dtrace_flags & CPU_DTRACE_NOFAULT) != 0) {
/*
Modified: head/sys/cddl/dev/dtrace/powerpc/dtrace_subr.c
==============================================================================
--- head/sys/cddl/dev/dtrace/powerpc/dtrace_subr.c Mon Jul 14 00:16:49 2014 (r268599)
+++ head/sys/cddl/dev/dtrace/powerpc/dtrace_subr.c Mon Jul 14 04:38:17 2014 (r268600)
@@ -262,24 +262,23 @@ dtrace_gethrestime(void)
/* Function to handle DTrace traps during probes. See powerpc/powerpc/trap.c */
int
-dtrace_trap(struct trapframe *frame, u_int type)
+dtrace_trap(struct trapframe *frame)
{
/*
* A trap can occur while DTrace executes a probe. Before
* executing the probe, DTrace blocks re-scheduling and sets
- * a flag in it's per-cpu flags to indicate that it doesn't
+ * a flag in its per-cpu flags to indicate that it doesn't
* want to fault. On returning from the probe, the no-fault
* flag is cleared and finally re-scheduling is enabled.
*
* Check if DTrace has enabled 'no-fault' mode:
- *
*/
if ((cpu_core[curcpu].cpuc_dtrace_flags & CPU_DTRACE_NOFAULT) != 0) {
/*
* There are only a couple of trap types that are expected.
* All the rest will be handled in the usual way.
*/
- switch (type) {
+ switch (frame->exc) {
/* Page fault. */
case EXC_DSI:
case EXC_DSE:
Modified: head/sys/i386/i386/trap.c
==============================================================================
--- head/sys/i386/i386/trap.c Mon Jul 14 00:16:49 2014 (r268599)
+++ head/sys/i386/i386/trap.c Mon Jul 14 04:38:17 2014 (r268600)
@@ -246,7 +246,7 @@ trap(struct trapframe *frame)
* flag is cleared and finally re-scheduling is enabled.
*/
if ((type == T_PROTFLT || type == T_PAGEFLT) &&
- dtrace_trap_func != NULL && (*dtrace_trap_func)(frame, type))
+ dtrace_trap_func != NULL && (*dtrace_trap_func)(frame))
goto out;
#endif
Modified: head/sys/mips/mips/trap.c
==============================================================================
--- head/sys/mips/mips/trap.c Mon Jul 14 00:16:49 2014 (r268599)
+++ head/sys/mips/mips/trap.c Mon Jul 14 04:38:17 2014 (r268600)
@@ -605,7 +605,7 @@ trap(struct trapframe *trapframe)
/*
* A trap can occur while DTrace executes a probe. Before
* executing the probe, DTrace blocks re-scheduling and sets
- * a flag in it's per-cpu flags to indicate that it doesn't
+ * a flag in its per-cpu flags to indicate that it doesn't
* want to fault. On returning from the probe, the no-fault
* flag is cleared and finally re-scheduling is enabled.
*
@@ -618,7 +618,7 @@ trap(struct trapframe *trapframe)
* XXXDTRACE: add pid probe handler here (if ever)
*/
if (!usermode) {
- if (dtrace_trap_func != NULL && (*dtrace_trap_func)(trapframe, type))
+ if (dtrace_trap_func != NULL && (*dtrace_trap_func)(trapframe))
return (trapframe->pc);
}
#endif
Modified: head/sys/powerpc/aim/trap.c
==============================================================================
--- head/sys/powerpc/aim/trap.c Mon Jul 14 00:16:49 2014 (r268599)
+++ head/sys/powerpc/aim/trap.c Mon Jul 14 04:38:17 2014 (r268600)
@@ -167,7 +167,7 @@ trap(struct trapframe *frame)
/*
* A trap can occur while DTrace executes a probe. Before
* executing the probe, DTrace blocks re-scheduling and sets
- * a flag in it's per-cpu flags to indicate that it doesn't
+ * a flag in its per-cpu flags to indicate that it doesn't
* want to fault. On returning from the probe, the no-fault
* flag is cleared and finally re-scheduling is enabled.
*
@@ -176,7 +176,7 @@ trap(struct trapframe *frame)
* handled the trap and modified the trap frame so that this
* function can return normally.
*/
- if (dtrace_trap_func != NULL && (*dtrace_trap_func)(frame, type))
+ if (dtrace_trap_func != NULL && (*dtrace_trap_func)(frame))
return;
#endif
Modified: head/sys/sys/dtrace_bsd.h
==============================================================================
--- head/sys/sys/dtrace_bsd.h Mon Jul 14 00:16:49 2014 (r268599)
+++ head/sys/sys/dtrace_bsd.h Mon Jul 14 04:38:17 2014 (r268600)
@@ -48,15 +48,14 @@ extern cyclic_clock_func_t cyclic_clock_
void clocksource_cyc_set(const struct bintime *t);
+int dtrace_trap(struct trapframe *);
+
/*
* The dtrace module handles traps that occur during a DTrace probe.
* This type definition is used in the trap handler to provide a
- * hook for the dtrace module to register it's handler with.
+ * hook for the dtrace module to register its handler with.
*/
-typedef int (*dtrace_trap_func_t)(struct trapframe *, u_int);
-
-int dtrace_trap(struct trapframe *, u_int);
-
+typedef int (*dtrace_trap_func_t)(struct trapframe *);
extern dtrace_trap_func_t dtrace_trap_func;
/*
More information about the svn-src-all
mailing list