1/* 2 * linux/arch/arm26/lib/getuser.S 3 * 4 * Copyright (C) 2001 Russell King 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 * 10 * Idea from x86 version, (C) Copyright 1998 Linus Torvalds 11 * 12 * These functions have a non-standard call interface to make them more 13 * efficient, especially as they return an error value in addition to 14 * the "real" return value. 15 * 16 * __get_user_X 17 * 18 * Inputs: r0 contains the address 19 * Outputs: r0 is the error code 20 * r1, r2 contains the zero-extended value 21 * lr corrupted 22 * 23 * No other registers must be altered. (see include/asm-arm/uaccess.h 24 * for specific ASM register usage). 25 * 26 * Note that ADDR_LIMIT is either 0 or 0xc0000000. 27 * Note also that it is intended that __get_user_bad is not global. 28 */ 29#include <asm/asm-offsets.h> 30#include <asm/thread_info.h> 31#include <asm/errno.h> 32 33 .global __get_user_1 34__get_user_1: 35 bic r1, sp, #0x1f00 36 bic r1, r1, #0x00ff 37 str lr, [sp, #-4]! 38 ldr r1, [r1, #TI_ADDR_LIMIT] 39 sub r1, r1, #1 40 cmp r0, r1 41 bge __get_user_bad 42 cmp r0, #0x02000000 431: ldrlsbt r1, [r0] 44 ldrgeb r1, [r0] 45 mov r0, #0 46 ldmfd sp!, {pc}^ 47 48 .global __get_user_2 49__get_user_2: 50 bic r2, sp, #0x1f00 51 bic r2, r2, #0x00ff 52 str lr, [sp, #-4]! 53 ldr r2, [r2, #TI_ADDR_LIMIT] 54 sub r2, r2, #2 55 cmp r0, r2 56 bge __get_user_bad 57 cmp r0, #0x02000000 582: ldrlsbt r1, [r0], #1 593: ldrlsbt r2, [r0] 60 ldrgeb r1, [r0], #1 61 ldrgeb r2, [r0] 62 orr r1, r1, r2, lsl #8 63 mov r0, #0 64 ldmfd sp!, {pc}^ 65 66 .global __get_user_4 67__get_user_4: 68 bic r1, sp, #0x1f00 69 bic r1, r1, #0x00ff 70 str lr, [sp, #-4]! 71 ldr r1, [r1, #TI_ADDR_LIMIT] 72 sub r1, r1, #4 73 cmp r0, r1 74 bge __get_user_bad 75 cmp r0, #0x02000000 764: ldrlst r1, [r0] 77 ldrge r1, [r0] 78 mov r0, #0 79 ldmfd sp!, {pc}^ 80 81 .global __get_user_8 82__get_user_8: 83 bic r2, sp, #0x1f00 84 bic r2, r2, #0x00ff 85 str lr, [sp, #-4]! 86 ldr r2, [r2, #TI_ADDR_LIMIT] 87 sub r2, r2, #8 88 cmp r0, r2 89 bge __get_user_bad_8 90 cmp r0, #0x02000000 915: ldrlst r1, [r0], #4 926: ldrlst r2, [r0] 93 ldrge r1, [r0], #4 94 ldrge r2, [r0] 95 mov r0, #0 96 ldmfd sp!, {pc}^ 97 98__get_user_bad_8: 99 mov r2, #0 100__get_user_bad: 101 mov r1, #0 102 mov r0, #-EFAULT 103 ldmfd sp!, {pc}^ 104 105.section __ex_table, "a" 106 .long 1b, __get_user_bad 107 .long 2b, __get_user_bad 108 .long 3b, __get_user_bad 109 .long 4b, __get_user_bad 110 .long 5b, __get_user_bad_8 111 .long 6b, __get_user_bad_8 112.previous 113