xref: /freebsd/sys/cddl/dev/dtrace/amd64/dtrace_asm.S (revision cc3da1955c16df5eb0019e0fef810696b035b7cf)
191eaf3e1SJohn Birrell/*
291eaf3e1SJohn Birrell * CDDL HEADER START
391eaf3e1SJohn Birrell *
491eaf3e1SJohn Birrell * The contents of this file are subject to the terms of the
591eaf3e1SJohn Birrell * Common Development and Distribution License (the "License").
691eaf3e1SJohn Birrell * You may not use this file except in compliance with the License.
791eaf3e1SJohn Birrell *
891eaf3e1SJohn Birrell * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
991eaf3e1SJohn Birrell * or http://www.opensolaris.org/os/licensing.
1091eaf3e1SJohn Birrell * See the License for the specific language governing permissions
1191eaf3e1SJohn Birrell * and limitations under the License.
1291eaf3e1SJohn Birrell *
1391eaf3e1SJohn Birrell * When distributing Covered Code, include this CDDL HEADER in each
1491eaf3e1SJohn Birrell * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1591eaf3e1SJohn Birrell * If applicable, add the following below this CDDL HEADER, with the
1691eaf3e1SJohn Birrell * fields enclosed by brackets "[]" replaced with your own identifying
1791eaf3e1SJohn Birrell * information: Portions Copyright [yyyy] [name of copyright owner]
1891eaf3e1SJohn Birrell *
1991eaf3e1SJohn Birrell * CDDL HEADER END
2091eaf3e1SJohn Birrell *
2191eaf3e1SJohn Birrell * Portions Copyright 2008 John Birrell <jb@freebsd.org>
2291eaf3e1SJohn Birrell *
2391eaf3e1SJohn Birrell */
2491eaf3e1SJohn Birrell/*
2591eaf3e1SJohn Birrell * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
2691eaf3e1SJohn Birrell * Use is subject to license terms.
2791eaf3e1SJohn Birrell */
2891eaf3e1SJohn Birrell
2991eaf3e1SJohn Birrell#define _ASM
3091eaf3e1SJohn Birrell
3191eaf3e1SJohn Birrell#include <machine/asmacros.h>
3291eaf3e1SJohn Birrell#include <sys/cpuvar_defs.h>
3391eaf3e1SJohn Birrell#include <sys/dtrace.h>
3491eaf3e1SJohn Birrell
35fc2a8776SEd Maste#include "assym.inc"
3691eaf3e1SJohn Birrell
3791eaf3e1SJohn Birrell#define INTR_POP				\
3891eaf3e1SJohn Birrell	movq	TF_RDI(%rsp),%rdi;		\
3991eaf3e1SJohn Birrell	movq	TF_RSI(%rsp),%rsi;		\
4091eaf3e1SJohn Birrell	movq	TF_RDX(%rsp),%rdx;		\
4191eaf3e1SJohn Birrell	movq	TF_RCX(%rsp),%rcx;		\
4291eaf3e1SJohn Birrell	movq	TF_R8(%rsp),%r8;		\
4391eaf3e1SJohn Birrell	movq	TF_R9(%rsp),%r9;		\
4491eaf3e1SJohn Birrell	movq	TF_RAX(%rsp),%rax;		\
4591eaf3e1SJohn Birrell	movq	TF_RBX(%rsp),%rbx;		\
4691eaf3e1SJohn Birrell	movq	TF_RBP(%rsp),%rbp;		\
4791eaf3e1SJohn Birrell	movq	TF_R10(%rsp),%r10;		\
4891eaf3e1SJohn Birrell	movq	TF_R11(%rsp),%r11;		\
4991eaf3e1SJohn Birrell	movq	TF_R12(%rsp),%r12;		\
5091eaf3e1SJohn Birrell	movq	TF_R13(%rsp),%r13;		\
5191eaf3e1SJohn Birrell	movq	TF_R14(%rsp),%r14;		\
5291eaf3e1SJohn Birrell	movq	TF_R15(%rsp),%r15;		\
5391eaf3e1SJohn Birrell	testb	$SEL_RPL_MASK,TF_CS(%rsp);	\
5491eaf3e1SJohn Birrell	jz	1f;				\
5591eaf3e1SJohn Birrell	cli;					\
5691eaf3e1SJohn Birrell	swapgs;					\
5791eaf3e1SJohn Birrell1:	addq	$TF_RIP,%rsp;
5891eaf3e1SJohn Birrell
5991eaf3e1SJohn Birrell	ENTRY(dtrace_invop_start)
6091eaf3e1SJohn Birrell
61*cc3da195SMark Johnston	KMSAN_ENTER
62*cc3da195SMark Johnston
6391eaf3e1SJohn Birrell	/*
6491eaf3e1SJohn Birrell	 * #BP traps with %rip set to the next address. We need to decrement
6591eaf3e1SJohn Birrell	 * the value to indicate the address of the int3 (0xcc) instruction
6691eaf3e1SJohn Birrell	 * that we substituted.
6791eaf3e1SJohn Birrell	 */
6891eaf3e1SJohn Birrell	movq	TF_RIP(%rsp), %rdi
6991eaf3e1SJohn Birrell	decq	%rdi
7091eaf3e1SJohn Birrell	movq	%rsp, %rsi
713ba8e9dcSMark Johnston
723ba8e9dcSMark Johnston	/*
733ba8e9dcSMark Johnston	 * Allocate some scratch space to let the invop handler return a value.
743ba8e9dcSMark Johnston	 * This is needed when emulating "call" instructions.
753ba8e9dcSMark Johnston	 */
763ba8e9dcSMark Johnston	subq	$16, %rsp
773ba8e9dcSMark Johnston	movq	%rsp, %rdx
783ba8e9dcSMark Johnston
7991eaf3e1SJohn Birrell	call	dtrace_invop
803ba8e9dcSMark Johnston	addq	$16, %rsp
813ba8e9dcSMark Johnston
82*cc3da195SMark Johnston#ifdef KMSAN
83*cc3da195SMark Johnston	movq	%rax, %r12
84*cc3da195SMark Johnston	KMSAN_LEAVE
85*cc3da195SMark Johnston	movq	%r12, %rax
86*cc3da195SMark Johnston#endif
87*cc3da195SMark Johnston
8891eaf3e1SJohn Birrell	cmpl	$DTRACE_INVOP_PUSHL_EBP, %eax
8991eaf3e1SJohn Birrell	je	bp_push
903ba8e9dcSMark Johnston	cmpl	$DTRACE_INVOP_CALL, %eax
913ba8e9dcSMark Johnston	je	bp_call
9291eaf3e1SJohn Birrell	cmpl	$DTRACE_INVOP_LEAVE, %eax
9391eaf3e1SJohn Birrell	je	bp_leave
9491eaf3e1SJohn Birrell	cmpl	$DTRACE_INVOP_NOP, %eax
9591eaf3e1SJohn Birrell	je	bp_nop
9691eaf3e1SJohn Birrell	cmpl	$DTRACE_INVOP_RET, %eax
9791eaf3e1SJohn Birrell	je	bp_ret
9891eaf3e1SJohn Birrell
9991eaf3e1SJohn Birrell	/* When all else fails handle the trap in the usual way. */
10091eaf3e1SJohn Birrell	jmpq	*dtrace_invop_calltrap_addr
10191eaf3e1SJohn Birrell
10291eaf3e1SJohn Birrellbp_push:
10391eaf3e1SJohn Birrell	/*
10491eaf3e1SJohn Birrell	 * We must emulate a "pushq %rbp".  To do this, we pull the stack
10591eaf3e1SJohn Birrell	 * down 8 bytes, and then store the base pointer.
10691eaf3e1SJohn Birrell	 */
10791eaf3e1SJohn Birrell	INTR_POP
10891eaf3e1SJohn Birrell	subq	$16, %rsp		/* make room for %rbp */
10991eaf3e1SJohn Birrell	pushq	%rax			/* push temp */
11091eaf3e1SJohn Birrell	movq	24(%rsp), %rax		/* load calling RIP */
11191eaf3e1SJohn Birrell	movq	%rax, 8(%rsp)		/* store calling RIP */
11291eaf3e1SJohn Birrell	movq	32(%rsp), %rax		/* load calling CS */
11391eaf3e1SJohn Birrell	movq	%rax, 16(%rsp)		/* store calling CS */
11491eaf3e1SJohn Birrell	movq	40(%rsp), %rax		/* load calling RFLAGS */
11591eaf3e1SJohn Birrell	movq	%rax, 24(%rsp)		/* store calling RFLAGS */
11691eaf3e1SJohn Birrell	movq	48(%rsp), %rax		/* load calling RSP */
11791eaf3e1SJohn Birrell	subq	$8, %rax		/* make room for %rbp */
11891eaf3e1SJohn Birrell	movq	%rax, 32(%rsp)		/* store calling RSP */
11991eaf3e1SJohn Birrell	movq	56(%rsp), %rax		/* load calling SS */
12091eaf3e1SJohn Birrell	movq	%rax, 40(%rsp)		/* store calling SS */
12191eaf3e1SJohn Birrell	movq	32(%rsp), %rax		/* reload calling RSP */
12291eaf3e1SJohn Birrell	movq	%rbp, (%rax)		/* store %rbp there */
12391eaf3e1SJohn Birrell	popq	%rax			/* pop off temp */
12491eaf3e1SJohn Birrell	iretq				/* return from interrupt */
12591eaf3e1SJohn Birrell	/*NOTREACHED*/
12691eaf3e1SJohn Birrell
1273ba8e9dcSMark Johnstonbp_call:
1283ba8e9dcSMark Johnston	/*
1293ba8e9dcSMark Johnston	 * Emulate a "call" instruction.  The invop handler must have already
1303ba8e9dcSMark Johnston	 * updated the saved copy of %rip in the register set.  It's our job to
1313ba8e9dcSMark Johnston	 * pull the hardware-saved registers down to make space for the return
1323ba8e9dcSMark Johnston	 * address, which is provided by the invop handler in our scratch
1333ba8e9dcSMark Johnston	 * space.
1343ba8e9dcSMark Johnston	 */
1353ba8e9dcSMark Johnston	INTR_POP
1363ba8e9dcSMark Johnston	subq	$16, %rsp		/* make room for %rbp */
1373ba8e9dcSMark Johnston	pushq	%rax			/* push temp */
1383ba8e9dcSMark Johnston	pushq	%rbx			/* push temp */
1393ba8e9dcSMark Johnston
1403ba8e9dcSMark Johnston	movq	32(%rsp), %rax		/* load calling RIP */
1413ba8e9dcSMark Johnston	movq	%rax, 16(%rsp)		/* store calling RIP */
1423ba8e9dcSMark Johnston	movq	40(%rsp), %rax		/* load calling CS */
1433ba8e9dcSMark Johnston	movq	%rax, 24(%rsp)		/* store calling CS */
1443ba8e9dcSMark Johnston	movq	48(%rsp), %rax		/* load calling RFLAGS */
1453ba8e9dcSMark Johnston	movq	%rax, 32(%rsp)		/* store calling RFLAGS */
1463ba8e9dcSMark Johnston	movq	56(%rsp), %rax		/* load calling RSP */
1473ba8e9dcSMark Johnston	subq	$8, %rax		/* make room for return address */
1483ba8e9dcSMark Johnston	movq	%rax, 40(%rsp)		/* store calling RSP */
1493ba8e9dcSMark Johnston	movq	64(%rsp), %rax		/* load calling SS */
1503ba8e9dcSMark Johnston	movq	%rax, 48(%rsp)		/* store calling SS */
1513ba8e9dcSMark Johnston
1523ba8e9dcSMark Johnston	movq	-(TF_RIP - 16)(%rsp), %rax /* load return address */
1533ba8e9dcSMark Johnston	movq	40(%rsp), %rbx		/* reload calling RSP */
1543ba8e9dcSMark Johnston	movq	%rax, (%rbx)		/* store return address */
1553ba8e9dcSMark Johnston
1563ba8e9dcSMark Johnston	popq	%rbx			/* pop temp */
1573ba8e9dcSMark Johnston	popq	%rax			/* pop temp */
1583ba8e9dcSMark Johnston	iretq				/* return from interrupt */
1593ba8e9dcSMark Johnston	/*NOTREACHED*/
1603ba8e9dcSMark Johnston
16191eaf3e1SJohn Birrellbp_leave:
16291eaf3e1SJohn Birrell	/*
16391eaf3e1SJohn Birrell	 * We must emulate a "leave", which is the same as a "movq %rbp, %rsp"
16491eaf3e1SJohn Birrell	 * followed by a "popq %rbp".  This is quite a bit simpler on amd64
16591eaf3e1SJohn Birrell	 * than it is on i386 -- we can exploit the fact that the %rsp is
16691eaf3e1SJohn Birrell	 * explicitly saved to effect the pop without having to reshuffle
16791eaf3e1SJohn Birrell	 * the other data pushed for the trap.
16891eaf3e1SJohn Birrell	 */
16991eaf3e1SJohn Birrell	INTR_POP
17091eaf3e1SJohn Birrell	pushq	%rax			/* push temp */
17191eaf3e1SJohn Birrell	movq	8(%rsp), %rax		/* load calling RIP */
17291eaf3e1SJohn Birrell	movq	%rax, 8(%rsp)		/* store calling RIP */
17391eaf3e1SJohn Birrell	movq	(%rbp), %rax		/* get new %rbp */
17491eaf3e1SJohn Birrell	addq	$8, %rbp		/* adjust new %rsp */
17591eaf3e1SJohn Birrell	movq	%rbp, 32(%rsp)		/* store new %rsp */
17691eaf3e1SJohn Birrell	movq	%rax, %rbp		/* set new %rbp */
17791eaf3e1SJohn Birrell	popq	%rax			/* pop off temp */
17891eaf3e1SJohn Birrell	iretq				/* return from interrupt */
17991eaf3e1SJohn Birrell	/*NOTREACHED*/
18091eaf3e1SJohn Birrell
18191eaf3e1SJohn Birrellbp_nop:
18291eaf3e1SJohn Birrell	/* We must emulate a "nop". */
18391eaf3e1SJohn Birrell	INTR_POP
18491eaf3e1SJohn Birrell	iretq
18591eaf3e1SJohn Birrell	/*NOTREACHED*/
18691eaf3e1SJohn Birrell
18791eaf3e1SJohn Birrellbp_ret:
18891eaf3e1SJohn Birrell	INTR_POP
18991eaf3e1SJohn Birrell	pushq	%rax			/* push temp */
19091eaf3e1SJohn Birrell	movq	32(%rsp), %rax		/* load %rsp */
19191eaf3e1SJohn Birrell	movq	(%rax), %rax		/* load calling RIP */
19291eaf3e1SJohn Birrell	movq	%rax, 8(%rsp)		/* store calling RIP */
19391eaf3e1SJohn Birrell	addq	$8, 32(%rsp)		/* adjust new %rsp */
19491eaf3e1SJohn Birrell	popq	%rax			/* pop off temp */
19591eaf3e1SJohn Birrell	iretq				/* return from interrupt */
19691eaf3e1SJohn Birrell	/*NOTREACHED*/
19791eaf3e1SJohn Birrell
19891eaf3e1SJohn Birrell	END(dtrace_invop_start)
19991eaf3e1SJohn Birrell
20091eaf3e1SJohn Birrell/*
20191eaf3e1SJohn Birrellgreg_t dtrace_getfp(void)
20291eaf3e1SJohn Birrell*/
20391eaf3e1SJohn Birrell	ENTRY(dtrace_getfp)
20491eaf3e1SJohn Birrell	movq	%rbp, %rax
20591eaf3e1SJohn Birrell	ret
20691eaf3e1SJohn Birrell	END(dtrace_getfp)
20791eaf3e1SJohn Birrell
20891eaf3e1SJohn Birrell/*
20991eaf3e1SJohn Birrelluint32_t
21091eaf3e1SJohn Birrelldtrace_cas32(uint32_t *target, uint32_t cmp, uint32_t new)
21191eaf3e1SJohn Birrell*/
21291eaf3e1SJohn Birrell	ENTRY(dtrace_cas32)
21391eaf3e1SJohn Birrell	movl	%esi, %eax
21491eaf3e1SJohn Birrell	lock
21591eaf3e1SJohn Birrell	cmpxchgl %edx, (%rdi)
21691eaf3e1SJohn Birrell	ret
21791eaf3e1SJohn Birrell	END(dtrace_cas32)
21891eaf3e1SJohn Birrell
21991eaf3e1SJohn Birrell/*
22091eaf3e1SJohn Birrellvoid *
22191eaf3e1SJohn Birrelldtrace_casptr(void *target, void *cmp, void *new)
22291eaf3e1SJohn Birrell*/
22391eaf3e1SJohn Birrell	ENTRY(dtrace_casptr)
22491eaf3e1SJohn Birrell	movq	%rsi, %rax
22591eaf3e1SJohn Birrell	lock
22691eaf3e1SJohn Birrell	cmpxchgq %rdx, (%rdi)
22791eaf3e1SJohn Birrell	ret
22891eaf3e1SJohn Birrell	END(dtrace_casptr)
22991eaf3e1SJohn Birrell
23091eaf3e1SJohn Birrell/*
23191eaf3e1SJohn Birrelluintptr_t
23291eaf3e1SJohn Birrelldtrace_caller(int aframes)
23391eaf3e1SJohn Birrell*/
23491eaf3e1SJohn Birrell	ENTRY(dtrace_caller)
23591eaf3e1SJohn Birrell	movq	$-1, %rax
23691eaf3e1SJohn Birrell	ret
23791eaf3e1SJohn Birrell	END(dtrace_caller)
23891eaf3e1SJohn Birrell
23991eaf3e1SJohn Birrell/*
24091eaf3e1SJohn Birrellvoid
24191eaf3e1SJohn Birrelldtrace_copy(uintptr_t src, uintptr_t dest, size_t size)
24291eaf3e1SJohn Birrell*/
2438ca79fbdSMateusz Guzik	ENTRY(dtrace_copy_nosmap)
24491eaf3e1SJohn Birrell	pushq	%rbp
24591eaf3e1SJohn Birrell	movq	%rsp, %rbp
24691eaf3e1SJohn Birrell
24791eaf3e1SJohn Birrell	xchgq	%rdi, %rsi		/* make %rsi source, %rdi dest */
24891eaf3e1SJohn Birrell	movq	%rdx, %rcx		/* load count */
24991eaf3e1SJohn Birrell	repz				/* repeat for count ... */
25091eaf3e1SJohn Birrell	smovb				/*   move from %ds:rsi to %ed:rdi */
25191eaf3e1SJohn Birrell	leave
25291eaf3e1SJohn Birrell	ret
2538ca79fbdSMateusz Guzik	END(dtrace_copy_nosmap)
2548ca79fbdSMateusz Guzik
2558ca79fbdSMateusz Guzik	ENTRY(dtrace_copy_smap)
2568ca79fbdSMateusz Guzik	pushq	%rbp
2578ca79fbdSMateusz Guzik	movq	%rsp, %rbp
2588ca79fbdSMateusz Guzik
2598ca79fbdSMateusz Guzik	xchgq	%rdi, %rsi		/* make %rsi source, %rdi dest */
2608ca79fbdSMateusz Guzik	movq	%rdx, %rcx		/* load count */
2618ca79fbdSMateusz Guzik	stac
2628ca79fbdSMateusz Guzik	repz				/* repeat for count ... */
2638ca79fbdSMateusz Guzik	smovb				/*   move from %ds:rsi to %ed:rdi */
2648ca79fbdSMateusz Guzik	clac
2658ca79fbdSMateusz Guzik	leave
2668ca79fbdSMateusz Guzik	ret
2678ca79fbdSMateusz Guzik	END(dtrace_copy_smap)
26891eaf3e1SJohn Birrell
26991eaf3e1SJohn Birrell/*
27091eaf3e1SJohn Birrellvoid
27191eaf3e1SJohn Birrelldtrace_copystr(uintptr_t uaddr, uintptr_t kaddr, size_t size,
27291eaf3e1SJohn Birrell    volatile uint16_t *flags)
27391eaf3e1SJohn Birrell*/
2748ca79fbdSMateusz Guzik	ENTRY(dtrace_copystr_nosmap)
27591eaf3e1SJohn Birrell	pushq	%rbp
27691eaf3e1SJohn Birrell	movq	%rsp, %rbp
27791eaf3e1SJohn Birrell
27891eaf3e1SJohn Birrell0:
27991eaf3e1SJohn Birrell	movb	(%rdi), %al		/* load from source */
28091eaf3e1SJohn Birrell	movb	%al, (%rsi)		/* store to destination */
28191eaf3e1SJohn Birrell	addq	$1, %rdi		/* increment source pointer */
28291eaf3e1SJohn Birrell	addq	$1, %rsi		/* increment destination pointer */
28391eaf3e1SJohn Birrell	subq	$1, %rdx		/* decrement remaining count */
28491eaf3e1SJohn Birrell	cmpb	$0, %al
28591eaf3e1SJohn Birrell	je	2f
28691eaf3e1SJohn Birrell	testq	$0xfff, %rdx		/* test if count is 4k-aligned */
28791eaf3e1SJohn Birrell	jnz	1f			/* if not, continue with copying */
28891eaf3e1SJohn Birrell	testq	$CPU_DTRACE_BADADDR, (%rcx) /* load and test dtrace flags */
28991eaf3e1SJohn Birrell	jnz	2f
29091eaf3e1SJohn Birrell1:
29191eaf3e1SJohn Birrell	cmpq	$0, %rdx
29291eaf3e1SJohn Birrell	jne	0b
29391eaf3e1SJohn Birrell2:
29491eaf3e1SJohn Birrell	leave
29591eaf3e1SJohn Birrell	ret
29691eaf3e1SJohn Birrell
2978ca79fbdSMateusz Guzik	END(dtrace_copystr_nosmap)
2988ca79fbdSMateusz Guzik
2998ca79fbdSMateusz Guzik	ENTRY(dtrace_copystr_smap)
3008ca79fbdSMateusz Guzik	pushq	%rbp
3018ca79fbdSMateusz Guzik	movq	%rsp, %rbp
3028ca79fbdSMateusz Guzik
3038ca79fbdSMateusz Guzik	stac
3048ca79fbdSMateusz Guzik0:
3058ca79fbdSMateusz Guzik	movb	(%rdi), %al		/* load from source */
3068ca79fbdSMateusz Guzik	movb	%al, (%rsi)		/* store to destination */
3078ca79fbdSMateusz Guzik	addq	$1, %rdi		/* increment source pointer */
3088ca79fbdSMateusz Guzik	addq	$1, %rsi		/* increment destination pointer */
3098ca79fbdSMateusz Guzik	subq	$1, %rdx		/* decrement remaining count */
3108ca79fbdSMateusz Guzik	cmpb	$0, %al
3118ca79fbdSMateusz Guzik	je	2f
3128ca79fbdSMateusz Guzik	testq	$0xfff, %rdx		/* test if count is 4k-aligned */
3138ca79fbdSMateusz Guzik	jnz	1f			/* if not, continue with copying */
3148ca79fbdSMateusz Guzik	testq	$CPU_DTRACE_BADADDR, (%rcx) /* load and test dtrace flags */
3158ca79fbdSMateusz Guzik	jnz	2f
3168ca79fbdSMateusz Guzik1:
3178ca79fbdSMateusz Guzik	cmpq	$0, %rdx
3188ca79fbdSMateusz Guzik	jne	0b
3198ca79fbdSMateusz Guzik2:
3208ca79fbdSMateusz Guzik	clac
3218ca79fbdSMateusz Guzik	leave
3228ca79fbdSMateusz Guzik	ret
3238ca79fbdSMateusz Guzik
3248ca79fbdSMateusz Guzik	END(dtrace_copystr_smap)
32591eaf3e1SJohn Birrell
32691eaf3e1SJohn Birrell/*
32791eaf3e1SJohn Birrelluintptr_t
32891eaf3e1SJohn Birrelldtrace_fulword(void *addr)
32991eaf3e1SJohn Birrell*/
3308ca79fbdSMateusz Guzik	ENTRY(dtrace_fulword_nosmap)
33191eaf3e1SJohn Birrell	movq	(%rdi), %rax
33291eaf3e1SJohn Birrell	ret
3338ca79fbdSMateusz Guzik	END(dtrace_fulword_nosmap)
3348ca79fbdSMateusz Guzik
3358ca79fbdSMateusz Guzik	ENTRY(dtrace_fulword_smap)
3368ca79fbdSMateusz Guzik	stac
3378ca79fbdSMateusz Guzik	movq	(%rdi), %rax
3388ca79fbdSMateusz Guzik	clac
3398ca79fbdSMateusz Guzik	ret
3408ca79fbdSMateusz Guzik	END(dtrace_fulword_smap)
34191eaf3e1SJohn Birrell
34291eaf3e1SJohn Birrell/*
34391eaf3e1SJohn Birrelluint8_t
34491eaf3e1SJohn Birrelldtrace_fuword8_nocheck(void *addr)
34591eaf3e1SJohn Birrell*/
3468ca79fbdSMateusz Guzik	ENTRY(dtrace_fuword8_nocheck_nosmap)
34791eaf3e1SJohn Birrell	xorq	%rax, %rax
34891eaf3e1SJohn Birrell	movb	(%rdi), %al
34991eaf3e1SJohn Birrell	ret
3508ca79fbdSMateusz Guzik	END(dtrace_fuword8_nocheck_nosmap)
3518ca79fbdSMateusz Guzik
3528ca79fbdSMateusz Guzik	ENTRY(dtrace_fuword8_nocheck_smap)
3538ca79fbdSMateusz Guzik	stac
3548ca79fbdSMateusz Guzik	xorq	%rax, %rax
3558ca79fbdSMateusz Guzik	movb	(%rdi), %al
3568ca79fbdSMateusz Guzik	clac
3578ca79fbdSMateusz Guzik	ret
3588ca79fbdSMateusz Guzik	END(dtrace_fuword8_nocheck_smap)
35991eaf3e1SJohn Birrell
36091eaf3e1SJohn Birrell/*
36191eaf3e1SJohn Birrelluint16_t
36291eaf3e1SJohn Birrelldtrace_fuword16_nocheck(void *addr)
36391eaf3e1SJohn Birrell*/
3648ca79fbdSMateusz Guzik	ENTRY(dtrace_fuword16_nocheck_nosmap)
36591eaf3e1SJohn Birrell	xorq	%rax, %rax
36691eaf3e1SJohn Birrell	movw	(%rdi), %ax
36791eaf3e1SJohn Birrell	ret
3688ca79fbdSMateusz Guzik	END(dtrace_fuword16_nocheck_nosmap)
3698ca79fbdSMateusz Guzik
3708ca79fbdSMateusz Guzik	ENTRY(dtrace_fuword16_nocheck_smap)
3718ca79fbdSMateusz Guzik	stac
3728ca79fbdSMateusz Guzik	xorq	%rax, %rax
3738ca79fbdSMateusz Guzik	movw	(%rdi), %ax
3748ca79fbdSMateusz Guzik	clac
3758ca79fbdSMateusz Guzik	ret
3768ca79fbdSMateusz Guzik	END(dtrace_fuword16_nocheck_smap)
37791eaf3e1SJohn Birrell
37891eaf3e1SJohn Birrell/*
37991eaf3e1SJohn Birrelluint32_t
38091eaf3e1SJohn Birrelldtrace_fuword32_nocheck(void *addr)
38191eaf3e1SJohn Birrell*/
3828ca79fbdSMateusz Guzik	ENTRY(dtrace_fuword32_nocheck_nosmap)
38391eaf3e1SJohn Birrell	xorq	%rax, %rax
38491eaf3e1SJohn Birrell	movl	(%rdi), %eax
38591eaf3e1SJohn Birrell	ret
3868ca79fbdSMateusz Guzik	END(dtrace_fuword32_nocheck_nosmap)
3878ca79fbdSMateusz Guzik
3888ca79fbdSMateusz Guzik	ENTRY(dtrace_fuword32_nocheck_smap)
3898ca79fbdSMateusz Guzik	stac
3908ca79fbdSMateusz Guzik	xorq	%rax, %rax
3918ca79fbdSMateusz Guzik	movl	(%rdi), %eax
3928ca79fbdSMateusz Guzik	clac
3938ca79fbdSMateusz Guzik	ret
3948ca79fbdSMateusz Guzik	END(dtrace_fuword32_nocheck_smap)
39591eaf3e1SJohn Birrell
39691eaf3e1SJohn Birrell/*
39791eaf3e1SJohn Birrelluint64_t
39891eaf3e1SJohn Birrelldtrace_fuword64_nocheck(void *addr)
39991eaf3e1SJohn Birrell*/
4008ca79fbdSMateusz Guzik	ENTRY(dtrace_fuword64_nocheck_nosmap)
40191eaf3e1SJohn Birrell	movq	(%rdi), %rax
40291eaf3e1SJohn Birrell	ret
4038ca79fbdSMateusz Guzik	END(dtrace_fuword64_nocheck_nosmap)
4048ca79fbdSMateusz Guzik
4058ca79fbdSMateusz Guzik	ENTRY(dtrace_fuword64_nocheck_smap)
4068ca79fbdSMateusz Guzik	stac
4078ca79fbdSMateusz Guzik	movq	(%rdi), %rax
4088ca79fbdSMateusz Guzik	clac
4098ca79fbdSMateusz Guzik	ret
4108ca79fbdSMateusz Guzik	END(dtrace_fuword64_nocheck_smap)
41191eaf3e1SJohn Birrell
41291eaf3e1SJohn Birrell/*
41391eaf3e1SJohn Birrellvoid
41491eaf3e1SJohn Birrelldtrace_probe_error(dtrace_state_t *state, dtrace_epid_t epid, int which,
41591eaf3e1SJohn Birrell    int fault, int fltoffs, uintptr_t illval)
41691eaf3e1SJohn Birrell*/
41791eaf3e1SJohn Birrell	ENTRY(dtrace_probe_error)
41891eaf3e1SJohn Birrell	pushq	%rbp
41991eaf3e1SJohn Birrell	movq	%rsp, %rbp
42091eaf3e1SJohn Birrell	subq	$0x8, %rsp
42191eaf3e1SJohn Birrell	movq	%r9, (%rsp)
42291eaf3e1SJohn Birrell	movq	%r8, %r9
42391eaf3e1SJohn Birrell	movq	%rcx, %r8
42491eaf3e1SJohn Birrell	movq	%rdx, %rcx
42591eaf3e1SJohn Birrell	movq	%rsi, %rdx
42691eaf3e1SJohn Birrell	movq	%rdi, %rsi
42791eaf3e1SJohn Birrell	movl	dtrace_probeid_error(%rip), %edi
42891eaf3e1SJohn Birrell	call	dtrace_probe
42991eaf3e1SJohn Birrell	addq	$0x8, %rsp
43091eaf3e1SJohn Birrell	leave
43191eaf3e1SJohn Birrell	ret
43291eaf3e1SJohn Birrell	END(dtrace_probe_error)
43391eaf3e1SJohn Birrell
43491eaf3e1SJohn Birrell/*
43591eaf3e1SJohn Birrellvoid
43691eaf3e1SJohn Birrelldtrace_membar_producer(void)
43791eaf3e1SJohn Birrell*/
43891eaf3e1SJohn Birrell	ENTRY(dtrace_membar_producer)
43991eaf3e1SJohn Birrell	rep;	ret	/* use 2 byte return instruction when branch target */
44091eaf3e1SJohn Birrell			/* AMD Software Optimization Guide - Section 6.2 */
44191eaf3e1SJohn Birrell	END(dtrace_membar_producer)
44291eaf3e1SJohn Birrell
44391eaf3e1SJohn Birrell/*
44491eaf3e1SJohn Birrellvoid
44591eaf3e1SJohn Birrelldtrace_membar_consumer(void)
44691eaf3e1SJohn Birrell*/
44791eaf3e1SJohn Birrell	ENTRY(dtrace_membar_consumer)
44891eaf3e1SJohn Birrell	rep;	ret	/* use 2 byte return instruction when branch target */
44991eaf3e1SJohn Birrell			/* AMD Software Optimization Guide - Section 6.2 */
45091eaf3e1SJohn Birrell	END(dtrace_membar_consumer)
45191eaf3e1SJohn Birrell
45291eaf3e1SJohn Birrell/*
45391eaf3e1SJohn Birrelldtrace_icookie_t
45491eaf3e1SJohn Birrelldtrace_interrupt_disable(void)
45591eaf3e1SJohn Birrell*/
45691eaf3e1SJohn Birrell	ENTRY(dtrace_interrupt_disable)
45791eaf3e1SJohn Birrell	pushfq
45891eaf3e1SJohn Birrell	popq	%rax
45991eaf3e1SJohn Birrell	cli
46091eaf3e1SJohn Birrell	ret
46191eaf3e1SJohn Birrell	END(dtrace_interrupt_disable)
46291eaf3e1SJohn Birrell
46391eaf3e1SJohn Birrell/*
46491eaf3e1SJohn Birrellvoid
46591eaf3e1SJohn Birrelldtrace_interrupt_enable(dtrace_icookie_t cookie)
46691eaf3e1SJohn Birrell*/
46791eaf3e1SJohn Birrell	ENTRY(dtrace_interrupt_enable)
46891eaf3e1SJohn Birrell	pushq	%rdi
46991eaf3e1SJohn Birrell	popfq
47091eaf3e1SJohn Birrell	ret
47191eaf3e1SJohn Birrell	END(dtrace_interrupt_enable)
472