17c478bd9Sstevel@tonic-gate/* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 59acbbeafSnn35248 * Common Development and Distribution License (the "License"). 69acbbeafSnn35248 * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate/* 22b08adf18SBill Holler * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 2622cc0e45SBill Holler/* 27b08adf18SBill Holler * Copyright (c) 2009, Intel Corporation 2822cc0e45SBill Holler * All rights reserved. 2922cc0e45SBill Holler */ 3022cc0e45SBill Holler 317c478bd9Sstevel@tonic-gate/* Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */ 327c478bd9Sstevel@tonic-gate/* Copyright (c) 1984, 1986, 1987, 1988, 1989, 1990 AT&T */ 337c478bd9Sstevel@tonic-gate/* All Rights Reserved */ 347c478bd9Sstevel@tonic-gate 357c478bd9Sstevel@tonic-gate/* Copyright (c) 1987, 1988 Microsoft Corporation */ 367c478bd9Sstevel@tonic-gate/* All Rights Reserved */ 377c478bd9Sstevel@tonic-gate 38*9b6707c5SRobert Mustacchi/* 39*9b6707c5SRobert Mustacchi * Copyright 2016 Joyent, Inc. 40*9b6707c5SRobert Mustacchi */ 41*9b6707c5SRobert Mustacchi 427c478bd9Sstevel@tonic-gate#include <sys/errno.h> 437c478bd9Sstevel@tonic-gate#include <sys/asm_linkage.h> 447c478bd9Sstevel@tonic-gate 457c478bd9Sstevel@tonic-gate#if defined(__lint) 467c478bd9Sstevel@tonic-gate#include <sys/types.h> 477c478bd9Sstevel@tonic-gate#include <sys/systm.h> 487c478bd9Sstevel@tonic-gate#else /* __lint */ 497c478bd9Sstevel@tonic-gate#include "assym.h" 507c478bd9Sstevel@tonic-gate#endif /* __lint */ 517c478bd9Sstevel@tonic-gate 527c478bd9Sstevel@tonic-gate#define KCOPY_MIN_SIZE 128 /* Must be >= 16 bytes */ 537c478bd9Sstevel@tonic-gate#define XCOPY_MIN_SIZE 128 /* Must be >= 16 bytes */ 547c478bd9Sstevel@tonic-gate/* 557c478bd9Sstevel@tonic-gate * Non-temopral access (NTA) alignment requirement 567c478bd9Sstevel@tonic-gate */ 577c478bd9Sstevel@tonic-gate#define NTA_ALIGN_SIZE 4 /* Must be at least 4-byte aligned */ 587c478bd9Sstevel@tonic-gate#define NTA_ALIGN_MASK _CONST(NTA_ALIGN_SIZE-1) 597c478bd9Sstevel@tonic-gate#define COUNT_ALIGN_SIZE 16 /* Must be at least 16-byte aligned */ 607c478bd9Sstevel@tonic-gate#define COUNT_ALIGN_MASK _CONST(COUNT_ALIGN_SIZE-1) 617c478bd9Sstevel@tonic-gate 627c478bd9Sstevel@tonic-gate/* 6322cc0e45SBill Holler * The optimal 64-bit bcopy and kcopy for modern x86 processors uses 6422cc0e45SBill Holler * "rep smovq" for large sizes. Performance data shows that many calls to 6522cc0e45SBill Holler * bcopy/kcopy/bzero/kzero operate on small buffers. For best performance for 6622cc0e45SBill Holler * these small sizes unrolled code is used. For medium sizes loops writing 6722cc0e45SBill Holler * 64-bytes per loop are used. Transition points were determined experimentally. 6822cc0e45SBill Holler */ 6922cc0e45SBill Holler#define BZERO_USE_REP (1024) 7022cc0e45SBill Holler#define BCOPY_DFLT_REP (128) 7122cc0e45SBill Holler#define BCOPY_NHM_REP (768) 7222cc0e45SBill Holler 7322cc0e45SBill Holler/* 747c478bd9Sstevel@tonic-gate * Copy a block of storage, returning an error code if `from' or 757c478bd9Sstevel@tonic-gate * `to' takes a kernel pagefault which cannot be resolved. 767c478bd9Sstevel@tonic-gate * Returns errno value on pagefault error, 0 if all ok 777c478bd9Sstevel@tonic-gate */ 787c478bd9Sstevel@tonic-gate 797c478bd9Sstevel@tonic-gate#if defined(__lint) 807c478bd9Sstevel@tonic-gate 817c478bd9Sstevel@tonic-gate/* ARGSUSED */ 827c478bd9Sstevel@tonic-gateint 837c478bd9Sstevel@tonic-gatekcopy(const void *from, void *to, size_t count) 847c478bd9Sstevel@tonic-gate{ return (0); } 857c478bd9Sstevel@tonic-gate 867c478bd9Sstevel@tonic-gate#else /* __lint */ 877c478bd9Sstevel@tonic-gate 887c478bd9Sstevel@tonic-gate .globl kernelbase 89ae115bc7Smrj .globl postbootkernelbase 907c478bd9Sstevel@tonic-gate 917c478bd9Sstevel@tonic-gate#if defined(__amd64) 927c478bd9Sstevel@tonic-gate 937c478bd9Sstevel@tonic-gate ENTRY(kcopy) 947c478bd9Sstevel@tonic-gate pushq %rbp 957c478bd9Sstevel@tonic-gate movq %rsp, %rbp 967c478bd9Sstevel@tonic-gate#ifdef DEBUG 97ae115bc7Smrj cmpq postbootkernelbase(%rip), %rdi /* %rdi = from */ 987c478bd9Sstevel@tonic-gate jb 0f 99ae115bc7Smrj cmpq postbootkernelbase(%rip), %rsi /* %rsi = to */ 1007c478bd9Sstevel@tonic-gate jnb 1f 1017c478bd9Sstevel@tonic-gate0: leaq .kcopy_panic_msg(%rip), %rdi 1027c478bd9Sstevel@tonic-gate xorl %eax, %eax 1037c478bd9Sstevel@tonic-gate call panic 1047c478bd9Sstevel@tonic-gate1: 1057c478bd9Sstevel@tonic-gate#endif 1067c478bd9Sstevel@tonic-gate /* 1077c478bd9Sstevel@tonic-gate * pass lofault value as 4th argument to do_copy_fault 1087c478bd9Sstevel@tonic-gate */ 1097c478bd9Sstevel@tonic-gate leaq _kcopy_copyerr(%rip), %rcx 1107c478bd9Sstevel@tonic-gate movq %gs:CPU_THREAD, %r9 /* %r9 = thread addr */ 1117c478bd9Sstevel@tonic-gate 1127c478bd9Sstevel@tonic-gatedo_copy_fault: 1137c478bd9Sstevel@tonic-gate movq T_LOFAULT(%r9), %r11 /* save the current lofault */ 1147c478bd9Sstevel@tonic-gate movq %rcx, T_LOFAULT(%r9) /* new lofault */ 11522cc0e45SBill Holler call bcopy_altentry 1167c478bd9Sstevel@tonic-gate xorl %eax, %eax /* return 0 (success) */ 1177c478bd9Sstevel@tonic-gate 1187c478bd9Sstevel@tonic-gate /* 1197c478bd9Sstevel@tonic-gate * A fault during do_copy_fault is indicated through an errno value 1207c478bd9Sstevel@tonic-gate * in %rax and we iretq from the trap handler to here. 1217c478bd9Sstevel@tonic-gate */ 1227c478bd9Sstevel@tonic-gate_kcopy_copyerr: 1237c478bd9Sstevel@tonic-gate movq %r11, T_LOFAULT(%r9) /* restore original lofault */ 1247c478bd9Sstevel@tonic-gate leave 1257c478bd9Sstevel@tonic-gate ret 1267c478bd9Sstevel@tonic-gate SET_SIZE(kcopy) 1277c478bd9Sstevel@tonic-gate 1287c478bd9Sstevel@tonic-gate#elif defined(__i386) 1297c478bd9Sstevel@tonic-gate 1307c478bd9Sstevel@tonic-gate#define ARG_FROM 8 1317c478bd9Sstevel@tonic-gate#define ARG_TO 12 1327c478bd9Sstevel@tonic-gate#define ARG_COUNT 16 1337c478bd9Sstevel@tonic-gate 1347c478bd9Sstevel@tonic-gate ENTRY(kcopy) 1357c478bd9Sstevel@tonic-gate#ifdef DEBUG 1367c478bd9Sstevel@tonic-gate pushl %ebp 1377c478bd9Sstevel@tonic-gate movl %esp, %ebp 138ae115bc7Smrj movl postbootkernelbase, %eax 1397c478bd9Sstevel@tonic-gate cmpl %eax, ARG_FROM(%ebp) 1407c478bd9Sstevel@tonic-gate jb 0f 1417c478bd9Sstevel@tonic-gate cmpl %eax, ARG_TO(%ebp) 1427c478bd9Sstevel@tonic-gate jnb 1f 1437c478bd9Sstevel@tonic-gate0: pushl $.kcopy_panic_msg 1447c478bd9Sstevel@tonic-gate call panic 1457c478bd9Sstevel@tonic-gate1: popl %ebp 1467c478bd9Sstevel@tonic-gate#endif 1477c478bd9Sstevel@tonic-gate lea _kcopy_copyerr, %eax /* lofault value */ 1487c478bd9Sstevel@tonic-gate movl %gs:CPU_THREAD, %edx 1497c478bd9Sstevel@tonic-gate 1507c478bd9Sstevel@tonic-gatedo_copy_fault: 1517c478bd9Sstevel@tonic-gate pushl %ebp 1527c478bd9Sstevel@tonic-gate movl %esp, %ebp /* setup stack frame */ 1537c478bd9Sstevel@tonic-gate pushl %esi 1547c478bd9Sstevel@tonic-gate pushl %edi /* save registers */ 1557c478bd9Sstevel@tonic-gate 1567c478bd9Sstevel@tonic-gate movl T_LOFAULT(%edx), %edi 1577c478bd9Sstevel@tonic-gate pushl %edi /* save the current lofault */ 1587c478bd9Sstevel@tonic-gate movl %eax, T_LOFAULT(%edx) /* new lofault */ 1597c478bd9Sstevel@tonic-gate 1607c478bd9Sstevel@tonic-gate movl ARG_COUNT(%ebp), %ecx 1617c478bd9Sstevel@tonic-gate movl ARG_FROM(%ebp), %esi 1627c478bd9Sstevel@tonic-gate movl ARG_TO(%ebp), %edi 1637c478bd9Sstevel@tonic-gate shrl $2, %ecx /* word count */ 1647c478bd9Sstevel@tonic-gate rep 1657c478bd9Sstevel@tonic-gate smovl 1667c478bd9Sstevel@tonic-gate movl ARG_COUNT(%ebp), %ecx 1677c478bd9Sstevel@tonic-gate andl $3, %ecx /* bytes left over */ 1687c478bd9Sstevel@tonic-gate rep 1697c478bd9Sstevel@tonic-gate smovb 1707c478bd9Sstevel@tonic-gate xorl %eax, %eax 1717c478bd9Sstevel@tonic-gate 1727c478bd9Sstevel@tonic-gate /* 1737c478bd9Sstevel@tonic-gate * A fault during do_copy_fault is indicated through an errno value 1747c478bd9Sstevel@tonic-gate * in %eax and we iret from the trap handler to here. 1757c478bd9Sstevel@tonic-gate */ 1767c478bd9Sstevel@tonic-gate_kcopy_copyerr: 1777c478bd9Sstevel@tonic-gate popl %ecx 1787c478bd9Sstevel@tonic-gate popl %edi 1797c478bd9Sstevel@tonic-gate movl %ecx, T_LOFAULT(%edx) /* restore the original lofault */ 1807c478bd9Sstevel@tonic-gate popl %esi 1817c478bd9Sstevel@tonic-gate popl %ebp 1827c478bd9Sstevel@tonic-gate ret 1837c478bd9Sstevel@tonic-gate SET_SIZE(kcopy) 1847c478bd9Sstevel@tonic-gate 1857c478bd9Sstevel@tonic-gate#undef ARG_FROM 1867c478bd9Sstevel@tonic-gate#undef ARG_TO 1877c478bd9Sstevel@tonic-gate#undef ARG_COUNT 1887c478bd9Sstevel@tonic-gate 1897c478bd9Sstevel@tonic-gate#endif /* __i386 */ 1907c478bd9Sstevel@tonic-gate#endif /* __lint */ 1917c478bd9Sstevel@tonic-gate 1927c478bd9Sstevel@tonic-gate#if defined(__lint) 1937c478bd9Sstevel@tonic-gate 1947c478bd9Sstevel@tonic-gate/* 1957c478bd9Sstevel@tonic-gate * Copy a block of storage. Similar to kcopy but uses non-temporal 1967c478bd9Sstevel@tonic-gate * instructions. 1977c478bd9Sstevel@tonic-gate */ 1987c478bd9Sstevel@tonic-gate 1997c478bd9Sstevel@tonic-gate/* ARGSUSED */ 2007c478bd9Sstevel@tonic-gateint 2017c478bd9Sstevel@tonic-gatekcopy_nta(const void *from, void *to, size_t count, int copy_cached) 2027c478bd9Sstevel@tonic-gate{ return (0); } 2037c478bd9Sstevel@tonic-gate 2047c478bd9Sstevel@tonic-gate#else /* __lint */ 2057c478bd9Sstevel@tonic-gate 2067c478bd9Sstevel@tonic-gate#if defined(__amd64) 2077c478bd9Sstevel@tonic-gate 2087c478bd9Sstevel@tonic-gate#define COPY_LOOP_INIT(src, dst, cnt) \ 2097c478bd9Sstevel@tonic-gate addq cnt, src; \ 2107c478bd9Sstevel@tonic-gate addq cnt, dst; \ 2117c478bd9Sstevel@tonic-gate shrq $3, cnt; \ 2127c478bd9Sstevel@tonic-gate neg cnt 2137c478bd9Sstevel@tonic-gate 2147c478bd9Sstevel@tonic-gate /* Copy 16 bytes per loop. Uses %rax and %r8 */ 2157c478bd9Sstevel@tonic-gate#define COPY_LOOP_BODY(src, dst, cnt) \ 2167c478bd9Sstevel@tonic-gate prefetchnta 0x100(src, cnt, 8); \ 2177c478bd9Sstevel@tonic-gate movq (src, cnt, 8), %rax; \ 2187c478bd9Sstevel@tonic-gate movq 0x8(src, cnt, 8), %r8; \ 2197c478bd9Sstevel@tonic-gate movnti %rax, (dst, cnt, 8); \ 2207c478bd9Sstevel@tonic-gate movnti %r8, 0x8(dst, cnt, 8); \ 2217c478bd9Sstevel@tonic-gate addq $2, cnt 2227c478bd9Sstevel@tonic-gate 2237c478bd9Sstevel@tonic-gate ENTRY(kcopy_nta) 2247c478bd9Sstevel@tonic-gate pushq %rbp 2257c478bd9Sstevel@tonic-gate movq %rsp, %rbp 2267c478bd9Sstevel@tonic-gate#ifdef DEBUG 227ae115bc7Smrj cmpq postbootkernelbase(%rip), %rdi /* %rdi = from */ 2287c478bd9Sstevel@tonic-gate jb 0f 229ae115bc7Smrj cmpq postbootkernelbase(%rip), %rsi /* %rsi = to */ 2307c478bd9Sstevel@tonic-gate jnb 1f 2317c478bd9Sstevel@tonic-gate0: leaq .kcopy_panic_msg(%rip), %rdi 2327c478bd9Sstevel@tonic-gate xorl %eax, %eax 2337c478bd9Sstevel@tonic-gate call panic 2347c478bd9Sstevel@tonic-gate1: 2357c478bd9Sstevel@tonic-gate#endif 2367c478bd9Sstevel@tonic-gate 2377c478bd9Sstevel@tonic-gate movq %gs:CPU_THREAD, %r9 2387c478bd9Sstevel@tonic-gate cmpq $0, %rcx /* No non-temporal access? */ 2397c478bd9Sstevel@tonic-gate /* 2407c478bd9Sstevel@tonic-gate * pass lofault value as 4th argument to do_copy_fault 2417c478bd9Sstevel@tonic-gate */ 2427c478bd9Sstevel@tonic-gate leaq _kcopy_nta_copyerr(%rip), %rcx /* doesn't set rflags */ 2437c478bd9Sstevel@tonic-gate jnz do_copy_fault /* use regular access */ 2447c478bd9Sstevel@tonic-gate /* 2457c478bd9Sstevel@tonic-gate * Make sure cnt is >= KCOPY_MIN_SIZE 2467c478bd9Sstevel@tonic-gate */ 2477c478bd9Sstevel@tonic-gate cmpq $KCOPY_MIN_SIZE, %rdx 2487c478bd9Sstevel@tonic-gate jb do_copy_fault 2497c478bd9Sstevel@tonic-gate 2507c478bd9Sstevel@tonic-gate /* 2517c478bd9Sstevel@tonic-gate * Make sure src and dst are NTA_ALIGN_SIZE aligned, 2527c478bd9Sstevel@tonic-gate * count is COUNT_ALIGN_SIZE aligned. 2537c478bd9Sstevel@tonic-gate */ 2547c478bd9Sstevel@tonic-gate movq %rdi, %r10 2557c478bd9Sstevel@tonic-gate orq %rsi, %r10 2567c478bd9Sstevel@tonic-gate andq $NTA_ALIGN_MASK, %r10 2577c478bd9Sstevel@tonic-gate orq %rdx, %r10 2587c478bd9Sstevel@tonic-gate andq $COUNT_ALIGN_MASK, %r10 2597c478bd9Sstevel@tonic-gate jnz do_copy_fault 2607c478bd9Sstevel@tonic-gate 2617c478bd9Sstevel@tonic-gate ALTENTRY(do_copy_fault_nta) 2627c478bd9Sstevel@tonic-gate movq %gs:CPU_THREAD, %r9 /* %r9 = thread addr */ 2637c478bd9Sstevel@tonic-gate movq T_LOFAULT(%r9), %r11 /* save the current lofault */ 2647c478bd9Sstevel@tonic-gate movq %rcx, T_LOFAULT(%r9) /* new lofault */ 2657c478bd9Sstevel@tonic-gate 2667c478bd9Sstevel@tonic-gate /* 2677c478bd9Sstevel@tonic-gate * COPY_LOOP_BODY uses %rax and %r8 2687c478bd9Sstevel@tonic-gate */ 2697c478bd9Sstevel@tonic-gate COPY_LOOP_INIT(%rdi, %rsi, %rdx) 2707c478bd9Sstevel@tonic-gate2: COPY_LOOP_BODY(%rdi, %rsi, %rdx) 2717c478bd9Sstevel@tonic-gate jnz 2b 2727c478bd9Sstevel@tonic-gate 2737c478bd9Sstevel@tonic-gate mfence 2747c478bd9Sstevel@tonic-gate xorl %eax, %eax /* return 0 (success) */ 2757c478bd9Sstevel@tonic-gate 2767c478bd9Sstevel@tonic-gate_kcopy_nta_copyerr: 2777c478bd9Sstevel@tonic-gate movq %r11, T_LOFAULT(%r9) /* restore original lofault */ 2787c478bd9Sstevel@tonic-gate leave 2797c478bd9Sstevel@tonic-gate ret 2807c478bd9Sstevel@tonic-gate SET_SIZE(do_copy_fault_nta) 2817c478bd9Sstevel@tonic-gate SET_SIZE(kcopy_nta) 2827c478bd9Sstevel@tonic-gate 2837c478bd9Sstevel@tonic-gate#elif defined(__i386) 2847c478bd9Sstevel@tonic-gate 2857c478bd9Sstevel@tonic-gate#define ARG_FROM 8 2867c478bd9Sstevel@tonic-gate#define ARG_TO 12 2877c478bd9Sstevel@tonic-gate#define ARG_COUNT 16 2887c478bd9Sstevel@tonic-gate 2897c478bd9Sstevel@tonic-gate#define COPY_LOOP_INIT(src, dst, cnt) \ 2907c478bd9Sstevel@tonic-gate addl cnt, src; \ 2917c478bd9Sstevel@tonic-gate addl cnt, dst; \ 2927c478bd9Sstevel@tonic-gate shrl $3, cnt; \ 2937c478bd9Sstevel@tonic-gate neg cnt 2947c478bd9Sstevel@tonic-gate 2957c478bd9Sstevel@tonic-gate#define COPY_LOOP_BODY(src, dst, cnt) \ 2967c478bd9Sstevel@tonic-gate prefetchnta 0x100(src, cnt, 8); \ 2977c478bd9Sstevel@tonic-gate movl (src, cnt, 8), %esi; \ 2987c478bd9Sstevel@tonic-gate movnti %esi, (dst, cnt, 8); \ 2997c478bd9Sstevel@tonic-gate movl 0x4(src, cnt, 8), %esi; \ 3007c478bd9Sstevel@tonic-gate movnti %esi, 0x4(dst, cnt, 8); \ 3017c478bd9Sstevel@tonic-gate movl 0x8(src, cnt, 8), %esi; \ 3027c478bd9Sstevel@tonic-gate movnti %esi, 0x8(dst, cnt, 8); \ 3037c478bd9Sstevel@tonic-gate movl 0xc(src, cnt, 8), %esi; \ 3047c478bd9Sstevel@tonic-gate movnti %esi, 0xc(dst, cnt, 8); \ 3057c478bd9Sstevel@tonic-gate addl $2, cnt 3067c478bd9Sstevel@tonic-gate 3077c478bd9Sstevel@tonic-gate /* 3087c478bd9Sstevel@tonic-gate * kcopy_nta is not implemented for 32-bit as no performance 3097c478bd9Sstevel@tonic-gate * improvement was shown. We simply jump directly to kcopy 3107c478bd9Sstevel@tonic-gate * and discard the 4 arguments. 3117c478bd9Sstevel@tonic-gate */ 3127c478bd9Sstevel@tonic-gate ENTRY(kcopy_nta) 3137c478bd9Sstevel@tonic-gate jmp kcopy 3147c478bd9Sstevel@tonic-gate 3157c478bd9Sstevel@tonic-gate lea _kcopy_nta_copyerr, %eax /* lofault value */ 3167c478bd9Sstevel@tonic-gate ALTENTRY(do_copy_fault_nta) 3177c478bd9Sstevel@tonic-gate pushl %ebp 3187c478bd9Sstevel@tonic-gate movl %esp, %ebp /* setup stack frame */ 3197c478bd9Sstevel@tonic-gate pushl %esi 3207c478bd9Sstevel@tonic-gate pushl %edi 3217c478bd9Sstevel@tonic-gate 3227c478bd9Sstevel@tonic-gate movl %gs:CPU_THREAD, %edx 3237c478bd9Sstevel@tonic-gate movl T_LOFAULT(%edx), %edi 3247c478bd9Sstevel@tonic-gate pushl %edi /* save the current lofault */ 3257c478bd9Sstevel@tonic-gate movl %eax, T_LOFAULT(%edx) /* new lofault */ 3267c478bd9Sstevel@tonic-gate 3277c478bd9Sstevel@tonic-gate /* COPY_LOOP_BODY needs to use %esi */ 3287c478bd9Sstevel@tonic-gate movl ARG_COUNT(%ebp), %ecx 3297c478bd9Sstevel@tonic-gate movl ARG_FROM(%ebp), %edi 3307c478bd9Sstevel@tonic-gate movl ARG_TO(%ebp), %eax 3317c478bd9Sstevel@tonic-gate COPY_LOOP_INIT(%edi, %eax, %ecx) 3327c478bd9Sstevel@tonic-gate1: COPY_LOOP_BODY(%edi, %eax, %ecx) 3337c478bd9Sstevel@tonic-gate jnz 1b 3347c478bd9Sstevel@tonic-gate mfence 3357c478bd9Sstevel@tonic-gate 3367c478bd9Sstevel@tonic-gate xorl %eax, %eax 3377c478bd9Sstevel@tonic-gate_kcopy_nta_copyerr: 3387c478bd9Sstevel@tonic-gate popl %ecx 3397c478bd9Sstevel@tonic-gate popl %edi 3407c478bd9Sstevel@tonic-gate movl %ecx, T_LOFAULT(%edx) /* restore the original lofault */ 3417c478bd9Sstevel@tonic-gate popl %esi 3427c478bd9Sstevel@tonic-gate leave 3437c478bd9Sstevel@tonic-gate ret 3447c478bd9Sstevel@tonic-gate SET_SIZE(do_copy_fault_nta) 3457c478bd9Sstevel@tonic-gate SET_SIZE(kcopy_nta) 3467c478bd9Sstevel@tonic-gate 3477c478bd9Sstevel@tonic-gate#undef ARG_FROM 3487c478bd9Sstevel@tonic-gate#undef ARG_TO 3497c478bd9Sstevel@tonic-gate#undef ARG_COUNT 3507c478bd9Sstevel@tonic-gate 3517c478bd9Sstevel@tonic-gate#endif /* __i386 */ 3527c478bd9Sstevel@tonic-gate#endif /* __lint */ 3537c478bd9Sstevel@tonic-gate 3547c478bd9Sstevel@tonic-gate#if defined(__lint) 3557c478bd9Sstevel@tonic-gate 3567c478bd9Sstevel@tonic-gate/* ARGSUSED */ 3577c478bd9Sstevel@tonic-gatevoid 3587c478bd9Sstevel@tonic-gatebcopy(const void *from, void *to, size_t count) 3597c478bd9Sstevel@tonic-gate{} 3607c478bd9Sstevel@tonic-gate 3617c478bd9Sstevel@tonic-gate#else /* __lint */ 3627c478bd9Sstevel@tonic-gate 3637c478bd9Sstevel@tonic-gate#if defined(__amd64) 3647c478bd9Sstevel@tonic-gate 3657c478bd9Sstevel@tonic-gate ENTRY(bcopy) 3667c478bd9Sstevel@tonic-gate#ifdef DEBUG 3677c478bd9Sstevel@tonic-gate orq %rdx, %rdx /* %rdx = count */ 3687c478bd9Sstevel@tonic-gate jz 1f 369ae115bc7Smrj cmpq postbootkernelbase(%rip), %rdi /* %rdi = from */ 3707c478bd9Sstevel@tonic-gate jb 0f 371ae115bc7Smrj cmpq postbootkernelbase(%rip), %rsi /* %rsi = to */ 3727c478bd9Sstevel@tonic-gate jnb 1f 3737c478bd9Sstevel@tonic-gate0: leaq .bcopy_panic_msg(%rip), %rdi 3747c478bd9Sstevel@tonic-gate jmp call_panic /* setup stack and call panic */ 3757c478bd9Sstevel@tonic-gate1: 3767c478bd9Sstevel@tonic-gate#endif 37722cc0e45SBill Holler /* 37822cc0e45SBill Holler * bcopy_altentry() is called from kcopy, i.e., do_copy_fault. 37922cc0e45SBill Holler * kcopy assumes that bcopy doesn't touch %r9 and %r11. If bcopy 38022cc0e45SBill Holler * uses these registers in future they must be saved and restored. 38122cc0e45SBill Holler */ 38222cc0e45SBill Holler ALTENTRY(bcopy_altentry) 3837c478bd9Sstevel@tonic-gatedo_copy: 38422cc0e45SBill Holler#define L(s) .bcopy/**/s 38522cc0e45SBill Holler cmpq $0x50, %rdx /* 80 */ 386*9b6707c5SRobert Mustacchi jae bcopy_ck_size 38722cc0e45SBill Holler 38822cc0e45SBill Holler /* 38922cc0e45SBill Holler * Performance data shows many caller's copy small buffers. So for 39022cc0e45SBill Holler * best perf for these sizes unrolled code is used. Store data without 39122cc0e45SBill Holler * worrying about alignment. 39222cc0e45SBill Holler */ 39322cc0e45SBill Holler leaq L(fwdPxQx)(%rip), %r10 39422cc0e45SBill Holler addq %rdx, %rdi 39522cc0e45SBill Holler addq %rdx, %rsi 39622cc0e45SBill Holler movslq (%r10,%rdx,4), %rcx 39722cc0e45SBill Holler leaq (%rcx,%r10,1), %r10 39822cc0e45SBill Holler jmpq *%r10 39922cc0e45SBill Holler 40022cc0e45SBill Holler .p2align 4 40122cc0e45SBill HollerL(fwdPxQx): 40222cc0e45SBill Holler .int L(P0Q0)-L(fwdPxQx) /* 0 */ 40322cc0e45SBill Holler .int L(P1Q0)-L(fwdPxQx) 40422cc0e45SBill Holler .int L(P2Q0)-L(fwdPxQx) 40522cc0e45SBill Holler .int L(P3Q0)-L(fwdPxQx) 40622cc0e45SBill Holler .int L(P4Q0)-L(fwdPxQx) 40722cc0e45SBill Holler .int L(P5Q0)-L(fwdPxQx) 40822cc0e45SBill Holler .int L(P6Q0)-L(fwdPxQx) 40922cc0e45SBill Holler .int L(P7Q0)-L(fwdPxQx) 41022cc0e45SBill Holler 41122cc0e45SBill Holler .int L(P0Q1)-L(fwdPxQx) /* 8 */ 41222cc0e45SBill Holler .int L(P1Q1)-L(fwdPxQx) 41322cc0e45SBill Holler .int L(P2Q1)-L(fwdPxQx) 41422cc0e45SBill Holler .int L(P3Q1)-L(fwdPxQx) 41522cc0e45SBill Holler .int L(P4Q1)-L(fwdPxQx) 41622cc0e45SBill Holler .int L(P5Q1)-L(fwdPxQx) 41722cc0e45SBill Holler .int L(P6Q1)-L(fwdPxQx) 41822cc0e45SBill Holler .int L(P7Q1)-L(fwdPxQx) 41922cc0e45SBill Holler 42022cc0e45SBill Holler .int L(P0Q2)-L(fwdPxQx) /* 16 */ 42122cc0e45SBill Holler .int L(P1Q2)-L(fwdPxQx) 42222cc0e45SBill Holler .int L(P2Q2)-L(fwdPxQx) 42322cc0e45SBill Holler .int L(P3Q2)-L(fwdPxQx) 42422cc0e45SBill Holler .int L(P4Q2)-L(fwdPxQx) 42522cc0e45SBill Holler .int L(P5Q2)-L(fwdPxQx) 42622cc0e45SBill Holler .int L(P6Q2)-L(fwdPxQx) 42722cc0e45SBill Holler .int L(P7Q2)-L(fwdPxQx) 42822cc0e45SBill Holler 42922cc0e45SBill Holler .int L(P0Q3)-L(fwdPxQx) /* 24 */ 43022cc0e45SBill Holler .int L(P1Q3)-L(fwdPxQx) 43122cc0e45SBill Holler .int L(P2Q3)-L(fwdPxQx) 43222cc0e45SBill Holler .int L(P3Q3)-L(fwdPxQx) 43322cc0e45SBill Holler .int L(P4Q3)-L(fwdPxQx) 43422cc0e45SBill Holler .int L(P5Q3)-L(fwdPxQx) 43522cc0e45SBill Holler .int L(P6Q3)-L(fwdPxQx) 43622cc0e45SBill Holler .int L(P7Q3)-L(fwdPxQx) 43722cc0e45SBill Holler 43822cc0e45SBill Holler .int L(P0Q4)-L(fwdPxQx) /* 32 */ 43922cc0e45SBill Holler .int L(P1Q4)-L(fwdPxQx) 44022cc0e45SBill Holler .int L(P2Q4)-L(fwdPxQx) 44122cc0e45SBill Holler .int L(P3Q4)-L(fwdPxQx) 44222cc0e45SBill Holler .int L(P4Q4)-L(fwdPxQx) 44322cc0e45SBill Holler .int L(P5Q4)-L(fwdPxQx) 44422cc0e45SBill Holler .int L(P6Q4)-L(fwdPxQx) 44522cc0e45SBill Holler .int L(P7Q4)-L(fwdPxQx) 44622cc0e45SBill Holler 44722cc0e45SBill Holler .int L(P0Q5)-L(fwdPxQx) /* 40 */ 44822cc0e45SBill Holler .int L(P1Q5)-L(fwdPxQx) 44922cc0e45SBill Holler .int L(P2Q5)-L(fwdPxQx) 45022cc0e45SBill Holler .int L(P3Q5)-L(fwdPxQx) 45122cc0e45SBill Holler .int L(P4Q5)-L(fwdPxQx) 45222cc0e45SBill Holler .int L(P5Q5)-L(fwdPxQx) 45322cc0e45SBill Holler .int L(P6Q5)-L(fwdPxQx) 45422cc0e45SBill Holler .int L(P7Q5)-L(fwdPxQx) 45522cc0e45SBill Holler 45622cc0e45SBill Holler .int L(P0Q6)-L(fwdPxQx) /* 48 */ 45722cc0e45SBill Holler .int L(P1Q6)-L(fwdPxQx) 45822cc0e45SBill Holler .int L(P2Q6)-L(fwdPxQx) 45922cc0e45SBill Holler .int L(P3Q6)-L(fwdPxQx) 46022cc0e45SBill Holler .int L(P4Q6)-L(fwdPxQx) 46122cc0e45SBill Holler .int L(P5Q6)-L(fwdPxQx) 46222cc0e45SBill Holler .int L(P6Q6)-L(fwdPxQx) 46322cc0e45SBill Holler .int L(P7Q6)-L(fwdPxQx) 46422cc0e45SBill Holler 46522cc0e45SBill Holler .int L(P0Q7)-L(fwdPxQx) /* 56 */ 46622cc0e45SBill Holler .int L(P1Q7)-L(fwdPxQx) 46722cc0e45SBill Holler .int L(P2Q7)-L(fwdPxQx) 46822cc0e45SBill Holler .int L(P3Q7)-L(fwdPxQx) 46922cc0e45SBill Holler .int L(P4Q7)-L(fwdPxQx) 47022cc0e45SBill Holler .int L(P5Q7)-L(fwdPxQx) 47122cc0e45SBill Holler .int L(P6Q7)-L(fwdPxQx) 47222cc0e45SBill Holler .int L(P7Q7)-L(fwdPxQx) 47322cc0e45SBill Holler 47422cc0e45SBill Holler .int L(P0Q8)-L(fwdPxQx) /* 64 */ 47522cc0e45SBill Holler .int L(P1Q8)-L(fwdPxQx) 47622cc0e45SBill Holler .int L(P2Q8)-L(fwdPxQx) 47722cc0e45SBill Holler .int L(P3Q8)-L(fwdPxQx) 47822cc0e45SBill Holler .int L(P4Q8)-L(fwdPxQx) 47922cc0e45SBill Holler .int L(P5Q8)-L(fwdPxQx) 48022cc0e45SBill Holler .int L(P6Q8)-L(fwdPxQx) 48122cc0e45SBill Holler .int L(P7Q8)-L(fwdPxQx) 48222cc0e45SBill Holler 48322cc0e45SBill Holler .int L(P0Q9)-L(fwdPxQx) /* 72 */ 48422cc0e45SBill Holler .int L(P1Q9)-L(fwdPxQx) 48522cc0e45SBill Holler .int L(P2Q9)-L(fwdPxQx) 48622cc0e45SBill Holler .int L(P3Q9)-L(fwdPxQx) 48722cc0e45SBill Holler .int L(P4Q9)-L(fwdPxQx) 48822cc0e45SBill Holler .int L(P5Q9)-L(fwdPxQx) 48922cc0e45SBill Holler .int L(P6Q9)-L(fwdPxQx) 49022cc0e45SBill Holler .int L(P7Q9)-L(fwdPxQx) /* 79 */ 49122cc0e45SBill Holler 49222cc0e45SBill Holler .p2align 4 49322cc0e45SBill HollerL(P0Q9): 49422cc0e45SBill Holler mov -0x48(%rdi), %rcx 49522cc0e45SBill Holler mov %rcx, -0x48(%rsi) 49622cc0e45SBill HollerL(P0Q8): 49722cc0e45SBill Holler mov -0x40(%rdi), %r10 49822cc0e45SBill Holler mov %r10, -0x40(%rsi) 49922cc0e45SBill HollerL(P0Q7): 50022cc0e45SBill Holler mov -0x38(%rdi), %r8 50122cc0e45SBill Holler mov %r8, -0x38(%rsi) 50222cc0e45SBill HollerL(P0Q6): 50322cc0e45SBill Holler mov -0x30(%rdi), %rcx 50422cc0e45SBill Holler mov %rcx, -0x30(%rsi) 50522cc0e45SBill HollerL(P0Q5): 50622cc0e45SBill Holler mov -0x28(%rdi), %r10 50722cc0e45SBill Holler mov %r10, -0x28(%rsi) 50822cc0e45SBill HollerL(P0Q4): 50922cc0e45SBill Holler mov -0x20(%rdi), %r8 51022cc0e45SBill Holler mov %r8, -0x20(%rsi) 51122cc0e45SBill HollerL(P0Q3): 51222cc0e45SBill Holler mov -0x18(%rdi), %rcx 51322cc0e45SBill Holler mov %rcx, -0x18(%rsi) 51422cc0e45SBill HollerL(P0Q2): 51522cc0e45SBill Holler mov -0x10(%rdi), %r10 51622cc0e45SBill Holler mov %r10, -0x10(%rsi) 51722cc0e45SBill HollerL(P0Q1): 51822cc0e45SBill Holler mov -0x8(%rdi), %r8 51922cc0e45SBill Holler mov %r8, -0x8(%rsi) 52022cc0e45SBill HollerL(P0Q0): 52122cc0e45SBill Holler ret 52222cc0e45SBill Holler 52322cc0e45SBill Holler .p2align 4 52422cc0e45SBill HollerL(P1Q9): 52522cc0e45SBill Holler mov -0x49(%rdi), %r8 52622cc0e45SBill Holler mov %r8, -0x49(%rsi) 52722cc0e45SBill HollerL(P1Q8): 52822cc0e45SBill Holler mov -0x41(%rdi), %rcx 52922cc0e45SBill Holler mov %rcx, -0x41(%rsi) 53022cc0e45SBill HollerL(P1Q7): 53122cc0e45SBill Holler mov -0x39(%rdi), %r10 53222cc0e45SBill Holler mov %r10, -0x39(%rsi) 53322cc0e45SBill HollerL(P1Q6): 53422cc0e45SBill Holler mov -0x31(%rdi), %r8 53522cc0e45SBill Holler mov %r8, -0x31(%rsi) 53622cc0e45SBill HollerL(P1Q5): 53722cc0e45SBill Holler mov -0x29(%rdi), %rcx 53822cc0e45SBill Holler mov %rcx, -0x29(%rsi) 53922cc0e45SBill HollerL(P1Q4): 54022cc0e45SBill Holler mov -0x21(%rdi), %r10 54122cc0e45SBill Holler mov %r10, -0x21(%rsi) 54222cc0e45SBill HollerL(P1Q3): 54322cc0e45SBill Holler mov -0x19(%rdi), %r8 54422cc0e45SBill Holler mov %r8, -0x19(%rsi) 54522cc0e45SBill HollerL(P1Q2): 54622cc0e45SBill Holler mov -0x11(%rdi), %rcx 54722cc0e45SBill Holler mov %rcx, -0x11(%rsi) 54822cc0e45SBill HollerL(P1Q1): 54922cc0e45SBill Holler mov -0x9(%rdi), %r10 55022cc0e45SBill Holler mov %r10, -0x9(%rsi) 55122cc0e45SBill HollerL(P1Q0): 55222cc0e45SBill Holler movzbq -0x1(%rdi), %r8 55322cc0e45SBill Holler mov %r8b, -0x1(%rsi) 55422cc0e45SBill Holler ret 55522cc0e45SBill Holler 55622cc0e45SBill Holler .p2align 4 55722cc0e45SBill HollerL(P2Q9): 55822cc0e45SBill Holler mov -0x4a(%rdi), %r8 55922cc0e45SBill Holler mov %r8, -0x4a(%rsi) 56022cc0e45SBill HollerL(P2Q8): 56122cc0e45SBill Holler mov -0x42(%rdi), %rcx 56222cc0e45SBill Holler mov %rcx, -0x42(%rsi) 56322cc0e45SBill HollerL(P2Q7): 56422cc0e45SBill Holler mov -0x3a(%rdi), %r10 56522cc0e45SBill Holler mov %r10, -0x3a(%rsi) 56622cc0e45SBill HollerL(P2Q6): 56722cc0e45SBill Holler mov -0x32(%rdi), %r8 56822cc0e45SBill Holler mov %r8, -0x32(%rsi) 56922cc0e45SBill HollerL(P2Q5): 57022cc0e45SBill Holler mov -0x2a(%rdi), %rcx 57122cc0e45SBill Holler mov %rcx, -0x2a(%rsi) 57222cc0e45SBill HollerL(P2Q4): 57322cc0e45SBill Holler mov -0x22(%rdi), %r10 57422cc0e45SBill Holler mov %r10, -0x22(%rsi) 57522cc0e45SBill HollerL(P2Q3): 57622cc0e45SBill Holler mov -0x1a(%rdi), %r8 57722cc0e45SBill Holler mov %r8, -0x1a(%rsi) 57822cc0e45SBill HollerL(P2Q2): 57922cc0e45SBill Holler mov -0x12(%rdi), %rcx 58022cc0e45SBill Holler mov %rcx, -0x12(%rsi) 58122cc0e45SBill HollerL(P2Q1): 58222cc0e45SBill Holler mov -0xa(%rdi), %r10 58322cc0e45SBill Holler mov %r10, -0xa(%rsi) 58422cc0e45SBill HollerL(P2Q0): 58522cc0e45SBill Holler movzwq -0x2(%rdi), %r8 58622cc0e45SBill Holler mov %r8w, -0x2(%rsi) 58722cc0e45SBill Holler ret 58822cc0e45SBill Holler 58922cc0e45SBill Holler .p2align 4 59022cc0e45SBill HollerL(P3Q9): 59122cc0e45SBill Holler mov -0x4b(%rdi), %r8 59222cc0e45SBill Holler mov %r8, -0x4b(%rsi) 59322cc0e45SBill HollerL(P3Q8): 59422cc0e45SBill Holler mov -0x43(%rdi), %rcx 59522cc0e45SBill Holler mov %rcx, -0x43(%rsi) 59622cc0e45SBill HollerL(P3Q7): 59722cc0e45SBill Holler mov -0x3b(%rdi), %r10 59822cc0e45SBill Holler mov %r10, -0x3b(%rsi) 59922cc0e45SBill HollerL(P3Q6): 60022cc0e45SBill Holler mov -0x33(%rdi), %r8 60122cc0e45SBill Holler mov %r8, -0x33(%rsi) 60222cc0e45SBill HollerL(P3Q5): 60322cc0e45SBill Holler mov -0x2b(%rdi), %rcx 60422cc0e45SBill Holler mov %rcx, -0x2b(%rsi) 60522cc0e45SBill HollerL(P3Q4): 60622cc0e45SBill Holler mov -0x23(%rdi), %r10 60722cc0e45SBill Holler mov %r10, -0x23(%rsi) 60822cc0e45SBill HollerL(P3Q3): 60922cc0e45SBill Holler mov -0x1b(%rdi), %r8 61022cc0e45SBill Holler mov %r8, -0x1b(%rsi) 61122cc0e45SBill HollerL(P3Q2): 61222cc0e45SBill Holler mov -0x13(%rdi), %rcx 61322cc0e45SBill Holler mov %rcx, -0x13(%rsi) 61422cc0e45SBill HollerL(P3Q1): 61522cc0e45SBill Holler mov -0xb(%rdi), %r10 61622cc0e45SBill Holler mov %r10, -0xb(%rsi) 61722cc0e45SBill Holler /* 61822cc0e45SBill Holler * These trailing loads/stores have to do all their loads 1st, 61922cc0e45SBill Holler * then do the stores. 62022cc0e45SBill Holler */ 62122cc0e45SBill HollerL(P3Q0): 62222cc0e45SBill Holler movzwq -0x3(%rdi), %r8 62322cc0e45SBill Holler movzbq -0x1(%rdi), %r10 62422cc0e45SBill Holler mov %r8w, -0x3(%rsi) 62522cc0e45SBill Holler mov %r10b, -0x1(%rsi) 62622cc0e45SBill Holler ret 62722cc0e45SBill Holler 62822cc0e45SBill Holler .p2align 4 62922cc0e45SBill HollerL(P4Q9): 63022cc0e45SBill Holler mov -0x4c(%rdi), %r8 63122cc0e45SBill Holler mov %r8, -0x4c(%rsi) 63222cc0e45SBill HollerL(P4Q8): 63322cc0e45SBill Holler mov -0x44(%rdi), %rcx 63422cc0e45SBill Holler mov %rcx, -0x44(%rsi) 63522cc0e45SBill HollerL(P4Q7): 63622cc0e45SBill Holler mov -0x3c(%rdi), %r10 63722cc0e45SBill Holler mov %r10, -0x3c(%rsi) 63822cc0e45SBill HollerL(P4Q6): 63922cc0e45SBill Holler mov -0x34(%rdi), %r8 64022cc0e45SBill Holler mov %r8, -0x34(%rsi) 64122cc0e45SBill HollerL(P4Q5): 64222cc0e45SBill Holler mov -0x2c(%rdi), %rcx 64322cc0e45SBill Holler mov %rcx, -0x2c(%rsi) 64422cc0e45SBill HollerL(P4Q4): 64522cc0e45SBill Holler mov -0x24(%rdi), %r10 64622cc0e45SBill Holler mov %r10, -0x24(%rsi) 64722cc0e45SBill HollerL(P4Q3): 64822cc0e45SBill Holler mov -0x1c(%rdi), %r8 64922cc0e45SBill Holler mov %r8, -0x1c(%rsi) 65022cc0e45SBill HollerL(P4Q2): 65122cc0e45SBill Holler mov -0x14(%rdi), %rcx 65222cc0e45SBill Holler mov %rcx, -0x14(%rsi) 65322cc0e45SBill HollerL(P4Q1): 65422cc0e45SBill Holler mov -0xc(%rdi), %r10 65522cc0e45SBill Holler mov %r10, -0xc(%rsi) 65622cc0e45SBill HollerL(P4Q0): 65722cc0e45SBill Holler mov -0x4(%rdi), %r8d 65822cc0e45SBill Holler mov %r8d, -0x4(%rsi) 65922cc0e45SBill Holler ret 66022cc0e45SBill Holler 66122cc0e45SBill Holler .p2align 4 66222cc0e45SBill HollerL(P5Q9): 66322cc0e45SBill Holler mov -0x4d(%rdi), %r8 66422cc0e45SBill Holler mov %r8, -0x4d(%rsi) 66522cc0e45SBill HollerL(P5Q8): 66622cc0e45SBill Holler mov -0x45(%rdi), %rcx 66722cc0e45SBill Holler mov %rcx, -0x45(%rsi) 66822cc0e45SBill HollerL(P5Q7): 66922cc0e45SBill Holler mov -0x3d(%rdi), %r10 67022cc0e45SBill Holler mov %r10, -0x3d(%rsi) 67122cc0e45SBill HollerL(P5Q6): 67222cc0e45SBill Holler mov -0x35(%rdi), %r8 67322cc0e45SBill Holler mov %r8, -0x35(%rsi) 67422cc0e45SBill HollerL(P5Q5): 67522cc0e45SBill Holler mov -0x2d(%rdi), %rcx 67622cc0e45SBill Holler mov %rcx, -0x2d(%rsi) 67722cc0e45SBill HollerL(P5Q4): 67822cc0e45SBill Holler mov -0x25(%rdi), %r10 67922cc0e45SBill Holler mov %r10, -0x25(%rsi) 68022cc0e45SBill HollerL(P5Q3): 68122cc0e45SBill Holler mov -0x1d(%rdi), %r8 68222cc0e45SBill Holler mov %r8, -0x1d(%rsi) 68322cc0e45SBill HollerL(P5Q2): 68422cc0e45SBill Holler mov -0x15(%rdi), %rcx 68522cc0e45SBill Holler mov %rcx, -0x15(%rsi) 68622cc0e45SBill HollerL(P5Q1): 68722cc0e45SBill Holler mov -0xd(%rdi), %r10 68822cc0e45SBill Holler mov %r10, -0xd(%rsi) 68922cc0e45SBill HollerL(P5Q0): 69022cc0e45SBill Holler mov -0x5(%rdi), %r8d 69122cc0e45SBill Holler movzbq -0x1(%rdi), %r10 69222cc0e45SBill Holler mov %r8d, -0x5(%rsi) 69322cc0e45SBill Holler mov %r10b, -0x1(%rsi) 69422cc0e45SBill Holler ret 69522cc0e45SBill Holler 69622cc0e45SBill Holler .p2align 4 69722cc0e45SBill HollerL(P6Q9): 69822cc0e45SBill Holler mov -0x4e(%rdi), %r8 69922cc0e45SBill Holler mov %r8, -0x4e(%rsi) 70022cc0e45SBill HollerL(P6Q8): 70122cc0e45SBill Holler mov -0x46(%rdi), %rcx 70222cc0e45SBill Holler mov %rcx, -0x46(%rsi) 70322cc0e45SBill HollerL(P6Q7): 70422cc0e45SBill Holler mov -0x3e(%rdi), %r10 70522cc0e45SBill Holler mov %r10, -0x3e(%rsi) 70622cc0e45SBill HollerL(P6Q6): 70722cc0e45SBill Holler mov -0x36(%rdi), %r8 70822cc0e45SBill Holler mov %r8, -0x36(%rsi) 70922cc0e45SBill HollerL(P6Q5): 71022cc0e45SBill Holler mov -0x2e(%rdi), %rcx 71122cc0e45SBill Holler mov %rcx, -0x2e(%rsi) 71222cc0e45SBill HollerL(P6Q4): 71322cc0e45SBill Holler mov -0x26(%rdi), %r10 71422cc0e45SBill Holler mov %r10, -0x26(%rsi) 71522cc0e45SBill HollerL(P6Q3): 71622cc0e45SBill Holler mov -0x1e(%rdi), %r8 71722cc0e45SBill Holler mov %r8, -0x1e(%rsi) 71822cc0e45SBill HollerL(P6Q2): 71922cc0e45SBill Holler mov -0x16(%rdi), %rcx 72022cc0e45SBill Holler mov %rcx, -0x16(%rsi) 72122cc0e45SBill HollerL(P6Q1): 72222cc0e45SBill Holler mov -0xe(%rdi), %r10 72322cc0e45SBill Holler mov %r10, -0xe(%rsi) 72422cc0e45SBill HollerL(P6Q0): 72522cc0e45SBill Holler mov -0x6(%rdi), %r8d 72622cc0e45SBill Holler movzwq -0x2(%rdi), %r10 72722cc0e45SBill Holler mov %r8d, -0x6(%rsi) 72822cc0e45SBill Holler mov %r10w, -0x2(%rsi) 72922cc0e45SBill Holler ret 73022cc0e45SBill Holler 73122cc0e45SBill Holler .p2align 4 73222cc0e45SBill HollerL(P7Q9): 73322cc0e45SBill Holler mov -0x4f(%rdi), %r8 73422cc0e45SBill Holler mov %r8, -0x4f(%rsi) 73522cc0e45SBill HollerL(P7Q8): 73622cc0e45SBill Holler mov -0x47(%rdi), %rcx 73722cc0e45SBill Holler mov %rcx, -0x47(%rsi) 73822cc0e45SBill HollerL(P7Q7): 73922cc0e45SBill Holler mov -0x3f(%rdi), %r10 74022cc0e45SBill Holler mov %r10, -0x3f(%rsi) 74122cc0e45SBill HollerL(P7Q6): 74222cc0e45SBill Holler mov -0x37(%rdi), %r8 74322cc0e45SBill Holler mov %r8, -0x37(%rsi) 74422cc0e45SBill HollerL(P7Q5): 74522cc0e45SBill Holler mov -0x2f(%rdi), %rcx 74622cc0e45SBill Holler mov %rcx, -0x2f(%rsi) 74722cc0e45SBill HollerL(P7Q4): 74822cc0e45SBill Holler mov -0x27(%rdi), %r10 74922cc0e45SBill Holler mov %r10, -0x27(%rsi) 75022cc0e45SBill HollerL(P7Q3): 75122cc0e45SBill Holler mov -0x1f(%rdi), %r8 75222cc0e45SBill Holler mov %r8, -0x1f(%rsi) 75322cc0e45SBill HollerL(P7Q2): 75422cc0e45SBill Holler mov -0x17(%rdi), %rcx 75522cc0e45SBill Holler mov %rcx, -0x17(%rsi) 75622cc0e45SBill HollerL(P7Q1): 75722cc0e45SBill Holler mov -0xf(%rdi), %r10 75822cc0e45SBill Holler mov %r10, -0xf(%rsi) 75922cc0e45SBill HollerL(P7Q0): 76022cc0e45SBill Holler mov -0x7(%rdi), %r8d 76122cc0e45SBill Holler movzwq -0x3(%rdi), %r10 76222cc0e45SBill Holler movzbq -0x1(%rdi), %rcx 76322cc0e45SBill Holler mov %r8d, -0x7(%rsi) 76422cc0e45SBill Holler mov %r10w, -0x3(%rsi) 76522cc0e45SBill Holler mov %cl, -0x1(%rsi) 76622cc0e45SBill Holler ret 76722cc0e45SBill Holler 76822cc0e45SBill Holler /* 76922cc0e45SBill Holler * For large sizes rep smovq is fastest. 77022cc0e45SBill Holler * Transition point determined experimentally as measured on 77122cc0e45SBill Holler * Intel Xeon processors (incl. Nehalem and previous generations) and 77222cc0e45SBill Holler * AMD Opteron. The transition value is patched at boot time to avoid 77322cc0e45SBill Holler * memory reference hit. 77422cc0e45SBill Holler */ 77522cc0e45SBill Holler .globl bcopy_patch_start 77622cc0e45SBill Hollerbcopy_patch_start: 77722cc0e45SBill Holler cmpq $BCOPY_NHM_REP, %rdx 77822cc0e45SBill Holler .globl bcopy_patch_end 77922cc0e45SBill Hollerbcopy_patch_end: 78022cc0e45SBill Holler 78122cc0e45SBill Holler .p2align 4 78222cc0e45SBill Holler .globl bcopy_ck_size 78322cc0e45SBill Hollerbcopy_ck_size: 78422cc0e45SBill Holler cmpq $BCOPY_DFLT_REP, %rdx 785*9b6707c5SRobert Mustacchi jae L(use_rep) 78622cc0e45SBill Holler 78722cc0e45SBill Holler /* 78822cc0e45SBill Holler * Align to a 8-byte boundary. Avoids penalties from unaligned stores 78922cc0e45SBill Holler * as well as from stores spanning cachelines. 79022cc0e45SBill Holler */ 79122cc0e45SBill Holler test $0x7, %rsi 79222cc0e45SBill Holler jz L(aligned_loop) 79322cc0e45SBill Holler test $0x1, %rsi 79422cc0e45SBill Holler jz 2f 79522cc0e45SBill Holler movzbq (%rdi), %r8 79622cc0e45SBill Holler dec %rdx 79722cc0e45SBill Holler inc %rdi 79822cc0e45SBill Holler mov %r8b, (%rsi) 79922cc0e45SBill Holler inc %rsi 80022cc0e45SBill Holler2: 80122cc0e45SBill Holler test $0x2, %rsi 80222cc0e45SBill Holler jz 4f 80322cc0e45SBill Holler movzwq (%rdi), %r8 80422cc0e45SBill Holler sub $0x2, %rdx 80522cc0e45SBill Holler add $0x2, %rdi 80622cc0e45SBill Holler mov %r8w, (%rsi) 80722cc0e45SBill Holler add $0x2, %rsi 80822cc0e45SBill Holler4: 80922cc0e45SBill Holler test $0x4, %rsi 81022cc0e45SBill Holler jz L(aligned_loop) 81122cc0e45SBill Holler mov (%rdi), %r8d 81222cc0e45SBill Holler sub $0x4, %rdx 81322cc0e45SBill Holler add $0x4, %rdi 81422cc0e45SBill Holler mov %r8d, (%rsi) 81522cc0e45SBill Holler add $0x4, %rsi 81622cc0e45SBill Holler 81722cc0e45SBill Holler /* 81822cc0e45SBill Holler * Copy 64-bytes per loop 81922cc0e45SBill Holler */ 82022cc0e45SBill Holler .p2align 4 82122cc0e45SBill HollerL(aligned_loop): 82222cc0e45SBill Holler mov (%rdi), %r8 82322cc0e45SBill Holler mov 0x8(%rdi), %r10 82422cc0e45SBill Holler lea -0x40(%rdx), %rdx 82522cc0e45SBill Holler mov %r8, (%rsi) 82622cc0e45SBill Holler mov %r10, 0x8(%rsi) 82722cc0e45SBill Holler mov 0x10(%rdi), %rcx 82822cc0e45SBill Holler mov 0x18(%rdi), %r8 82922cc0e45SBill Holler mov %rcx, 0x10(%rsi) 83022cc0e45SBill Holler mov %r8, 0x18(%rsi) 83122cc0e45SBill Holler 83222cc0e45SBill Holler cmp $0x40, %rdx 83322cc0e45SBill Holler mov 0x20(%rdi), %r10 83422cc0e45SBill Holler mov 0x28(%rdi), %rcx 83522cc0e45SBill Holler mov %r10, 0x20(%rsi) 83622cc0e45SBill Holler mov %rcx, 0x28(%rsi) 83722cc0e45SBill Holler mov 0x30(%rdi), %r8 83822cc0e45SBill Holler mov 0x38(%rdi), %r10 83922cc0e45SBill Holler lea 0x40(%rdi), %rdi 84022cc0e45SBill Holler mov %r8, 0x30(%rsi) 84122cc0e45SBill Holler mov %r10, 0x38(%rsi) 84222cc0e45SBill Holler lea 0x40(%rsi), %rsi 843*9b6707c5SRobert Mustacchi jae L(aligned_loop) 84422cc0e45SBill Holler 84522cc0e45SBill Holler /* 84622cc0e45SBill Holler * Copy remaining bytes (0-63) 84722cc0e45SBill Holler */ 84822cc0e45SBill HollerL(do_remainder): 84922cc0e45SBill Holler leaq L(fwdPxQx)(%rip), %r10 85022cc0e45SBill Holler addq %rdx, %rdi 85122cc0e45SBill Holler addq %rdx, %rsi 85222cc0e45SBill Holler movslq (%r10,%rdx,4), %rcx 85322cc0e45SBill Holler leaq (%rcx,%r10,1), %r10 85422cc0e45SBill Holler jmpq *%r10 85522cc0e45SBill Holler 85622cc0e45SBill Holler /* 85722cc0e45SBill Holler * Use rep smovq. Clear remainder via unrolled code 85822cc0e45SBill Holler */ 85922cc0e45SBill Holler .p2align 4 86022cc0e45SBill HollerL(use_rep): 8617c478bd9Sstevel@tonic-gate xchgq %rdi, %rsi /* %rsi = source, %rdi = destination */ 8627c478bd9Sstevel@tonic-gate movq %rdx, %rcx /* %rcx = count */ 8637c478bd9Sstevel@tonic-gate shrq $3, %rcx /* 8-byte word count */ 8647c478bd9Sstevel@tonic-gate rep 8657c478bd9Sstevel@tonic-gate smovq 8667c478bd9Sstevel@tonic-gate 86722cc0e45SBill Holler xchgq %rsi, %rdi /* %rdi = src, %rsi = destination */ 86822cc0e45SBill Holler andq $7, %rdx /* remainder */ 86922cc0e45SBill Holler jnz L(do_remainder) 8707c478bd9Sstevel@tonic-gate ret 87122cc0e45SBill Holler#undef L 8727c478bd9Sstevel@tonic-gate 8737c478bd9Sstevel@tonic-gate#ifdef DEBUG 8747c478bd9Sstevel@tonic-gate /* 8757c478bd9Sstevel@tonic-gate * Setup frame on the run-time stack. The end of the input argument 8767c478bd9Sstevel@tonic-gate * area must be aligned on a 16 byte boundary. The stack pointer %rsp, 8777c478bd9Sstevel@tonic-gate * always points to the end of the latest allocated stack frame. 8787c478bd9Sstevel@tonic-gate * panic(const char *format, ...) is a varargs function. When a 8797c478bd9Sstevel@tonic-gate * function taking variable arguments is called, %rax must be set 8807c478bd9Sstevel@tonic-gate * to eight times the number of floating point parameters passed 8817c478bd9Sstevel@tonic-gate * to the function in SSE registers. 8827c478bd9Sstevel@tonic-gate */ 8837c478bd9Sstevel@tonic-gatecall_panic: 8847c478bd9Sstevel@tonic-gate pushq %rbp /* align stack properly */ 8857c478bd9Sstevel@tonic-gate movq %rsp, %rbp 8867c478bd9Sstevel@tonic-gate xorl %eax, %eax /* no variable arguments */ 8877c478bd9Sstevel@tonic-gate call panic /* %rdi = format string */ 8887c478bd9Sstevel@tonic-gate#endif 88922cc0e45SBill Holler SET_SIZE(bcopy_altentry) 8907c478bd9Sstevel@tonic-gate SET_SIZE(bcopy) 8917c478bd9Sstevel@tonic-gate 8927c478bd9Sstevel@tonic-gate#elif defined(__i386) 8937c478bd9Sstevel@tonic-gate 8947c478bd9Sstevel@tonic-gate#define ARG_FROM 4 8957c478bd9Sstevel@tonic-gate#define ARG_TO 8 8967c478bd9Sstevel@tonic-gate#define ARG_COUNT 12 8977c478bd9Sstevel@tonic-gate 8987c478bd9Sstevel@tonic-gate ENTRY(bcopy) 8997c478bd9Sstevel@tonic-gate#ifdef DEBUG 9007c478bd9Sstevel@tonic-gate movl ARG_COUNT(%esp), %eax 9017c478bd9Sstevel@tonic-gate orl %eax, %eax 9027c478bd9Sstevel@tonic-gate jz 1f 903ae115bc7Smrj movl postbootkernelbase, %eax 9047c478bd9Sstevel@tonic-gate cmpl %eax, ARG_FROM(%esp) 9057c478bd9Sstevel@tonic-gate jb 0f 9067c478bd9Sstevel@tonic-gate cmpl %eax, ARG_TO(%esp) 9077c478bd9Sstevel@tonic-gate jnb 1f 9087c478bd9Sstevel@tonic-gate0: pushl %ebp 9097c478bd9Sstevel@tonic-gate movl %esp, %ebp 9107c478bd9Sstevel@tonic-gate pushl $.bcopy_panic_msg 9117c478bd9Sstevel@tonic-gate call panic 9127c478bd9Sstevel@tonic-gate1: 9137c478bd9Sstevel@tonic-gate#endif 9147c478bd9Sstevel@tonic-gatedo_copy: 9157c478bd9Sstevel@tonic-gate movl %esi, %eax /* save registers */ 9167c478bd9Sstevel@tonic-gate movl %edi, %edx 9177c478bd9Sstevel@tonic-gate movl ARG_COUNT(%esp), %ecx 9187c478bd9Sstevel@tonic-gate movl ARG_FROM(%esp), %esi 9197c478bd9Sstevel@tonic-gate movl ARG_TO(%esp), %edi 9207c478bd9Sstevel@tonic-gate 9217c478bd9Sstevel@tonic-gate shrl $2, %ecx /* word count */ 9227c478bd9Sstevel@tonic-gate rep 9237c478bd9Sstevel@tonic-gate smovl 9247c478bd9Sstevel@tonic-gate movl ARG_COUNT(%esp), %ecx 9257c478bd9Sstevel@tonic-gate andl $3, %ecx /* bytes left over */ 9267c478bd9Sstevel@tonic-gate rep 9277c478bd9Sstevel@tonic-gate smovb 9287c478bd9Sstevel@tonic-gate movl %eax, %esi /* restore registers */ 9297c478bd9Sstevel@tonic-gate movl %edx, %edi 9307c478bd9Sstevel@tonic-gate ret 9317c478bd9Sstevel@tonic-gate SET_SIZE(bcopy) 9327c478bd9Sstevel@tonic-gate 9337c478bd9Sstevel@tonic-gate#undef ARG_COUNT 9347c478bd9Sstevel@tonic-gate#undef ARG_FROM 9357c478bd9Sstevel@tonic-gate#undef ARG_TO 9367c478bd9Sstevel@tonic-gate 9377c478bd9Sstevel@tonic-gate#endif /* __i386 */ 9387c478bd9Sstevel@tonic-gate#endif /* __lint */ 9397c478bd9Sstevel@tonic-gate 9407c478bd9Sstevel@tonic-gate 9417c478bd9Sstevel@tonic-gate/* 9427c478bd9Sstevel@tonic-gate * Zero a block of storage, returning an error code if we 9437c478bd9Sstevel@tonic-gate * take a kernel pagefault which cannot be resolved. 9447c478bd9Sstevel@tonic-gate * Returns errno value on pagefault error, 0 if all ok 9457c478bd9Sstevel@tonic-gate */ 9467c478bd9Sstevel@tonic-gate 9477c478bd9Sstevel@tonic-gate#if defined(__lint) 9487c478bd9Sstevel@tonic-gate 9497c478bd9Sstevel@tonic-gate/* ARGSUSED */ 9507c478bd9Sstevel@tonic-gateint 9517c478bd9Sstevel@tonic-gatekzero(void *addr, size_t count) 9527c478bd9Sstevel@tonic-gate{ return (0); } 9537c478bd9Sstevel@tonic-gate 9547c478bd9Sstevel@tonic-gate#else /* __lint */ 9557c478bd9Sstevel@tonic-gate 9567c478bd9Sstevel@tonic-gate#if defined(__amd64) 9577c478bd9Sstevel@tonic-gate 9587c478bd9Sstevel@tonic-gate ENTRY(kzero) 9597c478bd9Sstevel@tonic-gate#ifdef DEBUG 960ae115bc7Smrj cmpq postbootkernelbase(%rip), %rdi /* %rdi = addr */ 9617c478bd9Sstevel@tonic-gate jnb 0f 9627c478bd9Sstevel@tonic-gate leaq .kzero_panic_msg(%rip), %rdi 9637c478bd9Sstevel@tonic-gate jmp call_panic /* setup stack and call panic */ 9647c478bd9Sstevel@tonic-gate0: 9657c478bd9Sstevel@tonic-gate#endif 9667c478bd9Sstevel@tonic-gate /* 967b08adf18SBill Holler * pass lofault value as 3rd argument for fault return 9687c478bd9Sstevel@tonic-gate */ 9697c478bd9Sstevel@tonic-gate leaq _kzeroerr(%rip), %rdx 9707c478bd9Sstevel@tonic-gate 9717c478bd9Sstevel@tonic-gate movq %gs:CPU_THREAD, %r9 /* %r9 = thread addr */ 9727c478bd9Sstevel@tonic-gate movq T_LOFAULT(%r9), %r11 /* save the current lofault */ 9737c478bd9Sstevel@tonic-gate movq %rdx, T_LOFAULT(%r9) /* new lofault */ 97422cc0e45SBill Holler call bzero_altentry 975b08adf18SBill Holler xorl %eax, %eax 976b08adf18SBill Holler movq %r11, T_LOFAULT(%r9) /* restore the original lofault */ 977b08adf18SBill Holler ret 9787c478bd9Sstevel@tonic-gate /* 979b08adf18SBill Holler * A fault during bzero is indicated through an errno value 9807c478bd9Sstevel@tonic-gate * in %rax when we iretq to here. 9817c478bd9Sstevel@tonic-gate */ 9827c478bd9Sstevel@tonic-gate_kzeroerr: 983b08adf18SBill Holler addq $8, %rsp /* pop bzero_altentry call ret addr */ 9847c478bd9Sstevel@tonic-gate movq %r11, T_LOFAULT(%r9) /* restore the original lofault */ 9857c478bd9Sstevel@tonic-gate ret 9867c478bd9Sstevel@tonic-gate SET_SIZE(kzero) 9877c478bd9Sstevel@tonic-gate 9887c478bd9Sstevel@tonic-gate#elif defined(__i386) 9897c478bd9Sstevel@tonic-gate 9907c478bd9Sstevel@tonic-gate#define ARG_ADDR 8 9917c478bd9Sstevel@tonic-gate#define ARG_COUNT 12 9927c478bd9Sstevel@tonic-gate 9937c478bd9Sstevel@tonic-gate ENTRY(kzero) 9947c478bd9Sstevel@tonic-gate#ifdef DEBUG 9957c478bd9Sstevel@tonic-gate pushl %ebp 9967c478bd9Sstevel@tonic-gate movl %esp, %ebp 997ae115bc7Smrj movl postbootkernelbase, %eax 9987c478bd9Sstevel@tonic-gate cmpl %eax, ARG_ADDR(%ebp) 9997c478bd9Sstevel@tonic-gate jnb 0f 10007c478bd9Sstevel@tonic-gate pushl $.kzero_panic_msg 10017c478bd9Sstevel@tonic-gate call panic 10027c478bd9Sstevel@tonic-gate0: popl %ebp 10037c478bd9Sstevel@tonic-gate#endif 10047c478bd9Sstevel@tonic-gate lea _kzeroerr, %eax /* kzeroerr is lofault value */ 10057c478bd9Sstevel@tonic-gate 10067c478bd9Sstevel@tonic-gate pushl %ebp /* save stack base */ 10077c478bd9Sstevel@tonic-gate movl %esp, %ebp /* set new stack base */ 10087c478bd9Sstevel@tonic-gate pushl %edi /* save %edi */ 10097c478bd9Sstevel@tonic-gate 10107c478bd9Sstevel@tonic-gate mov %gs:CPU_THREAD, %edx 10117c478bd9Sstevel@tonic-gate movl T_LOFAULT(%edx), %edi 10127c478bd9Sstevel@tonic-gate pushl %edi /* save the current lofault */ 10137c478bd9Sstevel@tonic-gate movl %eax, T_LOFAULT(%edx) /* new lofault */ 10147c478bd9Sstevel@tonic-gate 10157c478bd9Sstevel@tonic-gate movl ARG_COUNT(%ebp), %ecx /* get size in bytes */ 10167c478bd9Sstevel@tonic-gate movl ARG_ADDR(%ebp), %edi /* %edi <- address of bytes to clear */ 10177c478bd9Sstevel@tonic-gate shrl $2, %ecx /* Count of double words to zero */ 10187c478bd9Sstevel@tonic-gate xorl %eax, %eax /* sstol val */ 10197c478bd9Sstevel@tonic-gate rep 10207c478bd9Sstevel@tonic-gate sstol /* %ecx contains words to clear (%eax=0) */ 10217c478bd9Sstevel@tonic-gate 10227c478bd9Sstevel@tonic-gate movl ARG_COUNT(%ebp), %ecx /* get size in bytes */ 10237c478bd9Sstevel@tonic-gate andl $3, %ecx /* do mod 4 */ 10247c478bd9Sstevel@tonic-gate rep 10257c478bd9Sstevel@tonic-gate sstob /* %ecx contains residual bytes to clear */ 10267c478bd9Sstevel@tonic-gate 10277c478bd9Sstevel@tonic-gate /* 1028b08adf18SBill Holler * A fault during kzero is indicated through an errno value 10297c478bd9Sstevel@tonic-gate * in %eax when we iret to here. 10307c478bd9Sstevel@tonic-gate */ 10317c478bd9Sstevel@tonic-gate_kzeroerr: 10327c478bd9Sstevel@tonic-gate popl %edi 10337c478bd9Sstevel@tonic-gate movl %edi, T_LOFAULT(%edx) /* restore the original lofault */ 10347c478bd9Sstevel@tonic-gate popl %edi 10357c478bd9Sstevel@tonic-gate popl %ebp 10367c478bd9Sstevel@tonic-gate ret 10377c478bd9Sstevel@tonic-gate SET_SIZE(kzero) 10387c478bd9Sstevel@tonic-gate 10397c478bd9Sstevel@tonic-gate#undef ARG_ADDR 10407c478bd9Sstevel@tonic-gate#undef ARG_COUNT 10417c478bd9Sstevel@tonic-gate 10427c478bd9Sstevel@tonic-gate#endif /* __i386 */ 10437c478bd9Sstevel@tonic-gate#endif /* __lint */ 10447c478bd9Sstevel@tonic-gate 10457c478bd9Sstevel@tonic-gate/* 10467c478bd9Sstevel@tonic-gate * Zero a block of storage. 10477c478bd9Sstevel@tonic-gate */ 10487c478bd9Sstevel@tonic-gate 10497c478bd9Sstevel@tonic-gate#if defined(__lint) 10507c478bd9Sstevel@tonic-gate 10517c478bd9Sstevel@tonic-gate/* ARGSUSED */ 10527c478bd9Sstevel@tonic-gatevoid 10537c478bd9Sstevel@tonic-gatebzero(void *addr, size_t count) 10547c478bd9Sstevel@tonic-gate{} 10557c478bd9Sstevel@tonic-gate 10567c478bd9Sstevel@tonic-gate#else /* __lint */ 10577c478bd9Sstevel@tonic-gate 10587c478bd9Sstevel@tonic-gate#if defined(__amd64) 10597c478bd9Sstevel@tonic-gate 10607c478bd9Sstevel@tonic-gate ENTRY(bzero) 10617c478bd9Sstevel@tonic-gate#ifdef DEBUG 1062ae115bc7Smrj cmpq postbootkernelbase(%rip), %rdi /* %rdi = addr */ 10637c478bd9Sstevel@tonic-gate jnb 0f 10647c478bd9Sstevel@tonic-gate leaq .bzero_panic_msg(%rip), %rdi 10657c478bd9Sstevel@tonic-gate jmp call_panic /* setup stack and call panic */ 10667c478bd9Sstevel@tonic-gate0: 10677c478bd9Sstevel@tonic-gate#endif 106822cc0e45SBill Holler ALTENTRY(bzero_altentry) 10697c478bd9Sstevel@tonic-gatedo_zero: 107022cc0e45SBill Holler#define L(s) .bzero/**/s 107122cc0e45SBill Holler xorl %eax, %eax 107222cc0e45SBill Holler 107322cc0e45SBill Holler cmpq $0x50, %rsi /* 80 */ 1074*9b6707c5SRobert Mustacchi jae L(ck_align) 107522cc0e45SBill Holler 107622cc0e45SBill Holler /* 107722cc0e45SBill Holler * Performance data shows many caller's are zeroing small buffers. So 107822cc0e45SBill Holler * for best perf for these sizes unrolled code is used. Store zeros 107922cc0e45SBill Holler * without worrying about alignment. 108022cc0e45SBill Holler */ 108122cc0e45SBill Holler leaq L(setPxQx)(%rip), %r10 108222cc0e45SBill Holler addq %rsi, %rdi 108322cc0e45SBill Holler movslq (%r10,%rsi,4), %rcx 108422cc0e45SBill Holler leaq (%rcx,%r10,1), %r10 108522cc0e45SBill Holler jmpq *%r10 108622cc0e45SBill Holler 108722cc0e45SBill Holler .p2align 4 108822cc0e45SBill HollerL(setPxQx): 108922cc0e45SBill Holler .int L(P0Q0)-L(setPxQx) /* 0 */ 109022cc0e45SBill Holler .int L(P1Q0)-L(setPxQx) 109122cc0e45SBill Holler .int L(P2Q0)-L(setPxQx) 109222cc0e45SBill Holler .int L(P3Q0)-L(setPxQx) 109322cc0e45SBill Holler .int L(P4Q0)-L(setPxQx) 109422cc0e45SBill Holler .int L(P5Q0)-L(setPxQx) 109522cc0e45SBill Holler .int L(P6Q0)-L(setPxQx) 109622cc0e45SBill Holler .int L(P7Q0)-L(setPxQx) 109722cc0e45SBill Holler 109822cc0e45SBill Holler .int L(P0Q1)-L(setPxQx) /* 8 */ 109922cc0e45SBill Holler .int L(P1Q1)-L(setPxQx) 110022cc0e45SBill Holler .int L(P2Q1)-L(setPxQx) 110122cc0e45SBill Holler .int L(P3Q1)-L(setPxQx) 110222cc0e45SBill Holler .int L(P4Q1)-L(setPxQx) 110322cc0e45SBill Holler .int L(P5Q1)-L(setPxQx) 110422cc0e45SBill Holler .int L(P6Q1)-L(setPxQx) 110522cc0e45SBill Holler .int L(P7Q1)-L(setPxQx) 110622cc0e45SBill Holler 110722cc0e45SBill Holler .int L(P0Q2)-L(setPxQx) /* 16 */ 110822cc0e45SBill Holler .int L(P1Q2)-L(setPxQx) 110922cc0e45SBill Holler .int L(P2Q2)-L(setPxQx) 111022cc0e45SBill Holler .int L(P3Q2)-L(setPxQx) 111122cc0e45SBill Holler .int L(P4Q2)-L(setPxQx) 111222cc0e45SBill Holler .int L(P5Q2)-L(setPxQx) 111322cc0e45SBill Holler .int L(P6Q2)-L(setPxQx) 111422cc0e45SBill Holler .int L(P7Q2)-L(setPxQx) 111522cc0e45SBill Holler 111622cc0e45SBill Holler .int L(P0Q3)-L(setPxQx) /* 24 */ 111722cc0e45SBill Holler .int L(P1Q3)-L(setPxQx) 111822cc0e45SBill Holler .int L(P2Q3)-L(setPxQx) 111922cc0e45SBill Holler .int L(P3Q3)-L(setPxQx) 112022cc0e45SBill Holler .int L(P4Q3)-L(setPxQx) 112122cc0e45SBill Holler .int L(P5Q3)-L(setPxQx) 112222cc0e45SBill Holler .int L(P6Q3)-L(setPxQx) 112322cc0e45SBill Holler .int L(P7Q3)-L(setPxQx) 112422cc0e45SBill Holler 112522cc0e45SBill Holler .int L(P0Q4)-L(setPxQx) /* 32 */ 112622cc0e45SBill Holler .int L(P1Q4)-L(setPxQx) 112722cc0e45SBill Holler .int L(P2Q4)-L(setPxQx) 112822cc0e45SBill Holler .int L(P3Q4)-L(setPxQx) 112922cc0e45SBill Holler .int L(P4Q4)-L(setPxQx) 113022cc0e45SBill Holler .int L(P5Q4)-L(setPxQx) 113122cc0e45SBill Holler .int L(P6Q4)-L(setPxQx) 113222cc0e45SBill Holler .int L(P7Q4)-L(setPxQx) 113322cc0e45SBill Holler 113422cc0e45SBill Holler .int L(P0Q5)-L(setPxQx) /* 40 */ 113522cc0e45SBill Holler .int L(P1Q5)-L(setPxQx) 113622cc0e45SBill Holler .int L(P2Q5)-L(setPxQx) 113722cc0e45SBill Holler .int L(P3Q5)-L(setPxQx) 113822cc0e45SBill Holler .int L(P4Q5)-L(setPxQx) 113922cc0e45SBill Holler .int L(P5Q5)-L(setPxQx) 114022cc0e45SBill Holler .int L(P6Q5)-L(setPxQx) 114122cc0e45SBill Holler .int L(P7Q5)-L(setPxQx) 114222cc0e45SBill Holler 114322cc0e45SBill Holler .int L(P0Q6)-L(setPxQx) /* 48 */ 114422cc0e45SBill Holler .int L(P1Q6)-L(setPxQx) 114522cc0e45SBill Holler .int L(P2Q6)-L(setPxQx) 114622cc0e45SBill Holler .int L(P3Q6)-L(setPxQx) 114722cc0e45SBill Holler .int L(P4Q6)-L(setPxQx) 114822cc0e45SBill Holler .int L(P5Q6)-L(setPxQx) 114922cc0e45SBill Holler .int L(P6Q6)-L(setPxQx) 115022cc0e45SBill Holler .int L(P7Q6)-L(setPxQx) 115122cc0e45SBill Holler 115222cc0e45SBill Holler .int L(P0Q7)-L(setPxQx) /* 56 */ 115322cc0e45SBill Holler .int L(P1Q7)-L(setPxQx) 115422cc0e45SBill Holler .int L(P2Q7)-L(setPxQx) 115522cc0e45SBill Holler .int L(P3Q7)-L(setPxQx) 115622cc0e45SBill Holler .int L(P4Q7)-L(setPxQx) 115722cc0e45SBill Holler .int L(P5Q7)-L(setPxQx) 115822cc0e45SBill Holler .int L(P6Q7)-L(setPxQx) 115922cc0e45SBill Holler .int L(P7Q7)-L(setPxQx) 116022cc0e45SBill Holler 116122cc0e45SBill Holler .int L(P0Q8)-L(setPxQx) /* 64 */ 116222cc0e45SBill Holler .int L(P1Q8)-L(setPxQx) 116322cc0e45SBill Holler .int L(P2Q8)-L(setPxQx) 116422cc0e45SBill Holler .int L(P3Q8)-L(setPxQx) 116522cc0e45SBill Holler .int L(P4Q8)-L(setPxQx) 116622cc0e45SBill Holler .int L(P5Q8)-L(setPxQx) 116722cc0e45SBill Holler .int L(P6Q8)-L(setPxQx) 116822cc0e45SBill Holler .int L(P7Q8)-L(setPxQx) 116922cc0e45SBill Holler 117022cc0e45SBill Holler .int L(P0Q9)-L(setPxQx) /* 72 */ 117122cc0e45SBill Holler .int L(P1Q9)-L(setPxQx) 117222cc0e45SBill Holler .int L(P2Q9)-L(setPxQx) 117322cc0e45SBill Holler .int L(P3Q9)-L(setPxQx) 117422cc0e45SBill Holler .int L(P4Q9)-L(setPxQx) 117522cc0e45SBill Holler .int L(P5Q9)-L(setPxQx) 117622cc0e45SBill Holler .int L(P6Q9)-L(setPxQx) 117722cc0e45SBill Holler .int L(P7Q9)-L(setPxQx) /* 79 */ 117822cc0e45SBill Holler 117922cc0e45SBill Holler .p2align 4 118022cc0e45SBill HollerL(P0Q9): mov %rax, -0x48(%rdi) 118122cc0e45SBill HollerL(P0Q8): mov %rax, -0x40(%rdi) 118222cc0e45SBill HollerL(P0Q7): mov %rax, -0x38(%rdi) 118322cc0e45SBill HollerL(P0Q6): mov %rax, -0x30(%rdi) 118422cc0e45SBill HollerL(P0Q5): mov %rax, -0x28(%rdi) 118522cc0e45SBill HollerL(P0Q4): mov %rax, -0x20(%rdi) 118622cc0e45SBill HollerL(P0Q3): mov %rax, -0x18(%rdi) 118722cc0e45SBill HollerL(P0Q2): mov %rax, -0x10(%rdi) 118822cc0e45SBill HollerL(P0Q1): mov %rax, -0x8(%rdi) 118922cc0e45SBill HollerL(P0Q0): 119022cc0e45SBill Holler ret 119122cc0e45SBill Holler 119222cc0e45SBill Holler .p2align 4 119322cc0e45SBill HollerL(P1Q9): mov %rax, -0x49(%rdi) 119422cc0e45SBill HollerL(P1Q8): mov %rax, -0x41(%rdi) 119522cc0e45SBill HollerL(P1Q7): mov %rax, -0x39(%rdi) 119622cc0e45SBill HollerL(P1Q6): mov %rax, -0x31(%rdi) 119722cc0e45SBill HollerL(P1Q5): mov %rax, -0x29(%rdi) 119822cc0e45SBill HollerL(P1Q4): mov %rax, -0x21(%rdi) 119922cc0e45SBill HollerL(P1Q3): mov %rax, -0x19(%rdi) 120022cc0e45SBill HollerL(P1Q2): mov %rax, -0x11(%rdi) 120122cc0e45SBill HollerL(P1Q1): mov %rax, -0x9(%rdi) 120222cc0e45SBill HollerL(P1Q0): mov %al, -0x1(%rdi) 120322cc0e45SBill Holler ret 120422cc0e45SBill Holler 120522cc0e45SBill Holler .p2align 4 120622cc0e45SBill HollerL(P2Q9): mov %rax, -0x4a(%rdi) 120722cc0e45SBill HollerL(P2Q8): mov %rax, -0x42(%rdi) 120822cc0e45SBill HollerL(P2Q7): mov %rax, -0x3a(%rdi) 120922cc0e45SBill HollerL(P2Q6): mov %rax, -0x32(%rdi) 121022cc0e45SBill HollerL(P2Q5): mov %rax, -0x2a(%rdi) 121122cc0e45SBill HollerL(P2Q4): mov %rax, -0x22(%rdi) 121222cc0e45SBill HollerL(P2Q3): mov %rax, -0x1a(%rdi) 121322cc0e45SBill HollerL(P2Q2): mov %rax, -0x12(%rdi) 121422cc0e45SBill HollerL(P2Q1): mov %rax, -0xa(%rdi) 121522cc0e45SBill HollerL(P2Q0): mov %ax, -0x2(%rdi) 121622cc0e45SBill Holler ret 121722cc0e45SBill Holler 121822cc0e45SBill Holler .p2align 4 121922cc0e45SBill HollerL(P3Q9): mov %rax, -0x4b(%rdi) 122022cc0e45SBill HollerL(P3Q8): mov %rax, -0x43(%rdi) 122122cc0e45SBill HollerL(P3Q7): mov %rax, -0x3b(%rdi) 122222cc0e45SBill HollerL(P3Q6): mov %rax, -0x33(%rdi) 122322cc0e45SBill HollerL(P3Q5): mov %rax, -0x2b(%rdi) 122422cc0e45SBill HollerL(P3Q4): mov %rax, -0x23(%rdi) 122522cc0e45SBill HollerL(P3Q3): mov %rax, -0x1b(%rdi) 122622cc0e45SBill HollerL(P3Q2): mov %rax, -0x13(%rdi) 122722cc0e45SBill HollerL(P3Q1): mov %rax, -0xb(%rdi) 122822cc0e45SBill HollerL(P3Q0): mov %ax, -0x3(%rdi) 122922cc0e45SBill Holler mov %al, -0x1(%rdi) 123022cc0e45SBill Holler ret 123122cc0e45SBill Holler 123222cc0e45SBill Holler .p2align 4 123322cc0e45SBill HollerL(P4Q9): mov %rax, -0x4c(%rdi) 123422cc0e45SBill HollerL(P4Q8): mov %rax, -0x44(%rdi) 123522cc0e45SBill HollerL(P4Q7): mov %rax, -0x3c(%rdi) 123622cc0e45SBill HollerL(P4Q6): mov %rax, -0x34(%rdi) 123722cc0e45SBill HollerL(P4Q5): mov %rax, -0x2c(%rdi) 123822cc0e45SBill HollerL(P4Q4): mov %rax, -0x24(%rdi) 123922cc0e45SBill HollerL(P4Q3): mov %rax, -0x1c(%rdi) 124022cc0e45SBill HollerL(P4Q2): mov %rax, -0x14(%rdi) 124122cc0e45SBill HollerL(P4Q1): mov %rax, -0xc(%rdi) 124222cc0e45SBill HollerL(P4Q0): mov %eax, -0x4(%rdi) 124322cc0e45SBill Holler ret 124422cc0e45SBill Holler 124522cc0e45SBill Holler .p2align 4 124622cc0e45SBill HollerL(P5Q9): mov %rax, -0x4d(%rdi) 124722cc0e45SBill HollerL(P5Q8): mov %rax, -0x45(%rdi) 124822cc0e45SBill HollerL(P5Q7): mov %rax, -0x3d(%rdi) 124922cc0e45SBill HollerL(P5Q6): mov %rax, -0x35(%rdi) 125022cc0e45SBill HollerL(P5Q5): mov %rax, -0x2d(%rdi) 125122cc0e45SBill HollerL(P5Q4): mov %rax, -0x25(%rdi) 125222cc0e45SBill HollerL(P5Q3): mov %rax, -0x1d(%rdi) 125322cc0e45SBill HollerL(P5Q2): mov %rax, -0x15(%rdi) 125422cc0e45SBill HollerL(P5Q1): mov %rax, -0xd(%rdi) 125522cc0e45SBill HollerL(P5Q0): mov %eax, -0x5(%rdi) 125622cc0e45SBill Holler mov %al, -0x1(%rdi) 125722cc0e45SBill Holler ret 125822cc0e45SBill Holler 125922cc0e45SBill Holler .p2align 4 126022cc0e45SBill HollerL(P6Q9): mov %rax, -0x4e(%rdi) 126122cc0e45SBill HollerL(P6Q8): mov %rax, -0x46(%rdi) 126222cc0e45SBill HollerL(P6Q7): mov %rax, -0x3e(%rdi) 126322cc0e45SBill HollerL(P6Q6): mov %rax, -0x36(%rdi) 126422cc0e45SBill HollerL(P6Q5): mov %rax, -0x2e(%rdi) 126522cc0e45SBill HollerL(P6Q4): mov %rax, -0x26(%rdi) 126622cc0e45SBill HollerL(P6Q3): mov %rax, -0x1e(%rdi) 126722cc0e45SBill HollerL(P6Q2): mov %rax, -0x16(%rdi) 126822cc0e45SBill HollerL(P6Q1): mov %rax, -0xe(%rdi) 126922cc0e45SBill HollerL(P6Q0): mov %eax, -0x6(%rdi) 127022cc0e45SBill Holler mov %ax, -0x2(%rdi) 127122cc0e45SBill Holler ret 127222cc0e45SBill Holler 127322cc0e45SBill Holler .p2align 4 127422cc0e45SBill HollerL(P7Q9): mov %rax, -0x4f(%rdi) 127522cc0e45SBill HollerL(P7Q8): mov %rax, -0x47(%rdi) 127622cc0e45SBill HollerL(P7Q7): mov %rax, -0x3f(%rdi) 127722cc0e45SBill HollerL(P7Q6): mov %rax, -0x37(%rdi) 127822cc0e45SBill HollerL(P7Q5): mov %rax, -0x2f(%rdi) 127922cc0e45SBill HollerL(P7Q4): mov %rax, -0x27(%rdi) 128022cc0e45SBill HollerL(P7Q3): mov %rax, -0x1f(%rdi) 128122cc0e45SBill HollerL(P7Q2): mov %rax, -0x17(%rdi) 128222cc0e45SBill HollerL(P7Q1): mov %rax, -0xf(%rdi) 128322cc0e45SBill HollerL(P7Q0): mov %eax, -0x7(%rdi) 128422cc0e45SBill Holler mov %ax, -0x3(%rdi) 128522cc0e45SBill Holler mov %al, -0x1(%rdi) 128622cc0e45SBill Holler ret 128722cc0e45SBill Holler 128822cc0e45SBill Holler /* 128922cc0e45SBill Holler * Align to a 16-byte boundary. Avoids penalties from unaligned stores 129022cc0e45SBill Holler * as well as from stores spanning cachelines. Note 16-byte alignment 129122cc0e45SBill Holler * is better in case where rep sstosq is used. 129222cc0e45SBill Holler */ 129322cc0e45SBill Holler .p2align 4 129422cc0e45SBill HollerL(ck_align): 129522cc0e45SBill Holler test $0xf, %rdi 129622cc0e45SBill Holler jz L(aligned_now) 129722cc0e45SBill Holler test $1, %rdi 129822cc0e45SBill Holler jz 2f 129922cc0e45SBill Holler mov %al, (%rdi) 130022cc0e45SBill Holler dec %rsi 130122cc0e45SBill Holler lea 1(%rdi),%rdi 130222cc0e45SBill Holler2: 130322cc0e45SBill Holler test $2, %rdi 130422cc0e45SBill Holler jz 4f 130522cc0e45SBill Holler mov %ax, (%rdi) 130622cc0e45SBill Holler sub $2, %rsi 130722cc0e45SBill Holler lea 2(%rdi),%rdi 130822cc0e45SBill Holler4: 130922cc0e45SBill Holler test $4, %rdi 131022cc0e45SBill Holler jz 8f 131122cc0e45SBill Holler mov %eax, (%rdi) 131222cc0e45SBill Holler sub $4, %rsi 131322cc0e45SBill Holler lea 4(%rdi),%rdi 131422cc0e45SBill Holler8: 131522cc0e45SBill Holler test $8, %rdi 131622cc0e45SBill Holler jz L(aligned_now) 131722cc0e45SBill Holler mov %rax, (%rdi) 131822cc0e45SBill Holler sub $8, %rsi 131922cc0e45SBill Holler lea 8(%rdi),%rdi 132022cc0e45SBill Holler 132122cc0e45SBill Holler /* 132222cc0e45SBill Holler * For large sizes rep sstoq is fastest. 132322cc0e45SBill Holler * Transition point determined experimentally as measured on 132422cc0e45SBill Holler * Intel Xeon processors (incl. Nehalem) and AMD Opteron. 132522cc0e45SBill Holler */ 132622cc0e45SBill HollerL(aligned_now): 132722cc0e45SBill Holler cmp $BZERO_USE_REP, %rsi 1328*9b6707c5SRobert Mustacchi ja L(use_rep) 132922cc0e45SBill Holler 133022cc0e45SBill Holler /* 133122cc0e45SBill Holler * zero 64-bytes per loop 133222cc0e45SBill Holler */ 133322cc0e45SBill Holler .p2align 4 133422cc0e45SBill HollerL(bzero_loop): 133522cc0e45SBill Holler leaq -0x40(%rsi), %rsi 133622cc0e45SBill Holler cmpq $0x40, %rsi 133722cc0e45SBill Holler movq %rax, (%rdi) 133822cc0e45SBill Holler movq %rax, 0x8(%rdi) 133922cc0e45SBill Holler movq %rax, 0x10(%rdi) 134022cc0e45SBill Holler movq %rax, 0x18(%rdi) 134122cc0e45SBill Holler movq %rax, 0x20(%rdi) 134222cc0e45SBill Holler movq %rax, 0x28(%rdi) 134322cc0e45SBill Holler movq %rax, 0x30(%rdi) 134422cc0e45SBill Holler movq %rax, 0x38(%rdi) 134522cc0e45SBill Holler leaq 0x40(%rdi), %rdi 1346*9b6707c5SRobert Mustacchi jae L(bzero_loop) 134722cc0e45SBill Holler 134822cc0e45SBill Holler /* 134922cc0e45SBill Holler * Clear any remaining bytes.. 135022cc0e45SBill Holler */ 135122cc0e45SBill Holler9: 135222cc0e45SBill Holler leaq L(setPxQx)(%rip), %r10 135322cc0e45SBill Holler addq %rsi, %rdi 135422cc0e45SBill Holler movslq (%r10,%rsi,4), %rcx 135522cc0e45SBill Holler leaq (%rcx,%r10,1), %r10 135622cc0e45SBill Holler jmpq *%r10 135722cc0e45SBill Holler 135822cc0e45SBill Holler /* 135922cc0e45SBill Holler * Use rep sstoq. Clear any remainder via unrolled code 136022cc0e45SBill Holler */ 136122cc0e45SBill Holler .p2align 4 136222cc0e45SBill HollerL(use_rep): 13637c478bd9Sstevel@tonic-gate movq %rsi, %rcx /* get size in bytes */ 13647c478bd9Sstevel@tonic-gate shrq $3, %rcx /* count of 8-byte words to zero */ 13657c478bd9Sstevel@tonic-gate rep 13667c478bd9Sstevel@tonic-gate sstoq /* %rcx = words to clear (%rax=0) */ 136722cc0e45SBill Holler andq $7, %rsi /* remaining bytes */ 136822cc0e45SBill Holler jnz 9b 13697c478bd9Sstevel@tonic-gate ret 137022cc0e45SBill Holler#undef L 137122cc0e45SBill Holler SET_SIZE(bzero_altentry) 13727c478bd9Sstevel@tonic-gate SET_SIZE(bzero) 13737c478bd9Sstevel@tonic-gate 13747c478bd9Sstevel@tonic-gate#elif defined(__i386) 13757c478bd9Sstevel@tonic-gate 13767c478bd9Sstevel@tonic-gate#define ARG_ADDR 4 13777c478bd9Sstevel@tonic-gate#define ARG_COUNT 8 13787c478bd9Sstevel@tonic-gate 13797c478bd9Sstevel@tonic-gate ENTRY(bzero) 13807c478bd9Sstevel@tonic-gate#ifdef DEBUG 1381ae115bc7Smrj movl postbootkernelbase, %eax 13827c478bd9Sstevel@tonic-gate cmpl %eax, ARG_ADDR(%esp) 13837c478bd9Sstevel@tonic-gate jnb 0f 13847c478bd9Sstevel@tonic-gate pushl %ebp 13857c478bd9Sstevel@tonic-gate movl %esp, %ebp 13867c478bd9Sstevel@tonic-gate pushl $.bzero_panic_msg 13877c478bd9Sstevel@tonic-gate call panic 13887c478bd9Sstevel@tonic-gate0: 13897c478bd9Sstevel@tonic-gate#endif 13907c478bd9Sstevel@tonic-gatedo_zero: 13917c478bd9Sstevel@tonic-gate movl %edi, %edx 13927c478bd9Sstevel@tonic-gate movl ARG_COUNT(%esp), %ecx 13937c478bd9Sstevel@tonic-gate movl ARG_ADDR(%esp), %edi 13947c478bd9Sstevel@tonic-gate shrl $2, %ecx 13957c478bd9Sstevel@tonic-gate xorl %eax, %eax 13967c478bd9Sstevel@tonic-gate rep 13977c478bd9Sstevel@tonic-gate sstol 13987c478bd9Sstevel@tonic-gate movl ARG_COUNT(%esp), %ecx 13997c478bd9Sstevel@tonic-gate andl $3, %ecx 14007c478bd9Sstevel@tonic-gate rep 14017c478bd9Sstevel@tonic-gate sstob 14027c478bd9Sstevel@tonic-gate movl %edx, %edi 14037c478bd9Sstevel@tonic-gate ret 14047c478bd9Sstevel@tonic-gate SET_SIZE(bzero) 14057c478bd9Sstevel@tonic-gate 14067c478bd9Sstevel@tonic-gate#undef ARG_ADDR 14077c478bd9Sstevel@tonic-gate#undef ARG_COUNT 14087c478bd9Sstevel@tonic-gate 14097c478bd9Sstevel@tonic-gate#endif /* __i386 */ 14107c478bd9Sstevel@tonic-gate#endif /* __lint */ 14117c478bd9Sstevel@tonic-gate 14127c478bd9Sstevel@tonic-gate/* 14137c478bd9Sstevel@tonic-gate * Transfer data to and from user space - 14147c478bd9Sstevel@tonic-gate * Note that these routines can cause faults 14157c478bd9Sstevel@tonic-gate * It is assumed that the kernel has nothing at 14167c478bd9Sstevel@tonic-gate * less than KERNELBASE in the virtual address space. 14177c478bd9Sstevel@tonic-gate * 14187c478bd9Sstevel@tonic-gate * Note that copyin(9F) and copyout(9F) are part of the 14197c478bd9Sstevel@tonic-gate * DDI/DKI which specifies that they return '-1' on "errors." 14207c478bd9Sstevel@tonic-gate * 14217c478bd9Sstevel@tonic-gate * Sigh. 14227c478bd9Sstevel@tonic-gate * 14237c478bd9Sstevel@tonic-gate * So there's two extremely similar routines - xcopyin_nta() and 14247c478bd9Sstevel@tonic-gate * xcopyout_nta() which return the errno that we've faithfully computed. 14257c478bd9Sstevel@tonic-gate * This allows other callers (e.g. uiomove(9F)) to work correctly. 14267c478bd9Sstevel@tonic-gate * Given that these are used pretty heavily, we expand the calling 14277c478bd9Sstevel@tonic-gate * sequences inline for all flavours (rather than making wrappers). 14287c478bd9Sstevel@tonic-gate */ 14297c478bd9Sstevel@tonic-gate 14307c478bd9Sstevel@tonic-gate/* 14317c478bd9Sstevel@tonic-gate * Copy user data to kernel space. 14327c478bd9Sstevel@tonic-gate */ 14337c478bd9Sstevel@tonic-gate 14347c478bd9Sstevel@tonic-gate#if defined(__lint) 14357c478bd9Sstevel@tonic-gate 14367c478bd9Sstevel@tonic-gate/* ARGSUSED */ 14377c478bd9Sstevel@tonic-gateint 14387c478bd9Sstevel@tonic-gatecopyin(const void *uaddr, void *kaddr, size_t count) 14397c478bd9Sstevel@tonic-gate{ return (0); } 14407c478bd9Sstevel@tonic-gate 14417c478bd9Sstevel@tonic-gate#else /* lint */ 14427c478bd9Sstevel@tonic-gate 14437c478bd9Sstevel@tonic-gate#if defined(__amd64) 14447c478bd9Sstevel@tonic-gate 14457c478bd9Sstevel@tonic-gate ENTRY(copyin) 14467c478bd9Sstevel@tonic-gate pushq %rbp 14477c478bd9Sstevel@tonic-gate movq %rsp, %rbp 1448b08adf18SBill Holler subq $24, %rsp 14497c478bd9Sstevel@tonic-gate 14507c478bd9Sstevel@tonic-gate /* 14517c478bd9Sstevel@tonic-gate * save args in case we trap and need to rerun as a copyop 14527c478bd9Sstevel@tonic-gate */ 14537c478bd9Sstevel@tonic-gate movq %rdi, (%rsp) 14547c478bd9Sstevel@tonic-gate movq %rsi, 0x8(%rsp) 14557c478bd9Sstevel@tonic-gate movq %rdx, 0x10(%rsp) 14567c478bd9Sstevel@tonic-gate 14577c478bd9Sstevel@tonic-gate movq kernelbase(%rip), %rax 14587c478bd9Sstevel@tonic-gate#ifdef DEBUG 14597c478bd9Sstevel@tonic-gate cmpq %rax, %rsi /* %rsi = kaddr */ 14607c478bd9Sstevel@tonic-gate jnb 1f 14617c478bd9Sstevel@tonic-gate leaq .copyin_panic_msg(%rip), %rdi 14627c478bd9Sstevel@tonic-gate xorl %eax, %eax 14637c478bd9Sstevel@tonic-gate call panic 14647c478bd9Sstevel@tonic-gate1: 14657c478bd9Sstevel@tonic-gate#endif 14667c478bd9Sstevel@tonic-gate /* 14677c478bd9Sstevel@tonic-gate * pass lofault value as 4th argument to do_copy_fault 14687c478bd9Sstevel@tonic-gate */ 14697c478bd9Sstevel@tonic-gate leaq _copyin_err(%rip), %rcx 14707c478bd9Sstevel@tonic-gate 14717c478bd9Sstevel@tonic-gate movq %gs:CPU_THREAD, %r9 14727c478bd9Sstevel@tonic-gate cmpq %rax, %rdi /* test uaddr < kernelbase */ 14737c478bd9Sstevel@tonic-gate jb do_copy_fault 14747c478bd9Sstevel@tonic-gate jmp 3f 14757c478bd9Sstevel@tonic-gate 14767c478bd9Sstevel@tonic-gate_copyin_err: 14777c478bd9Sstevel@tonic-gate movq %r11, T_LOFAULT(%r9) /* restore original lofault */ 1478b08adf18SBill Holler addq $8, %rsp /* pop bcopy_altentry call ret addr */ 14797c478bd9Sstevel@tonic-gate3: 14807c478bd9Sstevel@tonic-gate movq T_COPYOPS(%r9), %rax 14817c478bd9Sstevel@tonic-gate cmpq $0, %rax 14827c478bd9Sstevel@tonic-gate jz 2f 14837c478bd9Sstevel@tonic-gate /* 14847c478bd9Sstevel@tonic-gate * reload args for the copyop 14857c478bd9Sstevel@tonic-gate */ 14867c478bd9Sstevel@tonic-gate movq (%rsp), %rdi 14877c478bd9Sstevel@tonic-gate movq 0x8(%rsp), %rsi 14887c478bd9Sstevel@tonic-gate movq 0x10(%rsp), %rdx 14897c478bd9Sstevel@tonic-gate leave 14907c478bd9Sstevel@tonic-gate jmp *CP_COPYIN(%rax) 14917c478bd9Sstevel@tonic-gate 14927c478bd9Sstevel@tonic-gate2: movl $-1, %eax 14937c478bd9Sstevel@tonic-gate leave 14947c478bd9Sstevel@tonic-gate ret 14957c478bd9Sstevel@tonic-gate SET_SIZE(copyin) 14967c478bd9Sstevel@tonic-gate 14977c478bd9Sstevel@tonic-gate#elif defined(__i386) 14987c478bd9Sstevel@tonic-gate 14997c478bd9Sstevel@tonic-gate#define ARG_UADDR 4 15007c478bd9Sstevel@tonic-gate#define ARG_KADDR 8 15017c478bd9Sstevel@tonic-gate 15027c478bd9Sstevel@tonic-gate ENTRY(copyin) 15037c478bd9Sstevel@tonic-gate movl kernelbase, %ecx 15047c478bd9Sstevel@tonic-gate#ifdef DEBUG 15057c478bd9Sstevel@tonic-gate cmpl %ecx, ARG_KADDR(%esp) 15067c478bd9Sstevel@tonic-gate jnb 1f 15077c478bd9Sstevel@tonic-gate pushl %ebp 15087c478bd9Sstevel@tonic-gate movl %esp, %ebp 15097c478bd9Sstevel@tonic-gate pushl $.copyin_panic_msg 15107c478bd9Sstevel@tonic-gate call panic 15117c478bd9Sstevel@tonic-gate1: 15127c478bd9Sstevel@tonic-gate#endif 15137c478bd9Sstevel@tonic-gate lea _copyin_err, %eax 15147c478bd9Sstevel@tonic-gate 15157c478bd9Sstevel@tonic-gate movl %gs:CPU_THREAD, %edx 15167c478bd9Sstevel@tonic-gate cmpl %ecx, ARG_UADDR(%esp) /* test uaddr < kernelbase */ 15177c478bd9Sstevel@tonic-gate jb do_copy_fault 15187c478bd9Sstevel@tonic-gate jmp 3f 15197c478bd9Sstevel@tonic-gate 15207c478bd9Sstevel@tonic-gate_copyin_err: 15217c478bd9Sstevel@tonic-gate popl %ecx 15227c478bd9Sstevel@tonic-gate popl %edi 15237c478bd9Sstevel@tonic-gate movl %ecx, T_LOFAULT(%edx) /* restore original lofault */ 15247c478bd9Sstevel@tonic-gate popl %esi 15257c478bd9Sstevel@tonic-gate popl %ebp 15267c478bd9Sstevel@tonic-gate3: 15277c478bd9Sstevel@tonic-gate movl T_COPYOPS(%edx), %eax 15287c478bd9Sstevel@tonic-gate cmpl $0, %eax 15297c478bd9Sstevel@tonic-gate jz 2f 15307c478bd9Sstevel@tonic-gate jmp *CP_COPYIN(%eax) 15317c478bd9Sstevel@tonic-gate 15327c478bd9Sstevel@tonic-gate2: movl $-1, %eax 15337c478bd9Sstevel@tonic-gate ret 15347c478bd9Sstevel@tonic-gate SET_SIZE(copyin) 15357c478bd9Sstevel@tonic-gate 15367c478bd9Sstevel@tonic-gate#undef ARG_UADDR 15377c478bd9Sstevel@tonic-gate#undef ARG_KADDR 15387c478bd9Sstevel@tonic-gate 15397c478bd9Sstevel@tonic-gate#endif /* __i386 */ 15407c478bd9Sstevel@tonic-gate#endif /* __lint */ 15417c478bd9Sstevel@tonic-gate 15427c478bd9Sstevel@tonic-gate#if defined(__lint) 15437c478bd9Sstevel@tonic-gate 15447c478bd9Sstevel@tonic-gate/* ARGSUSED */ 15457c478bd9Sstevel@tonic-gateint 15467c478bd9Sstevel@tonic-gatexcopyin_nta(const void *uaddr, void *kaddr, size_t count, int copy_cached) 15477c478bd9Sstevel@tonic-gate{ return (0); } 15487c478bd9Sstevel@tonic-gate 15497c478bd9Sstevel@tonic-gate#else /* __lint */ 15507c478bd9Sstevel@tonic-gate 15517c478bd9Sstevel@tonic-gate#if defined(__amd64) 15527c478bd9Sstevel@tonic-gate 15537c478bd9Sstevel@tonic-gate ENTRY(xcopyin_nta) 15547c478bd9Sstevel@tonic-gate pushq %rbp 15557c478bd9Sstevel@tonic-gate movq %rsp, %rbp 1556b08adf18SBill Holler subq $24, %rsp 15577c478bd9Sstevel@tonic-gate 15587c478bd9Sstevel@tonic-gate /* 15597c478bd9Sstevel@tonic-gate * save args in case we trap and need to rerun as a copyop 15607c478bd9Sstevel@tonic-gate * %rcx is consumed in this routine so we don't need to save 15617c478bd9Sstevel@tonic-gate * it. 15627c478bd9Sstevel@tonic-gate */ 15637c478bd9Sstevel@tonic-gate movq %rdi, (%rsp) 15647c478bd9Sstevel@tonic-gate movq %rsi, 0x8(%rsp) 15657c478bd9Sstevel@tonic-gate movq %rdx, 0x10(%rsp) 15667c478bd9Sstevel@tonic-gate 15677c478bd9Sstevel@tonic-gate movq kernelbase(%rip), %rax 15687c478bd9Sstevel@tonic-gate#ifdef DEBUG 15697c478bd9Sstevel@tonic-gate cmpq %rax, %rsi /* %rsi = kaddr */ 15707c478bd9Sstevel@tonic-gate jnb 1f 15717c478bd9Sstevel@tonic-gate leaq .xcopyin_panic_msg(%rip), %rdi 15727c478bd9Sstevel@tonic-gate xorl %eax, %eax 15737c478bd9Sstevel@tonic-gate call panic 15747c478bd9Sstevel@tonic-gate1: 15757c478bd9Sstevel@tonic-gate#endif 15767c478bd9Sstevel@tonic-gate movq %gs:CPU_THREAD, %r9 15777c478bd9Sstevel@tonic-gate cmpq %rax, %rdi /* test uaddr < kernelbase */ 1578b737e79eSnn35248 jae 4f 15797c478bd9Sstevel@tonic-gate cmpq $0, %rcx /* No non-temporal access? */ 15807c478bd9Sstevel@tonic-gate /* 15817c478bd9Sstevel@tonic-gate * pass lofault value as 4th argument to do_copy_fault 15827c478bd9Sstevel@tonic-gate */ 15837c478bd9Sstevel@tonic-gate leaq _xcopyin_err(%rip), %rcx /* doesn't set rflags */ 15847c478bd9Sstevel@tonic-gate jnz do_copy_fault /* use regular access */ 15857c478bd9Sstevel@tonic-gate /* 15867c478bd9Sstevel@tonic-gate * Make sure cnt is >= XCOPY_MIN_SIZE bytes 15877c478bd9Sstevel@tonic-gate */ 15887c478bd9Sstevel@tonic-gate cmpq $XCOPY_MIN_SIZE, %rdx 15897c478bd9Sstevel@tonic-gate jb do_copy_fault 15907c478bd9Sstevel@tonic-gate 15917c478bd9Sstevel@tonic-gate /* 15927c478bd9Sstevel@tonic-gate * Make sure src and dst are NTA_ALIGN_SIZE aligned, 15937c478bd9Sstevel@tonic-gate * count is COUNT_ALIGN_SIZE aligned. 15947c478bd9Sstevel@tonic-gate */ 15957c478bd9Sstevel@tonic-gate movq %rdi, %r10 15967c478bd9Sstevel@tonic-gate orq %rsi, %r10 15977c478bd9Sstevel@tonic-gate andq $NTA_ALIGN_MASK, %r10 15987c478bd9Sstevel@tonic-gate orq %rdx, %r10 15997c478bd9Sstevel@tonic-gate andq $COUNT_ALIGN_MASK, %r10 16007c478bd9Sstevel@tonic-gate jnz do_copy_fault 1601b08adf18SBill Holler leaq _xcopyin_nta_err(%rip), %rcx /* doesn't set rflags */ 16027c478bd9Sstevel@tonic-gate jmp do_copy_fault_nta /* use non-temporal access */ 16037c478bd9Sstevel@tonic-gate 1604b737e79eSnn352484: 1605b737e79eSnn35248 movl $EFAULT, %eax 1606b737e79eSnn35248 jmp 3f 1607b737e79eSnn35248 16087c478bd9Sstevel@tonic-gate /* 16097c478bd9Sstevel@tonic-gate * A fault during do_copy_fault or do_copy_fault_nta is 16107c478bd9Sstevel@tonic-gate * indicated through an errno value in %rax and we iret from the 16117c478bd9Sstevel@tonic-gate * trap handler to here. 16127c478bd9Sstevel@tonic-gate */ 16137c478bd9Sstevel@tonic-gate_xcopyin_err: 1614b08adf18SBill Holler addq $8, %rsp /* pop bcopy_altentry call ret addr */ 1615b08adf18SBill Holler_xcopyin_nta_err: 16167c478bd9Sstevel@tonic-gate movq %r11, T_LOFAULT(%r9) /* restore original lofault */ 16177c478bd9Sstevel@tonic-gate3: 16187c478bd9Sstevel@tonic-gate movq T_COPYOPS(%r9), %r8 16197c478bd9Sstevel@tonic-gate cmpq $0, %r8 16207c478bd9Sstevel@tonic-gate jz 2f 16217c478bd9Sstevel@tonic-gate 16227c478bd9Sstevel@tonic-gate /* 16237c478bd9Sstevel@tonic-gate * reload args for the copyop 16247c478bd9Sstevel@tonic-gate */ 16257c478bd9Sstevel@tonic-gate movq (%rsp), %rdi 16267c478bd9Sstevel@tonic-gate movq 0x8(%rsp), %rsi 16277c478bd9Sstevel@tonic-gate movq 0x10(%rsp), %rdx 16287c478bd9Sstevel@tonic-gate leave 16297c478bd9Sstevel@tonic-gate jmp *CP_XCOPYIN(%r8) 16307c478bd9Sstevel@tonic-gate 16317c478bd9Sstevel@tonic-gate2: leave 16327c478bd9Sstevel@tonic-gate ret 16337c478bd9Sstevel@tonic-gate SET_SIZE(xcopyin_nta) 16347c478bd9Sstevel@tonic-gate 16357c478bd9Sstevel@tonic-gate#elif defined(__i386) 16367c478bd9Sstevel@tonic-gate 16377c478bd9Sstevel@tonic-gate#define ARG_UADDR 4 16387c478bd9Sstevel@tonic-gate#define ARG_KADDR 8 16397c478bd9Sstevel@tonic-gate#define ARG_COUNT 12 16407c478bd9Sstevel@tonic-gate#define ARG_CACHED 16 16417c478bd9Sstevel@tonic-gate 16427c478bd9Sstevel@tonic-gate .globl use_sse_copy 16437c478bd9Sstevel@tonic-gate 16447c478bd9Sstevel@tonic-gate ENTRY(xcopyin_nta) 16457c478bd9Sstevel@tonic-gate movl kernelbase, %ecx 16467c478bd9Sstevel@tonic-gate lea _xcopyin_err, %eax 16477c478bd9Sstevel@tonic-gate movl %gs:CPU_THREAD, %edx 16487c478bd9Sstevel@tonic-gate cmpl %ecx, ARG_UADDR(%esp) /* test uaddr < kernelbase */ 1649b737e79eSnn35248 jae 4f 16507c478bd9Sstevel@tonic-gate 16517c478bd9Sstevel@tonic-gate cmpl $0, use_sse_copy /* no sse support */ 16527c478bd9Sstevel@tonic-gate jz do_copy_fault 16537c478bd9Sstevel@tonic-gate 16547c478bd9Sstevel@tonic-gate cmpl $0, ARG_CACHED(%esp) /* copy_cached hint set? */ 16557c478bd9Sstevel@tonic-gate jnz do_copy_fault 16567c478bd9Sstevel@tonic-gate 16577c478bd9Sstevel@tonic-gate /* 16587c478bd9Sstevel@tonic-gate * Make sure cnt is >= XCOPY_MIN_SIZE bytes 16597c478bd9Sstevel@tonic-gate */ 16607c478bd9Sstevel@tonic-gate cmpl $XCOPY_MIN_SIZE, ARG_COUNT(%esp) 16617c478bd9Sstevel@tonic-gate jb do_copy_fault 16627c478bd9Sstevel@tonic-gate 16637c478bd9Sstevel@tonic-gate /* 16647c478bd9Sstevel@tonic-gate * Make sure src and dst are NTA_ALIGN_SIZE aligned, 16657c478bd9Sstevel@tonic-gate * count is COUNT_ALIGN_SIZE aligned. 16667c478bd9Sstevel@tonic-gate */ 16677c478bd9Sstevel@tonic-gate movl ARG_UADDR(%esp), %ecx 16687c478bd9Sstevel@tonic-gate orl ARG_KADDR(%esp), %ecx 16697c478bd9Sstevel@tonic-gate andl $NTA_ALIGN_MASK, %ecx 16707c478bd9Sstevel@tonic-gate orl ARG_COUNT(%esp), %ecx 16717c478bd9Sstevel@tonic-gate andl $COUNT_ALIGN_MASK, %ecx 16727c478bd9Sstevel@tonic-gate jnz do_copy_fault 16737c478bd9Sstevel@tonic-gate 16747c478bd9Sstevel@tonic-gate jmp do_copy_fault_nta /* use regular access */ 16757c478bd9Sstevel@tonic-gate 1676b737e79eSnn352484: 1677b737e79eSnn35248 movl $EFAULT, %eax 1678b737e79eSnn35248 jmp 3f 1679b737e79eSnn35248 16807c478bd9Sstevel@tonic-gate /* 16817c478bd9Sstevel@tonic-gate * A fault during do_copy_fault or do_copy_fault_nta is 16827c478bd9Sstevel@tonic-gate * indicated through an errno value in %eax and we iret from the 16837c478bd9Sstevel@tonic-gate * trap handler to here. 16847c478bd9Sstevel@tonic-gate */ 16857c478bd9Sstevel@tonic-gate_xcopyin_err: 16867c478bd9Sstevel@tonic-gate popl %ecx 16877c478bd9Sstevel@tonic-gate popl %edi 16887c478bd9Sstevel@tonic-gate movl %ecx, T_LOFAULT(%edx) /* restore original lofault */ 16897c478bd9Sstevel@tonic-gate popl %esi 16907c478bd9Sstevel@tonic-gate popl %ebp 16917c478bd9Sstevel@tonic-gate3: 16927c478bd9Sstevel@tonic-gate cmpl $0, T_COPYOPS(%edx) 16937c478bd9Sstevel@tonic-gate jz 2f 16947c478bd9Sstevel@tonic-gate movl T_COPYOPS(%edx), %eax 16957c478bd9Sstevel@tonic-gate jmp *CP_XCOPYIN(%eax) 16967c478bd9Sstevel@tonic-gate 169785641879Skalai2: rep; ret /* use 2 byte return instruction when branch target */ 169885641879Skalai /* AMD Software Optimization Guide - Section 6.2 */ 16997c478bd9Sstevel@tonic-gate SET_SIZE(xcopyin_nta) 17007c478bd9Sstevel@tonic-gate 17017c478bd9Sstevel@tonic-gate#undef ARG_UADDR 17027c478bd9Sstevel@tonic-gate#undef ARG_KADDR 17037c478bd9Sstevel@tonic-gate#undef ARG_COUNT 17047c478bd9Sstevel@tonic-gate#undef ARG_CACHED 17057c478bd9Sstevel@tonic-gate 17067c478bd9Sstevel@tonic-gate#endif /* __i386 */ 17077c478bd9Sstevel@tonic-gate#endif /* __lint */ 17087c478bd9Sstevel@tonic-gate 17097c478bd9Sstevel@tonic-gate/* 17107c478bd9Sstevel@tonic-gate * Copy kernel data to user space. 17117c478bd9Sstevel@tonic-gate */ 17127c478bd9Sstevel@tonic-gate 17137c478bd9Sstevel@tonic-gate#if defined(__lint) 17147c478bd9Sstevel@tonic-gate 17157c478bd9Sstevel@tonic-gate/* ARGSUSED */ 17167c478bd9Sstevel@tonic-gateint 17177c478bd9Sstevel@tonic-gatecopyout(const void *kaddr, void *uaddr, size_t count) 17187c478bd9Sstevel@tonic-gate{ return (0); } 17197c478bd9Sstevel@tonic-gate 17207c478bd9Sstevel@tonic-gate#else /* __lint */ 17217c478bd9Sstevel@tonic-gate 17227c478bd9Sstevel@tonic-gate#if defined(__amd64) 17237c478bd9Sstevel@tonic-gate 17247c478bd9Sstevel@tonic-gate ENTRY(copyout) 17257c478bd9Sstevel@tonic-gate pushq %rbp 17267c478bd9Sstevel@tonic-gate movq %rsp, %rbp 1727b08adf18SBill Holler subq $24, %rsp 17287c478bd9Sstevel@tonic-gate 17297c478bd9Sstevel@tonic-gate /* 17307c478bd9Sstevel@tonic-gate * save args in case we trap and need to rerun as a copyop 17317c478bd9Sstevel@tonic-gate */ 17327c478bd9Sstevel@tonic-gate movq %rdi, (%rsp) 17337c478bd9Sstevel@tonic-gate movq %rsi, 0x8(%rsp) 17347c478bd9Sstevel@tonic-gate movq %rdx, 0x10(%rsp) 17357c478bd9Sstevel@tonic-gate 17367c478bd9Sstevel@tonic-gate movq kernelbase(%rip), %rax 17377c478bd9Sstevel@tonic-gate#ifdef DEBUG 17387c478bd9Sstevel@tonic-gate cmpq %rax, %rdi /* %rdi = kaddr */ 17397c478bd9Sstevel@tonic-gate jnb 1f 17407c478bd9Sstevel@tonic-gate leaq .copyout_panic_msg(%rip), %rdi 17417c478bd9Sstevel@tonic-gate xorl %eax, %eax 17427c478bd9Sstevel@tonic-gate call panic 17437c478bd9Sstevel@tonic-gate1: 17447c478bd9Sstevel@tonic-gate#endif 17457c478bd9Sstevel@tonic-gate /* 17467c478bd9Sstevel@tonic-gate * pass lofault value as 4th argument to do_copy_fault 17477c478bd9Sstevel@tonic-gate */ 17487c478bd9Sstevel@tonic-gate leaq _copyout_err(%rip), %rcx 17497c478bd9Sstevel@tonic-gate 17507c478bd9Sstevel@tonic-gate movq %gs:CPU_THREAD, %r9 17517c478bd9Sstevel@tonic-gate cmpq %rax, %rsi /* test uaddr < kernelbase */ 17527c478bd9Sstevel@tonic-gate jb do_copy_fault 17537c478bd9Sstevel@tonic-gate jmp 3f 17547c478bd9Sstevel@tonic-gate 17557c478bd9Sstevel@tonic-gate_copyout_err: 17567c478bd9Sstevel@tonic-gate movq %r11, T_LOFAULT(%r9) /* restore original lofault */ 1757b08adf18SBill Holler addq $8, %rsp /* pop bcopy_altentry call ret addr */ 17587c478bd9Sstevel@tonic-gate3: 17597c478bd9Sstevel@tonic-gate movq T_COPYOPS(%r9), %rax 17607c478bd9Sstevel@tonic-gate cmpq $0, %rax 17617c478bd9Sstevel@tonic-gate jz 2f 17627c478bd9Sstevel@tonic-gate 17637c478bd9Sstevel@tonic-gate /* 17647c478bd9Sstevel@tonic-gate * reload args for the copyop 17657c478bd9Sstevel@tonic-gate */ 17667c478bd9Sstevel@tonic-gate movq (%rsp), %rdi 17677c478bd9Sstevel@tonic-gate movq 0x8(%rsp), %rsi 17687c478bd9Sstevel@tonic-gate movq 0x10(%rsp), %rdx 17697c478bd9Sstevel@tonic-gate leave 17707c478bd9Sstevel@tonic-gate jmp *CP_COPYOUT(%rax) 17717c478bd9Sstevel@tonic-gate 17727c478bd9Sstevel@tonic-gate2: movl $-1, %eax 17737c478bd9Sstevel@tonic-gate leave 17747c478bd9Sstevel@tonic-gate ret 17757c478bd9Sstevel@tonic-gate SET_SIZE(copyout) 17767c478bd9Sstevel@tonic-gate 17777c478bd9Sstevel@tonic-gate#elif defined(__i386) 17787c478bd9Sstevel@tonic-gate 17797c478bd9Sstevel@tonic-gate#define ARG_KADDR 4 17807c478bd9Sstevel@tonic-gate#define ARG_UADDR 8 17817c478bd9Sstevel@tonic-gate 17827c478bd9Sstevel@tonic-gate ENTRY(copyout) 17837c478bd9Sstevel@tonic-gate movl kernelbase, %ecx 17847c478bd9Sstevel@tonic-gate#ifdef DEBUG 17857c478bd9Sstevel@tonic-gate cmpl %ecx, ARG_KADDR(%esp) 17867c478bd9Sstevel@tonic-gate jnb 1f 17877c478bd9Sstevel@tonic-gate pushl %ebp 17887c478bd9Sstevel@tonic-gate movl %esp, %ebp 17897c478bd9Sstevel@tonic-gate pushl $.copyout_panic_msg 17907c478bd9Sstevel@tonic-gate call panic 17917c478bd9Sstevel@tonic-gate1: 17927c478bd9Sstevel@tonic-gate#endif 17937c478bd9Sstevel@tonic-gate lea _copyout_err, %eax 17947c478bd9Sstevel@tonic-gate movl %gs:CPU_THREAD, %edx 17957c478bd9Sstevel@tonic-gate cmpl %ecx, ARG_UADDR(%esp) /* test uaddr < kernelbase */ 17967c478bd9Sstevel@tonic-gate jb do_copy_fault 17977c478bd9Sstevel@tonic-gate jmp 3f 17987c478bd9Sstevel@tonic-gate 17997c478bd9Sstevel@tonic-gate_copyout_err: 18007c478bd9Sstevel@tonic-gate popl %ecx 18017c478bd9Sstevel@tonic-gate popl %edi 18027c478bd9Sstevel@tonic-gate movl %ecx, T_LOFAULT(%edx) /* restore original lofault */ 18037c478bd9Sstevel@tonic-gate popl %esi 18047c478bd9Sstevel@tonic-gate popl %ebp 18057c478bd9Sstevel@tonic-gate3: 18067c478bd9Sstevel@tonic-gate movl T_COPYOPS(%edx), %eax 18077c478bd9Sstevel@tonic-gate cmpl $0, %eax 18087c478bd9Sstevel@tonic-gate jz 2f 18097c478bd9Sstevel@tonic-gate jmp *CP_COPYOUT(%eax) 18107c478bd9Sstevel@tonic-gate 18117c478bd9Sstevel@tonic-gate2: movl $-1, %eax 18127c478bd9Sstevel@tonic-gate ret 18137c478bd9Sstevel@tonic-gate SET_SIZE(copyout) 18147c478bd9Sstevel@tonic-gate 18157c478bd9Sstevel@tonic-gate#undef ARG_UADDR 18167c478bd9Sstevel@tonic-gate#undef ARG_KADDR 18177c478bd9Sstevel@tonic-gate 18187c478bd9Sstevel@tonic-gate#endif /* __i386 */ 18197c478bd9Sstevel@tonic-gate#endif /* __lint */ 18207c478bd9Sstevel@tonic-gate 18217c478bd9Sstevel@tonic-gate#if defined(__lint) 18227c478bd9Sstevel@tonic-gate 18237c478bd9Sstevel@tonic-gate/* ARGSUSED */ 18247c478bd9Sstevel@tonic-gateint 18257c478bd9Sstevel@tonic-gatexcopyout_nta(const void *kaddr, void *uaddr, size_t count, int copy_cached) 18267c478bd9Sstevel@tonic-gate{ return (0); } 18277c478bd9Sstevel@tonic-gate 18287c478bd9Sstevel@tonic-gate#else /* __lint */ 18297c478bd9Sstevel@tonic-gate 18307c478bd9Sstevel@tonic-gate#if defined(__amd64) 18317c478bd9Sstevel@tonic-gate 18327c478bd9Sstevel@tonic-gate ENTRY(xcopyout_nta) 18337c478bd9Sstevel@tonic-gate pushq %rbp 18347c478bd9Sstevel@tonic-gate movq %rsp, %rbp 1835b08adf18SBill Holler subq $24, %rsp 18367c478bd9Sstevel@tonic-gate 18377c478bd9Sstevel@tonic-gate /* 18387c478bd9Sstevel@tonic-gate * save args in case we trap and need to rerun as a copyop 18397c478bd9Sstevel@tonic-gate */ 18407c478bd9Sstevel@tonic-gate movq %rdi, (%rsp) 18417c478bd9Sstevel@tonic-gate movq %rsi, 0x8(%rsp) 18427c478bd9Sstevel@tonic-gate movq %rdx, 0x10(%rsp) 18437c478bd9Sstevel@tonic-gate 18447c478bd9Sstevel@tonic-gate movq kernelbase(%rip), %rax 18457c478bd9Sstevel@tonic-gate#ifdef DEBUG 18467c478bd9Sstevel@tonic-gate cmpq %rax, %rdi /* %rdi = kaddr */ 18477c478bd9Sstevel@tonic-gate jnb 1f 18487c478bd9Sstevel@tonic-gate leaq .xcopyout_panic_msg(%rip), %rdi 18497c478bd9Sstevel@tonic-gate xorl %eax, %eax 18507c478bd9Sstevel@tonic-gate call panic 18517c478bd9Sstevel@tonic-gate1: 18527c478bd9Sstevel@tonic-gate#endif 18537c478bd9Sstevel@tonic-gate movq %gs:CPU_THREAD, %r9 18547c478bd9Sstevel@tonic-gate cmpq %rax, %rsi /* test uaddr < kernelbase */ 1855b737e79eSnn35248 jae 4f 18567c478bd9Sstevel@tonic-gate 18577c478bd9Sstevel@tonic-gate cmpq $0, %rcx /* No non-temporal access? */ 18587c478bd9Sstevel@tonic-gate /* 18597c478bd9Sstevel@tonic-gate * pass lofault value as 4th argument to do_copy_fault 18607c478bd9Sstevel@tonic-gate */ 18617c478bd9Sstevel@tonic-gate leaq _xcopyout_err(%rip), %rcx 18627c478bd9Sstevel@tonic-gate jnz do_copy_fault 18637c478bd9Sstevel@tonic-gate /* 18647c478bd9Sstevel@tonic-gate * Make sure cnt is >= XCOPY_MIN_SIZE bytes 18657c478bd9Sstevel@tonic-gate */ 18667c478bd9Sstevel@tonic-gate cmpq $XCOPY_MIN_SIZE, %rdx 18677c478bd9Sstevel@tonic-gate jb do_copy_fault 18687c478bd9Sstevel@tonic-gate 18697c478bd9Sstevel@tonic-gate /* 18707c478bd9Sstevel@tonic-gate * Make sure src and dst are NTA_ALIGN_SIZE aligned, 18717c478bd9Sstevel@tonic-gate * count is COUNT_ALIGN_SIZE aligned. 18727c478bd9Sstevel@tonic-gate */ 18737c478bd9Sstevel@tonic-gate movq %rdi, %r10 18747c478bd9Sstevel@tonic-gate orq %rsi, %r10 18757c478bd9Sstevel@tonic-gate andq $NTA_ALIGN_MASK, %r10 18767c478bd9Sstevel@tonic-gate orq %rdx, %r10 18777c478bd9Sstevel@tonic-gate andq $COUNT_ALIGN_MASK, %r10 18787c478bd9Sstevel@tonic-gate jnz do_copy_fault 1879b08adf18SBill Holler leaq _xcopyout_nta_err(%rip), %rcx 18807c478bd9Sstevel@tonic-gate jmp do_copy_fault_nta 18817c478bd9Sstevel@tonic-gate 1882b737e79eSnn352484: 1883b737e79eSnn35248 movl $EFAULT, %eax 1884b737e79eSnn35248 jmp 3f 1885b737e79eSnn35248 18867c478bd9Sstevel@tonic-gate /* 18877c478bd9Sstevel@tonic-gate * A fault during do_copy_fault or do_copy_fault_nta is 18887c478bd9Sstevel@tonic-gate * indicated through an errno value in %rax and we iret from the 18897c478bd9Sstevel@tonic-gate * trap handler to here. 18907c478bd9Sstevel@tonic-gate */ 18917c478bd9Sstevel@tonic-gate_xcopyout_err: 1892b08adf18SBill Holler addq $8, %rsp /* pop bcopy_altentry call ret addr */ 1893b08adf18SBill Holler_xcopyout_nta_err: 18947c478bd9Sstevel@tonic-gate movq %r11, T_LOFAULT(%r9) /* restore original lofault */ 18957c478bd9Sstevel@tonic-gate3: 18967c478bd9Sstevel@tonic-gate movq T_COPYOPS(%r9), %r8 18977c478bd9Sstevel@tonic-gate cmpq $0, %r8 18987c478bd9Sstevel@tonic-gate jz 2f 18997c478bd9Sstevel@tonic-gate 19007c478bd9Sstevel@tonic-gate /* 19017c478bd9Sstevel@tonic-gate * reload args for the copyop 19027c478bd9Sstevel@tonic-gate */ 19037c478bd9Sstevel@tonic-gate movq (%rsp), %rdi 19047c478bd9Sstevel@tonic-gate movq 0x8(%rsp), %rsi 19057c478bd9Sstevel@tonic-gate movq 0x10(%rsp), %rdx 19067c478bd9Sstevel@tonic-gate leave 19077c478bd9Sstevel@tonic-gate jmp *CP_XCOPYOUT(%r8) 19087c478bd9Sstevel@tonic-gate 19097c478bd9Sstevel@tonic-gate2: leave 19107c478bd9Sstevel@tonic-gate ret 19117c478bd9Sstevel@tonic-gate SET_SIZE(xcopyout_nta) 19127c478bd9Sstevel@tonic-gate 19137c478bd9Sstevel@tonic-gate#elif defined(__i386) 19147c478bd9Sstevel@tonic-gate 19157c478bd9Sstevel@tonic-gate#define ARG_KADDR 4 19167c478bd9Sstevel@tonic-gate#define ARG_UADDR 8 19177c478bd9Sstevel@tonic-gate#define ARG_COUNT 12 19187c478bd9Sstevel@tonic-gate#define ARG_CACHED 16 19197c478bd9Sstevel@tonic-gate 19207c478bd9Sstevel@tonic-gate ENTRY(xcopyout_nta) 19217c478bd9Sstevel@tonic-gate movl kernelbase, %ecx 19227c478bd9Sstevel@tonic-gate lea _xcopyout_err, %eax 19237c478bd9Sstevel@tonic-gate movl %gs:CPU_THREAD, %edx 19247c478bd9Sstevel@tonic-gate cmpl %ecx, ARG_UADDR(%esp) /* test uaddr < kernelbase */ 1925b737e79eSnn35248 jae 4f 19267c478bd9Sstevel@tonic-gate 19277c478bd9Sstevel@tonic-gate cmpl $0, use_sse_copy /* no sse support */ 19287c478bd9Sstevel@tonic-gate jz do_copy_fault 19297c478bd9Sstevel@tonic-gate 19307c478bd9Sstevel@tonic-gate cmpl $0, ARG_CACHED(%esp) /* copy_cached hint set? */ 19317c478bd9Sstevel@tonic-gate jnz do_copy_fault 19327c478bd9Sstevel@tonic-gate 19337c478bd9Sstevel@tonic-gate /* 19347c478bd9Sstevel@tonic-gate * Make sure cnt is >= XCOPY_MIN_SIZE bytes 19357c478bd9Sstevel@tonic-gate */ 19367c478bd9Sstevel@tonic-gate cmpl $XCOPY_MIN_SIZE, %edx 19377c478bd9Sstevel@tonic-gate jb do_copy_fault 19387c478bd9Sstevel@tonic-gate 19397c478bd9Sstevel@tonic-gate /* 19407c478bd9Sstevel@tonic-gate * Make sure src and dst are NTA_ALIGN_SIZE aligned, 19417c478bd9Sstevel@tonic-gate * count is COUNT_ALIGN_SIZE aligned. 19427c478bd9Sstevel@tonic-gate */ 19437c478bd9Sstevel@tonic-gate movl ARG_UADDR(%esp), %ecx 19447c478bd9Sstevel@tonic-gate orl ARG_KADDR(%esp), %ecx 19457c478bd9Sstevel@tonic-gate andl $NTA_ALIGN_MASK, %ecx 19467c478bd9Sstevel@tonic-gate orl ARG_COUNT(%esp), %ecx 19477c478bd9Sstevel@tonic-gate andl $COUNT_ALIGN_MASK, %ecx 19487c478bd9Sstevel@tonic-gate jnz do_copy_fault 19497c478bd9Sstevel@tonic-gate jmp do_copy_fault_nta 19507c478bd9Sstevel@tonic-gate 1951b737e79eSnn352484: 1952b737e79eSnn35248 movl $EFAULT, %eax 1953b737e79eSnn35248 jmp 3f 1954b737e79eSnn35248 19557c478bd9Sstevel@tonic-gate /* 19567c478bd9Sstevel@tonic-gate * A fault during do_copy_fault or do_copy_fault_nta is 19577c478bd9Sstevel@tonic-gate * indicated through an errno value in %eax and we iret from the 19587c478bd9Sstevel@tonic-gate * trap handler to here. 19597c478bd9Sstevel@tonic-gate */ 19607c478bd9Sstevel@tonic-gate_xcopyout_err: 19617c478bd9Sstevel@tonic-gate / restore the original lofault 19627c478bd9Sstevel@tonic-gate popl %ecx 19637c478bd9Sstevel@tonic-gate popl %edi 19647c478bd9Sstevel@tonic-gate movl %ecx, T_LOFAULT(%edx) / original lofault 19657c478bd9Sstevel@tonic-gate popl %esi 19667c478bd9Sstevel@tonic-gate popl %ebp 19677c478bd9Sstevel@tonic-gate3: 19687c478bd9Sstevel@tonic-gate cmpl $0, T_COPYOPS(%edx) 19697c478bd9Sstevel@tonic-gate jz 2f 19707c478bd9Sstevel@tonic-gate movl T_COPYOPS(%edx), %eax 19717c478bd9Sstevel@tonic-gate jmp *CP_XCOPYOUT(%eax) 19727c478bd9Sstevel@tonic-gate 197385641879Skalai2: rep; ret /* use 2 byte return instruction when branch target */ 197485641879Skalai /* AMD Software Optimization Guide - Section 6.2 */ 19757c478bd9Sstevel@tonic-gate SET_SIZE(xcopyout_nta) 19767c478bd9Sstevel@tonic-gate 19777c478bd9Sstevel@tonic-gate#undef ARG_UADDR 19787c478bd9Sstevel@tonic-gate#undef ARG_KADDR 19797c478bd9Sstevel@tonic-gate#undef ARG_COUNT 19807c478bd9Sstevel@tonic-gate#undef ARG_CACHED 19817c478bd9Sstevel@tonic-gate 19827c478bd9Sstevel@tonic-gate#endif /* __i386 */ 19837c478bd9Sstevel@tonic-gate#endif /* __lint */ 19847c478bd9Sstevel@tonic-gate 19857c478bd9Sstevel@tonic-gate/* 19867c478bd9Sstevel@tonic-gate * Copy a null terminated string from one point to another in 19877c478bd9Sstevel@tonic-gate * the kernel address space. 19887c478bd9Sstevel@tonic-gate */ 19897c478bd9Sstevel@tonic-gate 19907c478bd9Sstevel@tonic-gate#if defined(__lint) 19917c478bd9Sstevel@tonic-gate 19927c478bd9Sstevel@tonic-gate/* ARGSUSED */ 19937c478bd9Sstevel@tonic-gateint 19947c478bd9Sstevel@tonic-gatecopystr(const char *from, char *to, size_t maxlength, size_t *lencopied) 19957c478bd9Sstevel@tonic-gate{ return (0); } 19967c478bd9Sstevel@tonic-gate 19977c478bd9Sstevel@tonic-gate#else /* __lint */ 19987c478bd9Sstevel@tonic-gate 19997c478bd9Sstevel@tonic-gate#if defined(__amd64) 20007c478bd9Sstevel@tonic-gate 20017c478bd9Sstevel@tonic-gate ENTRY(copystr) 20027c478bd9Sstevel@tonic-gate pushq %rbp 20037c478bd9Sstevel@tonic-gate movq %rsp, %rbp 20047c478bd9Sstevel@tonic-gate#ifdef DEBUG 20057c478bd9Sstevel@tonic-gate movq kernelbase(%rip), %rax 20067c478bd9Sstevel@tonic-gate cmpq %rax, %rdi /* %rdi = from */ 20077c478bd9Sstevel@tonic-gate jb 0f 20087c478bd9Sstevel@tonic-gate cmpq %rax, %rsi /* %rsi = to */ 20097c478bd9Sstevel@tonic-gate jnb 1f 20107c478bd9Sstevel@tonic-gate0: leaq .copystr_panic_msg(%rip), %rdi 20117c478bd9Sstevel@tonic-gate xorl %eax, %eax 20127c478bd9Sstevel@tonic-gate call panic 20137c478bd9Sstevel@tonic-gate1: 20147c478bd9Sstevel@tonic-gate#endif 20157c478bd9Sstevel@tonic-gate movq %gs:CPU_THREAD, %r9 20167c478bd9Sstevel@tonic-gate movq T_LOFAULT(%r9), %r8 /* pass current lofault value as */ 20177c478bd9Sstevel@tonic-gate /* 5th argument to do_copystr */ 20187c478bd9Sstevel@tonic-gatedo_copystr: 20197c478bd9Sstevel@tonic-gate movq %gs:CPU_THREAD, %r9 /* %r9 = thread addr */ 20207c478bd9Sstevel@tonic-gate movq T_LOFAULT(%r9), %r11 /* save the current lofault */ 20217c478bd9Sstevel@tonic-gate movq %r8, T_LOFAULT(%r9) /* new lofault */ 20227c478bd9Sstevel@tonic-gate 20237c478bd9Sstevel@tonic-gate movq %rdx, %r8 /* save maxlength */ 20247c478bd9Sstevel@tonic-gate 20257c478bd9Sstevel@tonic-gate cmpq $0, %rdx /* %rdx = maxlength */ 20267c478bd9Sstevel@tonic-gate je copystr_enametoolong /* maxlength == 0 */ 20277c478bd9Sstevel@tonic-gate 20287c478bd9Sstevel@tonic-gatecopystr_loop: 20297c478bd9Sstevel@tonic-gate decq %r8 20307c478bd9Sstevel@tonic-gate movb (%rdi), %al 20317c478bd9Sstevel@tonic-gate incq %rdi 20327c478bd9Sstevel@tonic-gate movb %al, (%rsi) 20337c478bd9Sstevel@tonic-gate incq %rsi 20347c478bd9Sstevel@tonic-gate cmpb $0, %al 20357c478bd9Sstevel@tonic-gate je copystr_null /* null char */ 20367c478bd9Sstevel@tonic-gate cmpq $0, %r8 20377c478bd9Sstevel@tonic-gate jne copystr_loop 20387c478bd9Sstevel@tonic-gate 20397c478bd9Sstevel@tonic-gatecopystr_enametoolong: 20407c478bd9Sstevel@tonic-gate movl $ENAMETOOLONG, %eax 20417c478bd9Sstevel@tonic-gate jmp copystr_out 20427c478bd9Sstevel@tonic-gate 20437c478bd9Sstevel@tonic-gatecopystr_null: 20447c478bd9Sstevel@tonic-gate xorl %eax, %eax /* no error */ 20457c478bd9Sstevel@tonic-gate 20467c478bd9Sstevel@tonic-gatecopystr_out: 20477c478bd9Sstevel@tonic-gate cmpq $0, %rcx /* want length? */ 20487c478bd9Sstevel@tonic-gate je copystr_done /* no */ 20497c478bd9Sstevel@tonic-gate subq %r8, %rdx /* compute length and store it */ 20507c478bd9Sstevel@tonic-gate movq %rdx, (%rcx) 20517c478bd9Sstevel@tonic-gate 20527c478bd9Sstevel@tonic-gatecopystr_done: 20537c478bd9Sstevel@tonic-gate movq %r11, T_LOFAULT(%r9) /* restore the original lofault */ 20547c478bd9Sstevel@tonic-gate leave 20557c478bd9Sstevel@tonic-gate ret 20567c478bd9Sstevel@tonic-gate SET_SIZE(copystr) 20577c478bd9Sstevel@tonic-gate 20587c478bd9Sstevel@tonic-gate#elif defined(__i386) 20597c478bd9Sstevel@tonic-gate 20607c478bd9Sstevel@tonic-gate#define ARG_FROM 8 20617c478bd9Sstevel@tonic-gate#define ARG_TO 12 20627c478bd9Sstevel@tonic-gate#define ARG_MAXLEN 16 20637c478bd9Sstevel@tonic-gate#define ARG_LENCOPIED 20 20647c478bd9Sstevel@tonic-gate 20657c478bd9Sstevel@tonic-gate ENTRY(copystr) 20667c478bd9Sstevel@tonic-gate#ifdef DEBUG 20677c478bd9Sstevel@tonic-gate pushl %ebp 20687c478bd9Sstevel@tonic-gate movl %esp, %ebp 20697c478bd9Sstevel@tonic-gate movl kernelbase, %eax 20707c478bd9Sstevel@tonic-gate cmpl %eax, ARG_FROM(%esp) 20717c478bd9Sstevel@tonic-gate jb 0f 20727c478bd9Sstevel@tonic-gate cmpl %eax, ARG_TO(%esp) 20737c478bd9Sstevel@tonic-gate jnb 1f 20747c478bd9Sstevel@tonic-gate0: pushl $.copystr_panic_msg 20757c478bd9Sstevel@tonic-gate call panic 20767c478bd9Sstevel@tonic-gate1: popl %ebp 20777c478bd9Sstevel@tonic-gate#endif 20787c478bd9Sstevel@tonic-gate /* get the current lofault address */ 20797c478bd9Sstevel@tonic-gate movl %gs:CPU_THREAD, %eax 20807c478bd9Sstevel@tonic-gate movl T_LOFAULT(%eax), %eax 20817c478bd9Sstevel@tonic-gatedo_copystr: 20827c478bd9Sstevel@tonic-gate pushl %ebp /* setup stack frame */ 20837c478bd9Sstevel@tonic-gate movl %esp, %ebp 20847c478bd9Sstevel@tonic-gate pushl %ebx /* save registers */ 20857c478bd9Sstevel@tonic-gate pushl %edi 20867c478bd9Sstevel@tonic-gate 20877c478bd9Sstevel@tonic-gate movl %gs:CPU_THREAD, %ebx 20887c478bd9Sstevel@tonic-gate movl T_LOFAULT(%ebx), %edi 20897c478bd9Sstevel@tonic-gate pushl %edi /* save the current lofault */ 20907c478bd9Sstevel@tonic-gate movl %eax, T_LOFAULT(%ebx) /* new lofault */ 20917c478bd9Sstevel@tonic-gate 20927c478bd9Sstevel@tonic-gate movl ARG_MAXLEN(%ebp), %ecx 20937c478bd9Sstevel@tonic-gate cmpl $0, %ecx 20947c478bd9Sstevel@tonic-gate je copystr_enametoolong /* maxlength == 0 */ 20957c478bd9Sstevel@tonic-gate 20967c478bd9Sstevel@tonic-gate movl ARG_FROM(%ebp), %ebx /* source address */ 20977c478bd9Sstevel@tonic-gate movl ARG_TO(%ebp), %edx /* destination address */ 20987c478bd9Sstevel@tonic-gate 20997c478bd9Sstevel@tonic-gatecopystr_loop: 21007c478bd9Sstevel@tonic-gate decl %ecx 21017c478bd9Sstevel@tonic-gate movb (%ebx), %al 21027c478bd9Sstevel@tonic-gate incl %ebx 21037c478bd9Sstevel@tonic-gate movb %al, (%edx) 21047c478bd9Sstevel@tonic-gate incl %edx 21057c478bd9Sstevel@tonic-gate cmpb $0, %al 21067c478bd9Sstevel@tonic-gate je copystr_null /* null char */ 21077c478bd9Sstevel@tonic-gate cmpl $0, %ecx 21087c478bd9Sstevel@tonic-gate jne copystr_loop 21097c478bd9Sstevel@tonic-gate 21107c478bd9Sstevel@tonic-gatecopystr_enametoolong: 21117c478bd9Sstevel@tonic-gate movl $ENAMETOOLONG, %eax 21127c478bd9Sstevel@tonic-gate jmp copystr_out 21137c478bd9Sstevel@tonic-gate 21147c478bd9Sstevel@tonic-gatecopystr_null: 21157c478bd9Sstevel@tonic-gate xorl %eax, %eax /* no error */ 21167c478bd9Sstevel@tonic-gate 21177c478bd9Sstevel@tonic-gatecopystr_out: 21187c478bd9Sstevel@tonic-gate cmpl $0, ARG_LENCOPIED(%ebp) /* want length? */ 21197c478bd9Sstevel@tonic-gate je copystr_done /* no */ 21207c478bd9Sstevel@tonic-gate movl ARG_MAXLEN(%ebp), %edx 21217c478bd9Sstevel@tonic-gate subl %ecx, %edx /* compute length and store it */ 21227c478bd9Sstevel@tonic-gate movl ARG_LENCOPIED(%ebp), %ecx 21237c478bd9Sstevel@tonic-gate movl %edx, (%ecx) 21247c478bd9Sstevel@tonic-gate 21257c478bd9Sstevel@tonic-gatecopystr_done: 21267c478bd9Sstevel@tonic-gate popl %edi 21277c478bd9Sstevel@tonic-gate movl %gs:CPU_THREAD, %ebx 21287c478bd9Sstevel@tonic-gate movl %edi, T_LOFAULT(%ebx) /* restore the original lofault */ 21297c478bd9Sstevel@tonic-gate 21307c478bd9Sstevel@tonic-gate popl %edi 21317c478bd9Sstevel@tonic-gate popl %ebx 21327c478bd9Sstevel@tonic-gate popl %ebp 21337c478bd9Sstevel@tonic-gate ret 21347c478bd9Sstevel@tonic-gate SET_SIZE(copystr) 21357c478bd9Sstevel@tonic-gate 21367c478bd9Sstevel@tonic-gate#undef ARG_FROM 21377c478bd9Sstevel@tonic-gate#undef ARG_TO 21387c478bd9Sstevel@tonic-gate#undef ARG_MAXLEN 21397c478bd9Sstevel@tonic-gate#undef ARG_LENCOPIED 21407c478bd9Sstevel@tonic-gate 21417c478bd9Sstevel@tonic-gate#endif /* __i386 */ 21427c478bd9Sstevel@tonic-gate#endif /* __lint */ 21437c478bd9Sstevel@tonic-gate 21447c478bd9Sstevel@tonic-gate/* 21457c478bd9Sstevel@tonic-gate * Copy a null terminated string from the user address space into 21467c478bd9Sstevel@tonic-gate * the kernel address space. 21477c478bd9Sstevel@tonic-gate */ 21487c478bd9Sstevel@tonic-gate 21497c478bd9Sstevel@tonic-gate#if defined(__lint) 21507c478bd9Sstevel@tonic-gate 21517c478bd9Sstevel@tonic-gate/* ARGSUSED */ 21527c478bd9Sstevel@tonic-gateint 21537c478bd9Sstevel@tonic-gatecopyinstr(const char *uaddr, char *kaddr, size_t maxlength, 21547c478bd9Sstevel@tonic-gate size_t *lencopied) 21557c478bd9Sstevel@tonic-gate{ return (0); } 21567c478bd9Sstevel@tonic-gate 21577c478bd9Sstevel@tonic-gate#else /* __lint */ 21587c478bd9Sstevel@tonic-gate 21597c478bd9Sstevel@tonic-gate#if defined(__amd64) 21607c478bd9Sstevel@tonic-gate 21617c478bd9Sstevel@tonic-gate ENTRY(copyinstr) 21627c478bd9Sstevel@tonic-gate pushq %rbp 21637c478bd9Sstevel@tonic-gate movq %rsp, %rbp 21647c478bd9Sstevel@tonic-gate subq $32, %rsp 21657c478bd9Sstevel@tonic-gate 21667c478bd9Sstevel@tonic-gate /* 21677c478bd9Sstevel@tonic-gate * save args in case we trap and need to rerun as a copyop 21687c478bd9Sstevel@tonic-gate */ 21697c478bd9Sstevel@tonic-gate movq %rdi, (%rsp) 21707c478bd9Sstevel@tonic-gate movq %rsi, 0x8(%rsp) 21717c478bd9Sstevel@tonic-gate movq %rdx, 0x10(%rsp) 21727c478bd9Sstevel@tonic-gate movq %rcx, 0x18(%rsp) 21737c478bd9Sstevel@tonic-gate 21747c478bd9Sstevel@tonic-gate movq kernelbase(%rip), %rax 21757c478bd9Sstevel@tonic-gate#ifdef DEBUG 21767c478bd9Sstevel@tonic-gate cmpq %rax, %rsi /* %rsi = kaddr */ 21777c478bd9Sstevel@tonic-gate jnb 1f 21787c478bd9Sstevel@tonic-gate leaq .copyinstr_panic_msg(%rip), %rdi 21797c478bd9Sstevel@tonic-gate xorl %eax, %eax 21807c478bd9Sstevel@tonic-gate call panic 21817c478bd9Sstevel@tonic-gate1: 21827c478bd9Sstevel@tonic-gate#endif 21837c478bd9Sstevel@tonic-gate /* 21847c478bd9Sstevel@tonic-gate * pass lofault value as 5th argument to do_copystr 21857c478bd9Sstevel@tonic-gate */ 21867c478bd9Sstevel@tonic-gate leaq _copyinstr_error(%rip), %r8 21877c478bd9Sstevel@tonic-gate 21887c478bd9Sstevel@tonic-gate cmpq %rax, %rdi /* test uaddr < kernelbase */ 21897c478bd9Sstevel@tonic-gate jb do_copystr 21907c478bd9Sstevel@tonic-gate movq %gs:CPU_THREAD, %r9 21917c478bd9Sstevel@tonic-gate jmp 3f 21927c478bd9Sstevel@tonic-gate 21937c478bd9Sstevel@tonic-gate_copyinstr_error: 21947c478bd9Sstevel@tonic-gate movq %r11, T_LOFAULT(%r9) /* restore original lofault */ 21957c478bd9Sstevel@tonic-gate3: 21967c478bd9Sstevel@tonic-gate movq T_COPYOPS(%r9), %rax 21977c478bd9Sstevel@tonic-gate cmpq $0, %rax 21987c478bd9Sstevel@tonic-gate jz 2f 21997c478bd9Sstevel@tonic-gate 22007c478bd9Sstevel@tonic-gate /* 22017c478bd9Sstevel@tonic-gate * reload args for the copyop 22027c478bd9Sstevel@tonic-gate */ 22037c478bd9Sstevel@tonic-gate movq (%rsp), %rdi 22047c478bd9Sstevel@tonic-gate movq 0x8(%rsp), %rsi 22057c478bd9Sstevel@tonic-gate movq 0x10(%rsp), %rdx 22067c478bd9Sstevel@tonic-gate movq 0x18(%rsp), %rcx 22077c478bd9Sstevel@tonic-gate leave 22087c478bd9Sstevel@tonic-gate jmp *CP_COPYINSTR(%rax) 22097c478bd9Sstevel@tonic-gate 22107c478bd9Sstevel@tonic-gate2: movl $EFAULT, %eax /* return EFAULT */ 22117c478bd9Sstevel@tonic-gate leave 22127c478bd9Sstevel@tonic-gate ret 22137c478bd9Sstevel@tonic-gate SET_SIZE(copyinstr) 22147c478bd9Sstevel@tonic-gate 22157c478bd9Sstevel@tonic-gate#elif defined(__i386) 22167c478bd9Sstevel@tonic-gate 22177c478bd9Sstevel@tonic-gate#define ARG_UADDR 4 22187c478bd9Sstevel@tonic-gate#define ARG_KADDR 8 22197c478bd9Sstevel@tonic-gate 22207c478bd9Sstevel@tonic-gate ENTRY(copyinstr) 22217c478bd9Sstevel@tonic-gate movl kernelbase, %ecx 22227c478bd9Sstevel@tonic-gate#ifdef DEBUG 22237c478bd9Sstevel@tonic-gate cmpl %ecx, ARG_KADDR(%esp) 22247c478bd9Sstevel@tonic-gate jnb 1f 22257c478bd9Sstevel@tonic-gate pushl %ebp 22267c478bd9Sstevel@tonic-gate movl %esp, %ebp 22277c478bd9Sstevel@tonic-gate pushl $.copyinstr_panic_msg 22287c478bd9Sstevel@tonic-gate call panic 22297c478bd9Sstevel@tonic-gate1: 22307c478bd9Sstevel@tonic-gate#endif 22317c478bd9Sstevel@tonic-gate lea _copyinstr_error, %eax 22327c478bd9Sstevel@tonic-gate cmpl %ecx, ARG_UADDR(%esp) /* test uaddr < kernelbase */ 22337c478bd9Sstevel@tonic-gate jb do_copystr 22347c478bd9Sstevel@tonic-gate movl %gs:CPU_THREAD, %edx 22357c478bd9Sstevel@tonic-gate jmp 3f 22367c478bd9Sstevel@tonic-gate 22377c478bd9Sstevel@tonic-gate_copyinstr_error: 22387c478bd9Sstevel@tonic-gate popl %edi 22397c478bd9Sstevel@tonic-gate movl %gs:CPU_THREAD, %edx 22407c478bd9Sstevel@tonic-gate movl %edi, T_LOFAULT(%edx) /* original lofault */ 22417c478bd9Sstevel@tonic-gate 22427c478bd9Sstevel@tonic-gate popl %edi 22437c478bd9Sstevel@tonic-gate popl %ebx 22447c478bd9Sstevel@tonic-gate popl %ebp 22457c478bd9Sstevel@tonic-gate3: 22467c478bd9Sstevel@tonic-gate movl T_COPYOPS(%edx), %eax 22477c478bd9Sstevel@tonic-gate cmpl $0, %eax 22487c478bd9Sstevel@tonic-gate jz 2f 22497c478bd9Sstevel@tonic-gate jmp *CP_COPYINSTR(%eax) 22507c478bd9Sstevel@tonic-gate 22517c478bd9Sstevel@tonic-gate2: movl $EFAULT, %eax /* return EFAULT */ 22527c478bd9Sstevel@tonic-gate ret 22537c478bd9Sstevel@tonic-gate SET_SIZE(copyinstr) 22547c478bd9Sstevel@tonic-gate 22557c478bd9Sstevel@tonic-gate#undef ARG_UADDR 22567c478bd9Sstevel@tonic-gate#undef ARG_KADDR 22577c478bd9Sstevel@tonic-gate 22587c478bd9Sstevel@tonic-gate#endif /* __i386 */ 22597c478bd9Sstevel@tonic-gate#endif /* __lint */ 22607c478bd9Sstevel@tonic-gate 22617c478bd9Sstevel@tonic-gate/* 22627c478bd9Sstevel@tonic-gate * Copy a null terminated string from the kernel 22637c478bd9Sstevel@tonic-gate * address space to the user address space. 22647c478bd9Sstevel@tonic-gate */ 22657c478bd9Sstevel@tonic-gate 22667c478bd9Sstevel@tonic-gate#if defined(__lint) 22677c478bd9Sstevel@tonic-gate 22687c478bd9Sstevel@tonic-gate/* ARGSUSED */ 22697c478bd9Sstevel@tonic-gateint 22707c478bd9Sstevel@tonic-gatecopyoutstr(const char *kaddr, char *uaddr, size_t maxlength, 22717c478bd9Sstevel@tonic-gate size_t *lencopied) 22727c478bd9Sstevel@tonic-gate{ return (0); } 22737c478bd9Sstevel@tonic-gate 22747c478bd9Sstevel@tonic-gate#else /* __lint */ 22757c478bd9Sstevel@tonic-gate 22767c478bd9Sstevel@tonic-gate#if defined(__amd64) 22777c478bd9Sstevel@tonic-gate 22787c478bd9Sstevel@tonic-gate ENTRY(copyoutstr) 22797c478bd9Sstevel@tonic-gate pushq %rbp 22807c478bd9Sstevel@tonic-gate movq %rsp, %rbp 22817c478bd9Sstevel@tonic-gate subq $32, %rsp 22827c478bd9Sstevel@tonic-gate 22837c478bd9Sstevel@tonic-gate /* 22847c478bd9Sstevel@tonic-gate * save args in case we trap and need to rerun as a copyop 22857c478bd9Sstevel@tonic-gate */ 22867c478bd9Sstevel@tonic-gate movq %rdi, (%rsp) 22877c478bd9Sstevel@tonic-gate movq %rsi, 0x8(%rsp) 22887c478bd9Sstevel@tonic-gate movq %rdx, 0x10(%rsp) 22897c478bd9Sstevel@tonic-gate movq %rcx, 0x18(%rsp) 22907c478bd9Sstevel@tonic-gate 22917c478bd9Sstevel@tonic-gate movq kernelbase(%rip), %rax 22927c478bd9Sstevel@tonic-gate#ifdef DEBUG 22937c478bd9Sstevel@tonic-gate cmpq %rax, %rdi /* %rdi = kaddr */ 22947c478bd9Sstevel@tonic-gate jnb 1f 22957c478bd9Sstevel@tonic-gate leaq .copyoutstr_panic_msg(%rip), %rdi 22967c478bd9Sstevel@tonic-gate jmp call_panic /* setup stack and call panic */ 22977c478bd9Sstevel@tonic-gate1: 22987c478bd9Sstevel@tonic-gate#endif 22997c478bd9Sstevel@tonic-gate /* 23007c478bd9Sstevel@tonic-gate * pass lofault value as 5th argument to do_copystr 23017c478bd9Sstevel@tonic-gate */ 23027c478bd9Sstevel@tonic-gate leaq _copyoutstr_error(%rip), %r8 23037c478bd9Sstevel@tonic-gate 23047c478bd9Sstevel@tonic-gate cmpq %rax, %rsi /* test uaddr < kernelbase */ 23057c478bd9Sstevel@tonic-gate jb do_copystr 23067c478bd9Sstevel@tonic-gate movq %gs:CPU_THREAD, %r9 23077c478bd9Sstevel@tonic-gate jmp 3f 23087c478bd9Sstevel@tonic-gate 23097c478bd9Sstevel@tonic-gate_copyoutstr_error: 23107c478bd9Sstevel@tonic-gate movq %r11, T_LOFAULT(%r9) /* restore the original lofault */ 23117c478bd9Sstevel@tonic-gate3: 23127c478bd9Sstevel@tonic-gate movq T_COPYOPS(%r9), %rax 23137c478bd9Sstevel@tonic-gate cmpq $0, %rax 23147c478bd9Sstevel@tonic-gate jz 2f 23157c478bd9Sstevel@tonic-gate 23167c478bd9Sstevel@tonic-gate /* 23177c478bd9Sstevel@tonic-gate * reload args for the copyop 23187c478bd9Sstevel@tonic-gate */ 23197c478bd9Sstevel@tonic-gate movq (%rsp), %rdi 23207c478bd9Sstevel@tonic-gate movq 0x8(%rsp), %rsi 23217c478bd9Sstevel@tonic-gate movq 0x10(%rsp), %rdx 23227c478bd9Sstevel@tonic-gate movq 0x18(%rsp), %rcx 23237c478bd9Sstevel@tonic-gate leave 23247c478bd9Sstevel@tonic-gate jmp *CP_COPYOUTSTR(%rax) 23257c478bd9Sstevel@tonic-gate 23267c478bd9Sstevel@tonic-gate2: movl $EFAULT, %eax /* return EFAULT */ 23277c478bd9Sstevel@tonic-gate leave 23287c478bd9Sstevel@tonic-gate ret 23297c478bd9Sstevel@tonic-gate SET_SIZE(copyoutstr) 23307c478bd9Sstevel@tonic-gate 23317c478bd9Sstevel@tonic-gate#elif defined(__i386) 23327c478bd9Sstevel@tonic-gate 23337c478bd9Sstevel@tonic-gate#define ARG_KADDR 4 23347c478bd9Sstevel@tonic-gate#define ARG_UADDR 8 23357c478bd9Sstevel@tonic-gate 23367c478bd9Sstevel@tonic-gate ENTRY(copyoutstr) 23377c478bd9Sstevel@tonic-gate movl kernelbase, %ecx 23387c478bd9Sstevel@tonic-gate#ifdef DEBUG 23397c478bd9Sstevel@tonic-gate cmpl %ecx, ARG_KADDR(%esp) 23407c478bd9Sstevel@tonic-gate jnb 1f 23417c478bd9Sstevel@tonic-gate pushl %ebp 23427c478bd9Sstevel@tonic-gate movl %esp, %ebp 23437c478bd9Sstevel@tonic-gate pushl $.copyoutstr_panic_msg 23447c478bd9Sstevel@tonic-gate call panic 23457c478bd9Sstevel@tonic-gate1: 23467c478bd9Sstevel@tonic-gate#endif 23477c478bd9Sstevel@tonic-gate lea _copyoutstr_error, %eax 23487c478bd9Sstevel@tonic-gate cmpl %ecx, ARG_UADDR(%esp) /* test uaddr < kernelbase */ 23497c478bd9Sstevel@tonic-gate jb do_copystr 23507c478bd9Sstevel@tonic-gate movl %gs:CPU_THREAD, %edx 23517c478bd9Sstevel@tonic-gate jmp 3f 23527c478bd9Sstevel@tonic-gate 23537c478bd9Sstevel@tonic-gate_copyoutstr_error: 23547c478bd9Sstevel@tonic-gate popl %edi 23557c478bd9Sstevel@tonic-gate movl %gs:CPU_THREAD, %edx 23567c478bd9Sstevel@tonic-gate movl %edi, T_LOFAULT(%edx) /* restore the original lofault */ 23577c478bd9Sstevel@tonic-gate 23587c478bd9Sstevel@tonic-gate popl %edi 23597c478bd9Sstevel@tonic-gate popl %ebx 23607c478bd9Sstevel@tonic-gate popl %ebp 23617c478bd9Sstevel@tonic-gate3: 23627c478bd9Sstevel@tonic-gate movl T_COPYOPS(%edx), %eax 23637c478bd9Sstevel@tonic-gate cmpl $0, %eax 23647c478bd9Sstevel@tonic-gate jz 2f 23657c478bd9Sstevel@tonic-gate jmp *CP_COPYOUTSTR(%eax) 23667c478bd9Sstevel@tonic-gate 23677c478bd9Sstevel@tonic-gate2: movl $EFAULT, %eax /* return EFAULT */ 23687c478bd9Sstevel@tonic-gate ret 23697c478bd9Sstevel@tonic-gate SET_SIZE(copyoutstr) 23707c478bd9Sstevel@tonic-gate 23717c478bd9Sstevel@tonic-gate#undef ARG_KADDR 23727c478bd9Sstevel@tonic-gate#undef ARG_UADDR 23737c478bd9Sstevel@tonic-gate 23747c478bd9Sstevel@tonic-gate#endif /* __i386 */ 23757c478bd9Sstevel@tonic-gate#endif /* __lint */ 23767c478bd9Sstevel@tonic-gate 23777c478bd9Sstevel@tonic-gate/* 23787c478bd9Sstevel@tonic-gate * Since all of the fuword() variants are so similar, we have a macro to spit 23797c478bd9Sstevel@tonic-gate * them out. This allows us to create DTrace-unobservable functions easily. 23807c478bd9Sstevel@tonic-gate */ 23817c478bd9Sstevel@tonic-gate 23827c478bd9Sstevel@tonic-gate#if defined(__lint) 23837c478bd9Sstevel@tonic-gate 23847c478bd9Sstevel@tonic-gate#if defined(__amd64) 23857c478bd9Sstevel@tonic-gate 23867c478bd9Sstevel@tonic-gate/* ARGSUSED */ 23877c478bd9Sstevel@tonic-gateint 23887c478bd9Sstevel@tonic-gatefuword64(const void *addr, uint64_t *dst) 23897c478bd9Sstevel@tonic-gate{ return (0); } 23907c478bd9Sstevel@tonic-gate 23917c478bd9Sstevel@tonic-gate#endif 23927c478bd9Sstevel@tonic-gate 23937c478bd9Sstevel@tonic-gate/* ARGSUSED */ 23947c478bd9Sstevel@tonic-gateint 23957c478bd9Sstevel@tonic-gatefuword32(const void *addr, uint32_t *dst) 23967c478bd9Sstevel@tonic-gate{ return (0); } 23977c478bd9Sstevel@tonic-gate 23987c478bd9Sstevel@tonic-gate/* ARGSUSED */ 23997c478bd9Sstevel@tonic-gateint 24007c478bd9Sstevel@tonic-gatefuword16(const void *addr, uint16_t *dst) 24017c478bd9Sstevel@tonic-gate{ return (0); } 24027c478bd9Sstevel@tonic-gate 24037c478bd9Sstevel@tonic-gate/* ARGSUSED */ 24047c478bd9Sstevel@tonic-gateint 24057c478bd9Sstevel@tonic-gatefuword8(const void *addr, uint8_t *dst) 24067c478bd9Sstevel@tonic-gate{ return (0); } 24077c478bd9Sstevel@tonic-gate 24087c478bd9Sstevel@tonic-gate#else /* __lint */ 24097c478bd9Sstevel@tonic-gate 24107c478bd9Sstevel@tonic-gate#if defined(__amd64) 24117c478bd9Sstevel@tonic-gate 24127c478bd9Sstevel@tonic-gate/* 24137c478bd9Sstevel@tonic-gate * (Note that we don't save and reload the arguments here 24147c478bd9Sstevel@tonic-gate * because their values are not altered in the copy path) 24157c478bd9Sstevel@tonic-gate */ 24167c478bd9Sstevel@tonic-gate 24177c478bd9Sstevel@tonic-gate#define FUWORD(NAME, INSTR, REG, COPYOP) \ 24187c478bd9Sstevel@tonic-gate ENTRY(NAME) \ 24197c478bd9Sstevel@tonic-gate movq %gs:CPU_THREAD, %r9; \ 24207c478bd9Sstevel@tonic-gate cmpq kernelbase(%rip), %rdi; \ 24217c478bd9Sstevel@tonic-gate jae 1f; \ 24227c478bd9Sstevel@tonic-gate leaq _flt_/**/NAME, %rdx; \ 24237c478bd9Sstevel@tonic-gate movq %rdx, T_LOFAULT(%r9); \ 24247c478bd9Sstevel@tonic-gate INSTR (%rdi), REG; \ 24257c478bd9Sstevel@tonic-gate movq $0, T_LOFAULT(%r9); \ 24267c478bd9Sstevel@tonic-gate INSTR REG, (%rsi); \ 24277c478bd9Sstevel@tonic-gate xorl %eax, %eax; \ 24287c478bd9Sstevel@tonic-gate ret; \ 24297c478bd9Sstevel@tonic-gate_flt_/**/NAME: \ 24307c478bd9Sstevel@tonic-gate movq $0, T_LOFAULT(%r9); \ 24317c478bd9Sstevel@tonic-gate1: \ 24327c478bd9Sstevel@tonic-gate movq T_COPYOPS(%r9), %rax; \ 24337c478bd9Sstevel@tonic-gate cmpq $0, %rax; \ 24347c478bd9Sstevel@tonic-gate jz 2f; \ 24357c478bd9Sstevel@tonic-gate jmp *COPYOP(%rax); \ 24367c478bd9Sstevel@tonic-gate2: \ 24377c478bd9Sstevel@tonic-gate movl $-1, %eax; \ 24387c478bd9Sstevel@tonic-gate ret; \ 24397c478bd9Sstevel@tonic-gate SET_SIZE(NAME) 24407c478bd9Sstevel@tonic-gate 24417c478bd9Sstevel@tonic-gate FUWORD(fuword64, movq, %rax, CP_FUWORD64) 24427c478bd9Sstevel@tonic-gate FUWORD(fuword32, movl, %eax, CP_FUWORD32) 24437c478bd9Sstevel@tonic-gate FUWORD(fuword16, movw, %ax, CP_FUWORD16) 24447c478bd9Sstevel@tonic-gate FUWORD(fuword8, movb, %al, CP_FUWORD8) 24457c478bd9Sstevel@tonic-gate 24467c478bd9Sstevel@tonic-gate#elif defined(__i386) 24477c478bd9Sstevel@tonic-gate 24487c478bd9Sstevel@tonic-gate#define FUWORD(NAME, INSTR, REG, COPYOP) \ 24497c478bd9Sstevel@tonic-gate ENTRY(NAME) \ 24507c478bd9Sstevel@tonic-gate movl %gs:CPU_THREAD, %ecx; \ 24517c478bd9Sstevel@tonic-gate movl kernelbase, %eax; \ 24527c478bd9Sstevel@tonic-gate cmpl %eax, 4(%esp); \ 24537c478bd9Sstevel@tonic-gate jae 1f; \ 24547c478bd9Sstevel@tonic-gate lea _flt_/**/NAME, %edx; \ 24557c478bd9Sstevel@tonic-gate movl %edx, T_LOFAULT(%ecx); \ 24567c478bd9Sstevel@tonic-gate movl 4(%esp), %eax; \ 24577c478bd9Sstevel@tonic-gate movl 8(%esp), %edx; \ 24587c478bd9Sstevel@tonic-gate INSTR (%eax), REG; \ 24597c478bd9Sstevel@tonic-gate movl $0, T_LOFAULT(%ecx); \ 24607c478bd9Sstevel@tonic-gate INSTR REG, (%edx); \ 24617c478bd9Sstevel@tonic-gate xorl %eax, %eax; \ 24627c478bd9Sstevel@tonic-gate ret; \ 24637c478bd9Sstevel@tonic-gate_flt_/**/NAME: \ 24647c478bd9Sstevel@tonic-gate movl $0, T_LOFAULT(%ecx); \ 24657c478bd9Sstevel@tonic-gate1: \ 24667c478bd9Sstevel@tonic-gate movl T_COPYOPS(%ecx), %eax; \ 24677c478bd9Sstevel@tonic-gate cmpl $0, %eax; \ 24687c478bd9Sstevel@tonic-gate jz 2f; \ 24697c478bd9Sstevel@tonic-gate jmp *COPYOP(%eax); \ 24707c478bd9Sstevel@tonic-gate2: \ 24717c478bd9Sstevel@tonic-gate movl $-1, %eax; \ 24727c478bd9Sstevel@tonic-gate ret; \ 24737c478bd9Sstevel@tonic-gate SET_SIZE(NAME) 24747c478bd9Sstevel@tonic-gate 24757c478bd9Sstevel@tonic-gate FUWORD(fuword32, movl, %eax, CP_FUWORD32) 24767c478bd9Sstevel@tonic-gate FUWORD(fuword16, movw, %ax, CP_FUWORD16) 24777c478bd9Sstevel@tonic-gate FUWORD(fuword8, movb, %al, CP_FUWORD8) 24787c478bd9Sstevel@tonic-gate 24797c478bd9Sstevel@tonic-gate#endif /* __i386 */ 24807c478bd9Sstevel@tonic-gate 24817c478bd9Sstevel@tonic-gate#undef FUWORD 24827c478bd9Sstevel@tonic-gate 24837c478bd9Sstevel@tonic-gate#endif /* __lint */ 24847c478bd9Sstevel@tonic-gate 24857c478bd9Sstevel@tonic-gate/* 24867c478bd9Sstevel@tonic-gate * Set user word. 24877c478bd9Sstevel@tonic-gate */ 24887c478bd9Sstevel@tonic-gate 24897c478bd9Sstevel@tonic-gate#if defined(__lint) 24907c478bd9Sstevel@tonic-gate 24917c478bd9Sstevel@tonic-gate#if defined(__amd64) 24927c478bd9Sstevel@tonic-gate 24937c478bd9Sstevel@tonic-gate/* ARGSUSED */ 24947c478bd9Sstevel@tonic-gateint 24957c478bd9Sstevel@tonic-gatesuword64(void *addr, uint64_t value) 24967c478bd9Sstevel@tonic-gate{ return (0); } 24977c478bd9Sstevel@tonic-gate 24987c478bd9Sstevel@tonic-gate#endif 24997c478bd9Sstevel@tonic-gate 25007c478bd9Sstevel@tonic-gate/* ARGSUSED */ 25017c478bd9Sstevel@tonic-gateint 25027c478bd9Sstevel@tonic-gatesuword32(void *addr, uint32_t value) 25037c478bd9Sstevel@tonic-gate{ return (0); } 25047c478bd9Sstevel@tonic-gate 25057c478bd9Sstevel@tonic-gate/* ARGSUSED */ 25067c478bd9Sstevel@tonic-gateint 25077c478bd9Sstevel@tonic-gatesuword16(void *addr, uint16_t value) 25087c478bd9Sstevel@tonic-gate{ return (0); } 25097c478bd9Sstevel@tonic-gate 25107c478bd9Sstevel@tonic-gate/* ARGSUSED */ 25117c478bd9Sstevel@tonic-gateint 25127c478bd9Sstevel@tonic-gatesuword8(void *addr, uint8_t value) 25137c478bd9Sstevel@tonic-gate{ return (0); } 25147c478bd9Sstevel@tonic-gate 25157c478bd9Sstevel@tonic-gate#else /* lint */ 25167c478bd9Sstevel@tonic-gate 25177c478bd9Sstevel@tonic-gate#if defined(__amd64) 25187c478bd9Sstevel@tonic-gate 25197c478bd9Sstevel@tonic-gate/* 25207c478bd9Sstevel@tonic-gate * (Note that we don't save and reload the arguments here 25217c478bd9Sstevel@tonic-gate * because their values are not altered in the copy path) 25227c478bd9Sstevel@tonic-gate */ 25237c478bd9Sstevel@tonic-gate 25247c478bd9Sstevel@tonic-gate#define SUWORD(NAME, INSTR, REG, COPYOP) \ 25257c478bd9Sstevel@tonic-gate ENTRY(NAME) \ 25267c478bd9Sstevel@tonic-gate movq %gs:CPU_THREAD, %r9; \ 25277c478bd9Sstevel@tonic-gate cmpq kernelbase(%rip), %rdi; \ 25287c478bd9Sstevel@tonic-gate jae 1f; \ 25297c478bd9Sstevel@tonic-gate leaq _flt_/**/NAME, %rdx; \ 25307c478bd9Sstevel@tonic-gate movq %rdx, T_LOFAULT(%r9); \ 25317c478bd9Sstevel@tonic-gate INSTR REG, (%rdi); \ 25327c478bd9Sstevel@tonic-gate movq $0, T_LOFAULT(%r9); \ 25337c478bd9Sstevel@tonic-gate xorl %eax, %eax; \ 25347c478bd9Sstevel@tonic-gate ret; \ 25357c478bd9Sstevel@tonic-gate_flt_/**/NAME: \ 25367c478bd9Sstevel@tonic-gate movq $0, T_LOFAULT(%r9); \ 25377c478bd9Sstevel@tonic-gate1: \ 25387c478bd9Sstevel@tonic-gate movq T_COPYOPS(%r9), %rax; \ 25397c478bd9Sstevel@tonic-gate cmpq $0, %rax; \ 25407c478bd9Sstevel@tonic-gate jz 3f; \ 25417c478bd9Sstevel@tonic-gate jmp *COPYOP(%rax); \ 25427c478bd9Sstevel@tonic-gate3: \ 25437c478bd9Sstevel@tonic-gate movl $-1, %eax; \ 25447c478bd9Sstevel@tonic-gate ret; \ 25457c478bd9Sstevel@tonic-gate SET_SIZE(NAME) 25467c478bd9Sstevel@tonic-gate 25477c478bd9Sstevel@tonic-gate SUWORD(suword64, movq, %rsi, CP_SUWORD64) 25487c478bd9Sstevel@tonic-gate SUWORD(suword32, movl, %esi, CP_SUWORD32) 25497c478bd9Sstevel@tonic-gate SUWORD(suword16, movw, %si, CP_SUWORD16) 25507c478bd9Sstevel@tonic-gate SUWORD(suword8, movb, %sil, CP_SUWORD8) 25517c478bd9Sstevel@tonic-gate 25527c478bd9Sstevel@tonic-gate#elif defined(__i386) 25537c478bd9Sstevel@tonic-gate 25547c478bd9Sstevel@tonic-gate#define SUWORD(NAME, INSTR, REG, COPYOP) \ 25557c478bd9Sstevel@tonic-gate ENTRY(NAME) \ 25567c478bd9Sstevel@tonic-gate movl %gs:CPU_THREAD, %ecx; \ 25577c478bd9Sstevel@tonic-gate movl kernelbase, %eax; \ 25587c478bd9Sstevel@tonic-gate cmpl %eax, 4(%esp); \ 25597c478bd9Sstevel@tonic-gate jae 1f; \ 25607c478bd9Sstevel@tonic-gate lea _flt_/**/NAME, %edx; \ 25617c478bd9Sstevel@tonic-gate movl %edx, T_LOFAULT(%ecx); \ 25627c478bd9Sstevel@tonic-gate movl 4(%esp), %eax; \ 25637c478bd9Sstevel@tonic-gate movl 8(%esp), %edx; \ 25647c478bd9Sstevel@tonic-gate INSTR REG, (%eax); \ 25657c478bd9Sstevel@tonic-gate movl $0, T_LOFAULT(%ecx); \ 25667c478bd9Sstevel@tonic-gate xorl %eax, %eax; \ 25677c478bd9Sstevel@tonic-gate ret; \ 25687c478bd9Sstevel@tonic-gate_flt_/**/NAME: \ 25697c478bd9Sstevel@tonic-gate movl $0, T_LOFAULT(%ecx); \ 25707c478bd9Sstevel@tonic-gate1: \ 25717c478bd9Sstevel@tonic-gate movl T_COPYOPS(%ecx), %eax; \ 25727c478bd9Sstevel@tonic-gate cmpl $0, %eax; \ 25737c478bd9Sstevel@tonic-gate jz 3f; \ 25747c478bd9Sstevel@tonic-gate movl COPYOP(%eax), %ecx; \ 25757c478bd9Sstevel@tonic-gate jmp *%ecx; \ 25767c478bd9Sstevel@tonic-gate3: \ 25777c478bd9Sstevel@tonic-gate movl $-1, %eax; \ 25787c478bd9Sstevel@tonic-gate ret; \ 25797c478bd9Sstevel@tonic-gate SET_SIZE(NAME) 25807c478bd9Sstevel@tonic-gate 25817c478bd9Sstevel@tonic-gate SUWORD(suword32, movl, %edx, CP_SUWORD32) 25827c478bd9Sstevel@tonic-gate SUWORD(suword16, movw, %dx, CP_SUWORD16) 25837c478bd9Sstevel@tonic-gate SUWORD(suword8, movb, %dl, CP_SUWORD8) 25847c478bd9Sstevel@tonic-gate 25857c478bd9Sstevel@tonic-gate#endif /* __i386 */ 25867c478bd9Sstevel@tonic-gate 25877c478bd9Sstevel@tonic-gate#undef SUWORD 25887c478bd9Sstevel@tonic-gate 25897c478bd9Sstevel@tonic-gate#endif /* __lint */ 25907c478bd9Sstevel@tonic-gate 25917c478bd9Sstevel@tonic-gate#if defined(__lint) 25927c478bd9Sstevel@tonic-gate 25937c478bd9Sstevel@tonic-gate#if defined(__amd64) 25947c478bd9Sstevel@tonic-gate 25957c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 25967c478bd9Sstevel@tonic-gatevoid 25977c478bd9Sstevel@tonic-gatefuword64_noerr(const void *addr, uint64_t *dst) 25987c478bd9Sstevel@tonic-gate{} 25997c478bd9Sstevel@tonic-gate 26007c478bd9Sstevel@tonic-gate#endif 26017c478bd9Sstevel@tonic-gate 26027c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 26037c478bd9Sstevel@tonic-gatevoid 26047c478bd9Sstevel@tonic-gatefuword32_noerr(const void *addr, uint32_t *dst) 26057c478bd9Sstevel@tonic-gate{} 26067c478bd9Sstevel@tonic-gate 26077c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 26087c478bd9Sstevel@tonic-gatevoid 26097c478bd9Sstevel@tonic-gatefuword8_noerr(const void *addr, uint8_t *dst) 26107c478bd9Sstevel@tonic-gate{} 26117c478bd9Sstevel@tonic-gate 26127c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 26137c478bd9Sstevel@tonic-gatevoid 26147c478bd9Sstevel@tonic-gatefuword16_noerr(const void *addr, uint16_t *dst) 26157c478bd9Sstevel@tonic-gate{} 26167c478bd9Sstevel@tonic-gate 26177c478bd9Sstevel@tonic-gate#else /* __lint */ 26187c478bd9Sstevel@tonic-gate 26197c478bd9Sstevel@tonic-gate#if defined(__amd64) 26207c478bd9Sstevel@tonic-gate 26217c478bd9Sstevel@tonic-gate#define FUWORD_NOERR(NAME, INSTR, REG) \ 26227c478bd9Sstevel@tonic-gate ENTRY(NAME) \ 26237c478bd9Sstevel@tonic-gate cmpq kernelbase(%rip), %rdi; \ 26247c478bd9Sstevel@tonic-gate cmovnbq kernelbase(%rip), %rdi; \ 26257c478bd9Sstevel@tonic-gate INSTR (%rdi), REG; \ 26267c478bd9Sstevel@tonic-gate INSTR REG, (%rsi); \ 26277c478bd9Sstevel@tonic-gate ret; \ 26287c478bd9Sstevel@tonic-gate SET_SIZE(NAME) 26297c478bd9Sstevel@tonic-gate 26307c478bd9Sstevel@tonic-gate FUWORD_NOERR(fuword64_noerr, movq, %rax) 26317c478bd9Sstevel@tonic-gate FUWORD_NOERR(fuword32_noerr, movl, %eax) 26327c478bd9Sstevel@tonic-gate FUWORD_NOERR(fuword16_noerr, movw, %ax) 26337c478bd9Sstevel@tonic-gate FUWORD_NOERR(fuword8_noerr, movb, %al) 26347c478bd9Sstevel@tonic-gate 26357c478bd9Sstevel@tonic-gate#elif defined(__i386) 26367c478bd9Sstevel@tonic-gate 26377c478bd9Sstevel@tonic-gate#define FUWORD_NOERR(NAME, INSTR, REG) \ 26387c478bd9Sstevel@tonic-gate ENTRY(NAME) \ 26397c478bd9Sstevel@tonic-gate movl 4(%esp), %eax; \ 26407c478bd9Sstevel@tonic-gate cmpl kernelbase, %eax; \ 26417c478bd9Sstevel@tonic-gate jb 1f; \ 26427c478bd9Sstevel@tonic-gate movl kernelbase, %eax; \ 26437c478bd9Sstevel@tonic-gate1: movl 8(%esp), %edx; \ 26447c478bd9Sstevel@tonic-gate INSTR (%eax), REG; \ 26457c478bd9Sstevel@tonic-gate INSTR REG, (%edx); \ 26467c478bd9Sstevel@tonic-gate ret; \ 26477c478bd9Sstevel@tonic-gate SET_SIZE(NAME) 26487c478bd9Sstevel@tonic-gate 26497c478bd9Sstevel@tonic-gate FUWORD_NOERR(fuword32_noerr, movl, %ecx) 26507c478bd9Sstevel@tonic-gate FUWORD_NOERR(fuword16_noerr, movw, %cx) 26517c478bd9Sstevel@tonic-gate FUWORD_NOERR(fuword8_noerr, movb, %cl) 26527c478bd9Sstevel@tonic-gate 26537c478bd9Sstevel@tonic-gate#endif /* __i386 */ 26547c478bd9Sstevel@tonic-gate 26557c478bd9Sstevel@tonic-gate#undef FUWORD_NOERR 26567c478bd9Sstevel@tonic-gate 26577c478bd9Sstevel@tonic-gate#endif /* __lint */ 26587c478bd9Sstevel@tonic-gate 26597c478bd9Sstevel@tonic-gate#if defined(__lint) 26607c478bd9Sstevel@tonic-gate 26617c478bd9Sstevel@tonic-gate#if defined(__amd64) 26627c478bd9Sstevel@tonic-gate 26637c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 26647c478bd9Sstevel@tonic-gatevoid 26657c478bd9Sstevel@tonic-gatesuword64_noerr(void *addr, uint64_t value) 26667c478bd9Sstevel@tonic-gate{} 26677c478bd9Sstevel@tonic-gate 26687c478bd9Sstevel@tonic-gate#endif 26697c478bd9Sstevel@tonic-gate 26707c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 26717c478bd9Sstevel@tonic-gatevoid 26727c478bd9Sstevel@tonic-gatesuword32_noerr(void *addr, uint32_t value) 26737c478bd9Sstevel@tonic-gate{} 26747c478bd9Sstevel@tonic-gate 26757c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 26767c478bd9Sstevel@tonic-gatevoid 26777c478bd9Sstevel@tonic-gatesuword16_noerr(void *addr, uint16_t value) 26787c478bd9Sstevel@tonic-gate{} 26797c478bd9Sstevel@tonic-gate 26807c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 26817c478bd9Sstevel@tonic-gatevoid 26827c478bd9Sstevel@tonic-gatesuword8_noerr(void *addr, uint8_t value) 26837c478bd9Sstevel@tonic-gate{} 26847c478bd9Sstevel@tonic-gate 26857c478bd9Sstevel@tonic-gate#else /* lint */ 26867c478bd9Sstevel@tonic-gate 26877c478bd9Sstevel@tonic-gate#if defined(__amd64) 26887c478bd9Sstevel@tonic-gate 26897c478bd9Sstevel@tonic-gate#define SUWORD_NOERR(NAME, INSTR, REG) \ 26907c478bd9Sstevel@tonic-gate ENTRY(NAME) \ 26917c478bd9Sstevel@tonic-gate cmpq kernelbase(%rip), %rdi; \ 26927c478bd9Sstevel@tonic-gate cmovnbq kernelbase(%rip), %rdi; \ 26937c478bd9Sstevel@tonic-gate INSTR REG, (%rdi); \ 26947c478bd9Sstevel@tonic-gate ret; \ 26957c478bd9Sstevel@tonic-gate SET_SIZE(NAME) 26967c478bd9Sstevel@tonic-gate 26977c478bd9Sstevel@tonic-gate SUWORD_NOERR(suword64_noerr, movq, %rsi) 26987c478bd9Sstevel@tonic-gate SUWORD_NOERR(suword32_noerr, movl, %esi) 26997c478bd9Sstevel@tonic-gate SUWORD_NOERR(suword16_noerr, movw, %si) 27007c478bd9Sstevel@tonic-gate SUWORD_NOERR(suword8_noerr, movb, %sil) 27017c478bd9Sstevel@tonic-gate 27027c478bd9Sstevel@tonic-gate#elif defined(__i386) 27037c478bd9Sstevel@tonic-gate 27047c478bd9Sstevel@tonic-gate#define SUWORD_NOERR(NAME, INSTR, REG) \ 27057c478bd9Sstevel@tonic-gate ENTRY(NAME) \ 27067c478bd9Sstevel@tonic-gate movl 4(%esp), %eax; \ 27077c478bd9Sstevel@tonic-gate cmpl kernelbase, %eax; \ 27087c478bd9Sstevel@tonic-gate jb 1f; \ 27097c478bd9Sstevel@tonic-gate movl kernelbase, %eax; \ 27107c478bd9Sstevel@tonic-gate1: \ 27117c478bd9Sstevel@tonic-gate movl 8(%esp), %edx; \ 27127c478bd9Sstevel@tonic-gate INSTR REG, (%eax); \ 27137c478bd9Sstevel@tonic-gate ret; \ 27147c478bd9Sstevel@tonic-gate SET_SIZE(NAME) 27157c478bd9Sstevel@tonic-gate 27167c478bd9Sstevel@tonic-gate SUWORD_NOERR(suword32_noerr, movl, %edx) 27177c478bd9Sstevel@tonic-gate SUWORD_NOERR(suword16_noerr, movw, %dx) 27187c478bd9Sstevel@tonic-gate SUWORD_NOERR(suword8_noerr, movb, %dl) 27197c478bd9Sstevel@tonic-gate 27207c478bd9Sstevel@tonic-gate#endif /* __i386 */ 27217c478bd9Sstevel@tonic-gate 27227c478bd9Sstevel@tonic-gate#undef SUWORD_NOERR 27237c478bd9Sstevel@tonic-gate 27247c478bd9Sstevel@tonic-gate#endif /* lint */ 27257c478bd9Sstevel@tonic-gate 27267c478bd9Sstevel@tonic-gate 27277c478bd9Sstevel@tonic-gate#if defined(__lint) 27287c478bd9Sstevel@tonic-gate 27297c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 27307c478bd9Sstevel@tonic-gateint 27317c478bd9Sstevel@tonic-gatesubyte(void *addr, uchar_t value) 27327c478bd9Sstevel@tonic-gate{ return (0); } 27337c478bd9Sstevel@tonic-gate 27347c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 27357c478bd9Sstevel@tonic-gatevoid 27367c478bd9Sstevel@tonic-gatesubyte_noerr(void *addr, uchar_t value) 27377c478bd9Sstevel@tonic-gate{} 27387c478bd9Sstevel@tonic-gate 27397c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 27407c478bd9Sstevel@tonic-gateint 27417c478bd9Sstevel@tonic-gatefulword(const void *addr, ulong_t *valuep) 27427c478bd9Sstevel@tonic-gate{ return (0); } 27437c478bd9Sstevel@tonic-gate 27447c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 27457c478bd9Sstevel@tonic-gatevoid 27467c478bd9Sstevel@tonic-gatefulword_noerr(const void *addr, ulong_t *valuep) 27477c478bd9Sstevel@tonic-gate{} 27487c478bd9Sstevel@tonic-gate 27497c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 27507c478bd9Sstevel@tonic-gateint 27517c478bd9Sstevel@tonic-gatesulword(void *addr, ulong_t valuep) 27527c478bd9Sstevel@tonic-gate{ return (0); } 27537c478bd9Sstevel@tonic-gate 27547c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 27557c478bd9Sstevel@tonic-gatevoid 27567c478bd9Sstevel@tonic-gatesulword_noerr(void *addr, ulong_t valuep) 27577c478bd9Sstevel@tonic-gate{} 27587c478bd9Sstevel@tonic-gate 27597c478bd9Sstevel@tonic-gate#else 27607c478bd9Sstevel@tonic-gate 27617c478bd9Sstevel@tonic-gate .weak subyte 27627c478bd9Sstevel@tonic-gate subyte=suword8 27637c478bd9Sstevel@tonic-gate .weak subyte_noerr 27647c478bd9Sstevel@tonic-gate subyte_noerr=suword8_noerr 27657c478bd9Sstevel@tonic-gate 27667c478bd9Sstevel@tonic-gate#if defined(__amd64) 27677c478bd9Sstevel@tonic-gate 27687c478bd9Sstevel@tonic-gate .weak fulword 27697c478bd9Sstevel@tonic-gate fulword=fuword64 27707c478bd9Sstevel@tonic-gate .weak fulword_noerr 27717c478bd9Sstevel@tonic-gate fulword_noerr=fuword64_noerr 27727c478bd9Sstevel@tonic-gate .weak sulword 27737c478bd9Sstevel@tonic-gate sulword=suword64 27747c478bd9Sstevel@tonic-gate .weak sulword_noerr 27757c478bd9Sstevel@tonic-gate sulword_noerr=suword64_noerr 27767c478bd9Sstevel@tonic-gate 27777c478bd9Sstevel@tonic-gate#elif defined(__i386) 27787c478bd9Sstevel@tonic-gate 27797c478bd9Sstevel@tonic-gate .weak fulword 27807c478bd9Sstevel@tonic-gate fulword=fuword32 27817c478bd9Sstevel@tonic-gate .weak fulword_noerr 27827c478bd9Sstevel@tonic-gate fulword_noerr=fuword32_noerr 27837c478bd9Sstevel@tonic-gate .weak sulword 27847c478bd9Sstevel@tonic-gate sulword=suword32 27857c478bd9Sstevel@tonic-gate .weak sulword_noerr 27867c478bd9Sstevel@tonic-gate sulword_noerr=suword32_noerr 27877c478bd9Sstevel@tonic-gate 27887c478bd9Sstevel@tonic-gate#endif /* __i386 */ 27897c478bd9Sstevel@tonic-gate 27907c478bd9Sstevel@tonic-gate#endif /* __lint */ 27917c478bd9Sstevel@tonic-gate 27927c478bd9Sstevel@tonic-gate#if defined(__lint) 27937c478bd9Sstevel@tonic-gate 27947c478bd9Sstevel@tonic-gate/* 27957c478bd9Sstevel@tonic-gate * Copy a block of storage - must not overlap (from + len <= to). 27967c478bd9Sstevel@tonic-gate * No fault handler installed (to be called under on_fault()) 27977c478bd9Sstevel@tonic-gate */ 27987c478bd9Sstevel@tonic-gate 27997c478bd9Sstevel@tonic-gate/* ARGSUSED */ 28007c478bd9Sstevel@tonic-gatevoid 28017c478bd9Sstevel@tonic-gatecopyout_noerr(const void *kfrom, void *uto, size_t count) 28027c478bd9Sstevel@tonic-gate{} 28037c478bd9Sstevel@tonic-gate 28047c478bd9Sstevel@tonic-gate/* ARGSUSED */ 28057c478bd9Sstevel@tonic-gatevoid 28067c478bd9Sstevel@tonic-gatecopyin_noerr(const void *ufrom, void *kto, size_t count) 28077c478bd9Sstevel@tonic-gate{} 28087c478bd9Sstevel@tonic-gate 28097c478bd9Sstevel@tonic-gate/* 28107c478bd9Sstevel@tonic-gate * Zero a block of storage in user space 28117c478bd9Sstevel@tonic-gate */ 28127c478bd9Sstevel@tonic-gate 28137c478bd9Sstevel@tonic-gate/* ARGSUSED */ 28147c478bd9Sstevel@tonic-gatevoid 28157c478bd9Sstevel@tonic-gateuzero(void *addr, size_t count) 28167c478bd9Sstevel@tonic-gate{} 28177c478bd9Sstevel@tonic-gate 28187c478bd9Sstevel@tonic-gate/* 28197c478bd9Sstevel@tonic-gate * copy a block of storage in user space 28207c478bd9Sstevel@tonic-gate */ 28217c478bd9Sstevel@tonic-gate 28227c478bd9Sstevel@tonic-gate/* ARGSUSED */ 28237c478bd9Sstevel@tonic-gatevoid 28247c478bd9Sstevel@tonic-gateucopy(const void *ufrom, void *uto, size_t ulength) 28257c478bd9Sstevel@tonic-gate{} 28267c478bd9Sstevel@tonic-gate 28279acbbeafSnn35248/* 28289acbbeafSnn35248 * copy a string in user space 28299acbbeafSnn35248 */ 28309acbbeafSnn35248 28319acbbeafSnn35248/* ARGSUSED */ 28329acbbeafSnn35248void 28339acbbeafSnn35248ucopystr(const char *ufrom, char *uto, size_t umaxlength, size_t *lencopied) 28349acbbeafSnn35248{} 28359acbbeafSnn35248 28367c478bd9Sstevel@tonic-gate#else /* __lint */ 28377c478bd9Sstevel@tonic-gate 28387c478bd9Sstevel@tonic-gate#if defined(__amd64) 28397c478bd9Sstevel@tonic-gate 28407c478bd9Sstevel@tonic-gate ENTRY(copyin_noerr) 28417c478bd9Sstevel@tonic-gate movq kernelbase(%rip), %rax 28427c478bd9Sstevel@tonic-gate#ifdef DEBUG 28437c478bd9Sstevel@tonic-gate cmpq %rax, %rsi /* %rsi = kto */ 28447c478bd9Sstevel@tonic-gate jae 1f 28457c478bd9Sstevel@tonic-gate leaq .cpyin_ne_pmsg(%rip), %rdi 28467c478bd9Sstevel@tonic-gate jmp call_panic /* setup stack and call panic */ 28477c478bd9Sstevel@tonic-gate1: 28487c478bd9Sstevel@tonic-gate#endif 28497c478bd9Sstevel@tonic-gate cmpq %rax, %rdi /* ufrom < kernelbase */ 28507c478bd9Sstevel@tonic-gate jb do_copy 28517c478bd9Sstevel@tonic-gate movq %rax, %rdi /* force fault at kernelbase */ 28527c478bd9Sstevel@tonic-gate jmp do_copy 28537c478bd9Sstevel@tonic-gate SET_SIZE(copyin_noerr) 28547c478bd9Sstevel@tonic-gate 28557c478bd9Sstevel@tonic-gate ENTRY(copyout_noerr) 28567c478bd9Sstevel@tonic-gate movq kernelbase(%rip), %rax 28577c478bd9Sstevel@tonic-gate#ifdef DEBUG 28587c478bd9Sstevel@tonic-gate cmpq %rax, %rdi /* %rdi = kfrom */ 28597c478bd9Sstevel@tonic-gate jae 1f 28607c478bd9Sstevel@tonic-gate leaq .cpyout_ne_pmsg(%rip), %rdi 28617c478bd9Sstevel@tonic-gate jmp call_panic /* setup stack and call panic */ 28627c478bd9Sstevel@tonic-gate1: 28637c478bd9Sstevel@tonic-gate#endif 28647c478bd9Sstevel@tonic-gate cmpq %rax, %rsi /* uto < kernelbase */ 28657c478bd9Sstevel@tonic-gate jb do_copy 28667c478bd9Sstevel@tonic-gate movq %rax, %rsi /* force fault at kernelbase */ 28677c478bd9Sstevel@tonic-gate jmp do_copy 28687c478bd9Sstevel@tonic-gate SET_SIZE(copyout_noerr) 28697c478bd9Sstevel@tonic-gate 28707c478bd9Sstevel@tonic-gate ENTRY(uzero) 287140c00cd7Sahl movq kernelbase(%rip), %rax 287240c00cd7Sahl cmpq %rax, %rdi 287340c00cd7Sahl jb do_zero 287440c00cd7Sahl movq %rax, %rdi /* force fault at kernelbase */ 28757c478bd9Sstevel@tonic-gate jmp do_zero 28767c478bd9Sstevel@tonic-gate SET_SIZE(uzero) 28777c478bd9Sstevel@tonic-gate 28787c478bd9Sstevel@tonic-gate ENTRY(ucopy) 28797c478bd9Sstevel@tonic-gate movq kernelbase(%rip), %rax 288040c00cd7Sahl cmpq %rax, %rdi 28819acbbeafSnn35248 cmovaeq %rax, %rdi /* force fault at kernelbase */ 288240c00cd7Sahl cmpq %rax, %rsi 28839acbbeafSnn35248 cmovaeq %rax, %rsi /* force fault at kernelbase */ 28847c478bd9Sstevel@tonic-gate jmp do_copy 28857c478bd9Sstevel@tonic-gate SET_SIZE(ucopy) 28867c478bd9Sstevel@tonic-gate 28879acbbeafSnn35248 ENTRY(ucopystr) 288887131306SRobert Mustacchi pushq %rbp 288987131306SRobert Mustacchi movq %rsp, %rbp 28909acbbeafSnn35248 movq kernelbase(%rip), %rax 28919acbbeafSnn35248 cmpq %rax, %rdi 28929acbbeafSnn35248 cmovaeq %rax, %rdi /* force fault at kernelbase */ 28939acbbeafSnn35248 cmpq %rax, %rsi 28949acbbeafSnn35248 cmovaeq %rax, %rsi /* force fault at kernelbase */ 28959acbbeafSnn35248 /* do_copystr expects lofault address in %r8 */ 28969acbbeafSnn35248 movq %gs:CPU_THREAD, %r8 28979acbbeafSnn35248 movq T_LOFAULT(%r8), %r8 28989acbbeafSnn35248 jmp do_copystr 28999acbbeafSnn35248 SET_SIZE(ucopystr) 29009acbbeafSnn35248 29017c478bd9Sstevel@tonic-gate#elif defined(__i386) 29027c478bd9Sstevel@tonic-gate 29037c478bd9Sstevel@tonic-gate ENTRY(copyin_noerr) 29047c478bd9Sstevel@tonic-gate movl kernelbase, %eax 29057c478bd9Sstevel@tonic-gate#ifdef DEBUG 29067c478bd9Sstevel@tonic-gate cmpl %eax, 8(%esp) 29077c478bd9Sstevel@tonic-gate jae 1f 29087c478bd9Sstevel@tonic-gate pushl $.cpyin_ne_pmsg 29097c478bd9Sstevel@tonic-gate call panic 29107c478bd9Sstevel@tonic-gate1: 29117c478bd9Sstevel@tonic-gate#endif 29127c478bd9Sstevel@tonic-gate cmpl %eax, 4(%esp) 29137c478bd9Sstevel@tonic-gate jb do_copy 29147c478bd9Sstevel@tonic-gate movl %eax, 4(%esp) /* force fault at kernelbase */ 29157c478bd9Sstevel@tonic-gate jmp do_copy 29167c478bd9Sstevel@tonic-gate SET_SIZE(copyin_noerr) 29177c478bd9Sstevel@tonic-gate 29187c478bd9Sstevel@tonic-gate ENTRY(copyout_noerr) 29197c478bd9Sstevel@tonic-gate movl kernelbase, %eax 29207c478bd9Sstevel@tonic-gate#ifdef DEBUG 29217c478bd9Sstevel@tonic-gate cmpl %eax, 4(%esp) 29227c478bd9Sstevel@tonic-gate jae 1f 29237c478bd9Sstevel@tonic-gate pushl $.cpyout_ne_pmsg 29247c478bd9Sstevel@tonic-gate call panic 29257c478bd9Sstevel@tonic-gate1: 29267c478bd9Sstevel@tonic-gate#endif 29277c478bd9Sstevel@tonic-gate cmpl %eax, 8(%esp) 29287c478bd9Sstevel@tonic-gate jb do_copy 29297c478bd9Sstevel@tonic-gate movl %eax, 8(%esp) /* force fault at kernelbase */ 29307c478bd9Sstevel@tonic-gate jmp do_copy 29317c478bd9Sstevel@tonic-gate SET_SIZE(copyout_noerr) 29327c478bd9Sstevel@tonic-gate 29337c478bd9Sstevel@tonic-gate ENTRY(uzero) 29347c478bd9Sstevel@tonic-gate movl kernelbase, %eax 29357c478bd9Sstevel@tonic-gate cmpl %eax, 4(%esp) 293640c00cd7Sahl jb do_zero 293740c00cd7Sahl movl %eax, 4(%esp) /* force fault at kernelbase */ 29387c478bd9Sstevel@tonic-gate jmp do_zero 29397c478bd9Sstevel@tonic-gate SET_SIZE(uzero) 29407c478bd9Sstevel@tonic-gate 29417c478bd9Sstevel@tonic-gate ENTRY(ucopy) 29427c478bd9Sstevel@tonic-gate movl kernelbase, %eax 29437c478bd9Sstevel@tonic-gate cmpl %eax, 4(%esp) 29447c478bd9Sstevel@tonic-gate jb 1f 294540c00cd7Sahl movl %eax, 4(%esp) /* force fault at kernelbase */ 29467c478bd9Sstevel@tonic-gate1: 294740c00cd7Sahl cmpl %eax, 8(%esp) 294840c00cd7Sahl jb do_copy 294940c00cd7Sahl movl %eax, 8(%esp) /* force fault at kernelbase */ 29507c478bd9Sstevel@tonic-gate jmp do_copy 29517c478bd9Sstevel@tonic-gate SET_SIZE(ucopy) 29527c478bd9Sstevel@tonic-gate 29539acbbeafSnn35248 ENTRY(ucopystr) 29549acbbeafSnn35248 movl kernelbase, %eax 29559acbbeafSnn35248 cmpl %eax, 4(%esp) 29569acbbeafSnn35248 jb 1f 29579acbbeafSnn35248 movl %eax, 4(%esp) /* force fault at kernelbase */ 29589acbbeafSnn352481: 29599acbbeafSnn35248 cmpl %eax, 8(%esp) 29609acbbeafSnn35248 jb 2f 29619acbbeafSnn35248 movl %eax, 8(%esp) /* force fault at kernelbase */ 29629acbbeafSnn352482: 29639acbbeafSnn35248 /* do_copystr expects the lofault address in %eax */ 29649acbbeafSnn35248 movl %gs:CPU_THREAD, %eax 29659acbbeafSnn35248 movl T_LOFAULT(%eax), %eax 29669acbbeafSnn35248 jmp do_copystr 29679acbbeafSnn35248 SET_SIZE(ucopystr) 29689acbbeafSnn35248 29697c478bd9Sstevel@tonic-gate#endif /* __i386 */ 29707c478bd9Sstevel@tonic-gate 29717c478bd9Sstevel@tonic-gate#ifdef DEBUG 29727c478bd9Sstevel@tonic-gate .data 29737c478bd9Sstevel@tonic-gate.kcopy_panic_msg: 29747c478bd9Sstevel@tonic-gate .string "kcopy: arguments below kernelbase" 29757c478bd9Sstevel@tonic-gate.bcopy_panic_msg: 29767c478bd9Sstevel@tonic-gate .string "bcopy: arguments below kernelbase" 29777c478bd9Sstevel@tonic-gate.kzero_panic_msg: 29787c478bd9Sstevel@tonic-gate .string "kzero: arguments below kernelbase" 29797c478bd9Sstevel@tonic-gate.bzero_panic_msg: 29807c478bd9Sstevel@tonic-gate .string "bzero: arguments below kernelbase" 29817c478bd9Sstevel@tonic-gate.copyin_panic_msg: 29827c478bd9Sstevel@tonic-gate .string "copyin: kaddr argument below kernelbase" 29837c478bd9Sstevel@tonic-gate.xcopyin_panic_msg: 29847c478bd9Sstevel@tonic-gate .string "xcopyin: kaddr argument below kernelbase" 29857c478bd9Sstevel@tonic-gate.copyout_panic_msg: 29867c478bd9Sstevel@tonic-gate .string "copyout: kaddr argument below kernelbase" 29877c478bd9Sstevel@tonic-gate.xcopyout_panic_msg: 29887c478bd9Sstevel@tonic-gate .string "xcopyout: kaddr argument below kernelbase" 29897c478bd9Sstevel@tonic-gate.copystr_panic_msg: 29907c478bd9Sstevel@tonic-gate .string "copystr: arguments in user space" 29917c478bd9Sstevel@tonic-gate.copyinstr_panic_msg: 29927c478bd9Sstevel@tonic-gate .string "copyinstr: kaddr argument not in kernel address space" 29937c478bd9Sstevel@tonic-gate.copyoutstr_panic_msg: 29947c478bd9Sstevel@tonic-gate .string "copyoutstr: kaddr argument not in kernel address space" 29957c478bd9Sstevel@tonic-gate.cpyin_ne_pmsg: 29967c478bd9Sstevel@tonic-gate .string "copyin_noerr: argument not in kernel address space" 29977c478bd9Sstevel@tonic-gate.cpyout_ne_pmsg: 29987c478bd9Sstevel@tonic-gate .string "copyout_noerr: argument not in kernel address space" 29997c478bd9Sstevel@tonic-gate#endif 30007c478bd9Sstevel@tonic-gate 30017c478bd9Sstevel@tonic-gate#endif /* __lint */ 3002