patch-2.4.23 linux-2.4.23/include/asm-ppc/uaccess.h

Next file: linux-2.4.23/include/asm-ppc/ucontext.h
Previous file: linux-2.4.23/include/asm-ppc/sigcontext.h
Back to the patch index
Back to the overall index

diff -urN linux-2.4.22/include/asm-ppc/uaccess.h linux-2.4.23/include/asm-ppc/uaccess.h
@@ -77,16 +77,28 @@
  * As we use the same address space for kernel and user data on the
  * PowerPC, we can just do these as direct assignments.  (Of course, the
  * exception handling means that it's no longer "just"...)
+ *
+ * The "user64" versions of the user access functions are versions that 
+ * allow access of 64-bit data. The "get_user" functions do not 
+ * properly handle 64-bit data because the value gets down cast to a long. 
+ * The "put_user" functions already handle 64-bit data properly but we add 
+ * "user64" versions for completeness
  */
 #define get_user(x,ptr) \
   __get_user_check((x),(ptr),sizeof(*(ptr)))
+#define get_user64(x,ptr) \
+  __get_user64_check((x),(ptr),sizeof(*(ptr)))
 #define put_user(x,ptr) \
   __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
+#define put_user64(x,ptr) put_user(x,ptr)
 
 #define __get_user(x,ptr) \
   __get_user_nocheck((x),(ptr),sizeof(*(ptr)))
+#define __get_user64(x,ptr) \
+  __get_user64_nocheck((x),(ptr),sizeof(*(ptr)))
 #define __put_user(x,ptr) \
   __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
+#define __put_user64(x,ptr) __put_user(x,ptr)
 
 extern long __put_user_bad(void);
 
@@ -166,6 +178,15 @@
 	__gu_err;						\
 })
 
+#define __get_user64_nocheck(x,ptr,size)			\
+({								\
+	long __gu_err;						\
+	long long __gu_val;					\
+	__get_user_size64(__gu_val,(ptr),(size),__gu_err);	\
+	(x) = (__typeof__(*(ptr)))__gu_val;			\
+	__gu_err;						\
+})
+
 #define __get_user_check(x,ptr,size)					\
 ({									\
 	long __gu_err = -EFAULT, __gu_val = 0;				\
@@ -176,6 +197,17 @@
 	__gu_err;							\
 })
 
+#define __get_user64_check(x,ptr,size)					\
+({									\
+	long __gu_err = -EFAULT;					\
+	long long __gu_val = 0;						\
+	const __typeof__(*(ptr)) *__gu_addr = (ptr);			\
+	if (access_ok(VERIFY_READ,__gu_addr,size))			\
+		__get_user_size64(__gu_val,__gu_addr,(size),__gu_err);	\
+	(x) = (__typeof__(*(ptr)))__gu_val;				\
+	__gu_err;							\
+})
+
 extern long __get_user_bad(void);
 
 #define __get_user_size(x,ptr,size,retval)			\
@@ -185,6 +217,17 @@
 	  case 1: __get_user_asm(x,ptr,retval,"lbz"); break;	\
 	  case 2: __get_user_asm(x,ptr,retval,"lhz"); break;	\
 	  case 4: __get_user_asm(x,ptr,retval,"lwz"); break;	\
+	  default: (x) = __get_user_bad();			\
+	}							\
+} while (0)
+
+#define __get_user_size64(x,ptr,size,retval)			\
+do {								\
+	retval = 0;						\
+	switch (size) {						\
+	  case 1: __get_user_asm(x,ptr,retval,"lbz"); break;	\
+	  case 2: __get_user_asm(x,ptr,retval,"lhz"); break;	\
+	  case 4: __get_user_asm(x,ptr,retval,"lwz"); break;	\
 	  case 8: __get_user_asm2(x, ptr, retval); break;	\
 	  default: (x) = __get_user_bad();			\
 	}							\

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)