18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * User memory copy functions for kernel 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci/* 98c2ecf20Sopenharmony_ci * The right way to do this involves valignb 108c2ecf20Sopenharmony_ci * The easy way to do this is only speed up src/dest similar alignment. 118c2ecf20Sopenharmony_ci */ 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci/* 148c2ecf20Sopenharmony_ci * Copy to/from user are the same, except that for packets with a load and 158c2ecf20Sopenharmony_ci * a store, I don't know how to tell which kind of exception we got. 168c2ecf20Sopenharmony_ci * Therefore, we duplicate the function, and handle faulting addresses 178c2ecf20Sopenharmony_ci * differently for each function 188c2ecf20Sopenharmony_ci */ 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci/* 218c2ecf20Sopenharmony_ci * copy from user: loads can fault 228c2ecf20Sopenharmony_ci */ 238c2ecf20Sopenharmony_ci#define src_sav r13 248c2ecf20Sopenharmony_ci#define dst_sav r12 258c2ecf20Sopenharmony_ci#define src_dst_sav r13:12 268c2ecf20Sopenharmony_ci#define d_dbuf r15:14 278c2ecf20Sopenharmony_ci#define w_dbuf r15 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci#define dst r0 308c2ecf20Sopenharmony_ci#define src r1 318c2ecf20Sopenharmony_ci#define bytes r2 328c2ecf20Sopenharmony_ci#define loopcount r5 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci#define FUNCNAME raw_copy_from_user 358c2ecf20Sopenharmony_ci#include "copy_user_template.S" 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci /* LOAD FAULTS from COPY_FROM_USER */ 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci /* Alignment loop. r2 has been updated. Return it. */ 408c2ecf20Sopenharmony_ci .falign 418c2ecf20Sopenharmony_ci1009: 428c2ecf20Sopenharmony_ci2009: 438c2ecf20Sopenharmony_ci4009: 448c2ecf20Sopenharmony_ci { 458c2ecf20Sopenharmony_ci r0 = r2 468c2ecf20Sopenharmony_ci jumpr r31 478c2ecf20Sopenharmony_ci } 488c2ecf20Sopenharmony_ci /* Normal copy loops. Do epilog. Use src-src_sav to compute distance */ 498c2ecf20Sopenharmony_ci /* X - (A - B) == X + B - A */ 508c2ecf20Sopenharmony_ci .falign 518c2ecf20Sopenharmony_ci8089: 528c2ecf20Sopenharmony_ci { 538c2ecf20Sopenharmony_ci memd(dst) = d_dbuf 548c2ecf20Sopenharmony_ci r2 += sub(src_sav,src) 558c2ecf20Sopenharmony_ci } 568c2ecf20Sopenharmony_ci { 578c2ecf20Sopenharmony_ci r0 = r2 588c2ecf20Sopenharmony_ci jumpr r31 598c2ecf20Sopenharmony_ci } 608c2ecf20Sopenharmony_ci .falign 618c2ecf20Sopenharmony_ci4089: 628c2ecf20Sopenharmony_ci { 638c2ecf20Sopenharmony_ci memw(dst) = w_dbuf 648c2ecf20Sopenharmony_ci r2 += sub(src_sav,src) 658c2ecf20Sopenharmony_ci } 668c2ecf20Sopenharmony_ci { 678c2ecf20Sopenharmony_ci r0 = r2 688c2ecf20Sopenharmony_ci jumpr r31 698c2ecf20Sopenharmony_ci } 708c2ecf20Sopenharmony_ci .falign 718c2ecf20Sopenharmony_ci2089: 728c2ecf20Sopenharmony_ci { 738c2ecf20Sopenharmony_ci memh(dst) = w_dbuf 748c2ecf20Sopenharmony_ci r2 += sub(src_sav,src) 758c2ecf20Sopenharmony_ci } 768c2ecf20Sopenharmony_ci { 778c2ecf20Sopenharmony_ci r0 = r2 788c2ecf20Sopenharmony_ci jumpr r31 798c2ecf20Sopenharmony_ci } 808c2ecf20Sopenharmony_ci .falign 818c2ecf20Sopenharmony_ci1089: 828c2ecf20Sopenharmony_ci { 838c2ecf20Sopenharmony_ci memb(dst) = w_dbuf 848c2ecf20Sopenharmony_ci r2 += sub(src_sav,src) 858c2ecf20Sopenharmony_ci } 868c2ecf20Sopenharmony_ci { 878c2ecf20Sopenharmony_ci r0 = r2 888c2ecf20Sopenharmony_ci jumpr r31 898c2ecf20Sopenharmony_ci } 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci /* COPY FROM USER: only loads can fail */ 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci .section __ex_table,"a" 948c2ecf20Sopenharmony_ci .long 1000b,1009b 958c2ecf20Sopenharmony_ci .long 2000b,2009b 968c2ecf20Sopenharmony_ci .long 4000b,4009b 978c2ecf20Sopenharmony_ci .long 8080b,8089b 988c2ecf20Sopenharmony_ci .long 4080b,4089b 998c2ecf20Sopenharmony_ci .long 2080b,2089b 1008c2ecf20Sopenharmony_ci .long 1080b,1089b 1018c2ecf20Sopenharmony_ci .previous 102