10aea86a2SCatalin Marinas/* 20aea86a2SCatalin Marinas * Copyright (C) 2012 ARM Ltd. 30aea86a2SCatalin Marinas * 40aea86a2SCatalin Marinas * This program is free software; you can redistribute it and/or modify 50aea86a2SCatalin Marinas * it under the terms of the GNU General Public License version 2 as 60aea86a2SCatalin Marinas * published by the Free Software Foundation. 70aea86a2SCatalin Marinas * 80aea86a2SCatalin Marinas * This program is distributed in the hope that it will be useful, 90aea86a2SCatalin Marinas * but WITHOUT ANY WARRANTY; without even the implied warranty of 100aea86a2SCatalin Marinas * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 110aea86a2SCatalin Marinas * GNU General Public License for more details. 120aea86a2SCatalin Marinas * 130aea86a2SCatalin Marinas * You should have received a copy of the GNU General Public License 140aea86a2SCatalin Marinas * along with this program. If not, see <http://www.gnu.org/licenses/>. 150aea86a2SCatalin Marinas */ 160aea86a2SCatalin Marinas 170aea86a2SCatalin Marinas#include <linux/linkage.h> 18338d4f49SJames Morse 19338d4f49SJames Morse#include <asm/alternative.h> 200aea86a2SCatalin Marinas#include <asm/assembler.h> 21*40426882SFeng Kan#include <asm/cache.h> 22338d4f49SJames Morse#include <asm/cpufeature.h> 23338d4f49SJames Morse#include <asm/sysreg.h> 240aea86a2SCatalin Marinas 250aea86a2SCatalin Marinas/* 260aea86a2SCatalin Marinas * Copy from user space to a kernel buffer (alignment handled by the hardware) 270aea86a2SCatalin Marinas * 280aea86a2SCatalin Marinas * Parameters: 290aea86a2SCatalin Marinas * x0 - to 300aea86a2SCatalin Marinas * x1 - from 310aea86a2SCatalin Marinas * x2 - n 320aea86a2SCatalin Marinas * Returns: 330aea86a2SCatalin Marinas * x0 - bytes not copied 340aea86a2SCatalin Marinas */ 35*40426882SFeng Kan 36*40426882SFeng Kan .macro ldrb1 ptr, regB, val 37*40426882SFeng Kan USER(9998f, ldrb \ptr, [\regB], \val) 38*40426882SFeng Kan .endm 39*40426882SFeng Kan 40*40426882SFeng Kan .macro strb1 ptr, regB, val 41*40426882SFeng Kan strb \ptr, [\regB], \val 42*40426882SFeng Kan .endm 43*40426882SFeng Kan 44*40426882SFeng Kan .macro ldrh1 ptr, regB, val 45*40426882SFeng Kan USER(9998f, ldrh \ptr, [\regB], \val) 46*40426882SFeng Kan .endm 47*40426882SFeng Kan 48*40426882SFeng Kan .macro strh1 ptr, regB, val 49*40426882SFeng Kan strh \ptr, [\regB], \val 50*40426882SFeng Kan .endm 51*40426882SFeng Kan 52*40426882SFeng Kan .macro ldr1 ptr, regB, val 53*40426882SFeng Kan USER(9998f, ldr \ptr, [\regB], \val) 54*40426882SFeng Kan .endm 55*40426882SFeng Kan 56*40426882SFeng Kan .macro str1 ptr, regB, val 57*40426882SFeng Kan str \ptr, [\regB], \val 58*40426882SFeng Kan .endm 59*40426882SFeng Kan 60*40426882SFeng Kan .macro ldp1 ptr, regB, regC, val 61*40426882SFeng Kan USER(9998f, ldp \ptr, \regB, [\regC], \val) 62*40426882SFeng Kan .endm 63*40426882SFeng Kan 64*40426882SFeng Kan .macro stp1 ptr, regB, regC, val 65*40426882SFeng Kan stp \ptr, \regB, [\regC], \val 66*40426882SFeng Kan .endm 67*40426882SFeng Kan 68*40426882SFeng Kanend .req x5 690aea86a2SCatalin MarinasENTRY(__copy_from_user) 70338d4f49SJames MorseALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(0)), ARM64_HAS_PAN, \ 71338d4f49SJames Morse CONFIG_ARM64_PAN) 72*40426882SFeng Kan add end, x0, x2 73*40426882SFeng Kan#include "copy_template.S" 74338d4f49SJames MorseALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(1)), ARM64_HAS_PAN, \ 75338d4f49SJames Morse CONFIG_ARM64_PAN) 76*40426882SFeng Kan mov x0, #0 // Nothing to copy 770aea86a2SCatalin Marinas ret 780aea86a2SCatalin MarinasENDPROC(__copy_from_user) 790aea86a2SCatalin Marinas 800aea86a2SCatalin Marinas .section .fixup,"ax" 810aea86a2SCatalin Marinas .align 2 82*40426882SFeng Kan9998: 83*40426882SFeng Kan sub x0, end, dst 84*40426882SFeng Kan9999: 85*40426882SFeng Kan strb wzr, [dst], #1 // zero remaining buffer space 86*40426882SFeng Kan cmp dst, end 87*40426882SFeng Kan b.lo 9999b 880aea86a2SCatalin Marinas ret 890aea86a2SCatalin Marinas .previous 90