1b2441318SGreg Kroah-Hartman/* SPDX-License-Identifier: GPL-2.0 */ 21da177e4SLinus Torvalds/* 31da177e4SLinus Torvalds * arch/alpha/lib/clear_user.S 41da177e4SLinus Torvalds * Contributed by Richard Henderson <rth@tamu.edu> 51da177e4SLinus Torvalds * 61da177e4SLinus Torvalds * Zero user space, handling exceptions as we go. 71da177e4SLinus Torvalds * 81da177e4SLinus Torvalds * We have to make sure that $0 is always up-to-date and contains the 91da177e4SLinus Torvalds * right "bytes left to zero" value (and that it is updated only _after_ 101da177e4SLinus Torvalds * a successful copy). There is also some rather minor exception setup 111da177e4SLinus Torvalds * stuff. 121da177e4SLinus Torvalds */ 13*f3c78e94SMasahiro Yamada#include <linux/export.h> 141da177e4SLinus Torvalds 151da177e4SLinus Torvalds/* Allow an exception for an insn; exit if we get one. */ 161da177e4SLinus Torvalds#define EX(x,y...) \ 171da177e4SLinus Torvalds 99: x,##y; \ 181da177e4SLinus Torvalds .section __ex_table,"a"; \ 191da177e4SLinus Torvalds .long 99b - .; \ 201da177e4SLinus Torvalds lda $31, $exception-99b($31); \ 211da177e4SLinus Torvalds .previous 221da177e4SLinus Torvalds 231da177e4SLinus Torvalds .set noat 241da177e4SLinus Torvalds .set noreorder 251da177e4SLinus Torvalds .align 4 261da177e4SLinus Torvalds 2785250231SAl Viro .globl __clear_user 2885250231SAl Viro .ent __clear_user 2985250231SAl Viro .frame $30, 0, $26 301da177e4SLinus Torvalds .prologue 0 311da177e4SLinus Torvalds 321da177e4SLinus Torvalds$loop: 331da177e4SLinus Torvalds and $1, 3, $4 # e0 : 341da177e4SLinus Torvalds beq $4, 1f # .. e1 : 351da177e4SLinus Torvalds 3685250231SAl Viro0: EX( stq_u $31, 0($16) ) # e0 : zero one word 371da177e4SLinus Torvalds subq $0, 8, $0 # .. e1 : 381da177e4SLinus Torvalds subq $4, 1, $4 # e0 : 3985250231SAl Viro addq $16, 8, $16 # .. e1 : 401da177e4SLinus Torvalds bne $4, 0b # e1 : 411da177e4SLinus Torvalds unop # : 421da177e4SLinus Torvalds 431da177e4SLinus Torvalds1: bic $1, 3, $1 # e0 : 441da177e4SLinus Torvalds beq $1, $tail # .. e1 : 451da177e4SLinus Torvalds 4685250231SAl Viro2: EX( stq_u $31, 0($16) ) # e0 : zero four words 471da177e4SLinus Torvalds subq $0, 8, $0 # .. e1 : 4885250231SAl Viro EX( stq_u $31, 8($16) ) # e0 : 491da177e4SLinus Torvalds subq $0, 8, $0 # .. e1 : 5085250231SAl Viro EX( stq_u $31, 16($16) ) # e0 : 511da177e4SLinus Torvalds subq $0, 8, $0 # .. e1 : 5285250231SAl Viro EX( stq_u $31, 24($16) ) # e0 : 531da177e4SLinus Torvalds subq $0, 8, $0 # .. e1 : 541da177e4SLinus Torvalds subq $1, 4, $1 # e0 : 5585250231SAl Viro addq $16, 32, $16 # .. e1 : 561da177e4SLinus Torvalds bne $1, 2b # e1 : 571da177e4SLinus Torvalds 581da177e4SLinus Torvalds$tail: 591da177e4SLinus Torvalds bne $2, 1f # e1 : is there a tail to do? 6085250231SAl Viro ret $31, ($26), 1 # .. e1 : 611da177e4SLinus Torvalds 6285250231SAl Viro1: EX( ldq_u $5, 0($16) ) # e0 : 631da177e4SLinus Torvalds clr $0 # .. e1 : 641da177e4SLinus Torvalds nop # e1 : 651da177e4SLinus Torvalds mskqh $5, $0, $5 # e0 : 6685250231SAl Viro EX( stq_u $5, 0($16) ) # e0 : 6785250231SAl Viro ret $31, ($26), 1 # .. e1 : 681da177e4SLinus Torvalds 6985250231SAl Viro__clear_user: 7085250231SAl Viro and $17, $17, $0 7185250231SAl Viro and $16, 7, $4 # e0 : find dest misalignment 721da177e4SLinus Torvalds beq $0, $zerolength # .. e1 : 731da177e4SLinus Torvalds addq $0, $4, $1 # e0 : bias counter 741da177e4SLinus Torvalds and $1, 7, $2 # e1 : number of bytes in tail 751da177e4SLinus Torvalds srl $1, 3, $1 # e0 : 761da177e4SLinus Torvalds beq $4, $loop # .. e1 : 771da177e4SLinus Torvalds 7885250231SAl Viro EX( ldq_u $5, 0($16) ) # e0 : load dst word to mask back in 791da177e4SLinus Torvalds beq $1, $oneword # .. e1 : sub-word store? 801da177e4SLinus Torvalds 8185250231SAl Viro mskql $5, $16, $5 # e0 : take care of misaligned head 8285250231SAl Viro addq $16, 8, $16 # .. e1 : 8385250231SAl Viro EX( stq_u $5, -8($16) ) # e0 : 841da177e4SLinus Torvalds addq $0, $4, $0 # .. e1 : bytes left -= 8 - misalignment 851da177e4SLinus Torvalds subq $1, 1, $1 # e0 : 861da177e4SLinus Torvalds subq $0, 8, $0 # .. e1 : 871da177e4SLinus Torvalds br $loop # e1 : 881da177e4SLinus Torvalds unop # : 891da177e4SLinus Torvalds 901da177e4SLinus Torvalds$oneword: 9185250231SAl Viro mskql $5, $16, $4 # e0 : 921da177e4SLinus Torvalds mskqh $5, $2, $5 # e0 : 931da177e4SLinus Torvalds or $5, $4, $5 # e1 : 9485250231SAl Viro EX( stq_u $5, 0($16) ) # e0 : 951da177e4SLinus Torvalds clr $0 # .. e1 : 961da177e4SLinus Torvalds 971da177e4SLinus Torvalds$zerolength: 981da177e4SLinus Torvalds$exception: 9985250231SAl Viro ret $31, ($26), 1 # .. e1 : 1001da177e4SLinus Torvalds 10185250231SAl Viro .end __clear_user 10285250231SAl Viro EXPORT_SYMBOL(__clear_user) 103