On Tue, Nov 05, 2019 at 11:23:28AM +0000, Bjoern A. Zeeb wrote:
> Hi,
> 
> I had an i386 kernel (amd64 machine) simply going to POST.  After a lot 
> of “doh” I realised that it was a dtrace script which was matching a 
> lot of probes running as part of some automated stuff.
> 
> The problematic part from the middle of that script was a section which 
> I can reduce to
> 
> fbt:kernel::entry             # or simply :::
> /self->foo == 1/
> {
> 
>     printf(“Hello\n”);
> }
> 
> Anyone wants to investigate this or should I open a PR?

Can you test this patch?  I only tried to compile it.  Basically, we
must handle FBT probes before calling trap().

diff --git a/sys/i386/i386/exception.s b/sys/i386/i386/exception.s
index b288543dafe1..8a8de5fb1d09 100644
--- a/sys/i386/i386/exception.s
+++ b/sys/i386/i386/exception.s
@@ -175,7 +175,7 @@ alltraps_with_regs_pushed:
        FAKE_MCOUNT(TF_EIP(%esp))
 calltrap:
        pushl   %esp
-       movl    $trap,%eax
+       movl    $trap_check,%eax
        call    *%eax
        add     $4, %esp
 
@@ -317,7 +317,7 @@ dbg_user:
        movl    $handle_ibrs_entry,%eax
        call    *%eax
        pushl   %esp
-       movl    $trap,%eax
+       movl    $trap_check,%eax
        call    *%eax
        add     $4, %esp
        movl    $T_RESERVED, TF_TRAPNO(%esp)
diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c
index bb71317de000..83ac97887feb 100644
--- a/sys/i386/i386/trap.c
+++ b/sys/i386/i386/trap.c
@@ -112,6 +112,7 @@ PMC_SOFT_DEFINE( , , page_fault, write);
 #endif
 
 void trap(struct trapframe *frame);
+void trap_check(struct trapframe *frame);
 void syscall(struct trapframe *frame);
 
 static int trap_pfault(struct trapframe *, bool, vm_offset_t, int *, int *);
@@ -186,6 +187,21 @@ SYSCTL_INT(_machdep, OID_AUTO, uprintf_signal, CTLFLAG_RW,
     &uprintf_signal, 0,
     "Print debugging information on trap signal to ctty");
 
+/*
+ * Ensure that we ignore any DTrace-induced faults. This function cannot
+ * be instrumented, so it cannot generate such faults itself.
+ */
+void
+trap_check(struct trapframe *frame)
+{
+#ifdef KDTRACE_HOOKS
+       if (dtrace_trap_func != NULL &&
+           (*dtrace_trap_func)(frame, frame->tf_trapno))
+               return;
+#endif
+       trap(frame);
+}
+
 /*
  * Exception, fault, and trap interface to the FreeBSD kernel.
  * This common code is called from assembly language IDT gate entry
@@ -260,19 +276,6 @@ trap(struct trapframe *frame)
                return;
        }
 
-#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 ((type == T_PROTFLT || type == T_PAGEFLT) &&
-           dtrace_trap_func != NULL && (*dtrace_trap_func)(frame, type))
-               return;
-#endif
-
        /*
         * We must not allow context switches until %cr2 is read.
         * Also, for some Cyrix CPUs, %cr2 is clobbered by interrupts.
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-dtrace
To unsubscribe, send any mail to "[email protected]"

Reply via email to