Sophie

Sophie

distrib > Mandriva > 8.2 > i586 > by-pkgid > 795ae080bdb8618620666fed9e003621 > files > 53

kernel22-2.2.25-1.1mdk.src.rpm

diff -urN x/include/asm-alpha/smplock.h unlock-alpha/include/asm-alpha/smplock.h
--- x/include/asm-alpha/smplock.h	Mon Dec 11 16:58:03 2000
+++ unlock-alpha/include/asm-alpha/smplock.h	Thu Mar  1 16:43:46 2001
@@ -28,6 +28,25 @@
 		spin_lock(&kernel_flag);
 }
 
+#define DECLARE_LOCAL_LOCK_DEPTH(x) int x
+
+#define release_kernel_lock_save(local_depth) \
+do { \
+	(local_depth) = current->lock_depth; \
+	if ((local_depth) >= 0) { \
+		current->lock_depth = -1; \
+		spin_unlock(&kernel_flag); \
+	} \
+} while (0)
+
+#define reacquire_kernel_lock_restore(local_depth) \
+do { \
+	if ((local_depth) >= 0) { \
+		current->lock_depth = local_depth; \
+		spin_lock(&kernel_flag); \
+	} \
+} while (0)
+
 /*
  * Getting the big kernel lock.
  *
diff -urN x/include/asm-alpha/uaccess.h unlock-alpha/include/asm-alpha/uaccess.h
--- x/include/asm-alpha/uaccess.h	Thu Mar  1 16:38:54 2001
+++ unlock-alpha/include/asm-alpha/uaccess.h	Thu Mar  1 16:43:46 2001
@@ -3,6 +3,8 @@
 
 #include <linux/errno.h>
 #include <linux/sched.h>
+#include <linux/condsched.h>
+#include <linux/smp_lock.h>
 
 
 /*
@@ -402,8 +404,17 @@
 	return len;
 }
 
-#define __copy_to_user(to,from,n)   __copy_tofrom_user_nocheck((to),(from),(n))
-#define __copy_from_user(to,from,n) __copy_tofrom_user_nocheck((to),(from),(n))
+#define __copy_to_user(to,from,n)				\
+({								\
+	long ret;						\
+	DECLARE_LOCAL_LOCK_DEPTH(lock_depth);			\
+	release_kernel_lock_save(lock_depth);			\
+	ret = __copy_tofrom_user_nocheck((to),(from),(n));	\
+	conditional_schedule();					\
+	reacquire_kernel_lock_restore(lock_depth);		\
+	ret;							\
+})
+#define __copy_from_user(to,from,n) __copy_to_user(to,from,n)
 
 extern inline long
 copy_to_user(void *to, const void *from, long n)
@@ -430,7 +441,7 @@
 extern void __do_clear_user(void);
 
 extern inline long
-__clear_user(void *to, long len)
+____clear_user(void *to, long len)
 {
 	/* This little bit of silliness is to get the GP loaded for
 	   a function that ordinarily wouldn't.  Otherwise we could
@@ -448,20 +459,22 @@
 	return __cl_len;
 }
 
+#define __clear_user(to,len)				\
+({							\
+	long ret;					\
+	DECLARE_LOCAL_LOCK_DEPTH(lock_depth);		\
+	release_kernel_lock_save(lock_depth);		\
+	ret = ____clear_user((to),(len));		\
+	conditional_schedule();				\
+	reacquire_kernel_lock_restore(lock_depth);	\
+	ret;						\
+})
+
 extern inline long
 clear_user(void *to, long len)
 {
-	if (__access_ok((long)to, len, get_fs())) {
-		register void * pv __asm__("$27") = __do_clear_user;
-		register void * __cl_to __asm__("$6") = to;
-		register long __cl_len __asm__("$0") = len;
-		__asm__ __volatile__(
-			"jsr $28,(%2),__do_clear_user\n\tldgp $29,0($28)"
-			: "=r"(__cl_len), "=r"(__cl_to), "=r"(pv)
-			: "0"(__cl_len), "1"(__cl_to), "2"(pv)
-			: "$1","$2","$3","$4","$5","$28","memory");
-		len = __cl_len;
-	}
+	if (__access_ok((long)to, len, get_fs()))
+		len = __clear_user(to, len);
 	return len;
 }
 
@@ -474,8 +487,13 @@
 strncpy_from_user(char *to, const char *from, long n)
 {
 	long ret = -EFAULT;
-	if (__access_ok((long)from, 0, get_fs()))
+	if (__access_ok((long)from, 0, get_fs())) {
+		DECLARE_LOCAL_LOCK_DEPTH(lock_depth);
+		release_kernel_lock_save(lock_depth);
 		ret = __strncpy_from_user(to, from, n);
+		conditional_schedule();
+		reacquire_kernel_lock_restore(lock_depth);
+	}
 	return ret;
 }
 
@@ -485,7 +503,15 @@
 
 extern inline long strnlen_user(const char *str, long n)
 {
-	return access_ok(VERIFY_READ,str,0) ? __strnlen_user(str, n) : 0;
+	long ret = 0;
+	if (access_ok(VERIFY_READ,str,0)) {
+		DECLARE_LOCAL_LOCK_DEPTH(lock_depth);
+		release_kernel_lock_save(lock_depth);
+		ret = __strnlen_user(str, n);
+		conditional_schedule();
+		reacquire_kernel_lock_restore(lock_depth);
+	}
+	return ret;
 }
 
 /*