Index: sys/arm/arm/exception.S =================================================================== --- sys/arm/arm/exception.S +++ sys/arm/arm/exception.S @@ -52,13 +52,15 @@ #include #include #include +#include + __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 @@ -363,7 +365,42 @@ PUSHFRAMEINSVC /* mode stack, build trapframe there. */ adr lr, exception_exit /* Return from handler via standard */ mov r0, sp /* exception exit routine. Pass the */ - b undefinedinstruction /* trapframe to the handler. */ + +#ifdef KDTRACE_HOOKS + ldr r1, =_C_LABEL(dtrace_invop_jump_addr) /* check if dtrace enabled */ + ldr r3, [r1] + cmp r3, #0 + beq undefinedinstruction + + ldrb r4, [r0, #(TF_SPSR)] /* Load spsr byte to get the mode */ + and r4, r4, #(PSR_MODE) /* Mask out unneeded bits */ + cmp r4, #(PSR_USR32_MODE) /* Check if we came from usermode */ + beq undefinedinstruction + + ldr r2, [sp, #(TF_PC)] /* load pc */ +#if __ARM_ARCH >= 7 + tst r4, #(PSR_T) /* test if PSR_T */ + sub r2, r2, #(THUMB_INSN_SIZE) + b 1f +#else + sub r2, r2, #(INSN_SIZE) /* fix pc */ +#endif +1: + str r2, [sp, #TF_PC] /* store pc */ + ldr r4, [r2] /* load instrution */ + ldr r1, =FBT_PATCHVAL /* load fbt inv op */ + cmp r1, r4 + bne undefinedinstruction + + blx r3 /* call invop_jump_addr */ + + cmp r0, #0 /* check ret code */ + beq exception_exit /* exit if sucess */ + + adr lr, exception_exit /* prepare call standard */ + mov r0, sp /* prepare parameter */ +#endif + b undefinedinstruction /* call stadnard handler */ END(undefined_entry) /* Index: sys/arm/arm/genassym.c =================================================================== --- sys/arm/arm/genassym.c +++ sys/arm/arm/genassym.c @@ -118,6 +118,7 @@ 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)); Index: sys/arm/arm/undefined.c =================================================================== --- sys/arm/arm/undefined.c +++ sys/arm/arm/undefined.c @@ -99,10 +99,6 @@ #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]; @@ -350,12 +346,6 @@ #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"); } Index: sys/arm/include/trap.h =================================================================== --- sys/arm/include/trap.h +++ sys/arm/include/trap.h @@ -7,4 +7,5 @@ #define GDB5_BREAKPOINT 0xe7ffdefe #define PTRACE_BREAKPOINT 0xe7fffff0 #define KERNEL_BREAKPOINT 0xe7ffffff +#define FBT_PATCHVAL 0xe7f000f0 /* Specified undefined instruction */ #endif /* _MACHINE_TRAP_H_ */ Index: sys/cddl/dev/fbt/arm/fbt_isa.c =================================================================== --- sys/cddl/dev/fbt/arm/fbt_isa.c +++ sys/cddl/dev/fbt/arm/fbt_isa.c @@ -35,11 +35,10 @@ #include #include +#include #include "fbt.h" -#define FBT_PATCHVAL 0xe7f000f0 /* Specified undefined instruction */ - #define FBT_PUSHM 0xe92d0000 #define FBT_POPM 0xe8bd0000 #define FBT_JUMP 0xea000000 @@ -104,13 +103,6 @@ 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);