fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / arch / x86_64 / lib / usercopy.c
index 4a8603e..893d43f 100644 (file)
@@ -5,6 +5,7 @@
  * Copyright 1997 Linus Torvalds
  * Copyright 2002 Andi Kleen <ak@suse.de>
  */
+#include <linux/module.h>
 #include <asm/uaccess.h>
 
 /*
@@ -14,6 +15,7 @@
 #define __do_strncpy_from_user(dst,src,count,res)                         \
 do {                                                                      \
        long __d0, __d1, __d2;                                             \
+       might_sleep();                                                     \
        __asm__ __volatile__(                                              \
                "       testq %1,%1\n"                                     \
                "       jz 2f\n"                                           \
@@ -40,29 +42,32 @@ do {                                                                           \
 } while (0)
 
 long
-__strncpy_from_user(char *dst, const char *src, long count)
+__strncpy_from_user(char *dst, const char __user *src, long count)
 {
        long res;
        __do_strncpy_from_user(dst, src, count, res);
        return res;
 }
+EXPORT_SYMBOL(__strncpy_from_user);
 
 long
-strncpy_from_user(char *dst, const char *src, long count)
+strncpy_from_user(char *dst, const char __user *src, long count)
 {
        long res = -EFAULT;
        if (access_ok(VERIFY_READ, src, 1))
-               __do_strncpy_from_user(dst, src, count, res);
+               return __strncpy_from_user(dst, src, count);
        return res;
 }
+EXPORT_SYMBOL(strncpy_from_user);
 
 /*
  * Zero Userspace
  */
 
-unsigned long __clear_user(void *addr, unsigned long size)
+unsigned long __clear_user(void __user *addr, unsigned long size)
 {
        long __d0;
+       might_sleep();
        /* no memory constraint because it doesn't change any memory gcc knows
           about */
        asm volatile(
@@ -92,14 +97,15 @@ unsigned long __clear_user(void *addr, unsigned long size)
                  [zero] "r" (0UL), [eight] "r" (8UL));
        return size;
 }
+EXPORT_SYMBOL(__clear_user);
 
-
-unsigned long clear_user(void *to, unsigned long n)
+unsigned long clear_user(void __user *to, unsigned long n)
 {
        if (access_ok(VERIFY_WRITE, to, n))
                return __clear_user(to, n);
        return n;
 }
+EXPORT_SYMBOL(clear_user);
 
 /*
  * Return the size of a string (including the ending 0)
@@ -107,14 +113,11 @@ unsigned long clear_user(void *to, unsigned long n)
  * Return 0 on exception, a value greater than N if too long
  */
 
-long strnlen_user(const char *s, long n)
+long __strnlen_user(const char __user *s, long n)
 {
        long res = 0;
        char c;
 
-       if (!access_ok(VERIFY_READ, s, n))
-               return 0;
-
        while (1) {
                if (res>n)
                        return n+1;
@@ -126,8 +129,17 @@ long strnlen_user(const char *s, long n)
                s++;
        }
 }
+EXPORT_SYMBOL(__strnlen_user);
+
+long strnlen_user(const char __user *s, long n)
+{
+       if (!access_ok(VERIFY_READ, s, n))
+               return 0;
+       return __strnlen_user(s, n);
+}
+EXPORT_SYMBOL(strnlen_user);
 
-long strlen_user(const char *s)
+long strlen_user(const char __user *s)
 {
        long res = 0;
        char c;
@@ -141,11 +153,14 @@ long strlen_user(const char *s)
                s++;
        }
 }
+EXPORT_SYMBOL(strlen_user);
 
-unsigned long copy_in_user(void *to, const void *from, unsigned len)
+unsigned long copy_in_user(void __user *to, const void __user *from, unsigned len)
 {
        if (access_ok(VERIFY_WRITE, to, len) && access_ok(VERIFY_READ, from, len)) { 
-               return copy_user_generic(to, from, len);
+               return copy_user_generic((__force void *)to, (__force void *)from, len);
        } 
        return len;             
 }
+EXPORT_SYMBOL(copy_in_user);
+