1*d2912cb1SThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-only */ 21da177e4SLinus Torvalds/* 31da177e4SLinus Torvalds * linux/arch/arm/lib/putuser.S 41da177e4SLinus Torvalds * 51da177e4SLinus Torvalds * Copyright (C) 2001 Russell King 61da177e4SLinus Torvalds * 71da177e4SLinus Torvalds * Idea from x86 version, (C) Copyright 1998 Linus Torvalds 81da177e4SLinus Torvalds * 91da177e4SLinus Torvalds * These functions have a non-standard call interface to make 101da177e4SLinus Torvalds * them more efficient, especially as they return an error 111da177e4SLinus Torvalds * value in addition to the "real" return value. 121da177e4SLinus Torvalds * 131da177e4SLinus Torvalds * __put_user_X 141da177e4SLinus Torvalds * 151da177e4SLinus Torvalds * Inputs: r0 contains the address 168404663fSRussell King * r1 contains the address limit, which must be preserved 171da177e4SLinus Torvalds * r2, r3 contains the value 181da177e4SLinus Torvalds * Outputs: r0 is the error code 191da177e4SLinus Torvalds * lr corrupted 201da177e4SLinus Torvalds * 214baa9922SRussell King * No other registers must be altered. (see <asm/uaccess.h> 221da177e4SLinus Torvalds * for specific ASM register usage). 231da177e4SLinus Torvalds * 241da177e4SLinus Torvalds * Note that ADDR_LIMIT is either 0 or 0xc0000000 251da177e4SLinus Torvalds * Note also that it is intended that __put_user_bad is not global. 261da177e4SLinus Torvalds */ 2793ed3970SCatalin Marinas#include <linux/linkage.h> 288404663fSRussell King#include <asm/assembler.h> 291da177e4SLinus Torvalds#include <asm/errno.h> 30247055aaSCatalin Marinas#include <asm/domain.h> 311da177e4SLinus Torvalds 3293ed3970SCatalin MarinasENTRY(__put_user_1) 338404663fSRussell King check_uaccess r0, 1, r1, ip, __put_user_bad 344e7682d0SCatalin Marinas1: TUSER(strb) r2, [r0] 351da177e4SLinus Torvalds mov r0, #0 366ebbf2ceSRussell King ret lr 3793ed3970SCatalin MarinasENDPROC(__put_user_1) 381da177e4SLinus Torvalds 3993ed3970SCatalin MarinasENTRY(__put_user_2) 408404663fSRussell King check_uaccess r0, 2, r1, ip, __put_user_bad 41344eb553SVincent Whitchurch#if __LINUX_ARM_ARCH__ >= 6 42344eb553SVincent Whitchurch 43344eb553SVincent Whitchurch2: TUSER(strh) r2, [r0] 44344eb553SVincent Whitchurch 458b592783SCatalin Marinas#else 46344eb553SVincent Whitchurch 47344eb553SVincent Whitchurch mov ip, r2, lsr #8 481da177e4SLinus Torvalds#ifndef __ARMEB__ 494e7682d0SCatalin Marinas2: TUSER(strb) r2, [r0], #1 504e7682d0SCatalin Marinas3: TUSER(strb) ip, [r0] 511da177e4SLinus Torvalds#else 524e7682d0SCatalin Marinas2: TUSER(strb) ip, [r0], #1 534e7682d0SCatalin Marinas3: TUSER(strb) r2, [r0] 541da177e4SLinus Torvalds#endif 55344eb553SVincent Whitchurch 56344eb553SVincent Whitchurch#endif /* __LINUX_ARM_ARCH__ >= 6 */ 571da177e4SLinus Torvalds mov r0, #0 586ebbf2ceSRussell King ret lr 5993ed3970SCatalin MarinasENDPROC(__put_user_2) 601da177e4SLinus Torvalds 6193ed3970SCatalin MarinasENTRY(__put_user_4) 628404663fSRussell King check_uaccess r0, 4, r1, ip, __put_user_bad 634e7682d0SCatalin Marinas4: TUSER(str) r2, [r0] 641da177e4SLinus Torvalds mov r0, #0 656ebbf2ceSRussell King ret lr 6693ed3970SCatalin MarinasENDPROC(__put_user_4) 671da177e4SLinus Torvalds 6893ed3970SCatalin MarinasENTRY(__put_user_8) 698404663fSRussell King check_uaccess r0, 8, r1, ip, __put_user_bad 708b592783SCatalin Marinas#ifdef CONFIG_THUMB2_KERNEL 714e7682d0SCatalin Marinas5: TUSER(str) r2, [r0] 724e7682d0SCatalin Marinas6: TUSER(str) r3, [r0, #4] 738b592783SCatalin Marinas#else 744e7682d0SCatalin Marinas5: TUSER(str) r2, [r0], #4 754e7682d0SCatalin Marinas6: TUSER(str) r3, [r0] 768b592783SCatalin Marinas#endif 771da177e4SLinus Torvalds mov r0, #0 786ebbf2ceSRussell King ret lr 7993ed3970SCatalin MarinasENDPROC(__put_user_8) 801da177e4SLinus Torvalds 811da177e4SLinus Torvalds__put_user_bad: 821da177e4SLinus Torvalds mov r0, #-EFAULT 836ebbf2ceSRussell King ret lr 8493ed3970SCatalin MarinasENDPROC(__put_user_bad) 851da177e4SLinus Torvalds 864260415fSRussell King.pushsection __ex_table, "a" 871da177e4SLinus Torvalds .long 1b, __put_user_bad 881da177e4SLinus Torvalds .long 2b, __put_user_bad 89344eb553SVincent Whitchurch#if __LINUX_ARM_ARCH__ < 6 901da177e4SLinus Torvalds .long 3b, __put_user_bad 91344eb553SVincent Whitchurch#endif 921da177e4SLinus Torvalds .long 4b, __put_user_bad 931da177e4SLinus Torvalds .long 5b, __put_user_bad 941da177e4SLinus Torvalds .long 6b, __put_user_bad 954260415fSRussell King.popsection 96