patch-2.1.26 linux/arch/i386/lib/checksum.c

Next file: linux/drivers/ap1000/apfddi.c
Previous file: linux/arch/i386/kernel/traps.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.25/linux/arch/i386/lib/checksum.c linux/arch/i386/lib/checksum.c
@@ -100,225 +100,162 @@
 /*
  * Copy from ds while checksumming, otherwise like csum_partial
  *
- * The macros SRC and DST specify wether there should be exception handling
- * for the source and/or the destination addresses.
+ * The macros SRC and DST specify the type of access for the instruction.
+ * thus we can call a custom exception handler for all access types.
  *
  * FIXME: could someone double check wether i havent mixed up some SRC and
  *	  DST definitions? It's damn hard to trigger all cases, i hope i got
  *	  them all but theres no guarantee ...
  */
 
-#define csum_partial_copy_type(type) \
-unsigned int csum_partial_copy ##type (int * __csum_err, const char *src, char *dst,   \
-				  int len, int sum) {  \
-    __asm__( 									  \
-"		testl $2, %%edi		# Check alignment. 			\n" \
-"		jz 2f			# Jump if alignment is ok. 		\n" \
-"		subl $2, %%ecx		# Alignment uses up two bytes. 		\n" \
-"		jae 1f			# Jump if we had at least two bytes. 	\n" \
-"		addl $2, %%ecx		# ecx was < 2.  Deal with it. 		\n" \
-"		jmp 4f 								\n" \
-"	1000: 									\n" \
-"	 1:	movw (%%esi), %%bx						\n" \
-"		addl $2, %%esi							\n" \
-"	1001:									\n" \
-"		movw %%bx, (%%edi)						\n" \
-"		addl $2, %%edi							\n" \
-"		addw %%bx, %%ax							\n" \
-"		adcl $0, %%eax							\n" \
-"	2:									\n" \
-"		pushl %%ecx							\n" \
-"		shrl $5, %%ecx							\n" \
-"		jz 2f								\n" \
-"		testl %%esi, %%esi						\n" \
-"	1002:									\n" \
-"	1:	movl (%%esi), %%ebx						\n" \
-"	1003:									\n" \
-"		movl 4(%%esi), %%edx						\n" \
-"		adcl %%ebx, %%eax						\n" \
-"	1004:									\n" \
-"		movl %%ebx, (%%edi)						\n" \
-"		adcl %%edx, %%eax						\n" \
-"	1005:									\n" \
-"		movl %%edx, 4(%%edi)						\n" \
-"	 									\n" \
-"	1006:									\n" \
-"		movl 8(%%esi), %%ebx						\n" \
-"	1007:									\n" \
-"		movl 12(%%esi), %%edx						\n" \
-"		adcl %%ebx, %%eax						\n" \
-"	1008:									\n" \
-"		movl %%ebx, 8(%%edi)						\n" \
-"		adcl %%edx, %%eax						\n" \
-"	1009:									\n" \
-"		movl %%edx, 12(%%edi)						\n" \
-"	 									\n" \
-"	1010: 									\n" \
-"		movl 16(%%esi), %%ebx 						\n" \
-"	1011: 									\n" \
-"		movl 20(%%esi), %%edx						\n" \
-"		adcl %%ebx, %%eax						\n" \
-"	1012:									\n" \
-"		movl %%ebx, 16(%%edi)						\n" \
-"		adcl %%edx, %%eax						\n" \
-"	1013:									\n" \
-"		movl %%edx, 20(%%edi)						\n" \
-"										\n" \
-"	1014:									\n" \
-"		movl 24(%%esi), %%ebx						\n" \
-"	1015:									\n" \
-"		movl 28(%%esi), %%edx						\n" \
-"		adcl %%ebx, %%eax						\n" \
-"	1016:									\n" \
-"		movl %%ebx, 24(%%edi)						\n" \
-"		adcl %%edx, %%eax						\n" \
-"	1017:									\n" \
-"		movl %%edx, 28(%%edi)						\n" \
-"	 									\n" \
-"	1018:									\n" \
-"		lea 32(%%esi), %%esi						\n" \
-"	1019:									\n" \
-"		lea 32(%%edi), %%edi						\n" \
-"		dec %%ecx							\n" \
-"		jne 1b								\n" \
-"		adcl $0, %%eax							\n" \
-"	2:	popl %%edx							\n" \
-"		movl %%edx, %%ecx						\n" \
-"		andl $0x1c, %%edx						\n" \
-"		je 4f								\n" \
-"		shrl $2, %%edx		# This clears CF			\n" \
-"	1020:									\n" \
-"	3:	movl (%%esi), %%ebx						\n" \
-"		adcl %%ebx, %%eax						\n" \
-"	1021:									\n" \
-"		movl %%ebx, (%%edi)						\n" \
-"	1022:									\n" \
-"		lea 4(%%esi), %%esi						\n" \
-"	1023:									\n" \
-"		lea 4(%%edi), %%edi						\n" \
-"		dec %%edx							\n" \
-"		jne 3b								\n" \
-"		adcl $0, %%eax							\n" \
-"	4:	andl $3, %%ecx							\n" \
-"		jz 7f								\n" \
-"		cmpl $2, %%ecx							\n" \
-"		jb 5f								\n" \
-"	1024:									\n" \
-"		movw (%%esi), %%cx						\n" \
-"	1025:									\n" \
-"		leal 2(%%esi), %%esi						\n" \
-"	1026:									\n" \
-"		movw %%cx, (%%edi)						\n" \
-"	1027:									\n" \
-"		leal 2(%%edi), %%edi						\n" \
-"		je 6f								\n" \
-"		shll $16,%%ecx							\n" \
-"	1028:									\n" \
-"	5:	movb (%%esi), %%cl						\n" \
-"	1029:									\n" \
-"		movb %%cl, (%%edi)						\n" \
-"	6:	addl %%ecx, %%eax						\n" \
-"		adcl $0, %%eax							\n" \
-"	7:									\n" \
-"	2000:									\n" \
-"     	   .section .fixup,\"ax\"						\n" \
-"	3000:		movl %7,%1						\n" \
-/* FIXME: zero out the rest of the buffer here !!!!!! */			\
-"		jmp 2000b							\n" \
-"		.previous							\n" \
-"		.section __ex_table,\"a\"					\n" \
-"		.align 4                   					\n" \
-"										\n" \
-SRC(  "        .long 1000b,3000b        \n  "    ) \
-DST(  "        .long 1001b,3000b        \n  "    ) \
-SRC(  "        .long 1002b,3000b        \n  "    ) \
-SRC(  "        .long 1003b,3000b        \n  "    ) \
-DST(  "        .long 1004b,3000b        \n  "    ) \
-DST(  "        .long 1005b,3000b        \n  "    ) \
-SRC(  "        .long 1006b,3000b        \n  "    ) \
-SRC(  "        .long 1007b,3000b        \n  "    ) \
-DST(  "        .long 1008b,3000b        \n  "    ) \
-DST(  "        .long 1009b,3000b        \n  "    ) \
-SRC(  "        .long 1010b,3000b        \n  "    ) \
-SRC(  "        .long 1011b,3000b        \n  "    ) \
-DST(  "        .long 1012b,3000b        \n  "    ) \
-DST(  "        .long 1013b,3000b        \n  "    ) \
-SRC(  "        .long 1014b,3000b        \n  "    ) \
-SRC(  "        .long 1015b,3000b        \n  "    ) \
-DST(  "        .long 1016b,3000b        \n  "    ) \
-DST(  "        .long 1017b,3000b        \n  "    ) \
-SRC(  "        .long 1018b,3000b        \n  "    ) \
-DST(  "        .long 1019b,3000b        \n  "    ) \
-SRC(  "        .long 1020b,3000b        \n  "    ) \
-DST(  "        .long 1021b,3000b        \n  "    ) \
-SRC(  "        .long 1022b,3000b        \n  "    ) \
-DST(  "        .long 1023b,3000b        \n  "    ) \
-SRC(  "        .long 1024b,3000b        \n  "    ) \
-SRC(  "        .long 1025b,3000b        \n  "    ) \
-DST(  "        .long 1026b,3000b        \n  "    ) \
-DST(  "        .long 1027b,3000b        \n  "    ) \
-SRC(  "        .long 1028b,3000b        \n  "    ) \
-DST(  "        .long 1029b,3000b        \n  "    ) \
-"        .previous                      \n  " 				\
-	: "=a" (sum), "=r" (*__csum_err)   				\
-	:  "0" (sum), "c" (len), "S" (src), "D" (dst), 			\
-		"1" (*__csum_err), "i" (-EFAULT)   			\
-	: "bx", "cx", "dx", "si", "di" );  				\
- 									\
-    return(sum);  							\
-}
+#define SRC(y...)			\
+"	9999: "#y";			\n \
+	.section __ex_table, \"a\";	\n \
+	.long 9999b, src_access_fault	\n \
+	.previous"
+
+#define DST(y...)			\
+"	9999: "#y";			\n \
+	.section __ex_table, \"a\";	\n \
+	.long 9999b, dst_access_fault	\n \
+	.previous"
 
-/*
- *  Currently we need only 2 out of the 4 possible type combinations:
- */
-
-/*
- * Generate 'csum_partial_copy_from_user()', we need to do exception
- * handling for source addresses.
- */
-
-#define SRC(x) x
-#define DST(x)
-csum_partial_copy_type(_from_user)
-#undef SRC
-#undef DST
+unsigned int csum_partial_copy_generic (const char *src, char *dst,
+				  int len, int sum, int *src_err_ptr, int *dst_err_ptr)
+{
+    __asm__ __volatile__ ( "
+		testl $2, %%edi		# Check alignment. 
+		jz 2f			# Jump if alignment is ok.
+		subl $2, %%ecx		# Alignment uses up two bytes.
+		jae 1f			# Jump if we had at least two bytes.
+		addl $2, %%ecx		# ecx was < 2.  Deal with it.
+		jmp 4f
+"SRC(	1:	movw (%%esi), %%bx				)"
+		addl $2, %%esi
+"DST(		movw %%bx, (%%edi)				)"
+		addl $2, %%edi
+		addw %%bx, %%ax	
+		adcl $0, %%eax
+	2:
+		pushl %%ecx
+		shrl $5, %%ecx
+		jz 2f
+		testl %%esi, %%esi
+"SRC(	1:	movl (%%esi), %%ebx				)"
+"SRC(		movl 4(%%esi), %%edx				)"
+		adcl %%ebx, %%eax
+"DST(		movl %%ebx, (%%edi)				)"
+		adcl %%edx, %%eax
+"DST(		movl %%edx, 4(%%edi)				)"
+
+"SRC(		movl 8(%%esi), %%ebx				)"
+"SRC(		movl 12(%%esi), %%edx				)"
+		adcl %%ebx, %%eax
+"DST(		movl %%ebx, 8(%%edi)				)"
+		adcl %%edx, %%eax
+"DST(		movl %%edx, 12(%%edi)				)"
+
+"SRC(		movl 16(%%esi), %%ebx 				)"
+"SRC(		movl 20(%%esi), %%edx				)"
+		adcl %%ebx, %%eax
+"DST(		movl %%ebx, 16(%%edi)				)"
+		adcl %%edx, %%eax
+"DST(		movl %%edx, 20(%%edi)				)"
+
+"SRC(		movl 24(%%esi), %%ebx				)"
+"SRC(		movl 28(%%esi), %%edx				)"
+		adcl %%ebx, %%eax
+"DST(		movl %%ebx, 24(%%edi)				)"
+		adcl %%edx, %%eax
+"DST(		movl %%edx, 28(%%edi)				)"
+
+"SRC(		lea 32(%%esi), %%esi				)"
+"DST(		lea 32(%%edi), %%edi				)"
+		dec %%ecx
+		jne 1b
+		adcl $0, %%eax
+	2:	popl %%edx
+		movl %%edx, %%ecx
+		andl $0x1c, %%edx
+		je 4f
+		shrl $2, %%edx		# This clears CF
+"SRC(	3:	movl (%%esi), %%ebx				)"
+		adcl %%ebx, %%eax
+"DST(		movl %%ebx, (%%edi)				)"
+"SRC(		lea 4(%%esi), %%esi				)"
+"DST(		lea 4(%%edi), %%edi				)"
+		dec %%edx
+		jne 3b
+		adcl $0, %%eax
+	4:	andl $3, %%ecx
+		jz 7f
+		cmpl $2, %%ecx
+		jb 5f
+"SRC(		movw (%%esi), %%cx				)"
+"SRC(		leal 2(%%esi), %%esi				)"
+"DST(		movw %%cx, (%%edi)				)"
+"DST(		leal 2(%%edi), %%edi				)"
+		je 6f
+		shll $16,%%ecx
+"SRC(	5:	movb (%%esi), %%cl				)"
+"DST(		movb %%cl, (%%edi)				)"
+	6:	addl %%ecx, %%eax
+		adcl $0, %%eax
+	7:
+
+end_of_body:
+
+# Exception handler:
+################################################
+						#
+.section .fixup, \"a\"				#
+						#
+common_fixup:					#
+						#
+	movl	%7, (%%ebx)			#
+						#
+# FIXME: do zeroing of rest of the buffer here. #
+						#
+	jmp	end_of_body			#
+						#
+src_access_fault:				#
+	movl    %1, %%ebx			#
+	jmp	common_fixup			#
+						#
+dst_access_fault:				#
+	movl    %2, %%ebx			#
+	jmp	common_fixup			#
+						#
+.previous					#
+						#
+################################################
+
+"
+	: "=a" (sum), "=m" (src_err_ptr), "=m" (dst_err_ptr)
+	:  "0" (sum), "c" (len), "S" (src), "D" (dst),
+		"i" (-EFAULT)
+	: "bx", "cx", "dx", "si", "di" );
 
-/*
- * Generate 'csum_partial_copy_nocheck()', no need to do exception
- * handling.
- */
+    return(sum);
+}
 
-#define SRC(x)
-#define DST(x)
-csum_partial_copy_type(_nocheck_generic)
 #undef SRC
 #undef DST
 
 /*
- * Generate 'csum_partial_copy_old()', old and slow compability stuff,
- * full checking.
- *
- * tell us if you see something printk-ing on this. This function will be
- * removed soon.
+ * FIXME: old compatibility stuff, will be removed soon.
  */
 
-#define SRC(x) x
-#define DST(x) x
-csum_partial_copy_type(_old)
-#undef SRC
-#undef DST
-
-unsigned int csum_partial_copy ( const char *src, char *dst, 
-				  int len, int sum)
+unsigned int csum_partial_copy( const char *src, char *dst, int len, int sum)
 {
-	int ret;
-	int error = 0;
+	int src_err=0, dst_err=0;
 
-	ret = csum_partial_copy_old (&error, src, dst, len, sum);
+	sum = csum_partial_copy_generic ( src, dst, len, sum, &src_err, &dst_err);
 
-	if (error)
-		printk("csum_partial_copy_old(): tell mingo to convert me!\n");
+	if (src_err || dst_err)
+		printk("old csum_partial_copy_fromuser(), tell mingo to convert me.\n");
 
-	return ret;
+	return sum;
 }
+
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov