162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * linux/arch/arm/lib/putuser.S 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2001 Russell King 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Idea from x86 version, (C) Copyright 1998 Linus Torvalds 862306a36Sopenharmony_ci * 962306a36Sopenharmony_ci * These functions have a non-standard call interface to make 1062306a36Sopenharmony_ci * them more efficient, especially as they return an error 1162306a36Sopenharmony_ci * value in addition to the "real" return value. 1262306a36Sopenharmony_ci * 1362306a36Sopenharmony_ci * __put_user_X 1462306a36Sopenharmony_ci * 1562306a36Sopenharmony_ci * Inputs: r0 contains the address 1662306a36Sopenharmony_ci * r1 contains the address limit, which must be preserved 1762306a36Sopenharmony_ci * r2, r3 contains the value 1862306a36Sopenharmony_ci * Outputs: r0 is the error code 1962306a36Sopenharmony_ci * lr corrupted 2062306a36Sopenharmony_ci * 2162306a36Sopenharmony_ci * No other registers must be altered. (see <asm/uaccess.h> 2262306a36Sopenharmony_ci * for specific ASM register usage). 2362306a36Sopenharmony_ci * 2462306a36Sopenharmony_ci * Note that ADDR_LIMIT is either 0 or 0xc0000000 2562306a36Sopenharmony_ci * Note also that it is intended that __put_user_bad is not global. 2662306a36Sopenharmony_ci */ 2762306a36Sopenharmony_ci#include <linux/linkage.h> 2862306a36Sopenharmony_ci#include <asm/assembler.h> 2962306a36Sopenharmony_ci#include <asm/errno.h> 3062306a36Sopenharmony_ci#include <asm/domain.h> 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ciENTRY(__put_user_1) 3362306a36Sopenharmony_ci check_uaccess r0, 1, r1, ip, __put_user_bad 3462306a36Sopenharmony_ci1: TUSER(strb) r2, [r0] 3562306a36Sopenharmony_ci mov r0, #0 3662306a36Sopenharmony_ci ret lr 3762306a36Sopenharmony_ciENDPROC(__put_user_1) 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ciENTRY(__put_user_2) 4062306a36Sopenharmony_ci check_uaccess r0, 2, r1, ip, __put_user_bad 4162306a36Sopenharmony_ci#if __LINUX_ARM_ARCH__ >= 6 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci2: TUSER(strh) r2, [r0] 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci#else 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci mov ip, r2, lsr #8 4862306a36Sopenharmony_ci#ifndef __ARMEB__ 4962306a36Sopenharmony_ci2: TUSER(strb) r2, [r0], #1 5062306a36Sopenharmony_ci3: TUSER(strb) ip, [r0] 5162306a36Sopenharmony_ci#else 5262306a36Sopenharmony_ci2: TUSER(strb) ip, [r0], #1 5362306a36Sopenharmony_ci3: TUSER(strb) r2, [r0] 5462306a36Sopenharmony_ci#endif 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci#endif /* __LINUX_ARM_ARCH__ >= 6 */ 5762306a36Sopenharmony_ci mov r0, #0 5862306a36Sopenharmony_ci ret lr 5962306a36Sopenharmony_ciENDPROC(__put_user_2) 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ciENTRY(__put_user_4) 6262306a36Sopenharmony_ci check_uaccess r0, 4, r1, ip, __put_user_bad 6362306a36Sopenharmony_ci4: TUSER(str) r2, [r0] 6462306a36Sopenharmony_ci mov r0, #0 6562306a36Sopenharmony_ci ret lr 6662306a36Sopenharmony_ciENDPROC(__put_user_4) 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ciENTRY(__put_user_8) 6962306a36Sopenharmony_ci check_uaccess r0, 8, r1, ip, __put_user_bad 7062306a36Sopenharmony_ci#ifdef CONFIG_THUMB2_KERNEL 7162306a36Sopenharmony_ci5: TUSER(str) r2, [r0] 7262306a36Sopenharmony_ci6: TUSER(str) r3, [r0, #4] 7362306a36Sopenharmony_ci#else 7462306a36Sopenharmony_ci5: TUSER(str) r2, [r0], #4 7562306a36Sopenharmony_ci6: TUSER(str) r3, [r0] 7662306a36Sopenharmony_ci#endif 7762306a36Sopenharmony_ci mov r0, #0 7862306a36Sopenharmony_ci ret lr 7962306a36Sopenharmony_ciENDPROC(__put_user_8) 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci__put_user_bad: 8262306a36Sopenharmony_ci mov r0, #-EFAULT 8362306a36Sopenharmony_ci ret lr 8462306a36Sopenharmony_ciENDPROC(__put_user_bad) 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci.pushsection __ex_table, "a" 8762306a36Sopenharmony_ci .long 1b, __put_user_bad 8862306a36Sopenharmony_ci .long 2b, __put_user_bad 8962306a36Sopenharmony_ci#if __LINUX_ARM_ARCH__ < 6 9062306a36Sopenharmony_ci .long 3b, __put_user_bad 9162306a36Sopenharmony_ci#endif 9262306a36Sopenharmony_ci .long 4b, __put_user_bad 9362306a36Sopenharmony_ci .long 5b, __put_user_bad 9462306a36Sopenharmony_ci .long 6b, __put_user_bad 9562306a36Sopenharmony_ci.popsection 96