Subject: Re: Removing I386_CPU from GENERIC and INSTALL
To: Frank van der Linden <fvdl@netbsd.org>
From: Jason Thorpe <thorpej@shagadelic.org>
List: port-i386
Date: 11/01/2006 21:49:02
--Apple-Mail-1--544250858
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
	charset=US-ASCII;
	format=flowed;
	delsp=yes


On Oct 31, 2006, at 10:21 AM, Frank van der Linden wrote:

> The fix is just to to do kcopy what i386_copyout already has. It  
> isn't much work at all.

Something like this?  (Compile-tested only...)

-- thorpej
--Apple-Mail-1--544250858
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
	x-unix-mode=0644;
	name=i386-kcopy-patch.txt
Content-Disposition: attachment;
	filename=i386-kcopy-patch.txt

Index: i386/copy.S
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/i386/copy.S,v
retrieving revision 1.2
diff -u -p -r1.2 copy.S
--- i386/copy.S	11 Dec 2005 12:17:41 -0000	1.2
+++ i386/copy.S	2 Nov 2006 05:47:40 -0000
@@ -120,8 +120,135 @@ ENTRY(fillw)
  * int kcopy(const void *from, void *to, size_t len);
  * Copy len bytes, abort on fault.
  */
+
+#if defined(I386_CPU)
+#define	DEFAULT_KCOPY		_C_LABEL(i386_kcopy)
+#elif defined(I486_CPU)
+#define	DEFAULT_KCOPY		_C_LABEL(i486_kcopy)
+#elif defined(I586_CPU)
+#define	DEFAULT_KCOPY		_C_LABEL(i486_kcopy)
+#elif defined(I686_CPU)
+#define	DEFAULT_KCOPY		_C_LABEL(i486_kcopy)
+#endif
+
+	.data
+
+	.globl	_C_LABEL(kcopy_func)
+_C_LABEL(kcopy_func):
+	.long	DEFAULT_KCOPY
+
+	.text
+
 /* LINTSTUB: Func: int kcopy(const void *from, void *to, size_t len) */
 ENTRY(kcopy)
+	jmp	*_C_LABEL(kcopy_func)
+
+#if defined(I386_CPU)
+/* LINTSTUB: Func: int i386_kcopy(const void *from, void *to, size_t len) */
+ENTRY(i386_kcopy)
+	pushl	%esi
+	pushl	%edi
+	GET_CURPCB(%eax)		# load curpcb into eax and set on-fault
+	pushl	PCB_ONFAULT(%eax)
+	movl	$_C_LABEL(i386_kcopy_writefault), PCB_ONFAULT(%eax)
+
+	movl	16(%esp),%esi
+	movl	20(%esp),%edi
+	movl	24(%esp),%eax
+
+	/*
+	 * We have to compute each PTE for (write) permission, since
+	 * the CPU doesn't do it for us.
+	 */
+	
+	/* Compute number of pages. */
+	movl	%edi,%ecx
+	andl	$PGOFSET,%ecx
+	addl	%eax,%ecx
+	decl	%ecx
+	shrl	$PGSHIFT,%ecx
+
+	/* Compute PTE offset for start address. */
+	shrl	$PGSHIFT,%edi
+
+1:	/* Check PTE for each page. */
+	testb	$PG_RW,PTE_BASE(,%edi,4)
+	jz	_C_LABEL(i386_kcopy_writefault)
+
+	/* Note: this label referenced below in i386_kcopy_writefault: */
+4:	incl	%edi
+	decl	%ecx
+	jns	1b
+
+	movl	20(%esp),%edi
+	movl	24(%esp),%ecx
+	jmp	3f
+
+3:	GET_CURPCB(%edx)
+	movl	$_C_LABEL(kcopy_fault),PCB_ONFAULT(%edx)
+
+	movl	%edi,%eax
+	subl	%esi,%eax
+	cmpl	%ecx,%eax		# overlapping?
+	jb	1f
+
+	cld				# nope, copy forward
+	shrl	$2,%ecx			# copy by 32-bit words
+	rep
+	movsl
+	movl	24(%esp),%ecx
+	andl	$3,%ecx			# any bytes left?
+	rep
+	movsb
+
+	GET_CURPCB(%edx)		# XXX save curpcb?
+	popl	PCB_ONFAULT(%edx)
+	popl	%edi
+	popl	%esi
+	xorl	%eax,%eax
+	ret
+
+	ALIGN_TEXT
+1:	addl	%ecx,%edi		# copy backward
+	addl	%ecx,%esi
+	std
+	andl	$3,%ecx			# any fractional bytes?
+	decl	%edi
+	decl	%esi
+	rep
+	movsb
+	movl	24(%esp),%ecx		# copy remainder by 32-bit words
+	shrl	$2,%ecx
+	subl	$3,%esi
+	subl	$3,%edi
+	rep
+	movsl
+	cld
+
+	GET_CURPCB(%edx)
+	popl	PCB_ONFAULT(%edx)
+	popl	%edi
+	popl	%esi
+	xorl	%eax,%eax
+	ret
+
+NENTRY(i386_kcopy_writefault)
+	/* Simulate a trap. */
+	pushl	%ecx
+	movl	%edi,%eax
+	shll	$PGSHIFT,%eax
+	pushl	%eax
+	call	_C_LABEL(trapwrite_kcopy)	# trapwrite_kcopy(addr)
+	addl	$4,%esp				# pop argument
+	popl	%ecx
+	testl	%eax,%eax			# if not ok, return EFAULT
+	jz	4b
+	jmp	_C_LABEL(copy_efault)
+#endif /* I386_CPU */
+
+#if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU)
+/* LINTSTUB: Func: int i486_kcopy(const void *from, void *to, size_t len) */
+ENTRY(i486_kcopy)
 	pushl	%esi
 	pushl	%edi
 	GET_CURPCB(%eax)		# load curpcb into eax and set on-fault
@@ -135,6 +262,7 @@ ENTRY(kcopy)
 	subl	%esi,%eax
 	cmpl	%ecx,%eax		# overlapping?
 	jb	1f
+
 	cld				# nope, copy forward
 	shrl	$2,%ecx			# copy by 32-bit words
 	rep
@@ -174,6 +302,7 @@ ENTRY(kcopy)
 	popl	%esi
 	xorl	%eax,%eax
 	ret
+#endif /* I486_CPU || I586_CPU || I686_CPU */
 
 /*****************************************************************************/
 
@@ -193,11 +322,11 @@ ENTRY(kcopy)
 #define	DEFAULT_COPYOUT		_C_LABEL(i486_copyout)
 #define	DEFAULT_COPYIN		_C_LABEL(i386_copyin)
 #elif defined(I586_CPU)
-#define	DEFAULT_COPYOUT		_C_LABEL(i486_copyout)	/* XXX */
-#define	DEFAULT_COPYIN		_C_LABEL(i386_copyin)	/* XXX */
+#define	DEFAULT_COPYOUT		_C_LABEL(i486_copyout)
+#define	DEFAULT_COPYIN		_C_LABEL(i386_copyin)
 #elif defined(I686_CPU)
-#define	DEFAULT_COPYOUT		_C_LABEL(i486_copyout)	/* XXX */
-#define	DEFAULT_COPYIN		_C_LABEL(i386_copyin)	/* XXX */
+#define	DEFAULT_COPYOUT		_C_LABEL(i486_copyout)
+#define	DEFAULT_COPYIN		_C_LABEL(i386_copyin)
 #endif
 
 	.data
Index: i386/identcpu.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/i386/identcpu.c,v
retrieving revision 1.47
diff -u -p -r1.47 identcpu.c
--- i386/identcpu.c	12 Oct 2006 01:30:42 -0000	1.47
+++ i386/identcpu.c	2 Nov 2006 05:47:40 -0000
@@ -1543,16 +1543,19 @@ identifycpu(struct cpu_info *ci)
 #if defined(I686_CPU)
 	case CPUCLASS_686:
 		copyout_func = i486_copyout;
+		kcopy_func = i486_kcopy;
 		break;
 #endif
 #if defined(I586_CPU)
 	case CPUCLASS_586:
 		copyout_func = i486_copyout;
+		kcopy_func = i486_kcopy;
 		break;
 #endif
 #if defined(I486_CPU)
 	case CPUCLASS_486:
 		copyout_func = i486_copyout;
+		kcopy_func = i486_kcopy;
 		break;
 #endif
 	default:
Index: i386/trap.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/i386/trap.c,v
retrieving revision 1.214
diff -u -p -r1.214 trap.c
--- i386/trap.c	29 Sep 2006 14:48:15 -0000	1.214
+++ i386/trap.c	2 Nov 2006 05:47:41 -0000
@@ -132,6 +132,7 @@ void trap(struct trapframe *);
 void trap_tss(struct i386tss *, int, int);
 #if defined(I386_CPU)
 int trapwrite(unsigned);
+int trapwrite_kcopy(unsigned);
 #endif
 
 #ifdef KVM86
@@ -261,6 +262,9 @@ trap(frame)
 		    resume_iret[], resume_pop_ds[], resume_pop_es[],
 		    resume_pop_fs[], resume_pop_gs[],
 		    IDTVEC(osyscall)[];
+#if defined(I386_CPU)
+	extern char i386_kcopy_writefault[];
+#endif /* I386_CPU */
 	struct trapframe *vframe;
 	ksiginfo_t ksi;
 	int resume;
@@ -648,6 +652,9 @@ copyfault:
 				 */
 
 				if (onfault != kcopy_fault &&
+#if defined(I386_CPU)
+				    onfault != i386_kcopy_writefault &&
+#endif /* I386_CPU */
 				    curcpu()->ci_want_pmapload)
 					pmap_load();
 				return;
@@ -782,8 +789,7 @@ trapsignal:
  * Compensate for 386 brain damage (missing URKR)
  */
 int
-trapwrite(addr)
-	unsigned addr;
+trapwrite(unsigned addr)
 {
 	vaddr_t va;
 	struct proc *p;
@@ -804,6 +810,19 @@ trapwrite(addr)
 
 	return 0;
 }
+
+int
+trapwrite_kcopy(unsigned addr)
+{
+	vaddr_t va;
+
+	va = trunc_page((vaddr_t)addr);
+	
+	if (uvm_fault(kernel_map, va, VM_PROT_WRITE) != 0)
+		return 1;
+	
+	return 0;
+}
 #endif /* I386_CPU */
 
 /* 
Index: include/cpufunc.h
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/include/cpufunc.h,v
retrieving revision 1.33
diff -u -p -r1.33 cpufunc.h
--- include/cpufunc.h	26 Aug 2006 20:08:07 -0000	1.33
+++ include/cpufunc.h	2 Nov 2006 05:47:41 -0000
@@ -308,12 +308,16 @@ breakpoint(void)
 
 extern int (*copyout_func)(const void *, void *, size_t);
 extern int (*copyin_func)(const void *, void *, size_t);
+extern int (*kcopy_func)(const void *, void *, size_t);
 
 int	i386_copyout(const void *, void *, size_t);
 int	i486_copyout(const void *, void *, size_t);
 
 int	i386_copyin(const void *, void *, size_t);
 
+int	i386_kcopy(const void *, void *, size_t);
+int	i486_kcopy(const void *, void *, size_t);
+
 #endif /* _KERNEL */
 
 #endif /* !_I386_CPUFUNC_H_ */

--Apple-Mail-1--544250858--