···326326 (uaccess_kernel() ? ~0UL : TASK_SIZE)327327328328extern long strncpy_from_user(char *dest, const char __user *src, long count);329329-extern __must_check long strlen_user(const char __user *str);330329extern __must_check long strnlen_user(const char __user *str, long n);331330332331#include <asm/extable.h>
-1
arch/arm/include/asm/uaccess.h
···526526/* These are from lib/ code, and use __get_user() and friends */527527extern long strncpy_from_user(char *dest, const char __user *src, long count);528528529529-extern __must_check long strlen_user(const char __user *str);530529extern __must_check long strnlen_user(const char __user *str, long n);531530532531#endif /* _ASMARM_UACCESS_H */
-1
arch/arm64/include/asm/uaccess.h
···349349350350extern long strncpy_from_user(char *dest, const char __user *src, long count);351351352352-extern __must_check long strlen_user(const char __user *str);353352extern __must_check long strnlen_user(const char __user *str, long n);354353355354#endif /* __ASM_UACCESS_H */
···282282extern long strncpy_from_user(char *dst, const char __user *src, long count);283283extern long strnlen_user(const char __user *src, long count);284284285285-#define strlen_user(str) strnlen_user(str, 32767)286286-287285#endif /* _ASM_UACCESS_H */
-12
arch/ia64/include/asm/uaccess.h
···277277 __sfu_ret; \278278})279279280280-/* Returns: 0 if bad, string length+1 (memory size) of string if ok */281281-extern unsigned long __strlen_user (const char __user *);282282-283283-#define strlen_user(str) \284284-({ \285285- const char __user *__su_str = (str); \286286- unsigned long __su_ret = 0; \287287- if (__access_ok(__su_str, 0)) \288288- __su_ret = __strlen_user(__su_str); \289289- __su_ret; \290290-})291291-292280/*293281 * Returns: 0 if exception before NUL or reaching the supplied limit294282 * (N), a value greater than N if the limit would be exceeded, else
···11-/*22- * Optimized version of the strlen_user() function33- *44- * Inputs:55- * in0 address of buffer66- *77- * Outputs:88- * ret0 0 in case of fault, strlen(buffer)+1 otherwise99- *1010- * Copyright (C) 1998, 1999, 2001 Hewlett-Packard Co1111- * David Mosberger-Tang <davidm@hpl.hp.com>1212- * Stephane Eranian <eranian@hpl.hp.com>1313- *1414- * 01/19/99 S.Eranian heavily enhanced version (see details below)1515- * 09/24/99 S.Eranian added speculation recovery code1616- */1717-1818-#include <asm/asmmacro.h>1919-#include <asm/export.h>2020-2121-//2222-// int strlen_user(char *)2323-// ------------------------2424-// Returns:2525-// - length of string + 12626-// - 0 in case an exception is raised2727-//2828-// This is an enhanced version of the basic strlen_user. it includes a2929-// combination of compute zero index (czx), parallel comparisons, speculative3030-// loads and loop unroll using rotating registers.3131-//3232-// General Ideas about the algorithm:3333-// The goal is to look at the string in chunks of 8 bytes.3434-// so we need to do a few extra checks at the beginning because the3535-// string may not be 8-byte aligned. In this case we load the 8byte3636-// quantity which includes the start of the string and mask the unused3737-// bytes with 0xff to avoid confusing czx.3838-// We use speculative loads and software pipelining to hide memory3939-// latency and do read ahead safely. This way we defer any exception.4040-//4141-// Because we don't want the kernel to be relying on particular4242-// settings of the DCR register, we provide recovery code in case4343-// speculation fails. The recovery code is going to "redo" the work using4444-// only normal loads. If we still get a fault then we return an4545-// error (ret0=0). Otherwise we return the strlen+1 as usual.4646-// The fact that speculation may fail can be caused, for instance, by4747-// the DCR.dm bit being set. In this case TLB misses are deferred, i.e.,4848-// a NaT bit will be set if the translation is not present. The normal4949-// load, on the other hand, will cause the translation to be inserted5050-// if the mapping exists.5151-//5252-// It should be noted that we execute recovery code only when we need5353-// to use the data that has been speculatively loaded: we don't execute5454-// recovery code on pure read ahead data.5555-//5656-// Remarks:5757-// - the cmp r0,r0 is used as a fast way to initialize a predicate5858-// register to 1. This is required to make sure that we get the parallel5959-// compare correct.6060-//6161-// - we don't use the epilogue counter to exit the loop but we need to set6262-// it to zero beforehand.6363-//6464-// - after the loop we must test for Nat values because neither the6565-// czx nor cmp instruction raise a NaT consumption fault. We must be6666-// careful not to look too far for a Nat for which we don't care.6767-// For instance we don't need to look at a NaT in val2 if the zero byte6868-// was in val1.6969-//7070-// - Clearly performance tuning is required.7171-//7272-7373-#define saved_pfs r117474-#define tmp r107575-#define base r167676-#define orig r177777-#define saved_pr r187878-#define src r197979-#define mask r208080-#define val r218181-#define val1 r228282-#define val2 r238383-8484-GLOBAL_ENTRY(__strlen_user)8585- .prologue8686- .save ar.pfs, saved_pfs8787- alloc saved_pfs=ar.pfs,11,0,0,88888-8989- .rotr v[2], w[2] // declares our 4 aliases9090-9191- extr.u tmp=in0,0,3 // tmp=least significant 3 bits9292- mov orig=in0 // keep trackof initial byte address9393- dep src=0,in0,0,3 // src=8byte-aligned in0 address9494- .save pr, saved_pr9595- mov saved_pr=pr // preserve predicates (rotation)9696- ;;9797-9898- .body9999-100100- ld8.s v[1]=[src],8 // load the initial 8bytes (must speculate)101101- shl tmp=tmp,3 // multiply by 8bits/byte102102- mov mask=-1 // our mask103103- ;;104104- ld8.s w[1]=[src],8 // load next 8 bytes in 2nd pipeline105105- cmp.eq p6,p0=r0,r0 // sets p6 (required because of // cmp.and)106106- sub tmp=64,tmp // how many bits to shift our mask on the right107107- ;;108108- shr.u mask=mask,tmp // zero enough bits to hold v[1] valuable part109109- mov ar.ec=r0 // clear epilogue counter (saved in ar.pfs)110110- ;;111111- add base=-16,src // keep track of aligned base112112- chk.s v[1], .recover // if already NaT, then directly skip to recover113113- or v[1]=v[1],mask // now we have a safe initial byte pattern114114- ;;115115-1:116116- ld8.s v[0]=[src],8 // speculatively load next117117- czx1.r val1=v[1] // search 0 byte from right118118- czx1.r val2=w[1] // search 0 byte from right following 8bytes119119- ;;120120- ld8.s w[0]=[src],8 // speculatively load next to next121121- cmp.eq.and p6,p0=8,val1 // p6 = p6 and val1==8122122- cmp.eq.and p6,p0=8,val2 // p6 = p6 and mask==8123123-(p6) br.wtop.dptk.few 1b // loop until p6 == 0124124- ;;125125- //126126- // We must return try the recovery code iff127127- // val1_is_nat || (val1==8 && val2_is_nat)128128- //129129- // XXX Fixme130130- // - there must be a better way of doing the test131131- //132132- cmp.eq p8,p9=8,val1 // p6 = val1 had zero (disambiguate)133133- tnat.nz p6,p7=val1 // test NaT on val1134134-(p6) br.cond.spnt .recover // jump to recovery if val1 is NaT135135- ;;136136- //137137- // if we come here p7 is true, i.e., initialized for // cmp138138- //139139- cmp.eq.and p7,p0=8,val1// val1==8?140140- tnat.nz.and p7,p0=val2 // test NaT if val2141141-(p7) br.cond.spnt .recover // jump to recovery if val2 is NaT142142- ;;143143-(p8) mov val1=val2 // val2 contains the value144144-(p8) adds src=-16,src // correct position when 3 ahead145145-(p9) adds src=-24,src // correct position when 4 ahead146146- ;;147147- sub ret0=src,orig // distance from origin148148- sub tmp=7,val1 // 7=8-1 because this strlen returns strlen+1149149- mov pr=saved_pr,0xffffffffffff0000150150- ;;151151- sub ret0=ret0,tmp // length=now - back -1152152- mov ar.pfs=saved_pfs // because of ar.ec, restore no matter what153153- br.ret.sptk.many rp // end of normal execution154154-155155- //156156- // Outlined recovery code when speculation failed157157- //158158- // This time we don't use speculation and rely on the normal exception159159- // mechanism. that's why the loop is not as good as the previous one160160- // because read ahead is not possible161161- //162162- // XXX Fixme163163- // - today we restart from the beginning of the string instead164164- // of trying to continue where we left off.165165- //166166-.recover:167167- EX(.Lexit1, ld8 val=[base],8) // load the initial bytes168168- ;;169169- or val=val,mask // remask first bytes170170- cmp.eq p0,p6=r0,r0 // nullify first ld8 in loop171171- ;;172172- //173173- // ar.ec is still zero here174174- //175175-2:176176- EX(.Lexit1, (p6) ld8 val=[base],8)177177- ;;178178- czx1.r val1=val // search 0 byte from right179179- ;;180180- cmp.eq p6,p0=8,val1 // val1==8 ?181181-(p6) br.wtop.dptk.few 2b // loop until p6 == 0182182- ;;183183- sub ret0=base,orig // distance from base184184- sub tmp=7,val1 // 7=8-1 because this strlen returns strlen+1185185- mov pr=saved_pr,0xffffffffffff0000186186- ;;187187- sub ret0=ret0,tmp // length=now - back -1188188- mov ar.pfs=saved_pfs // because of ar.ec, restore no matter what189189- br.ret.sptk.many rp // end of successful recovery code190190-191191- //192192- // We failed even on the normal load (called from exception handler)193193- //194194-.Lexit1:195195- mov ret0=0196196- mov pr=saved_pr,0xffffffffffff0000197197- mov ar.pfs=saved_pfs // because of ar.ec, restore no matter what198198- br.ret.sptk.many rp199199-END(__strlen_user)200200-EXPORT_SYMBOL(__strlen_user)
-16
arch/m32r/include/asm/uaccess.h
···511511 */512512unsigned long clear_user(void __user *mem, unsigned long len);513513514514-/**515515- * strlen_user: - Get the size of a string in user space.516516- * @str: The string to measure.517517- *518518- * Context: User context only. This function may sleep if pagefaults are519519- * enabled.520520- *521521- * Get the size of a NUL-terminated string in user space.522522- *523523- * Returns the size of the string INCLUDING the terminating NUL.524524- * On exception, returns 0.525525- *526526- * If there is a limit on the length of a valid string, you may wish to527527- * consider using strnlen_user() instead.528528- */529529-#define strlen_user(str) strnlen_user(str, ~0UL >> 1)530514long strnlen_user(const char __user *str, long n);531515532516#endif /* _ASM_M32R_UACCESS_H */
-1
arch/m68k/include/asm/uaccess_mm.h
···378378 (uaccess_kernel() ? ~0UL : TASK_SIZE)379379380380extern long strncpy_from_user(char *dst, const char __user *src, long count);381381-extern __must_check long strlen_user(const char __user *str);382381extern __must_check long strnlen_user(const char __user *str, long n);383382384383unsigned long __clear_user(void __user *to, unsigned long n);
-2
arch/m68k/include/asm/uaccess_no.h
···141141 return(strlen(src) + 1); /* DAVIDM make safer */142142}143143144144-#define strlen_user(str) strnlen_user(str, 32767)145145-146144/*147145 * Zero Userspace148146 */
-2
arch/metag/include/asm/uaccess.h
···188188 */189189extern long __must_check strnlen_user(const char __user *src, long count);190190191191-#define strlen_user(str) strnlen_user(str, 32767)192192-193191extern unsigned long raw_copy_from_user(void *to, const void __user *from,194192 unsigned long n);195193extern unsigned long raw_copy_to_user(void __user *to, const void *from,
-44
arch/mips/include/asm/uaccess.h
···10731073 return res;10741074}1075107510761076-extern long __strlen_kernel_asm(const char __user *s);10771077-extern long __strlen_user_asm(const char __user *s);10781078-10791079-/*10801080- * strlen_user: - Get the size of a string in user space.10811081- * @str: The string to measure.10821082- *10831083- * Context: User context only. This function may sleep if pagefaults are10841084- * enabled.10851085- *10861086- * Get the size of a NUL-terminated string in user space.10871087- *10881088- * Returns the size of the string INCLUDING the terminating NUL.10891089- * On exception, returns 0.10901090- *10911091- * If there is a limit on the length of a valid string, you may wish to10921092- * consider using strnlen_user() instead.10931093- */10941094-static inline long strlen_user(const char __user *s)10951095-{10961096- long res;10971097-10981098- if (eva_kernel_access()) {10991099- __asm__ __volatile__(11001100- "move\t$4, %1\n\t"11011101- __MODULE_JAL(__strlen_kernel_asm)11021102- "move\t%0, $2"11031103- : "=r" (res)11041104- : "r" (s)11051105- : "$2", "$4", __UA_t0, "$31");11061106- } else {11071107- might_fault();11081108- __asm__ __volatile__(11091109- "move\t$4, %1\n\t"11101110- __MODULE_JAL(__strlen_user_asm)11111111- "move\t%0, $2"11121112- : "=r" (res)11131113- : "r" (s)11141114- : "$2", "$4", __UA_t0, "$31");11151115- }11161116-11171117- return res;11181118-}11191119-11201076extern long __strnlen_kernel_nocheck_asm(const char __user *s, long n);11211077extern long __strnlen_user_nocheck_asm(const char __user *s, long n);11221078
···11-/*22- * This file is subject to the terms and conditions of the GNU General Public33- * License. See the file "COPYING" in the main directory of this archive44- * for more details.55- *66- * Copyright (C) 1996, 1998, 1999, 2004 by Ralf Baechle77- * Copyright (C) 1999 Silicon Graphics, Inc.88- * Copyright (C) 2011 MIPS Technologies, Inc.99- */1010-#include <asm/asm.h>1111-#include <asm/asm-offsets.h>1212-#include <asm/export.h>1313-#include <asm/regdef.h>1414-1515-#define EX(insn,reg,addr,handler) \1616-9: insn reg, addr; \1717- .section __ex_table,"a"; \1818- PTR 9b, handler; \1919- .previous2020-2121-/*2222- * Return the size of a string (including the ending 0)2323- *2424- * Return 0 for error2525- */2626- .macro __BUILD_STRLEN_ASM func2727-LEAF(__strlen_\func\()_asm)2828- LONG_L v0, TI_ADDR_LIMIT($28) # pointer ok?2929- and v0, a03030- bnez v0, .Lfault\@3131-3232- move v0, a03333-.ifeqs "\func", "kernel"3434-1: EX(lbu, v1, (v0), .Lfault\@)3535-.else3636-1: EX(lbue, v1, (v0), .Lfault\@)3737-.endif3838- PTR_ADDIU v0, 13939- bnez v1, 1b4040- PTR_SUBU v0, a04141- jr ra4242- END(__strlen_\func\()_asm)4343-4444-.Lfault\@: move v0, zero4545- jr ra4646- .endm4747-4848-#ifndef CONFIG_EVA4949- /* Set aliases */5050- .global __strlen_user_asm5151- .set __strlen_user_asm, __strlen_kernel_asm5252-EXPORT_SYMBOL(__strlen_user_asm)5353-#endif5454-5555-__BUILD_STRLEN_ASM kernel5656-EXPORT_SYMBOL(__strlen_kernel_asm)5757-5858-#ifdef CONFIG_EVA5959-6060- .set push6161- .set eva6262-__BUILD_STRLEN_ASM user6363- .set pop6464-EXPORT_SYMBOL(__strlen_user_asm)6565-#endif
-1
arch/mn10300/include/asm/uaccess.h
···292292extern long strncpy_from_user(char *dst, const char __user *src, long count);293293extern long __strncpy_from_user(char *dst, const char __user *src, long count);294294extern long strnlen_user(const char __user *str, long n);295295-#define strlen_user(str) strnlen_user(str, ~0UL >> 1)296295extern unsigned long clear_user(void __user *mem, unsigned long len);297296extern unsigned long __clear_user(void __user *mem, unsigned long len);298297
-1
arch/openrisc/include/asm/uaccess.h
···264264265265extern long strncpy_from_user(char *dest, const char __user *src, long count);266266267267-extern __must_check long strlen_user(const char __user *str);268267extern __must_check long strnlen_user(const char __user *str, long n);269268270269#endif /* __ASM_OPENRISC_UACCESS_H */
···346346}347347348348extern long strncpy_from_user(char *dst, const char __user *src, long count);349349-extern __must_check long strlen_user(const char __user *str);350349extern __must_check long strnlen_user(const char __user *str, long n);351350352351#endif /* _ARCH_POWERPC_UACCESS_H */
-17
arch/s390/include/asm/uaccess.h
···276276 return __strnlen_user(src, n);277277}278278279279-/**280280- * strlen_user: - Get the size of a string in user space.281281- * @str: The string to measure.282282- *283283- * Context: User context only. This function may sleep if pagefaults are284284- * enabled.285285- *286286- * Get the size of a NUL-terminated string in user space.287287- *288288- * Returns the size of the string INCLUDING the terminating NUL.289289- * On exception, returns 0.290290- *291291- * If there is a limit on the length of a valid string, you may wish to292292- * consider using strnlen_user() instead.293293- */294294-#define strlen_user(str) strnlen_user(str, ~0UL)295295-296279/*297280 * Zero Userspace298281 */
-6
arch/score/include/asm/uaccess.h
···359359 return -EFAULT;360360}361361362362-extern int __strlen_user(const char *src);363363-static inline long strlen_user(const char __user *src)364364-{365365- return __strlen_user(src);366366-}367367-368362extern int __strnlen_user(const char *str, long len);369363static inline long strnlen_user(const char __user *str, long len)370364{
···565565extern __must_check long566566strncpy_from_user(char *dst, const char __user *src, long count);567567568568-extern __must_check long strlen_user(const char __user *str);569568extern __must_check long strnlen_user(const char __user *str, long n);570569571570unsigned long __must_check clear_user(void __user *mem, unsigned long len);
-3
arch/xtensa/include/asm/uaccess.h
···288288 return -EFAULT;289289}290290291291-292292-#define strlen_user(str) strnlen_user((str), TASK_SIZE - 1)293293-294291/*295292 * Return the size of a string (including the ending 0!)296293 */
-5
include/asm-generic/uaccess.h
···200200 return __strnlen_user(src, n);201201}202202203203-static inline long strlen_user(const char __user *src)204204-{205205- return strnlen_user(src, 32767);206206-}207207-208203/*209204 * Zero Userspace210205 */
-34
lib/strnlen_user.c
···121121 return 0;122122}123123EXPORT_SYMBOL(strnlen_user);124124-125125-/**126126- * strlen_user: - Get the size of a user string INCLUDING final NUL.127127- * @str: The string to measure.128128- *129129- * Context: User context only. This function may sleep if pagefaults are130130- * enabled.131131- *132132- * Get the size of a NUL-terminated string in user space.133133- *134134- * Returns the size of the string INCLUDING the terminating NUL.135135- * On exception, returns 0.136136- *137137- * If there is a limit on the length of a valid string, you may wish to138138- * consider using strnlen_user() instead.139139- */140140-long strlen_user(const char __user *str)141141-{142142- unsigned long max_addr, src_addr;143143-144144- max_addr = user_addr_max();145145- src_addr = (unsigned long)str;146146- if (likely(src_addr < max_addr)) {147147- unsigned long max = max_addr - src_addr;148148- long retval;149149-150150- user_access_begin();151151- retval = do_strnlen_user(str, ~0ul, max);152152- user_access_end();153153- return retval;154154- }155155- return 0;156156-}157157-EXPORT_SYMBOL(strlen_user);