Date: Mon, 14 Jul 2014 04:38:17 +0000 (UTC) From: Mark Johnston <markj@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: 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 Message-ID: <201407140438.s6E4cHCh016707@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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@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,@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; /*
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201407140438.s6E4cHCh016707>