10aea86a2SCatalin Marinas/* 20aea86a2SCatalin Marinas * Based on arch/arm/lib/clear_user.S 30aea86a2SCatalin Marinas * 40aea86a2SCatalin Marinas * Copyright (C) 2012 ARM Ltd. 50aea86a2SCatalin Marinas * 60aea86a2SCatalin Marinas * This program is free software; you can redistribute it and/or modify 70aea86a2SCatalin Marinas * it under the terms of the GNU General Public License version 2 as 80aea86a2SCatalin Marinas * published by the Free Software Foundation. 90aea86a2SCatalin Marinas * 100aea86a2SCatalin Marinas * This program is distributed in the hope that it will be useful, 110aea86a2SCatalin Marinas * but WITHOUT ANY WARRANTY; without even the implied warranty of 120aea86a2SCatalin Marinas * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 130aea86a2SCatalin Marinas * GNU General Public License for more details. 140aea86a2SCatalin Marinas * 150aea86a2SCatalin Marinas * You should have received a copy of the GNU General Public License 160aea86a2SCatalin Marinas * along with this program. If not, see <http://www.gnu.org/licenses/>. 170aea86a2SCatalin Marinas */ 180aea86a2SCatalin Marinas#include <linux/linkage.h> 19338d4f49SJames Morse 20338d4f49SJames Morse#include <asm/alternative.h> 210aea86a2SCatalin Marinas#include <asm/assembler.h> 22338d4f49SJames Morse#include <asm/cpufeature.h> 23338d4f49SJames Morse#include <asm/sysreg.h> 240aea86a2SCatalin Marinas 250aea86a2SCatalin Marinas .text 260aea86a2SCatalin Marinas 270aea86a2SCatalin Marinas/* Prototype: int __clear_user(void *addr, size_t sz) 280aea86a2SCatalin Marinas * Purpose : clear some user memory 290aea86a2SCatalin Marinas * Params : addr - user memory address to clear 300aea86a2SCatalin Marinas * : sz - number of bytes to clear 310aea86a2SCatalin Marinas * Returns : number of bytes NOT cleared 320aea86a2SCatalin Marinas * 330aea86a2SCatalin Marinas * Alignment fixed up by hardware. 340aea86a2SCatalin Marinas */ 350aea86a2SCatalin MarinasENTRY(__clear_user) 36338d4f49SJames MorseALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(0)), ARM64_HAS_PAN, \ 37338d4f49SJames Morse CONFIG_ARM64_PAN) 380aea86a2SCatalin Marinas mov x2, x1 // save the size for fixup return 390aea86a2SCatalin Marinas subs x1, x1, #8 400aea86a2SCatalin Marinas b.mi 2f 410aea86a2SCatalin Marinas1: 420aea86a2SCatalin MarinasUSER(9f, str xzr, [x0], #8 ) 430aea86a2SCatalin Marinas subs x1, x1, #8 440aea86a2SCatalin Marinas b.pl 1b 450aea86a2SCatalin Marinas2: adds x1, x1, #4 460aea86a2SCatalin Marinas b.mi 3f 470aea86a2SCatalin MarinasUSER(9f, str wzr, [x0], #4 ) 480aea86a2SCatalin Marinas sub x1, x1, #4 490aea86a2SCatalin Marinas3: adds x1, x1, #2 500aea86a2SCatalin Marinas b.mi 4f 510aea86a2SCatalin MarinasUSER(9f, strh wzr, [x0], #2 ) 520aea86a2SCatalin Marinas sub x1, x1, #2 530aea86a2SCatalin Marinas4: adds x1, x1, #1 540aea86a2SCatalin Marinas b.mi 5f 5597fc1543SKyle McMartinUSER(9f, strb wzr, [x0] ) 560aea86a2SCatalin Marinas5: mov x0, #0 57338d4f49SJames MorseALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(1)), ARM64_HAS_PAN, \ 58338d4f49SJames Morse CONFIG_ARM64_PAN) 590aea86a2SCatalin Marinas ret 600aea86a2SCatalin MarinasENDPROC(__clear_user) 610aea86a2SCatalin Marinas 620aea86a2SCatalin Marinas .section .fixup,"ax" 630aea86a2SCatalin Marinas .align 2 640aea86a2SCatalin Marinas9: mov x0, x2 // return the original size 650aea86a2SCatalin Marinas ret 660aea86a2SCatalin Marinas .previous 67