1/* SPDX-License-Identifier: GPL-2.0-only */ 2/* 3 * linux/arch/arm/lib/putuser.S 4 * 5 * Copyright (C) 2001 Russell King 6 * 7 * Idea from x86 version, (C) Copyright 1998 Linus Torvalds 8 * 9 * These functions have a non-standard call interface to make 10 * them more efficient, especially as they return an error 11 * value in addition to the "real" return value. 12 * 13 * __put_user_X 14 * 15 * Inputs: r0 contains the address 16 * r1 contains the address limit, which must be preserved 17 * r2, r3 contains the value 18 * Outputs: r0 is the error code 19 * lr corrupted 20 * 21 * No other registers must be altered. (see <asm/uaccess.h> 22 * for specific ASM register usage). 23 * 24 * Note that ADDR_LIMIT is either 0 or 0xc0000000 25 * Note also that it is intended that __put_user_bad is not global. 26 */ 27#include <linux/linkage.h> 28#include <asm/assembler.h> 29#include <asm/errno.h> 30#include <asm/domain.h> 31 32ENTRY(__put_user_1) 33 check_uaccess r0, 1, r1, ip, __put_user_bad 341: TUSER(strb) r2, [r0] 35 mov r0, #0 36 ret lr 37ENDPROC(__put_user_1) 38 39ENTRY(__put_user_2) 40 check_uaccess r0, 2, r1, ip, __put_user_bad 41#if __LINUX_ARM_ARCH__ >= 6 42 432: TUSER(strh) r2, [r0] 44 45#else 46 47 mov ip, r2, lsr #8 48#ifndef __ARMEB__ 492: TUSER(strb) r2, [r0], #1 503: TUSER(strb) ip, [r0] 51#else 522: TUSER(strb) ip, [r0], #1 533: TUSER(strb) r2, [r0] 54#endif 55 56#endif /* __LINUX_ARM_ARCH__ >= 6 */ 57 mov r0, #0 58 ret lr 59ENDPROC(__put_user_2) 60 61ENTRY(__put_user_4) 62 check_uaccess r0, 4, r1, ip, __put_user_bad 634: TUSER(str) r2, [r0] 64 mov r0, #0 65 ret lr 66ENDPROC(__put_user_4) 67 68ENTRY(__put_user_8) 69 check_uaccess r0, 8, r1, ip, __put_user_bad 70#ifdef CONFIG_THUMB2_KERNEL 715: TUSER(str) r2, [r0] 726: TUSER(str) r3, [r0, #4] 73#else 745: TUSER(str) r2, [r0], #4 756: TUSER(str) r3, [r0] 76#endif 77 mov r0, #0 78 ret lr 79ENDPROC(__put_user_8) 80 81__put_user_bad: 82 mov r0, #-EFAULT 83 ret lr 84ENDPROC(__put_user_bad) 85 86.pushsection __ex_table, "a" 87 .long 1b, __put_user_bad 88 .long 2b, __put_user_bad 89#if __LINUX_ARM_ARCH__ < 6 90 .long 3b, __put_user_bad 91#endif 92 .long 4b, __put_user_bad 93 .long 5b, __put_user_bad 94 .long 6b, __put_user_bad 95.popsection 96