| 
					
				 | 
			
			
				@@ -45,3 +45,94 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  * For historical reasons, the following macros are grossly misnamed: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define KERNEL_DS	((mm_segment_t) { ~0UL })		/* cf. access_ok() */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define USER_DS		((mm_segment_t) { TASK_SIZE-1 })	/* cf. access_ok() */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define VERIFY_READ	0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define VERIFY_WRITE	1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define get_ds()  (KERNEL_DS) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define get_fs()  (current_thread_info()->addr_limit) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define set_fs(x) (current_thread_info()->addr_limit = (x)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define segment_eq(a, b)	((a).seg == (b).seg) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * When accessing user memory, we need to make sure the entire area really is in 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * user-level space.  In order to do this efficiently, we make sure that the page at 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * address TASK_SIZE is never valid.  We also need to make sure that the address doesn't 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * point inside the virtually mapped linear page table. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define __access_ok(addr, size, segment)						\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+({											\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	__chk_user_ptr(addr);								\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	(likely((unsigned long) (addr) <= (segment).seg)				\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 && ((segment).seg == KERNEL_DS.seg						\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	     || likely(REGION_OFFSET((unsigned long) (addr)) < RGN_MAP_LIMIT)));	\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define access_ok(type, addr, size)	__access_ok((addr), (size), get_fs()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * These are the main single-value transfer routines.  They automatically 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * use the right size if we just have the right pointer type. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Careful to not 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * (a) re-use the arguments for side effects (sizeof/typeof is ok) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * (b) require any knowledge of processes at this stage 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define put_user(x, ptr)	__put_user_check((__typeof__(*(ptr))) (x), (ptr), sizeof(*(ptr)), get_fs()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define get_user(x, ptr)	__get_user_check((x), (ptr), sizeof(*(ptr)), get_fs()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * The "__xxx" versions do not do address space checking, useful when 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * doing multiple accesses to the same area (the programmer has to do the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * checks by hand with "access_ok()") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define __put_user(x, ptr)	__put_user_nocheck((__typeof__(*(ptr))) (x), (ptr), sizeof(*(ptr))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define __get_user(x, ptr)	__get_user_nocheck((x), (ptr), sizeof(*(ptr))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+extern long __put_user_unaligned_unknown (void); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define __put_user_unaligned(x, ptr)								\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+({												\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	long __ret;										\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	switch (sizeof(*(ptr))) {								\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		case 1: __ret = __put_user((x), (ptr)); break;					\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		case 2: __ret = (__put_user((x), (u8 __user *)(ptr)))				\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			| (__put_user((x) >> 8, ((u8 __user *)(ptr) + 1))); break;		\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		case 4: __ret = (__put_user((x), (u16 __user *)(ptr)))				\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			| (__put_user((x) >> 16, ((u16 __user *)(ptr) + 1))); break;		\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		case 8: __ret = (__put_user((x), (u32 __user *)(ptr)))				\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			| (__put_user((x) >> 32, ((u32 __user *)(ptr) + 1))); break;		\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		default: __ret = __put_user_unaligned_unknown();				\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	}											\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	__ret;											\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+extern long __get_user_unaligned_unknown (void); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define __get_user_unaligned(x, ptr)								\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+({												\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	long __ret;										\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	switch (sizeof(*(ptr))) {								\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		case 1: __ret = __get_user((x), (ptr)); break;					\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		case 2: __ret = (__get_user((x), (u8 __user *)(ptr)))				\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			| (__get_user((x) >> 8, ((u8 __user *)(ptr) + 1))); break;		\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		case 4: __ret = (__get_user((x), (u16 __user *)(ptr)))				\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			| (__get_user((x) >> 16, ((u16 __user *)(ptr) + 1))); break;		\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		case 8: __ret = (__get_user((x), (u32 __user *)(ptr)))				\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			| (__get_user((x) >> 32, ((u32 __user *)(ptr) + 1))); break;		\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		default: __ret = __get_user_unaligned_unknown();				\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	}											\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	__ret;											\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#ifdef ASM_SUPPORTED 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  struct __large_struct { unsigned long buf[100]; }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+# define __m(x) (*(struct __large_struct __user *)(x)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* We need to declare the __ex_table section before we can use it in .xdata.  */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+asm (".section \"__ex_table\", \"a\"\n\t.previous"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+# define __get_user_size(val, addr, n, err)							\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+do {												\ 
			 |