1/*
2 * Copy to/from userspace with optional address space checking.
3 *
4 * Copyright 2004-2006 Atmel Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <asm/page.h>
11#include <asm/thread_info.h>
12#include <asm/processor.h>
13#include <asm/asm.h>
14
15	.text
16	.align	1
17	.global	strnlen_user
18	.type	strnlen_user, "function"
19strnlen_user:
20	branch_if_kernel r8, __strnlen_user
21	sub	r8, r11, 1
22	add	r8, r12
23	retcs	0
24	brmi	adjust_length	/* do a closer inspection */
25
26	.global	__strnlen_user
27	.type	__strnlen_user, "function"
28__strnlen_user:
29	mov	r10, r12
30
3110:	ld.ub	r8, r12++
32	cp.w	r8, 0
33	breq	2f
34	sub	r11, 1
35	brne	10b
36
37	sub	r12, -1
382:	sub	r12, r10
39	retal	r12
40
41
42	.type	adjust_length, "function"
43adjust_length:
44	cp.w	r12, 0		/* addr must always be < TASK_SIZE */
45	retmi	0
46
47	pushm	lr
48	lddpc	lr, _task_size
49	sub	r11, lr, r12
50	mov	r9, r11
51	call	__strnlen_user
52	cp.w	r12, r9
53	brgt	1f
54	popm	pc
551:	popm	pc, r12=0
56
57	.align	2
58_task_size:
59	.long	TASK_SIZE
60
61	.section .fixup, "ax"
62	.align	1
6319:	retal	0
64
65	.section __ex_table, "a"
66	.align	2
67	.long	10b, 19b
68