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