Index: Makefile.inc1
===================================================================
--- Makefile.inc1
+++ Makefile.inc1
@@ -1770,7 +1770,7 @@
 # on select architectures though (see cddl/lib/Makefile)
 .if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "i386" || \
 	${MACHINE_CPUARCH} == "mips" || ${MACHINE_CPUARCH} == "powerpc" || \
-	${MACHINE_CPUARCH} == "arm"
+	${MACHINE_CPUARCH} == "arm" || ${MACHINE_CPUARCH} == "aarch64"
 _prebuild_libs+=	lib/libproc lib/librtld_db
 .endif
 
Index: cddl/contrib/opensolaris/lib/libdtrace/aarch64/dt_isadep.c
===================================================================
--- cddl/contrib/opensolaris/lib/libdtrace/aarch64/dt_isadep.c
+++ cddl/contrib/opensolaris/lib/libdtrace/aarch64/dt_isadep.c
@@ -0,0 +1,139 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ * Copyright 2014 Howard Su
+ * Copyright 2015 George V. Neville-Neil
+ * Copyright 2015 Ruslan Bukin 
+ */
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#if !defined(sun)
+#include 
+#endif
+
+/*ARGSUSED*/
+int
+dt_pid_create_entry_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,
+    fasttrap_probe_spec_t *ftp, const GElf_Sym *symp)
+{
+
+	ftp->ftps_type = DTFTP_ENTRY;
+	ftp->ftps_pc = (uintptr_t)symp->st_value;
+	ftp->ftps_size = (size_t)symp->st_size;
+	ftp->ftps_noffs = 1;
+	ftp->ftps_offs[0] = 0;
+
+	if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) {
+		dt_dprintf("fasttrap probe creation ioctl failed: %s\n",
+		    strerror(errno));
+		return (dt_set_errno(dtp, errno));
+	}
+
+	return (1);
+}
+
+int
+dt_pid_create_return_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,
+    fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, uint64_t *stret)
+{
+
+	dt_dprintf("%s: unimplemented\n", __func__);
+
+	return (DT_PROC_ERR);
+}
+
+/*ARGSUSED*/
+int
+dt_pid_create_offset_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,
+    fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, ulong_t off)
+{
+
+	if (!ALIGNED_POINTER(off, 4))
+		return (DT_PROC_ALIGN);
+
+	ftp->ftps_type = DTFTP_OFFSETS;
+	ftp->ftps_pc = (uintptr_t)symp->st_value;
+	ftp->ftps_size = (size_t)symp->st_size;
+	ftp->ftps_noffs = 1;
+	ftp->ftps_offs[0] = off;
+
+	if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) {
+		dt_dprintf("fasttrap probe creation ioctl failed: %s\n",
+		    strerror(errno));
+		return (dt_set_errno(dtp, errno));
+	}
+
+	return (1);
+}
+
+/*ARGSUSED*/
+int
+dt_pid_create_glob_offset_probes(struct ps_prochandle *P, dtrace_hdl_t *dtp,
+    fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, const char *pattern)
+{
+	ulong_t i;
+
+	ftp->ftps_type = DTFTP_OFFSETS;
+	ftp->ftps_pc = (uintptr_t)symp->st_value;
+	ftp->ftps_size = (size_t)symp->st_size;
+	ftp->ftps_noffs = 0;
+
+	/*
+	 * If we're matching against everything, just iterate through each
+	 * instruction in the function, otherwise look for matching offset
+	 * names by constructing the string and comparing it against the
+	 * pattern.
+	 */
+	if (strcmp("*", pattern) == 0) {
+		for (i = 0; i < symp->st_size; i += 4) {
+			ftp->ftps_offs[ftp->ftps_noffs++] = i;
+		}
+	} else {
+		char name[sizeof (i) * 2 + 1];
+
+		for (i = 0; i < symp->st_size; i += 4) {
+			(void) sprintf(name, "%lx", i);
+			if (gmatch(name, pattern))
+				ftp->ftps_offs[ftp->ftps_noffs++] = i;
+		}
+	}
+
+	if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) {
+		dt_dprintf("fasttrap probe creation ioctl failed: %s\n",
+		    strerror(errno));
+		return (dt_set_errno(dtp, errno));
+	}
+
+	return (ftp->ftps_noffs);
+}
Index: cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c
===================================================================
--- cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c
+++ cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c
@@ -230,6 +230,9 @@
 #if defined(__arm__)
 /* XXX */
 printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__);
+#elif defined(__aarch64__)
+/* XXX */
+printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__);
 #elif defined(__i386) || defined(__amd64)
 			rel->r_offset = s->dofs_offset +
 			    dofr[j].dofr_offset;
@@ -428,6 +431,8 @@
 		for (j = 0; j < nrel; j++) {
 #if defined(__arm__)
 /* XXX */
+#elif defined(__aarch64__)
+/* XXX */
 #elif defined(__mips__)
 /* XXX */
 #elif defined(__powerpc__)
@@ -831,6 +836,15 @@
 printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__);
 	return (0);
 }
+#elif defined(__aarch64__)
+/* XXX */
+static int
+dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela,
+    uint32_t *off)
+{
+printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__);
+	return (0);
+}
 #elif defined(__mips__)
 /* XXX */
 static int
Index: cddl/lib/Makefile
===================================================================
--- cddl/lib/Makefile
+++ cddl/lib/Makefile
@@ -28,7 +28,7 @@
 
 .if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "i386" || \
 	${MACHINE_CPUARCH} == "mips" || ${MACHINE_CPUARCH} == "powerpc" || \
-	${MACHINE_CPUARCH} == "arm"
+	${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "arm"
 _drti=		drti
 _libdtrace=	libdtrace
 .endif
Index: cddl/lib/libdtrace/Makefile
===================================================================
--- cddl/lib/libdtrace/Makefile
+++ cddl/lib/libdtrace/Makefile
@@ -86,6 +86,10 @@
 CFLAGS+=	-I${OPENSOLARIS_SYS_DISTDIR}/uts/arm
 .PATH:		${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libdtrace/arm
 .PATH:		${.CURDIR}/../../../sys/cddl/dev/dtrace/arm
+.elif ${MACHINE_CPUARCH} == "aarch64"
+CFLAGS+=	-I${OPENSOLARIS_SYS_DISTDIR}/uts/aarch64
+.PATH:		${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libdtrace/aarch64
+.PATH:		${.CURDIR}/../../../sys/cddl/dev/dtrace/aarch64
 .elif ${MACHINE_CPUARCH} == "powerpc"
 CFLAGS+=	-I${OPENSOLARIS_SYS_DISTDIR}/uts/powerpc
 .PATH:		${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libdtrace/powerpc
Index: cddl/usr.sbin/Makefile
===================================================================
--- cddl/usr.sbin/Makefile
+++ cddl/usr.sbin/Makefile
@@ -30,7 +30,7 @@
 .endif
 .endif
 
-.if ${MACHINE_CPUARCH} == "arm"
+.if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "arm"
 _dtrace=	dtrace
 _dtruss=	dtruss
 _lockstat=	lockstat
Index: lib/Makefile
===================================================================
--- lib/Makefile
+++ lib/Makefile
@@ -216,7 +216,8 @@
 # built for certain architectures.
 .if ${MK_CLANG} != "no" && ${COMPILER_TYPE} == "clang" && \
     (${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64" || \
-    (${MACHINE_CPUARCH} == "arm" && ${MACHINE_ARCH} != "armeb"))
+    (${MACHINE_CPUARCH} == "arm" && ${MACHINE_ARCH} != "armeb") || \
+    (${MACHINE_CPUARCH} == "aarch64"))
 _libclang_rt=	libclang_rt
 .endif
 
@@ -273,7 +274,7 @@
 _libsmb=	libsmb
 .endif
 
-.if ${MACHINE_CPUARCH} == "arm"
+.if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "arm"
 _libsmb=	libsmb
 _libproc=	libproc
 _librtld_db=	librtld_db
Index: lib/libproc/proc_bkpt.c
===================================================================
--- lib/libproc/proc_bkpt.c
+++ lib/libproc/proc_bkpt.c
@@ -54,6 +54,9 @@
 #elif defined(__arm__)
 #define BREAKPOINT_INSTR	0xe7ffffff	/* bkpt */
 #define BREAKPOINT_INSTR_SZ	4
+#elif defined(__aarch64__)
+#define BREAKPOINT_INSTR	0xd4200000	/* brk */
+#define BREAKPOINT_INSTR_SZ	4
 #else
 #error "Add support for your architecture"
 #endif
Index: lib/libproc/proc_regs.c
===================================================================
--- lib/libproc/proc_regs.c
+++ lib/libproc/proc_regs.c
@@ -58,6 +58,8 @@
 		*regvalue = regs.r_rip;
 #elif defined(__arm__)
 		*regvalue = regs.r_pc;
+#elif defined(__aarch64__)
+		*regvalue = regs.elr;
 #elif defined(__i386__)
 		*regvalue = regs.r_eip;
 #elif defined(__mips__)
@@ -71,6 +73,8 @@
 		*regvalue = regs.r_rsp;
 #elif defined(__arm__)
 		*regvalue = regs.r_sp;
+#elif defined(__aarch64__)
+		*regvalue = regs.sp;
 #elif defined(__i386__)
 		*regvalue = regs.r_esp;
 #elif defined(__mips__)
@@ -105,6 +109,8 @@
 		regs.r_rip = regvalue;
 #elif defined(__arm__)
 		regs.r_pc = regvalue;
+#elif defined(__aarch64__)
+		regs.elr = regvalue;
 #elif defined(__i386__)
 		regs.r_eip = regvalue;
 #elif defined(__mips__)
@@ -118,6 +124,8 @@
 		regs.r_rsp = regvalue;
 #elif defined(__arm__)
 		regs.r_sp = regvalue;
+#elif defined(__aarch64__)
+		regs.sp = regvalue;
 #elif defined(__i386__)
 		regs.r_esp = regvalue;
 #elif defined(__mips__)
Index: sys/arm64/arm64/exception.S
===================================================================
--- sys/arm64/arm64/exception.S
+++ sys/arm64/arm64/exception.S
@@ -35,6 +35,7 @@
 .macro	save_registers el
 .if \el == 1
 	mov	x18, sp
+	sub	sp, sp, #128
 .endif
 	stp	x28, x29, [sp, #-16]!
 	stp	x26, x27, [sp, #-16]!
Index: sys/arm64/arm64/trap.c
===================================================================
--- sys/arm64/arm64/trap.c
+++ sys/arm64/arm64/trap.c
@@ -53,6 +53,10 @@
 #include 
 #include 
 
+#ifdef KDTRACE_HOOKS
+#include 
+#endif
+
 #ifdef VFP
 #include 
 #endif
@@ -72,6 +76,8 @@
 void do_el0_sync(struct trapframe *);
 void do_el0_error(struct trapframe *);
 
+int (*dtrace_invop_jump_addr)(struct trapframe *);
+
 static __inline void
 call_trapsignal(struct thread *td, int sig, u_long code)
 {
@@ -230,6 +236,11 @@
 	esr = READ_SPECIALREG(esr_el1);
 	exception = ESR_ELx_EXCEPTION(esr);
 
+#ifdef KDTRACE_HOOKS
+	if (dtrace_trap_func != NULL && (*dtrace_trap_func)(frame, exception))
+		return;
+#endif
+
 	/*
 	 * Sanity check we are in an exception er can handle. The IL bit
 	 * is used to indicate the instruction length, except in a few
@@ -252,6 +263,12 @@
 		data_abort(frame, esr, 0);
 		break;
 	case EXCP_BRK:
+#ifdef KDTRACE_HOOKS
+	if (dtrace_invop_jump_addr != 0) {
+		dtrace_invop_jump_addr(frame);
+		break;
+	}
+#endif
 	case EXCP_WATCHPT_EL1:
 	case EXCP_SOFTSTP_EL1:
 #ifdef KDB
Index: sys/cddl/contrib/opensolaris/uts/aarch64/dtrace/fasttrap_isa.c
===================================================================
--- sys/cddl/contrib/opensolaris/uts/aarch64/dtrace/fasttrap_isa.c
+++ sys/cddl/contrib/opensolaris/uts/aarch64/dtrace/fasttrap_isa.c
@@ -0,0 +1,29 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ *	XXX: Placeholder for AArch64 fasttrap code
+ */
Index: sys/cddl/contrib/opensolaris/uts/aarch64/sys/fasttrap_isa.h
===================================================================
--- sys/cddl/contrib/opensolaris/uts/aarch64/sys/fasttrap_isa.h
+++ sys/cddl/contrib/opensolaris/uts/aarch64/sys/fasttrap_isa.h
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef	_FASTTRAP_ISA_H
+#define	_FASTTRAP_ISA_H
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#include 
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef uint32_t	fasttrap_instr_t;
+
+/* XXX: Place for AArch64 fasttrap headers */
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _FASTTRAP_ISA_H */
Index: sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
===================================================================
--- sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
+++ sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
@@ -11884,7 +11884,8 @@
 	int i;
 
 	*factor = 1;
-#if defined(__amd64__) || defined(__arm__) || defined(__mips__) || defined(__powerpc__)
+#if defined(__aarch64__) || defined(__amd64__) || defined(__arm__) || \
+    defined(__mips__) || defined(__powerpc__)
 	/*
 	 * FreeBSD isn't good at limiting the amount of memory we
 	 * ask to malloc, so let's place a limit here before trying
Index: sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h
===================================================================
--- sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h
+++ sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h
@@ -2445,6 +2445,32 @@
 #define DTRACE_INVOP_POPM	2
 #define DTRACE_INVOP_B		3
 
+#elif defined(__aarch64__)
+
+#define	INSN_SIZE	4
+
+#define	B_MASK		0xff000000
+#define	B_DATA_MASK	0x00ffffff
+#define	B_INSTR		0x14000000
+
+#define	LDP_STP_MASK	0xffc00000
+#define	STP_32		0x29800000
+#define	STP_64		0xa9800000
+#define	LDP_32		0x28c00000
+#define	LDP_64		0xa8c00000
+#define	LDP_STP_PREIND	(1 << 24)
+#define	LDP_STP_DIR	(1 << 22) /* Load instruction */
+#define	ARG1_SHIFT	0
+#define	ARG1_MASK	0x1f
+#define	ARG2_SHIFT	10
+#define	ARG2_MASK	0x1f
+#define	OFFSET_SHIFT	15
+#define	OFFSET_SIZE	7
+#define	OFFSET_MASK	((1 << OFFSET_SIZE) - 1)
+
+#define	DTRACE_INVOP_PUSHM	1
+#define	DTRACE_INVOP_POPM	2
+#define	DTRACE_INVOP_B		3
 
 #endif
 
Index: sys/cddl/dev/dtrace/aarch64/dtrace_asm.S
===================================================================
--- sys/cddl/dev/dtrace/aarch64/dtrace_asm.S
+++ sys/cddl/dev/dtrace/aarch64/dtrace_asm.S
@@ -0,0 +1,165 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ * $FreeBSD$
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#define _ASM
+#define _LOCORE
+
+#include 
+#include 
+
+#include 
+#include 
+
+#include "assym.s"
+
+/*
+void dtrace_membar_producer(void)
+*/
+ENTRY(dtrace_membar_producer)
+	RET
+END(dtrace_membar_producer)
+
+/*
+void dtrace_membar_consumer(void)
+*/
+ENTRY(dtrace_membar_consumer)
+	RET
+END(dtrace_membar_consumer)
+
+/*
+dtrace_icookie_t dtrace_interrupt_disable(void)
+*/
+ENTRY(dtrace_interrupt_disable)
+	msr	daifset, #2
+	RET
+END(dtrace_interrupt_disable)
+
+/*
+void dtrace_interrupt_enable(dtrace_icookie_t cookie)
+*/
+ENTRY(dtrace_interrupt_enable)
+	msr	daifclr, #2
+	RET
+END(dtrace_interrupt_enable)
+/*
+uint8_t
+dtrace_fuword8_nocheck(void *addr)
+*/
+ENTRY(dtrace_fuword8_nocheck)
+	ldrb	w0, [x0]
+	RET
+END(dtrace_fuword8_nocheck)
+
+/*
+uint16_t
+dtrace_fuword16_nocheck(void *addr)
+*/
+ENTRY(dtrace_fuword16_nocheck)
+	ldrh	w0, [x0]
+	RET
+END(dtrace_fuword16_nocheck)
+
+/*
+uint32_t
+dtrace_fuword32_nocheck(void *addr)
+*/
+ENTRY(dtrace_fuword32_nocheck)
+	ldr	w0, [x0]
+	RET
+END(dtrace_fuword32_nocheck)
+
+/*
+uint64_t
+dtrace_fuword64_nocheck(void *addr)
+*/
+ENTRY(dtrace_fuword64_nocheck)
+	ldr	x0, [x0]
+	RET
+END(dtrace_fuword64_nocheck)
+
+/*
+void
+dtrace_copy(uintptr_t uaddr, uintptr_t kaddr, size_t size)
+*/
+ENTRY(dtrace_copy)
+	cbz	x2, 2f		/* If len == 0 then skip loop */
+1:
+	ldrb	w4, [x0], #1	/* Load from uaddr */
+	strb	w4, [x1], #1	/* Store in kaddr */
+	sub	x2, x2, #1	/* len-- */
+	cbnz	x2, 1b
+2:
+	RET
+END(dtrace_copy)
+
+/*
+void
+dtrace_copystr(uintptr_t uaddr, uintptr_t kaddr, size_t size,
+    volatile uint16_t *flags)
+XXX: Check for flags?
+*/
+ENTRY(dtrace_copystr)
+	cbz     x2, 2f          /* If len == 0 then skip loop */
+ 
+1:	ldrb    w4, [x0], #1    /* Load from uaddr */
+	strb    w4, [x1], #1    /* Store in kaddr */
+	cbz     w4, 2f          /* If == 0 then break */
+	sub     x2, x2, #1      /* len-- */
+	cbnz    x2, 1b
+2:
+	RET
+END(dtrace_copystr)
+
+/*
+uintptr_t
+dtrace_caller(int aframes)
+*/
+ENTRY(dtrace_caller)
+	mov	x0, #-1
+	RET
+END(dtrace_caller)
+
+/*
+uint32_t
+dtrace_cas32(uint32_t *target, uint32_t cmp, uint32_t new)
+
+void *
+dtrace_casptr(volatile void *target, volatile void *cmp, volatile void *new)
+*/
+ENTRY(dtrace_cas32)
+EENTRY(dtrace_casptr)
+1:	ldxr	x3, [x0]	/* Load target */
+	cmp	x3, x1		/* Check if *target == cmp */
+	bne	2f		/* No, return */
+	stxr	w12, x2, [x0]	/* Store new to target */
+	cmp	w12, #0		/* Did the store succeed? */
+	bne	1b		/* No, try again */
+2:	mov	x0, x3		/* Return the value loaded from target */
+	RET
+EEND(dtrace_casptr)
+END(dtrace_cas32)
Index: sys/cddl/dev/dtrace/aarch64/dtrace_isa.c
===================================================================
--- sys/cddl/dev/dtrace/aarch64/dtrace_isa.c
+++ sys/cddl/dev/dtrace/aarch64/dtrace_isa.c
@@ -0,0 +1,287 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ * $FreeBSD$
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "regset.h"
+
+/*
+ * Wee need some reasonable default to prevent backtrace code
+ * from wandering too far
+ */
+#define	MAX_FUNCTION_SIZE 0x10000
+#define	MAX_PROLOGUE_SIZE 0x100
+
+uint8_t dtrace_fuword8_nocheck(void *);
+uint16_t dtrace_fuword16_nocheck(void *);
+uint32_t dtrace_fuword32_nocheck(void *);
+uint64_t dtrace_fuword64_nocheck(void *);
+
+void
+dtrace_getpcstack(pc_t *pcstack, int pcstack_limit, int aframes,
+    uint32_t *intrpc)
+{
+	struct unwind_state state;
+	int scp_offset;
+	register_t sp;
+	int depth;
+
+	depth = 0;
+
+	if (intrpc != 0) {
+		pcstack[depth++] = (pc_t) intrpc;
+	}
+
+	aframes++;
+
+	__asm __volatile("mov %0, sp" : "=&r" (sp));
+
+	state.fp = (uint64_t)__builtin_frame_address(0);
+	state.sp = sp;
+	state.pc = (uint64_t)dtrace_getpcstack;
+
+	while (depth < pcstack_limit) {
+		if (unwind_frame(&state))
+			break;
+
+		if (!INKERNEL(state.pc) || !INKERNEL(state.fp))
+			break;
+
+		/*
+		 * NB: Unlike some other architectures, we don't need to
+		 * explicitly insert cpu_dtrace_caller as it appears in the
+		 * normal kernel stack trace rather than a special trap frame.
+		 */
+		if (aframes > 0) {
+			aframes--;
+		} else {
+			pcstack[depth++] = state.pc;
+		}
+
+	}
+
+	for (; depth < pcstack_limit; depth++) {
+		pcstack[depth] = 0;
+	}
+}
+
+void
+dtrace_getupcstack(uint64_t *pcstack, int pcstack_limit)
+{
+
+	printf("IMPLEMENT ME: %s\n", __func__);
+}
+
+int
+dtrace_getustackdepth(void)
+{
+
+	printf("IMPLEMENT ME: %s\n", __func__);
+
+	return (0);
+}
+
+void
+dtrace_getufpstack(uint64_t *pcstack, uint64_t *fpstack, int pcstack_limit)
+{
+
+	printf("IMPLEMENT ME: %s\n", __func__);
+}
+
+/*ARGSUSED*/
+uint64_t
+dtrace_getarg(int arg, int aframes)
+{
+
+	printf("IMPLEMENT ME: %s\n", __func__);
+
+	return (0);
+}
+
+int
+dtrace_getstackdepth(int aframes)
+{
+	struct unwind_state state;
+	int scp_offset;
+	register_t sp;
+	int depth;
+	int done;
+
+	depth = 1;
+	done = 0;
+
+	__asm __volatile("mov %0, sp" : "=&r" (sp));
+
+	state.fp = (uint64_t)__builtin_frame_address(0);
+	state.sp = sp;
+	state.pc = (uint64_t)dtrace_getstackdepth;
+
+	do {
+		done = unwind_frame(&state);
+		if (!INKERNEL(state.pc) || !INKERNEL(state.fp))
+			break;
+		depth++;
+	} while (!done);
+
+	if (depth < aframes)
+		return (0);
+	else
+		return (depth - aframes);
+}
+
+ulong_t
+dtrace_getreg(struct trapframe *rp, uint_t reg)
+{
+
+	printf("IMPLEMENT ME: %s\n", __func__);
+
+	return (0);
+}
+
+static int
+dtrace_copycheck(uintptr_t uaddr, uintptr_t kaddr, size_t size)
+{
+
+	if (uaddr + size > VM_MAXUSER_ADDRESS || uaddr + size < uaddr) {
+		DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
+		cpu_core[curcpu].cpuc_dtrace_illval = uaddr;
+		return (0);
+	}
+
+	return (1);
+}
+
+void
+dtrace_copyin(uintptr_t uaddr, uintptr_t kaddr, size_t size,
+    volatile uint16_t *flags)
+{
+
+	if (dtrace_copycheck(uaddr, kaddr, size))
+		dtrace_copy(uaddr, kaddr, size);
+}
+
+void
+dtrace_copyout(uintptr_t kaddr, uintptr_t uaddr, size_t size,
+    volatile uint16_t *flags)
+{
+
+	if (dtrace_copycheck(uaddr, kaddr, size))
+		dtrace_copy(kaddr, uaddr, size);
+}
+
+void
+dtrace_copyinstr(uintptr_t uaddr, uintptr_t kaddr, size_t size,
+    volatile uint16_t *flags)
+{
+
+	if (dtrace_copycheck(uaddr, kaddr, size))
+		dtrace_copystr(uaddr, kaddr, size, flags);
+}
+
+void
+dtrace_copyoutstr(uintptr_t kaddr, uintptr_t uaddr, size_t size,
+    volatile uint16_t *flags)
+{
+
+	if (dtrace_copycheck(uaddr, kaddr, size))
+		dtrace_copystr(kaddr, uaddr, size, flags);
+}
+
+uint8_t
+dtrace_fuword8(void *uaddr)
+{
+
+	if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) {
+		DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
+		cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr;
+		return (0);
+	}
+
+	return (dtrace_fuword8_nocheck(uaddr));
+}
+
+uint16_t
+dtrace_fuword16(void *uaddr)
+{
+
+	if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) {
+		DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
+		cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr;
+		return (0);
+	}
+
+	return (dtrace_fuword16_nocheck(uaddr));
+}
+
+uint32_t
+dtrace_fuword32(void *uaddr)
+{
+
+	if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) {
+		DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
+		cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr;
+		return (0);
+	}
+
+	return (dtrace_fuword32_nocheck(uaddr));
+}
+
+uint64_t
+dtrace_fuword64(void *uaddr)
+{
+
+	if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) {
+		DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
+		cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr;
+		return (0);
+	}
+
+	return (dtrace_fuword64_nocheck(uaddr));
+}
Index: sys/cddl/dev/dtrace/aarch64/dtrace_subr.c
===================================================================
--- sys/cddl/dev/dtrace/aarch64/dtrace_subr.c
+++ sys/cddl/dev/dtrace/aarch64/dtrace_subr.c
@@ -0,0 +1,306 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ * $FreeBSD$
+ *
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include 
+__FBSDID("$FreeBSD$");
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+extern uintptr_t 	dtrace_in_probe_addr;
+extern int		dtrace_in_probe;
+extern dtrace_id_t	dtrace_probeid_error;
+extern int (*dtrace_invop_jump_addr)(struct trapframe *);
+extern void dtrace_getnanotime(struct timespec *tsp);
+
+int dtrace_invop(uintptr_t, uintptr_t *, uintptr_t);
+void dtrace_invop_init(void);
+void dtrace_invop_uninit(void);
+
+typedef struct dtrace_invop_hdlr {
+	int (*dtih_func)(uintptr_t, uintptr_t *, uintptr_t);
+	struct dtrace_invop_hdlr *dtih_next;
+} dtrace_invop_hdlr_t;
+
+dtrace_invop_hdlr_t *dtrace_invop_hdlr;
+
+int
+dtrace_invop(uintptr_t addr, uintptr_t *stack, uintptr_t eax)
+{
+	dtrace_invop_hdlr_t *hdlr;
+	int rval;
+
+	for (hdlr = dtrace_invop_hdlr; hdlr != NULL; hdlr = hdlr->dtih_next)
+		if ((rval = hdlr->dtih_func(addr, stack, eax)) != 0)
+			return (rval);
+
+	return (0);
+}
+
+
+void
+dtrace_invop_add(int (*func)(uintptr_t, uintptr_t *, uintptr_t))
+{
+	dtrace_invop_hdlr_t *hdlr;
+
+	hdlr = kmem_alloc(sizeof (dtrace_invop_hdlr_t), KM_SLEEP);
+	hdlr->dtih_func = func;
+	hdlr->dtih_next = dtrace_invop_hdlr;
+	dtrace_invop_hdlr = hdlr;
+}
+
+void
+dtrace_invop_remove(int (*func)(uintptr_t, uintptr_t *, uintptr_t))
+{
+	dtrace_invop_hdlr_t *hdlr, *prev;
+
+	hdlr = dtrace_invop_hdlr;
+	prev = NULL;
+
+	for (;;) {
+		if (hdlr == NULL)
+			panic("attempt to remove non-existent invop handler");
+
+		if (hdlr->dtih_func == func)
+			break;
+
+		prev = hdlr;
+		hdlr = hdlr->dtih_next;
+	}
+
+	if (prev == NULL) {
+		ASSERT(dtrace_invop_hdlr == hdlr);
+		dtrace_invop_hdlr = hdlr->dtih_next;
+	} else {
+		ASSERT(dtrace_invop_hdlr != hdlr);
+		prev->dtih_next = hdlr->dtih_next;
+	}
+
+	kmem_free(hdlr, 0);
+}
+
+/*ARGSUSED*/
+void
+dtrace_toxic_ranges(void (*func)(uintptr_t base, uintptr_t limit))
+{
+
+	printf("IMPLEMENT ME: dtrace_toxic_ranges\n");
+}
+
+void
+dtrace_xcall(processorid_t cpu, dtrace_xcall_t func, void *arg)
+{
+	cpuset_t cpus;
+
+	if (cpu == DTRACE_CPUALL)
+		cpus = all_cpus;
+	else
+		CPU_SETOF(cpu, &cpus);
+
+	smp_rendezvous_cpus(cpus, smp_no_rendevous_barrier, func,
+	    smp_no_rendevous_barrier, arg);
+}
+
+static void
+dtrace_sync_func(void)
+{
+
+}
+
+void
+dtrace_sync(void)
+{
+
+	dtrace_xcall(DTRACE_CPUALL, (dtrace_xcall_t)dtrace_sync_func, NULL);
+}
+
+/*
+ * DTrace needs a high resolution time function which can
+ * be called from a probe context and guaranteed not to have
+ * instrumented with probes itself.
+ *
+ * Returns nanoseconds since boot.
+ */
+uint64_t
+dtrace_gethrtime()
+{
+	struct timespec curtime;
+
+	nanouptime(&curtime);
+
+	return (curtime.tv_sec * 1000000000UL + curtime.tv_nsec);
+
+}
+
+uint64_t
+dtrace_gethrestime(void)
+{
+	struct timespec current_time;
+
+	dtrace_getnanotime(¤t_time);
+
+	return (current_time.tv_sec * 1000000000UL + current_time.tv_nsec);
+}
+
+/* Function to handle DTrace traps during probes. See arm64/arm64/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 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) {
+		case EXCP_DATA_ABORT:
+			/* Flag a bad address. */
+			cpu_core[curcpu].cpuc_dtrace_flags |= CPU_DTRACE_BADADDR;
+			cpu_core[curcpu].cpuc_dtrace_illval = 0;
+
+			/*
+			 * Offset the instruction pointer to the instruction
+			 * following the one causing the fault.
+			 */
+			frame->tf_elr += 4;
+			return (1);
+		default:
+			/* Handle all other traps in the usual way. */
+			break;
+		}
+	}
+
+	/* Handle the trap in the usual way. */
+	return (0);
+}
+
+void
+dtrace_probe_error(dtrace_state_t *state, dtrace_epid_t epid, int which,
+    int fault, int fltoffs, uintptr_t illval)
+{
+
+	dtrace_probe(dtrace_probeid_error, (uint64_t)(uintptr_t)state,
+	    (uintptr_t)epid,
+	    (uintptr_t)which, (uintptr_t)fault, (uintptr_t)fltoffs);
+}
+
+static int
+dtrace_invop_start(struct trapframe *frame)
+{
+	int data, invop, reg, update_sp;
+	register_t arg1, arg2;
+	register_t *sp;
+	int offs;
+	int tmp;
+	int i;
+
+	invop = dtrace_invop(frame->tf_elr, (uintptr_t *)frame, frame->tf_elr);
+
+	tmp = (invop & LDP_STP_MASK);
+	if (tmp == STP_64 || tmp == LDP_64) {
+		sp = (register_t *)frame->tf_sp;
+		data = invop;
+		arg1 = (data >> ARG1_SHIFT) & ARG1_MASK;
+		arg2 = (data >> ARG2_SHIFT) & ARG2_MASK;
+
+		offs = (data >> OFFSET_SHIFT) & OFFSET_MASK;
+
+		switch (tmp) {
+		case STP_64:
+			if (offs >> (OFFSET_SIZE - 1))
+				sp -= (~offs & OFFSET_MASK) + 1;
+			else
+				sp += (offs);
+			*(sp + 0) = frame->tf_x[arg1];
+			*(sp + 1) = frame->tf_x[arg2];
+			break;
+		case LDP_64:
+			frame->tf_x[arg1] = *(sp + 0);
+			frame->tf_x[arg2] = *(sp + 1);
+			if (offs >> (OFFSET_SIZE - 1))
+				sp -= (~offs & OFFSET_MASK) + 1;
+			else
+				sp += (offs);
+			break;
+		default:
+			break;
+		}
+
+		/* Update the stack pointer and program counter to continue */
+		frame->tf_sp = (register_t)sp;
+		frame->tf_elr += INSN_SIZE;
+		return (0);
+	}
+
+	if ((invop & B_MASK) == B_INSTR) {
+		data = (invop & B_DATA_MASK);
+		/* The data is the number of 4-byte words to change the pc */
+		data *= 4;
+		frame->tf_elr += data;
+		return (0);
+	}
+
+	return (-1);
+}
+
+void
+dtrace_invop_init(void)
+{
+
+	dtrace_invop_jump_addr = dtrace_invop_start;
+}
+
+void
+dtrace_invop_uninit(void)
+{
+
+	dtrace_invop_jump_addr = 0;
+}
Index: sys/cddl/dev/dtrace/aarch64/regset.h
===================================================================
--- sys/cddl/dev/dtrace/aarch64/regset.h
+++ sys/cddl/dev/dtrace/aarch64/regset.h
@@ -0,0 +1,51 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ * $FreeBSD$ 
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*	Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */
+
+/*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T		*/
+/*	All Rights Reserved	*/
+
+#ifndef	_REGSET_H
+#define	_REGSET_H
+
+/*
+ * #pragma ident	"@(#)regset.h	1.11	05/06/08 SMI"
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Place here */
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _REGSET_H */
Index: sys/cddl/dev/fbt/aarch64/fbt_isa.h
===================================================================
--- sys/cddl/dev/fbt/aarch64/fbt_isa.h
+++ sys/cddl/dev/fbt/aarch64/fbt_isa.h
@@ -0,0 +1,30 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ * $FreeBSD$
+ *
+ */
+
+#ifndef _FBT_ISA_H_
+#define _FBT_ISA_H_
+
+typedef uint32_t fbt_patchval_t;
+
+#endif
Index: sys/cddl/dev/fbt/aarch64/fbt_isa.c
===================================================================
--- sys/cddl/dev/fbt/aarch64/fbt_isa.c
+++ sys/cddl/dev/fbt/aarch64/fbt_isa.c
@@ -0,0 +1,214 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ * Portions Copyright 2006-2008 John Birrell jb@freebsd.org
+ * Portions Copyright 2013 Justin Hibbits jhibbits@freebsd.org
+ * Portions Copyright 2013 Howard Su howardsu@freebsd.org
+ * Portions Copyright 2015 Ruslan Bukin 
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include 
+#include 
+
+#include 
+
+#include "fbt.h"
+
+#define	FBT_PATCHVAL	0xd4200000 /* brk */
+#define	FBT_ENTRY	"entry"
+#define	FBT_RETURN	"return"
+
+int
+fbt_invop(uintptr_t addr, uintptr_t *stack, uintptr_t rval)
+{
+	struct trapframe *frame;
+	solaris_cpu_t *cpu;
+	fbt_probe_t *fbt;
+
+	frame = (struct trapframe *)stack;
+	cpu = &solaris_cpu[curcpu];
+	fbt = fbt_probetab[FBT_ADDR2NDX(addr)];
+
+	for (; fbt != NULL; fbt = fbt->fbtp_hashnext) {
+		if ((uintptr_t)fbt->fbtp_patchpoint == addr) {
+			fbt->fbtp_invop_cnt++;
+			cpu->cpu_dtrace_caller = addr;
+
+			dtrace_probe(fbt->fbtp_id, frame->tf_x[0],
+			    frame->tf_x[1], frame->tf_x[2],
+			    frame->tf_x[3], frame->tf_x[4]);
+
+			cpu->cpu_dtrace_caller = 0;
+			return (fbt->fbtp_savedval);
+		}
+	}
+
+	return (0);
+}
+
+void
+fbt_patch_tracepoint(fbt_probe_t *fbt, fbt_patchval_t val)
+{
+
+	*fbt->fbtp_patchpoint = val;
+	cpu_icache_sync_range((vm_offset_t)fbt->fbtp_patchpoint, 4);
+}
+
+int
+fbt_provide_module_function(linker_file_t lf, int symindx,
+    linker_symval_t *symval, void *opaque)
+{
+	fbt_probe_t *fbt, *retfbt;
+	uint32_t *target, *start;
+	uint32_t *instr, *limit;
+	const char *name;
+	char *modname;
+	int offs;
+	int popm;
+
+	modname = opaque;
+	name = symval->name;
+
+	if (strncmp(name, "dtrace_", 7) == 0 &&
+	    strncmp(name, "dtrace_safe_", 12) != 0) {
+		/*
+		 * Anything beginning with "dtrace_" may be called
+		 * from probe context unless it explicitly indicates
+		 * that it won't be called from probe context by
+		 * using the prefix "dtrace_safe_".
+		 */
+		return (0);
+	}
+
+	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);
+
+	/*
+	 * In absence of DTrace kernel-module support on ARM, we need to
+	 * manually exclude FBT functions from instrumentation.
+	 */
+	if (strncmp(name, "fbt_", 4) == 0)
+		return (0);
+
+	instr = (uint32_t *)(symval->value);
+	limit = (uint32_t *)(symval->value + symval->size);
+
+	/* Look for stp (pre-indexed) operation */
+	for (; instr < limit; instr++) {
+		if ((*instr & LDP_STP_MASK) == STP_64)
+			break;
+	}
+
+	if (instr >= limit)
+		return (0);
+
+	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);
+	fbt->fbtp_patchpoint = instr;
+	fbt->fbtp_ctl = lf;
+	fbt->fbtp_loadcnt = lf->loadcnt;
+	fbt->fbtp_savedval = *instr;
+	fbt->fbtp_patchval = FBT_PATCHVAL;
+	fbt->fbtp_rval = DTRACE_INVOP_PUSHM;
+	fbt->fbtp_symindx = symindx;
+
+	fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)];
+	fbt_probetab[FBT_ADDR2NDX(instr)] = fbt;
+
+	lf->fbt_nentries++;
+
+	/* Assemble coresponding ldp instruction */
+	popm = (*instr);
+	popm &= ~(LDP_STP_PREIND); /* Change to post-indexed */
+	popm |= (LDP_STP_DIR); /* Change from stp to ldp */
+	offs = (popm >> OFFSET_SHIFT) & OFFSET_MASK;
+	popm &= ~(OFFSET_MASK << OFFSET_SHIFT);
+        if (offs >> (OFFSET_SIZE - 1))
+		popm |= (((~offs & OFFSET_MASK) + 1) << OFFSET_SHIFT);
+	else
+		popm |= ((~(offs - 1) & OFFSET_MASK) << OFFSET_SHIFT);
+
+	retfbt = NULL;
+again:
+	for (; instr < limit; instr++) {
+		if (*instr == popm)
+			break;
+		else if ((*instr & B_MASK) == B_INSTR) {
+			offs = (*instr & B_DATA_MASK);
+			offs *= 4;
+			target = (instr + offs);
+			start = (uint32_t *)symval->value;
+			if (target >= limit || target < start)
+				break;
+			instr++; /* skip delay slot */
+		}
+	}
+
+	if (instr >= limit)
+		return (0);
+
+	/*
+	 * We have a winner!
+	 */
+	fbt = malloc(sizeof (fbt_probe_t), M_FBT, M_WAITOK | M_ZERO);
+	fbt->fbtp_name = name;
+	if (retfbt == NULL) {
+		fbt->fbtp_id = dtrace_probe_create(fbt_id, modname,
+		    name, FBT_RETURN, 3, fbt);
+	} else {
+		retfbt->fbtp_next = fbt;
+		fbt->fbtp_id = retfbt->fbtp_id;
+	}
+	retfbt = fbt;
+
+	fbt->fbtp_patchpoint = instr;
+	fbt->fbtp_ctl = lf;
+	fbt->fbtp_loadcnt = lf->loadcnt;
+	fbt->fbtp_symindx = symindx;
+	if ((*instr & B_MASK) == B_INSTR)
+		fbt->fbtp_rval = DTRACE_INVOP_B;
+	else
+		fbt->fbtp_rval = DTRACE_INVOP_POPM;
+	fbt->fbtp_savedval = *instr;
+	fbt->fbtp_patchval = FBT_PATCHVAL;
+	fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)];
+	fbt_probetab[FBT_ADDR2NDX(instr)] = fbt;
+
+	lf->fbt_nentries++;
+
+	instr++;
+	goto again;
+}
Index: sys/cddl/dev/lockstat/lockstat.c
===================================================================
--- sys/cddl/dev/lockstat/lockstat.c
+++ sys/cddl/dev/lockstat/lockstat.c
@@ -43,9 +43,8 @@
 #include 
 #include 
 
-#if defined(__i386__) || defined(__amd64__) || \
-	defined(__mips__) || defined(__powerpc__) || \
-	defined(__arm__)
+#if defined(__aarch64__) || defined(__amd64__) || defined(__arm__) || \
+    defined(__i386__) || defined(__mips__) || defined(__powerpc__)
 #define LOCKSTAT_AFRAMES 1
 #else
 #error "architecture not supported"
Index: sys/cddl/dev/profile/profile.c
===================================================================
--- sys/cddl/dev/profile/profile.c
+++ sys/cddl/dev/profile/profile.c
@@ -140,6 +140,11 @@
 #define	PROF_ARTIFICIAL_FRAMES	10
 #endif
 
+#ifdef __aarch64__
+/* TODO: verify */
+#define	PROF_ARTIFICIAL_FRAMES	10
+#endif
+
 typedef struct profile_probe {
 	char		prof_name[PROF_NAMELEN];
 	dtrace_id_t	prof_id;
Index: sys/conf/files.arm64
===================================================================
--- sys/conf/files.arm64
+++ sys/conf/files.arm64
@@ -58,3 +58,7 @@
 libkern/flsll.c			standard
 libkern/memmove.c		standard
 libkern/memset.c		standard
+cddl/compat/opensolaris/kern/opensolaris_atomic.c	optional zfs | dtrace compile-with "${CDDL_C}"
+cddl/dev/dtrace/aarch64/dtrace_asm.S			optional dtrace compile-with "${DTRACE_S}"
+cddl/dev/dtrace/aarch64/dtrace_subr.c			optional dtrace compile-with "${DTRACE_C}"
+cddl/dev/fbt/aarch64/fbt_isa.c				optional dtrace_fbt | dtraceall compile-with "${FBT_C}"
Index: sys/modules/dtrace/Makefile
===================================================================
--- sys/modules/dtrace/Makefile
+++ sys/modules/dtrace/Makefile
@@ -22,7 +22,7 @@
 .if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_ARCH} == "powerpc64"
 SUBDIR+=	systrace_freebsd32
 .endif
-.if ${MACHINE_CPUARCH} == "arm"
+.if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "arm"
 SUBDIR+=	fbt
 .endif
 .include 
Index: sys/modules/dtrace/dtraceall/dtraceall.c
===================================================================
--- sys/modules/dtrace/dtraceall/dtraceall.c
+++ sys/modules/dtrace/dtraceall/dtraceall.c
@@ -69,7 +69,8 @@
 #if defined(NFSCL)
 MODULE_DEPEND(dtraceall, dtnfscl, 1, 1, 1);
 #endif
-#if defined(__amd64__) || defined(__i386__) || defined(__powerpc__) || defined(__arm__)
+#if defined(__aarch64__) || defined(__amd64__) || defined(__arm__) || \
+    defined(__i386__) || defined(__powerpc__)
 MODULE_DEPEND(dtraceall, fbt, 1, 1, 1);
 #endif
 #if defined(__amd64__) || defined(__i386__)