Re: 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

2014-07-16 Thread Konstantin Belousov
On Wed, Jul 16, 2014 at 12:11:23AM -0400, Mark Johnston wrote:
> On Mon, Jul 14, 2014 at 11:10:50AM +0300, Konstantin Belousov wrote:
> > On Mon, Jul 14, 2014 at 04:38:17AM +, Mark Johnston wrote:
> > > 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  (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.
> > > +  */
> > > + movqdtrace_trap_func,%rax
> > > + testq   %rax,%rax
> > > + je  skiphook
> > > + call*%rax
> > > + testq   %rax,%rax
> > > + jne skiptrap
> > > + movq%rsp,%rdi
> > > +skiphook:
> > > +#endif
> > >   calltrap
> > Why is this fragment done in asm ?  I see it relatively easy to
> > either move to the start of trap(), or create a new wrapper around
> > current trap() which calls dtrace_trap_func conditionally, and then
> > resorts to the old trap.
> 
> You're right, it looks like this could be done in C by introducing a
> wrapper. I'm not sure how moving the conditional call to
> dtrace_trap_func() around within trap() would fix the original problem,
> though.
Ok.

> 
> The diff below adds such a wrapper, and modifies DTrace to explicitly
> ignore it when creating function boundary probes. Additionally, trap()
> is marked __noinline to ensure that it can still be instrumented. I've
> named it "_trap" for now for lack of a better name, but that will need
> to change.
Looks fine.  This should also fix the issue of kgdb and ddb not able to
unwind the trap frames.

> 
> Thanks,
> -Mark
> 
> diff --git a/sys/amd64/amd64/exception.S b/sys/amd64/amd64/exception.S
> index bb5fd56..3d34724 100644
> --- a/sys/amd64/amd64/exception.S
> +++ b/sys/amd64/amd64/exception.S
> @@ -228,24 +228,7 @@ 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.
> -  */
> - movqdtrace_trap_func,%rax
> - testq   %rax,%rax
> - je  skiphook
> - call*%rax
> - testq   %rax,%rax
> - jne skiptrap
> - movq%rsp,%rdi
> -skiphook:
> -#endif
> - calltrap
> -#ifdef KDTRACE_HOOKS
> -skiptrap:
> -#endif
> + call_trap
>   MEXITCOUNT
>   jmp doreti  /* Handle any pending ASTs */
>  
> diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
> index d9203bc..545174a 100644
> --- a/sys/amd64/amd64/trap.c
> +++ b/sys/amd64/amd64/trap.c
> @@ -97,7 +97,8 @@ PMC_SOFT_DEFINE( , , page_fault, write);
>  #include 
>  #endif
>  
> -extern void trap(struct trapframe *frame);
> +extern void _trap(struct trapframe *frame);
> +extern void __noinline trap(struct trapframe *frame);
>  extern void syscall(struct trapframe *frame);
>  void dblfault_handler(struct trapframe *frame);
>  
> @@ -604,6 +605,19 @@ out:
>   return;
>  }
>  
> +/*
> + * Ensure that we ignore any DTrace-induced faults. This function cannot
> + * be instrumented, so it cannot generate such faults itself.
> + */
> +void
> +_trap(struct trapframe *frame)
> +{
> +
> + if (dtrace_trap_func != NULL && (*dtrace_trap_func)(frame))
> + return;
> + trap(frame);
> +}
> +
>  static int
>  trap_pfault(frame, usermode)
>   struct trapframe *frame;
> diff --git a/sys/cddl/dev/fbt/fbt.c b/sys/cd

Re: 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

2014-07-15 Thread Mark Johnston
On Mon, Jul 14, 2014 at 11:10:50AM +0300, Konstantin Belousov wrote:
> On Mon, Jul 14, 2014 at 04:38:17AM +, Mark Johnston wrote:
> > 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  (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.SMon Jul 14 00:16:49 2014
> > (r268599)
> > +++ head/sys/amd64/amd64/exception.SMon 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.
> > +*/
> > +   movqdtrace_trap_func,%rax
> > +   testq   %rax,%rax
> > +   je  skiphook
> > +   call*%rax
> > +   testq   %rax,%rax
> > +   jne skiptrap
> > +   movq%rsp,%rdi
> > +skiphook:
> > +#endif
> > calltrap
> Why is this fragment done in asm ?  I see it relatively easy to
> either move to the start of trap(), or create a new wrapper around
> current trap() which calls dtrace_trap_func conditionally, and then
> resorts to the old trap.

You're right, it looks like this could be done in C by introducing a
wrapper. I'm not sure how moving the conditional call to
dtrace_trap_func() around within trap() would fix the original problem,
though.

The diff below adds such a wrapper, and modifies DTrace to explicitly
ignore it when creating function boundary probes. Additionally, trap()
is marked __noinline to ensure that it can still be instrumented. I've
named it "_trap" for now for lack of a better name, but that will need
to change.

Thanks,
-Mark

diff --git a/sys/amd64/amd64/exception.S b/sys/amd64/amd64/exception.S
index bb5fd56..3d34724 100644
--- a/sys/amd64/amd64/exception.S
+++ b/sys/amd64/amd64/exception.S
@@ -228,24 +228,7 @@ 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.
-*/
-   movqdtrace_trap_func,%rax
-   testq   %rax,%rax
-   je  skiphook
-   call*%rax
-   testq   %rax,%rax
-   jne skiptrap
-   movq%rsp,%rdi
-skiphook:
-#endif
-   calltrap
-#ifdef KDTRACE_HOOKS
-skiptrap:
-#endif
+   call_trap
MEXITCOUNT
jmp doreti  /* Handle any pending ASTs */
 
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
index d9203bc..545174a 100644
--- a/sys/amd64/amd64/trap.c
+++ b/sys/amd64/amd64/trap.c
@@ -97,7 +97,8 @@ PMC_SOFT_DEFINE( , , page_fault, write);
 #include 
 #endif
 
-extern void trap(struct trapframe *frame);
+extern void _trap(struct trapframe *frame);
+extern void __noinline trap(struct trapframe *frame);
 extern void syscall(struct trapframe *frame);
 void dblfault_handler(struct trapframe *frame);
 
@@ -604,6 +605,19 @@ out:
return;
 }
 
+/*
+ * Ensure that we ignore any DTrace-induced faults. This function cannot
+ * be instrumented, so it cannot generate such faults itself.
+ */
+void
+_trap(struct trapframe *frame)
+{
+
+   if (dtrace_trap_func != NULL && (*dtrace_trap_func)(frame))
+   return;
+   trap(frame);
+}
+
 static int
 trap_pfault(frame, usermode)
struct trapframe *frame;
diff --git a/sys/cddl/dev/fbt/fbt.c b/sys/cddl/dev/fbt/fbt.c
index 7e256e7..0cc2db2 100644
--- a/sys/cddl/dev/fbt/fbt.c
+++ b/sys/cddl/dev/fbt/fbt.c
@@ -232,13 +232,18 @@ fbt_provide_module_function(linker_file_t lf, int symindx,
int size;
u_int8_t *instr, *limit;
 
-   if (strncmp(name, "dtrace_", 7) == 0 &&
-   strncmp(name, "dtrace_safe_", 12) != 0) {
+   if ((strncmp(name, "dtrace_", 7) 

Re: 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

2014-07-14 Thread Konstantin Belousov
On Mon, Jul 14, 2014 at 04:38:17AM +, Mark Johnston wrote:
> 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  (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.
> +  */
> + movqdtrace_trap_func,%rax
> + testq   %rax,%rax
> + je  skiphook
> + call*%rax
> + testq   %rax,%rax
> + jne skiptrap
> + movq%rsp,%rdi
> +skiphook:
> +#endif
>   calltrap
Why is this fragment done in asm ?  I see it relatively easy to
either move to the start of trap(), or create a new wrapper around
current trap() which calls dtrace_trap_func conditionally, and then
resorts to the old 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 * 10ULL + 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) {
>

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

2014-07-13 Thread Mark Johnston
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  (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.SMon Jul 14 00:16:49 2014
(r268599)
+++ head/sys/amd64/amd64/exception.SMon 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.
+*/
+   movqdtrace_trap_func,%rax
+   testq   %rax,%rax
+   je  skiphook
+   call*%rax
+   testq   %rax,%rax
+   jne skiptrap
+   movq%rsp,%rdi
+skiphook:
+#endif
calltrap
+#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.cMon Jul 14 00:16:49 
2014(r268599)
+++ head/sys/cddl/dev/dtrace/amd64/dtrace_subr.cMon Jul 14 04:38:17 
2014(r268600)
@@ -462,29 +462,27 @@ dtrace_gethrestime(void)
return (current_time.tv_sec * 10ULL + 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)