aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-05-24 18:10:28 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-24 18:10:28 -0400
commitce004178be1bbaa292e9e6497939e2970300095a (patch)
tree1cd5306548947deaedd612189b56d35265217e8e /arch/sparc
parent9978306e31a8f89bd81fbc4c49fd9aefb1d30d10 (diff)
parentc5389831cda3b38a56606a348a537a1332f2d729 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc
Pull sparc changes from David S. Miller: "This has the generic strncpy_from_user() implementation architectures can now use, which we've been developing on linux-arch over the past few days. For good measure I ran both a 32-bit and a 64-bit glibc testsuite run, and the latter of which pointed out an adjustment I needed to make to sparc's user_addr_max() definition. Linus, you were right, STACK_TOP was not the right thing to use, even on sparc itself :-) From Sam Ravnborg, we have a conversion of sparc32 over to the common alloc_thread_info_node(), since the aspect which originally blocked our doing so (sun4c) has been removed." Fix up trivial arch/sparc/Kconfig and lib/Makefile conflicts. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc: sparc: Fix user_addr_max() definition. lib: Sparc's strncpy_from_user is generic enough, move under lib/ kernel: Move REPEAT_BYTE definition into linux/kernel.h sparc: Increase portability of strncpy_from_user() implementation. sparc: Optimize strncpy_from_user() zero byte search. sparc: Add full proper error handling to strncpy_from_user(). sparc32: use the common implementation of alloc_thread_info_node()
Diffstat (limited to 'arch/sparc')
-rw-r--r--arch/sparc/Kconfig2
-rw-r--r--arch/sparc/include/asm/processor_64.h4
-rw-r--r--arch/sparc/include/asm/thread_info_32.h11
-rw-r--r--arch/sparc/include/asm/uaccess.h6
-rw-r--r--arch/sparc/include/asm/uaccess_32.h10
-rw-r--r--arch/sparc/include/asm/uaccess_64.h4
-rw-r--r--arch/sparc/lib/Makefile2
-rw-r--r--arch/sparc/lib/ksyms.c3
-rw-r--r--arch/sparc/lib/strncpy_from_user_32.S47
-rw-r--r--arch/sparc/lib/strncpy_from_user_64.S133
-rw-r--r--arch/sparc/lib/usercopy.c1
-rw-r--r--arch/sparc/mm/srmmu.c27
12 files changed, 14 insertions, 236 deletions
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 2d493a3bdfe1..15e9e05740da 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -34,12 +34,12 @@ config SPARC
34 select GENERIC_SMP_IDLE_THREAD 34 select GENERIC_SMP_IDLE_THREAD
35 select GENERIC_CMOS_UPDATE 35 select GENERIC_CMOS_UPDATE
36 select GENERIC_CLOCKEVENTS 36 select GENERIC_CLOCKEVENTS
37 select GENERIC_STRNCPY_FROM_USER
37 38
38config SPARC32 39config SPARC32
39 def_bool !64BIT 40 def_bool !64BIT
40 select GENERIC_ATOMIC64 41 select GENERIC_ATOMIC64
41 select CLZ_TAB 42 select CLZ_TAB
42 select ARCH_THREAD_INFO_ALLOCATOR
43 select ARCH_USES_GETTIMEOFFSET 43 select ARCH_USES_GETTIMEOFFSET
44 44
45config SPARC64 45config SPARC64
diff --git a/arch/sparc/include/asm/processor_64.h b/arch/sparc/include/asm/processor_64.h
index 67df5cc10011..4e5a483122a0 100644
--- a/arch/sparc/include/asm/processor_64.h
+++ b/arch/sparc/include/asm/processor_64.h
@@ -42,7 +42,9 @@
42#define TASK_SIZE_OF(tsk) \ 42#define TASK_SIZE_OF(tsk) \
43 (test_tsk_thread_flag(tsk,TIF_32BIT) ? \ 43 (test_tsk_thread_flag(tsk,TIF_32BIT) ? \
44 (1UL << 32UL) : ((unsigned long)-VPTE_SIZE)) 44 (1UL << 32UL) : ((unsigned long)-VPTE_SIZE))
45#define TASK_SIZE TASK_SIZE_OF(current) 45#define TASK_SIZE \
46 (test_thread_flag(TIF_32BIT) ? \
47 (1UL << 32UL) : ((unsigned long)-VPTE_SIZE))
46#ifdef __KERNEL__ 48#ifdef __KERNEL__
47 49
48#define STACK_TOP32 ((1UL << 32UL) - PAGE_SIZE) 50#define STACK_TOP32 ((1UL << 32UL) - PAGE_SIZE)
diff --git a/arch/sparc/include/asm/thread_info_32.h b/arch/sparc/include/asm/thread_info_32.h
index 21a38946541d..5af664932452 100644
--- a/arch/sparc/include/asm/thread_info_32.h
+++ b/arch/sparc/include/asm/thread_info_32.h
@@ -77,18 +77,11 @@ register struct thread_info *current_thread_info_reg asm("g6");
77/* 77/*
78 * thread information allocation 78 * thread information allocation
79 */ 79 */
80#define THREAD_INFO_ORDER 1 80#define THREAD_SIZE_ORDER 1
81
82struct thread_info * alloc_thread_info_node(struct task_struct *tsk, int node);
83void free_thread_info(struct thread_info *);
84 81
85#endif /* __ASSEMBLY__ */ 82#endif /* __ASSEMBLY__ */
86 83
87/* 84/* Size of kernel stack for each process */
88 * Size of kernel stack for each process.
89 * Observe the order of get_free_pages() in alloc_thread_info_node().
90 * The sun4 has 8K stack too, because it's short on memory, and 16K is a waste.
91 */
92#define THREAD_SIZE (2 * PAGE_SIZE) 85#define THREAD_SIZE (2 * PAGE_SIZE)
93 86
94/* 87/*
diff --git a/arch/sparc/include/asm/uaccess.h b/arch/sparc/include/asm/uaccess.h
index e88fbe5c0457..0167d26d0d1d 100644
--- a/arch/sparc/include/asm/uaccess.h
+++ b/arch/sparc/include/asm/uaccess.h
@@ -5,4 +5,10 @@
5#else 5#else
6#include <asm/uaccess_32.h> 6#include <asm/uaccess_32.h>
7#endif 7#endif
8
9#define user_addr_max() \
10 (segment_eq(get_fs(), USER_DS) ? TASK_SIZE : ~0UL)
11
12extern long strncpy_from_user(char *dest, const char __user *src, long count);
13
8#endif 14#endif
diff --git a/arch/sparc/include/asm/uaccess_32.h b/arch/sparc/include/asm/uaccess_32.h
index d50c310f5d38..59586b57ef1a 100644
--- a/arch/sparc/include/asm/uaccess_32.h
+++ b/arch/sparc/include/asm/uaccess_32.h
@@ -304,16 +304,6 @@ static inline unsigned long clear_user(void __user *addr, unsigned long n)
304 return n; 304 return n;
305} 305}
306 306
307extern long __strncpy_from_user(char *dest, const char __user *src, long count);
308
309static inline long strncpy_from_user(char *dest, const char __user *src, long count)
310{
311 if (__access_ok((unsigned long) src, count))
312 return __strncpy_from_user(dest, src, count);
313 else
314 return -EFAULT;
315}
316
317extern long __strlen_user(const char __user *); 307extern long __strlen_user(const char __user *);
318extern long __strnlen_user(const char __user *, long len); 308extern long __strnlen_user(const char __user *, long len);
319 309
diff --git a/arch/sparc/include/asm/uaccess_64.h b/arch/sparc/include/asm/uaccess_64.h
index a1091afb8831..dcdfb89cbf3f 100644
--- a/arch/sparc/include/asm/uaccess_64.h
+++ b/arch/sparc/include/asm/uaccess_64.h
@@ -257,10 +257,6 @@ extern unsigned long __must_check __clear_user(void __user *, unsigned long);
257 257
258#define clear_user __clear_user 258#define clear_user __clear_user
259 259
260extern long __must_check __strncpy_from_user(char *dest, const char __user *src, long count);
261
262#define strncpy_from_user __strncpy_from_user
263
264extern long __strlen_user(const char __user *); 260extern long __strlen_user(const char __user *);
265extern long __strnlen_user(const char __user *, long len); 261extern long __strnlen_user(const char __user *, long len);
266 262
diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile
index 389628f50a15..943d98dc4cdb 100644
--- a/arch/sparc/lib/Makefile
+++ b/arch/sparc/lib/Makefile
@@ -10,7 +10,7 @@ lib-y += strlen.o
10lib-y += checksum_$(BITS).o 10lib-y += checksum_$(BITS).o
11lib-$(CONFIG_SPARC32) += blockops.o 11lib-$(CONFIG_SPARC32) += blockops.o
12lib-y += memscan_$(BITS).o memcmp.o strncmp_$(BITS).o 12lib-y += memscan_$(BITS).o memcmp.o strncmp_$(BITS).o
13lib-y += strncpy_from_user_$(BITS).o strlen_user_$(BITS).o 13lib-y += strlen_user_$(BITS).o
14lib-$(CONFIG_SPARC32) += divdi3.o udivdi3.o 14lib-$(CONFIG_SPARC32) += divdi3.o udivdi3.o
15lib-$(CONFIG_SPARC32) += copy_user.o locks.o 15lib-$(CONFIG_SPARC32) += copy_user.o locks.o
16lib-$(CONFIG_SPARC64) += atomic_64.o 16lib-$(CONFIG_SPARC64) += atomic_64.o
diff --git a/arch/sparc/lib/ksyms.c b/arch/sparc/lib/ksyms.c
index 2dc30875c8bc..6b278abdb63d 100644
--- a/arch/sparc/lib/ksyms.c
+++ b/arch/sparc/lib/ksyms.c
@@ -33,9 +33,6 @@ EXPORT_SYMBOL(memset);
33EXPORT_SYMBOL(memmove); 33EXPORT_SYMBOL(memmove);
34EXPORT_SYMBOL(__bzero); 34EXPORT_SYMBOL(__bzero);
35 35
36/* Moving data to/from/in userspace. */
37EXPORT_SYMBOL(__strncpy_from_user);
38
39/* Networking helper routines. */ 36/* Networking helper routines. */
40EXPORT_SYMBOL(csum_partial); 37EXPORT_SYMBOL(csum_partial);
41 38
diff --git a/arch/sparc/lib/strncpy_from_user_32.S b/arch/sparc/lib/strncpy_from_user_32.S
deleted file mode 100644
index db0ed2964bdb..000000000000
--- a/arch/sparc/lib/strncpy_from_user_32.S
+++ /dev/null
@@ -1,47 +0,0 @@
1/* strncpy_from_user.S: Sparc strncpy from userspace.
2 *
3 * Copyright(C) 1996 David S. Miller
4 */
5
6#include <linux/linkage.h>
7#include <asm/ptrace.h>
8#include <asm/errno.h>
9
10 .text
11
12 /* Must return:
13 *
14 * -EFAULT for an exception
15 * count if we hit the buffer limit
16 * bytes copied if we hit a null byte
17 */
18
19ENTRY(__strncpy_from_user)
20 /* %o0=dest, %o1=src, %o2=count */
21 mov %o2, %o3
221:
23 subcc %o2, 1, %o2
24 bneg 2f
25 nop
2610:
27 ldub [%o1], %o4
28 add %o0, 1, %o0
29 cmp %o4, 0
30 add %o1, 1, %o1
31 bne 1b
32 stb %o4, [%o0 - 1]
332:
34 add %o2, 1, %o0
35 retl
36 sub %o3, %o0, %o0
37ENDPROC(__strncpy_from_user)
38
39 .section .fixup,#alloc,#execinstr
40 .align 4
414:
42 retl
43 mov -EFAULT, %o0
44
45 .section __ex_table,#alloc
46 .align 4
47 .word 10b, 4b
diff --git a/arch/sparc/lib/strncpy_from_user_64.S b/arch/sparc/lib/strncpy_from_user_64.S
deleted file mode 100644
index d1246b713077..000000000000
--- a/arch/sparc/lib/strncpy_from_user_64.S
+++ /dev/null
@@ -1,133 +0,0 @@
1/*
2 * strncpy_from_user.S: Sparc64 strncpy from userspace.
3 *
4 * Copyright (C) 1997, 1999 Jakub Jelinek (jj@ultra.linux.cz)
5 */
6
7#include <linux/linkage.h>
8#include <asm/asi.h>
9#include <asm/errno.h>
10
11 .data
12 .align 8
130: .xword 0x0101010101010101
14
15 .text
16
17 /* Must return:
18 *
19 * -EFAULT for an exception
20 * count if we hit the buffer limit
21 * bytes copied if we hit a null byte
22 * (without the null byte)
23 *
24 * This implementation assumes:
25 * %o1 is 8 aligned => !(%o2 & 7)
26 * %o0 is 8 aligned (if not, it will be slooooow, but will work)
27 *
28 * This is optimized for the common case:
29 * in my stats, 90% of src are 8 aligned (even on sparc32)
30 * and average length is 18 or so.
31 */
32
33ENTRY(__strncpy_from_user)
34 /* %o0=dest, %o1=src, %o2=count */
35 andcc %o1, 7, %g0 ! IEU1 Group
36 bne,pn %icc, 30f ! CTI
37 add %o0, %o2, %g3 ! IEU0
3860: ldxa [%o1] %asi, %g1 ! Load Group
39 brlez,pn %o2, 10f ! CTI
40 mov %o0, %o3 ! IEU0
4150: sethi %hi(0b), %o4 ! IEU0 Group
42 ldx [%o4 + %lo(0b)], %o4 ! Load
43 sllx %o4, 7, %o5 ! IEU1 Group
441: sub %g1, %o4, %g2 ! IEU0 Group
45 stx %g1, [%o0] ! Store
46 add %o0, 8, %o0 ! IEU1
47 andcc %g2, %o5, %g0 ! IEU1 Group
48 bne,pn %xcc, 5f ! CTI
49 add %o1, 8, %o1 ! IEU0
50 cmp %o0, %g3 ! IEU1 Group
51 bl,a,pt %xcc, 1b ! CTI
5261: ldxa [%o1] %asi, %g1 ! Load
5310: retl ! CTI Group
54 mov %o2, %o0 ! IEU0
555: srlx %g2, 32, %g7 ! IEU0 Group
56 sethi %hi(0xff00), %o4 ! IEU1
57 andcc %g7, %o5, %g0 ! IEU1 Group
58 be,pn %icc, 2f ! CTI
59 or %o4, %lo(0xff00), %o4 ! IEU0
60 srlx %g1, 48, %g7 ! IEU0 Group
61 andcc %g7, %o4, %g0 ! IEU1 Group
62 be,pn %icc, 50f ! CTI
63 andcc %g7, 0xff, %g0 ! IEU1 Group
64 be,pn %icc, 51f ! CTI
65 srlx %g1, 32, %g7 ! IEU0
66 andcc %g7, %o4, %g0 ! IEU1 Group
67 be,pn %icc, 52f ! CTI
68 andcc %g7, 0xff, %g0 ! IEU1 Group
69 be,pn %icc, 53f ! CTI
702: andcc %g2, %o5, %g0 ! IEU1 Group
71 be,pn %icc, 2f ! CTI
72 srl %g1, 16, %g7 ! IEU0
73 andcc %g7, %o4, %g0 ! IEU1 Group
74 be,pn %icc, 54f ! CTI
75 andcc %g7, 0xff, %g0 ! IEU1 Group
76 be,pn %icc, 55f ! CTI
77 andcc %g1, %o4, %g0 ! IEU1 Group
78 be,pn %icc, 56f ! CTI
79 andcc %g1, 0xff, %g0 ! IEU1 Group
80 be,a,pn %icc, 57f ! CTI
81 sub %o0, %o3, %o0 ! IEU0
822: cmp %o0, %g3 ! IEU1 Group
83 bl,a,pt %xcc, 50b ! CTI
8462: ldxa [%o1] %asi, %g1 ! Load
85 retl ! CTI Group
86 mov %o2, %o0 ! IEU0
8750: sub %o0, %o3, %o0
88 retl
89 sub %o0, 8, %o0
9051: sub %o0, %o3, %o0
91 retl
92 sub %o0, 7, %o0
9352: sub %o0, %o3, %o0
94 retl
95 sub %o0, 6, %o0
9653: sub %o0, %o3, %o0
97 retl
98 sub %o0, 5, %o0
9954: sub %o0, %o3, %o0
100 retl
101 sub %o0, 4, %o0
10255: sub %o0, %o3, %o0
103 retl
104 sub %o0, 3, %o0
10556: sub %o0, %o3, %o0
106 retl
107 sub %o0, 2, %o0
10857: retl
109 sub %o0, 1, %o0
11030: brlez,pn %o2, 3f
111 sub %g0, %o2, %o3
112 add %o0, %o2, %o0
11363: lduba [%o1] %asi, %o4
1141: add %o1, 1, %o1
115 brz,pn %o4, 2f
116 stb %o4, [%o0 + %o3]
117 addcc %o3, 1, %o3
118 bne,pt %xcc, 1b
11964: lduba [%o1] %asi, %o4
1203: retl
121 mov %o2, %o0
1222: retl
123 add %o2, %o3, %o0
124ENDPROC(__strncpy_from_user)
125
126 .section __ex_table,"a"
127 .align 4
128 .word 60b, __retl_efault
129 .word 61b, __retl_efault
130 .word 62b, __retl_efault
131 .word 63b, __retl_efault
132 .word 64b, __retl_efault
133 .previous
diff --git a/arch/sparc/lib/usercopy.c b/arch/sparc/lib/usercopy.c
index 14b363fec8a2..5c4284ce1c03 100644
--- a/arch/sparc/lib/usercopy.c
+++ b/arch/sparc/lib/usercopy.c
@@ -1,4 +1,5 @@
1#include <linux/module.h> 1#include <linux/module.h>
2#include <linux/kernel.h>
2#include <linux/bug.h> 3#include <linux/bug.h>
3 4
4void copy_from_user_overflow(void) 5void copy_from_user_overflow(void)
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
index 8e97e0305b01..256db6b22c54 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -467,33 +467,6 @@ void srmmu_unmapiorange(unsigned long virt_addr, unsigned int len)
467 flush_tlb_all(); 467 flush_tlb_all();
468} 468}
469 469
470/*
471 * On the SRMMU we do not have the problems with limited tlb entries
472 * for mapping kernel pages, so we just take things from the free page
473 * pool. As a side effect we are putting a little too much pressure
474 * on the gfp() subsystem. This setup also makes the logic of the
475 * iommu mapping code a lot easier as we can transparently handle
476 * mappings on the kernel stack without any special code.
477 */
478struct thread_info *alloc_thread_info_node(struct task_struct *tsk, int node)
479{
480 struct thread_info *ret;
481
482 ret = (struct thread_info *)__get_free_pages(GFP_KERNEL,
483 THREAD_INFO_ORDER);
484#ifdef CONFIG_DEBUG_STACK_USAGE
485 if (ret)
486 memset(ret, 0, PAGE_SIZE << THREAD_INFO_ORDER);
487#endif /* DEBUG_STACK_USAGE */
488
489 return ret;
490}
491
492void free_thread_info(struct thread_info *ti)
493{
494 free_pages((unsigned long)ti, THREAD_INFO_ORDER);
495}
496
497/* tsunami.S */ 470/* tsunami.S */
498extern void tsunami_flush_cache_all(void); 471extern void tsunami_flush_cache_all(void);
499extern void tsunami_flush_cache_mm(struct mm_struct *mm); 472extern void tsunami_flush_cache_mm(struct mm_struct *mm);