162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * User memory copy functions for kernel 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci/* 962306a36Sopenharmony_ci * The right way to do this involves valignb 1062306a36Sopenharmony_ci * The easy way to do this is only speed up src/dest similar alignment. 1162306a36Sopenharmony_ci */ 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci/* 1462306a36Sopenharmony_ci * Copy to/from user are the same, except that for packets with a load and 1562306a36Sopenharmony_ci * a store, I don't know how to tell which kind of exception we got. 1662306a36Sopenharmony_ci * Therefore, we duplicate the function, and handle faulting addresses 1762306a36Sopenharmony_ci * differently for each function 1862306a36Sopenharmony_ci */ 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci/* 2162306a36Sopenharmony_ci * copy from user: loads can fault 2262306a36Sopenharmony_ci */ 2362306a36Sopenharmony_ci#define src_sav r13 2462306a36Sopenharmony_ci#define dst_sav r12 2562306a36Sopenharmony_ci#define src_dst_sav r13:12 2662306a36Sopenharmony_ci#define d_dbuf r15:14 2762306a36Sopenharmony_ci#define w_dbuf r15 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci#define dst r0 3062306a36Sopenharmony_ci#define src r1 3162306a36Sopenharmony_ci#define bytes r2 3262306a36Sopenharmony_ci#define loopcount r5 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci#define FUNCNAME raw_copy_from_user 3562306a36Sopenharmony_ci#include "copy_user_template.S" 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci /* LOAD FAULTS from COPY_FROM_USER */ 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci /* Alignment loop. r2 has been updated. Return it. */ 4062306a36Sopenharmony_ci .falign 4162306a36Sopenharmony_ci1009: 4262306a36Sopenharmony_ci2009: 4362306a36Sopenharmony_ci4009: 4462306a36Sopenharmony_ci { 4562306a36Sopenharmony_ci r0 = r2 4662306a36Sopenharmony_ci jumpr r31 4762306a36Sopenharmony_ci } 4862306a36Sopenharmony_ci /* Normal copy loops. Do epilog. Use src-src_sav to compute distance */ 4962306a36Sopenharmony_ci /* X - (A - B) == X + B - A */ 5062306a36Sopenharmony_ci .falign 5162306a36Sopenharmony_ci8089: 5262306a36Sopenharmony_ci { 5362306a36Sopenharmony_ci memd(dst) = d_dbuf 5462306a36Sopenharmony_ci r2 += sub(src_sav,src) 5562306a36Sopenharmony_ci } 5662306a36Sopenharmony_ci { 5762306a36Sopenharmony_ci r0 = r2 5862306a36Sopenharmony_ci jumpr r31 5962306a36Sopenharmony_ci } 6062306a36Sopenharmony_ci .falign 6162306a36Sopenharmony_ci4089: 6262306a36Sopenharmony_ci { 6362306a36Sopenharmony_ci memw(dst) = w_dbuf 6462306a36Sopenharmony_ci r2 += sub(src_sav,src) 6562306a36Sopenharmony_ci } 6662306a36Sopenharmony_ci { 6762306a36Sopenharmony_ci r0 = r2 6862306a36Sopenharmony_ci jumpr r31 6962306a36Sopenharmony_ci } 7062306a36Sopenharmony_ci .falign 7162306a36Sopenharmony_ci2089: 7262306a36Sopenharmony_ci { 7362306a36Sopenharmony_ci memh(dst) = w_dbuf 7462306a36Sopenharmony_ci r2 += sub(src_sav,src) 7562306a36Sopenharmony_ci } 7662306a36Sopenharmony_ci { 7762306a36Sopenharmony_ci r0 = r2 7862306a36Sopenharmony_ci jumpr r31 7962306a36Sopenharmony_ci } 8062306a36Sopenharmony_ci .falign 8162306a36Sopenharmony_ci1089: 8262306a36Sopenharmony_ci { 8362306a36Sopenharmony_ci memb(dst) = w_dbuf 8462306a36Sopenharmony_ci r2 += sub(src_sav,src) 8562306a36Sopenharmony_ci } 8662306a36Sopenharmony_ci { 8762306a36Sopenharmony_ci r0 = r2 8862306a36Sopenharmony_ci jumpr r31 8962306a36Sopenharmony_ci } 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci /* COPY FROM USER: only loads can fail */ 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci .section __ex_table,"a" 9462306a36Sopenharmony_ci .long 1000b,1009b 9562306a36Sopenharmony_ci .long 2000b,2009b 9662306a36Sopenharmony_ci .long 4000b,4009b 9762306a36Sopenharmony_ci .long 8080b,8089b 9862306a36Sopenharmony_ci .long 4080b,4089b 9962306a36Sopenharmony_ci .long 2080b,2089b 10062306a36Sopenharmony_ci .long 1080b,1089b 10162306a36Sopenharmony_ci .previous 102