PERFORCE change 132237 for review
John Birrell
jb at FreeBSD.org
Tue Jan 1 01:04:44 PST 2008
http://perforce.freebsd.org/chv.cgi?CH=132237
Change 132237 by jb at jb_freebsd1 on 2008/01/01 09:03:56
Remove the M_DTRACE memory type references.
Add the dtrace_trap() function which is hooked into the trap handler
to deal with traps that occur during DTrace probe execution.
Affected files ...
.. //depot/projects/dtrace/src/sys/cddl/dev/dtrace/amd64/dtrace_subr.c#2 edit
.. //depot/projects/dtrace/src/sys/cddl/dev/dtrace/i386/dtrace_subr.c#5 edit
Differences ...
==== //depot/projects/dtrace/src/sys/cddl/dev/dtrace/amd64/dtrace_subr.c#2 (text+ko) ====
@@ -35,14 +35,14 @@
#include <sys/kmem.h>
#include <sys/dtrace_impl.h>
#include <sys/dtrace_bsd.h>
+#include <machine/frame.h>
extern uintptr_t kernelbase;
extern uintptr_t dtrace_in_probe_addr;
extern int dtrace_in_probe;
int dtrace_invop(uintptr_t, uintptr_t *, uintptr_t);
-
-MALLOC_DECLARE(M_DTRACE);
+int dtrace_trap(struct trapframe *, u_int);
typedef struct dtrace_invop_hdlr {
int (*dtih_func)(uintptr_t, uintptr_t *, uintptr_t);
@@ -96,7 +96,7 @@
{
dtrace_invop_hdlr_t *hdlr;
- hdlr = malloc(sizeof (dtrace_invop_hdlr_t), M_DTRACE, M_WAITOK);
+ hdlr = kmem_alloc(sizeof (dtrace_invop_hdlr_t), KM_SLEEP);
hdlr->dtih_func = func;
hdlr->dtih_next = dtrace_invop_hdlr;
dtrace_invop_hdlr = hdlr;
@@ -130,7 +130,7 @@
prev->dtih_next = hdlr->dtih_next;
}
- free(hdlr, M_DTRACE);
+ kmem_free(hdlr, 0);
#ifdef DOODAD
if (dtrace_invop_hdlr == NULL)
@@ -438,3 +438,56 @@
printf("%s(%d): XXX\n",__func__,__LINE__);
return (0);
}
+
+/* Function to handle DTrace traps during probes. See amd64/amd64/trap.c */
+int
+dtrace_trap(struct trapframe *frame, u_int type)
+{
+ /*
+ * 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
+ * want to fault. On returning from the 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) {
+ /* General protection fault. */
+ case T_PROTFLT:
+ /* Flag an illegal operation. */
+ cpu_core[curcpu].cpuc_dtrace_flags |= CPU_DTRACE_ILLOP;
+
+ /*
+ * Offset the instruction pointer to the instruction
+ * following the one causing the fault.
+ */
+ frame->tf_rip += dtrace_instr_size((u_char *) frame->tf_rip);
+ return (1);
+ /* Page fault. */
+ case T_PAGEFLT:
+ /* Flag a bad address. */
+ cpu_core[curcpu].cpuc_dtrace_flags |= CPU_DTRACE_BADADDR;
+ cpu_core[curcpu].cpuc_dtrace_illval = frame->tf_addr;
+
+ /*
+ * Offset the instruction pointer to the instruction
+ * following the one causing the fault.
+ */
+ frame->tf_rip += dtrace_instr_size((u_char *) frame->tf_rip);
+ return (1);
+ default:
+ /* Handle all other traps in the usual way. */
+ break;
+ }
+ }
+
+ /* Handle the trap in the usual way. */
+ return (0);
+}
==== //depot/projects/dtrace/src/sys/cddl/dev/dtrace/i386/dtrace_subr.c#5 (text+ko) ====
@@ -42,8 +42,6 @@
int dtrace_invop(uintptr_t, uintptr_t *, uintptr_t);
-MALLOC_DECLARE(M_DTRACE);
-
typedef struct dtrace_invop_hdlr {
int (*dtih_func)(uintptr_t, uintptr_t *, uintptr_t);
struct dtrace_invop_hdlr *dtih_next;
@@ -96,7 +94,7 @@
{
dtrace_invop_hdlr_t *hdlr;
- hdlr = malloc(sizeof (dtrace_invop_hdlr_t), M_DTRACE, M_WAITOK);
+ hdlr = kmem_alloc(sizeof (dtrace_invop_hdlr_t), KM_SLEEP);
hdlr->dtih_func = func;
hdlr->dtih_next = dtrace_invop_hdlr;
dtrace_invop_hdlr = hdlr;
@@ -128,7 +126,7 @@
prev->dtih_next = hdlr->dtih_next;
}
- free(hdlr, M_DTRACE);
+ kmem_free(hdlr, 0);
if (dtrace_invop_hdlr == NULL)
dtrace_invop_func = NULL;
@@ -427,3 +425,56 @@
return (1);
}
#endif
+
+/* Function to handle DTrace traps during probes. See i386/i386/trap.c */
+int
+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
+ * want to fault. On returning from the 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) {
+ /* General protection fault. */
+ case T_PROTFLT:
+ /* Flag an illegal operation. */
+ cpu_core[curcpu].cpuc_dtrace_flags |= CPU_DTRACE_ILLOP;
+
+ /*
+ * Offset the instruction pointer to the instruction
+ * following the one causing the fault.
+ */
+ frame->tf_eip += dtrace_instr_size((u_char *) frame->tf_eip);
+ return (1);
+ /* Page fault. */
+ case T_PAGEFLT:
+ /* Flag a bad address. */
+ cpu_core[curcpu].cpuc_dtrace_flags |= CPU_DTRACE_BADADDR;
+ cpu_core[curcpu].cpuc_dtrace_illval = rcr2();
+
+ /*
+ * Offset the instruction pointer to the instruction
+ * following the one causing the fault.
+ */
+ frame->tf_eip += dtrace_instr_size((u_char *) frame->tf_eip);
+ return (1);
+ default:
+ /* Handle all other traps in the usual way. */
+ break;
+ }
+ }
+
+ /* Handle the trap in the usual way. */
+ return (0);
+}
More information about the p4-projects
mailing list