xref: /openbmc/linux/arch/arm/lib/putuser.S (revision d2912cb1)
1d2912cb1SThomas 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