--- 2.2.18pre7aa1/include/asm-alpha/uaccess.h.~1~ Thu Aug 24 19:11:39 2000 +++ 2.2.18pre7aa1/include/asm-alpha/uaccess.h Fri Sep 15 05:39:17 2000 @@ -3,6 +3,8 @@ #include #include +#include +#include /* @@ -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; } @@ -484,7 +502,15 @@ extern inline long strlen_user(const char *str) { - return access_ok(VERIFY_READ,str,0) ? __strlen_user(str) : 0; + long ret = 0; + if (access_ok(VERIFY_READ,str,0)) { + DECLARE_LOCAL_LOCK_DEPTH(lock_depth); + release_kernel_lock_save(lock_depth); + ret = __strlen_user(str); + conditional_schedule(); + reacquire_kernel_lock_restore(lock_depth); + } + return ret; } /* Returns: 0 if exception before NUL or reaching the supplied limit (N), @@ -493,7 +519,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; } /* --- 2.2.18pre7aa1/include/asm-alpha/smplock.h.~1~ Thu Sep 14 19:28:09 2000 +++ 2.2.18pre7aa1/include/asm-alpha/smplock.h Fri Sep 15 05:30:12 2000 @@ -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. *