1 /*
2  * Copyright (c) 1994 William F. Jolitz.
3  * 386BSD Copyright Restrictions Apply. All Other Rights Reserved.
4  *
5  * $Id: $
6  * Copy a fixed length segment from a user process to the kernel.
7  */
8 
9 __INLINE int
10 copyin(struct proc *p, void *from, void *toaddr, u_int size)
11 {
12 	extern const int zero;		/* compiler bug workaround */
13 	const void *f = from + zero;	/* compiler bug workaround */
14 	int rv;
15 
16 	/* is this in the range of a valid user process address? */
17 	/*if ((unsigned)from > ENDUSERMEM || (unsigned)from + size > ENDUSERMEM)
18 		return(EFAULT);*/
19 
20 	/* set fault vector */
21 	asm volatile ("movl $4f, %0" : "=m" (p->p_md.md_onfault));
22 
23 	/* copy the string */
24 	asm volatile ("cld ; repe ; movsl"
25 		 : "=D" (toaddr), "=S" (f)
26 		 : "0" (toaddr), "1" (f), "c" (size / 4));
27 	asm volatile ("repe ; movsb"
28 		 : "=D" (toaddr), "=S" (f)
29 		 : "0" (toaddr), "1" (f), "c" (size & 3));
30 
31 	/* catch the possible fault */
32 	asm volatile ("\
33 		xorl %0, %0 ;		\
34 		jmp 5f ;		\
35 	4:	movl %1, %0 ;		\
36 	5:				"
37 		: "=r" (rv)
38 		: "i" (EFAULT));
39 
40 	/* clear the fault vector */
41 	p->p_md.md_onfault = 0;
42 
43 	return (rv);
44 }
45