svn commit: r291852 - in head/sys: arm/arm arm/include cddl/dev/fbt/arm

Howard Su howard0su at gmail.com
Sat Dec 5 12:53:14 UTC 2015


On Saturday, December 5, 2015, Andrew Turner <andrew at freebsd.org> wrote:

> Author: andrew
> Date: Sat Dec  5 09:32:36 2015
> New Revision: 291852
> URL: https://svnweb.freebsd.org/changeset/base/291852
>
> Log:
>   Move the check to see if we are tracing a function with the DTrace
> Function
>   Boundary Trace to assembly to reduce the overhead of these checks.
>
>   Submitted by: Howard Su <howard0su at gmail.com <javascript:;>>
>   Relnotes:     Yes
>   Differential Revision:        https://reviews.freebsd.org/D4266
>
> Modified:
>   head/sys/arm/arm/exception.S
>   head/sys/arm/arm/genassym.c
>   head/sys/arm/arm/trap-v6.c
>   head/sys/arm/arm/undefined.c
>   head/sys/arm/include/trap.h
>   head/sys/cddl/dev/fbt/arm/fbt_isa.c
>
> Modified: head/sys/arm/arm/exception.S
>
> ==============================================================================
> --- head/sys/arm/arm/exception.S        Sat Dec  5 08:52:37 2015
> (r291851)
> +++ head/sys/arm/arm/exception.S        Sat Dec  5 09:32:36 2015
> (r291852)
> @@ -52,13 +52,15 @@
>  #include <machine/asm.h>
>  #include <machine/armreg.h>
>  #include <machine/asmacros.h>
> +#include <machine/trap.h>
> +
>  __FBSDID("$FreeBSD$");
>
>  #ifdef KDTRACE_HOOKS
>         .bss
>         .align 4
> -       .global _C_LABEL(dtrace_invop_calltrap_addr)
> -_C_LABEL(dtrace_invop_calltrap_addr):
> +       .global _C_LABEL(dtrace_invop_jump_addr)
> +_C_LABEL(dtrace_invop_jump_addr):
>         .word 0
>         .word 0
>  #endif
> @@ -361,9 +363,39 @@ END(data_abort_entry)
>   */
>  ASENTRY_NP(undefined_entry)
>         PUSHFRAMEINSVC                  /* mode stack, build trapframe
> there. */
> +       mov     r4, r0                  /* R0 contains SPSR */
>         adr     lr, exception_exit      /* Return from handler via
> standard */
> -       mov     r0, sp                  /* exception exit routine.  Pass
> the */
> -       b       undefinedinstruction    /* trapframe to the handler. */
> +       mov     r0, sp                  /* exception exit routine. pass
> frame */
> +
> +       ldr     r2, [sp, #(TF_PC)]      /* load pc */
> +#if __ARM_ARCH >= 7
> +       tst     r4, #(PSR_T)            /* test if PSR_T */
> +       subne   r2, r2, #(THUMB_INSN_SIZE)
> +       subeq   r2, r2, #(INSN_SIZE)
> +#else
> +       sub     r2, r2, #(INSN_SIZE)    /* fix pc */
> +#endif
> +       str     r2, [sp, #TF_PC]        /* store pc */
> +
> +#ifdef KDTRACE_HOOKS
> +       /* Check if dtrace is enabled */
> +       ldr     r1, =_C_LABEL(dtrace_invop_jump_addr)
> +       ldr     r3, [r1]
> +       cmp     r3, #0
> +       beq     undefinedinstruction
> +
> +       and     r4, r4, #(PSR_MODE)     /* Mask out unneeded bits */
> +       cmp     r4, #(PSR_USR32_MODE)   /* Check if we came from usermode
> */
> +       beq     undefinedinstruction
> +
> +       ldr     r4, [r2]                /* load instrution */
> +       ldr     r1, =FBT_BREAKPOINT     /* load fbt inv op */
> +       cmp     r1, r4
> +       bne     undefinedinstruction
> +
> +       bx      r3                      /* call invop_jump_addr */
> +#endif
> +       b       undefinedinstruction    /* call stadnard handler */
>  END(undefined_entry)
>
>  /*
>
> Modified: head/sys/arm/arm/genassym.c
>
> ==============================================================================
> --- head/sys/arm/arm/genassym.c Sat Dec  5 08:52:37 2015        (r291851)
> +++ head/sys/arm/arm/genassym.c Sat Dec  5 09:32:36 2015        (r291852)
> @@ -118,6 +118,7 @@ ASSYM(MD_TP, offsetof(struct mdthread, m
>  ASSYM(MD_RAS_START, offsetof(struct mdthread, md_ras_start));
>  ASSYM(MD_RAS_END, offsetof(struct mdthread, md_ras_end));
>
> +ASSYM(TF_SPSR, offsetof(struct trapframe, tf_spsr));
>  ASSYM(TF_R0, offsetof(struct trapframe, tf_r0));
>  ASSYM(TF_R1, offsetof(struct trapframe, tf_r1));
>  ASSYM(TF_PC, offsetof(struct trapframe, tf_pc));
>
> Modified: head/sys/arm/arm/trap-v6.c
>
> ==============================================================================
> --- head/sys/arm/arm/trap-v6.c  Sat Dec  5 08:52:37 2015        (r291851)
> +++ head/sys/arm/arm/trap-v6.c  Sat Dec  5 09:32:36 2015        (r291852)
> @@ -66,6 +66,10 @@ __FBSDID("$FreeBSD$");
>  #include <machine/db_machdep.h>
>  #endif
>
> +#ifdef KDTRACE_HOOKS
> +#include <sys/dtrace_bsd.h>
> +#endif
> +
>  extern char fusubailout[];
>  extern char cachebailout[];
>
> @@ -561,6 +565,13 @@ abort_fatal(struct trapframe *tf, u_int
>         const char *rw_mode;
>
>         usermode = TRAPF_USERMODE(tf);
> +#ifdef KDTRACE_HOOKS
> +       if (!usermode) {
> +               if (dtrace_trap_func != NULL && (*dtrace_trap_func)(tf,
> far))
> +                       return (0);
> +       }
> +#endif
> +
>         mode = usermode ? "user" : "kernel";
>         rw_mode  = fsr & FSR_WNR ? "write" : "read";
>         disable_interrupts(PSR_I|PSR_F);
>
> Modified: head/sys/arm/arm/undefined.c
>
> ==============================================================================
> --- head/sys/arm/arm/undefined.c        Sat Dec  5 08:52:37 2015
> (r291851)
> +++ head/sys/arm/arm/undefined.c        Sat Dec  5 09:32:36 2015
> (r291852)
> @@ -99,10 +99,6 @@ __FBSDID("$FreeBSD$");
>
>  #define        COPROC_VFP      10
>
> -#ifdef KDTRACE_HOOKS
> -int (*dtrace_invop_jump_addr)(struct trapframe *);
> -#endif
> -
>  static int gdb_trapper(u_int, u_int, struct trapframe *, int);
>
>  LIST_HEAD(, undefined_handler) undefined_handlers[MAX_COPROCS];
> @@ -206,12 +202,6 @@ undefinedinstruction(struct trapframe *f
>
>         PCPU_INC(cnt.v_trap);
>
> -#if __ARM_ARCH >= 7
> -       if ((frame->tf_spsr & PSR_T) != 0)
> -               frame->tf_pc -= THUMB_INSN_SIZE;
> -       else
> -#endif
> -               frame->tf_pc -= INSN_SIZE;
>         fault_pc = frame->tf_pc;
>
>         /*
> @@ -350,12 +340,6 @@ undefinedinstruction(struct trapframe *f
>  #endif
>                         return;
>                 }
> -#ifdef KDTRACE_HOOKS
> -               else if (dtrace_invop_jump_addr != 0) {
> -                       dtrace_invop_jump_addr(frame);
> -                       return;
> -               }
> -#endif
>                 else
>                         panic("Undefined instruction in kernel.\n");
>         }
>
> Modified: head/sys/arm/include/trap.h
>
> ==============================================================================
> --- head/sys/arm/include/trap.h Sat Dec  5 08:52:37 2015        (r291851)
> +++ head/sys/arm/include/trap.h Sat Dec  5 09:32:36 2015        (r291852)
> @@ -7,4 +7,5 @@
>  #define GDB5_BREAKPOINT                0xe7ffdefe
>  #define PTRACE_BREAKPOINT      0xe7fffff0
>  #define KERNEL_BREAKPOINT      0xe7ffffff
> +#define FBT_BREAKPOINT         0xe7f000f0
>  #endif /* _MACHINE_TRAP_H_ */
>
> Modified: head/sys/cddl/dev/fbt/arm/fbt_isa.c
>
> ==============================================================================
> --- head/sys/cddl/dev/fbt/arm/fbt_isa.c Sat Dec  5 08:52:37 2015
> (r291851)
> +++ head/sys/cddl/dev/fbt/arm/fbt_isa.c Sat Dec  5 09:32:36 2015
> (r291852)
> @@ -35,11 +35,10 @@
>  #include <sys/param.h>
>
>  #include <sys/dtrace.h>
> +#include <machine/trap.h>
>
>  #include "fbt.h"
>
> -#define        FBT_PATCHVAL            0xe7f000f0 /* Specified undefined
> instruction */
> -
>  #define        FBT_PUSHM               0xe92d0000
>  #define        FBT_POPM                0xe8bd0000
>  #define        FBT_JUMP                0xea000000
> @@ -53,15 +52,20 @@ fbt_invop(uintptr_t addr, uintptr_t *sta
>         struct trapframe *frame = (struct trapframe *)stack;
>         solaris_cpu_t *cpu = &solaris_cpu[curcpu];
>         fbt_probe_t *fbt = fbt_probetab[FBT_ADDR2NDX(addr)];
> +       register_t fifthparam;
>
>         for (; fbt != NULL; fbt = fbt->fbtp_hashnext) {
>                 if ((uintptr_t)fbt->fbtp_patchpoint == addr) {
>                         cpu->cpu_dtrace_caller = addr;
>
> -                       /* TODO: Need 5th parameter from stack */
> +                       /* Get 5th parameter from stack */
> +                       DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
> +                       fifthparam = *(register_t *)frame->tf_usr_sp;
> +                       DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT |
> CPU_DTRACE_BADADDR);
> +
>                         dtrace_probe(fbt->fbtp_id, frame->tf_r0,
>                             frame->tf_r1, frame->tf_r2,
> -                           frame->tf_r3, 0);
> +                           frame->tf_r3, fifthparam);
>
>                         cpu->cpu_dtrace_caller = 0;
>
> @@ -77,7 +81,7 @@ fbt_patch_tracepoint(fbt_probe_t *fbt, f
>  {
>
>         *fbt->fbtp_patchpoint = val;
> -       cpu_icache_sync_range((vm_offset_t)fbt->fbtp_patchpoint, 4);
> +       cpu_icache_sync_range((vm_offset_t)fbt->fbtp_patchpoint,
> sizeof(val));
>  }
>
>  int
> @@ -104,13 +108,6 @@ fbt_provide_module_function(linker_file_
>         if (name[0] == '_' && name[1] == '_')
>                 return (0);
>
> -       /*
> -        * Architecture-specific exclusion list, largely to do with FBT
> trap
> -        * processing, to prevent reentrance.
> -        */
> -       if (strcmp(name, "undefinedinstruction") == 0)
> -               return (0);
> -
>         instr = (uint32_t *)symval->value;
>         limit = (uint32_t *)(symval->value + symval->size);
>
> @@ -125,12 +122,12 @@ fbt_provide_module_function(linker_file_
>         fbt = malloc(sizeof (fbt_probe_t), M_FBT, M_WAITOK | M_ZERO);
>         fbt->fbtp_name = name;
>         fbt->fbtp_id = dtrace_probe_create(fbt_id, modname,
> -           name, FBT_ENTRY, 3, fbt);
> +           name, FBT_ENTRY, 2, fbt);
>         fbt->fbtp_patchpoint = instr;
>         fbt->fbtp_ctl = lf;
>         fbt->fbtp_loadcnt = lf->loadcnt;
>         fbt->fbtp_savedval = *instr;
> -       fbt->fbtp_patchval = FBT_PATCHVAL;
> +       fbt->fbtp_patchval = FBT_BREAKPOINT;
>         fbt->fbtp_rval = DTRACE_INVOP_PUSHM;
>         fbt->fbtp_symindx = symindx;
>
> @@ -157,7 +154,6 @@ again:
>                         start = (uint32_t *)symval->value;
>                         if (target >= limit || target < start)
>                                 break;
> -                       instr++; /* skip delay slot */
>                 }
>         }
>
> @@ -171,7 +167,7 @@ again:
>         fbt->fbtp_name = name;
>         if (retfbt == NULL) {
>                 fbt->fbtp_id = dtrace_probe_create(fbt_id, modname,
> -                   name, FBT_RETURN, 3, fbt);
> +                   name, FBT_RETURN, 2, fbt);
>         } else {
>                 retfbt->fbtp_next = fbt;
>                 fbt->fbtp_id = retfbt->fbtp_id;
> @@ -187,7 +183,7 @@ again:
>         else
>                 fbt->fbtp_rval = DTRACE_INVOP_POPM;
>         fbt->fbtp_savedval = *instr;
> -       fbt->fbtp_patchval = FBT_PATCHVAL;
> +       fbt->fbtp_patchval = FBT_BREAKPOINT;
>         fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)];
>         fbt_probetab[FBT_ADDR2NDX(instr)] = fbt;
>
> While I am here,
1. Remove a copy&paste code to skip "delay slot" which ARM doesn't have.
2. Support fifth arg in fbt. this leads to add missing KDTRACE hook code in
trap-v6.c


-- 
-Howard


More information about the svn-src-head mailing list