From owner-p4-projects@FreeBSD.ORG Tue Jan 1 09:04:44 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id D0D4916A468; Tue, 1 Jan 2008 09:04:43 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 9663316A420 for ; Tue, 1 Jan 2008 09:04:43 +0000 (UTC) (envelope-from jb@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 8656A13C455 for ; Tue, 1 Jan 2008 09:04:43 +0000 (UTC) (envelope-from jb@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id m0194e28086464 for ; Tue, 1 Jan 2008 09:04:40 GMT (envelope-from jb@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id m0194eoY086461 for perforce@freebsd.org; Tue, 1 Jan 2008 09:04:40 GMT (envelope-from jb@freebsd.org) Date: Tue, 1 Jan 2008 09:04:40 GMT Message-Id: <200801010904.m0194eoY086461@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to jb@freebsd.org using -f From: John Birrell To: Perforce Change Reviews Cc: Subject: PERFORCE change 132237 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 01 Jan 2008 09:04:44 -0000 http://perforce.freebsd.org/chv.cgi?CH=132237 Change 132237 by jb@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 #include #include +#include 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); +}