aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-11-20 18:02:50 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-11-20 18:02:50 -0500
commitdc6ec87d4c77029457a79fd6fa9b6f8304dc8348 (patch)
tree966392c36ef35c8cf388c0b7a57d1d7c1fe429dc
parent8a60ba0a0512c00553c9a20f83f7eabd2662ac0b (diff)
parent964f413323e8306ac0acb5e08ccdb5f12418835b (diff)
Merge branch 'parisc-3.13' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux
Pull parisc fixes from Helge Deller: - revert an access_ok() patch which broke 32bit userspace on 64bit kernels - avoid a gcc miscompilation in two internal pa_memcpy() functions by not inlining those - do not export the definition of SOCK_NONBLOCK via uapi header (fixes build of audit package) - depending on the fault type we now correctly report either SIGBUS or SIGSEGV - a small fix to not compare a size_t variable for < 0 * 'parisc-3.13' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux: parisc: size_t is unsigned, so comparison size < 0 doesn't make sense. parisc: improve SIGBUS/SIGSEGV error reporting parisc: break out SOCK_NONBLOCK define to own asm header file parisc: do not inline pa_memcpy() internal functions Revert "parisc: implement full version of access_ok()"
-rw-r--r--arch/parisc/include/asm/socket.h11
-rw-r--r--arch/parisc/include/asm/uaccess.h46
-rw-r--r--arch/parisc/include/uapi/asm/socket.h11
-rw-r--r--arch/parisc/lib/memcpy.c6
-rw-r--r--arch/parisc/mm/fault.c22
5 files changed, 41 insertions, 55 deletions
diff --git a/arch/parisc/include/asm/socket.h b/arch/parisc/include/asm/socket.h
new file mode 100644
index 000000000000..748016cb122d
--- /dev/null
+++ b/arch/parisc/include/asm/socket.h
@@ -0,0 +1,11 @@
1#ifndef _ASM_SOCKET_H
2#define _ASM_SOCKET_H
3
4#include <uapi/asm/socket.h>
5
6/* O_NONBLOCK clashes with the bits used for socket types. Therefore we
7 * have to define SOCK_NONBLOCK to a different value here.
8 */
9#define SOCK_NONBLOCK 0x40000000
10
11#endif /* _ASM_SOCKET_H */
diff --git a/arch/parisc/include/asm/uaccess.h b/arch/parisc/include/asm/uaccess.h
index 63f4dd0b49c2..4006964d8e12 100644
--- a/arch/parisc/include/asm/uaccess.h
+++ b/arch/parisc/include/asm/uaccess.h
@@ -4,14 +4,11 @@
4/* 4/*
5 * User space memory access functions 5 * User space memory access functions
6 */ 6 */
7#include <asm/processor.h>
8#include <asm/page.h> 7#include <asm/page.h>
9#include <asm/cache.h> 8#include <asm/cache.h>
10#include <asm/errno.h> 9#include <asm/errno.h>
11#include <asm-generic/uaccess-unaligned.h> 10#include <asm-generic/uaccess-unaligned.h>
12 11
13#include <linux/sched.h>
14
15#define VERIFY_READ 0 12#define VERIFY_READ 0
16#define VERIFY_WRITE 1 13#define VERIFY_WRITE 1
17 14
@@ -36,43 +33,12 @@ extern int __get_user_bad(void);
36extern int __put_kernel_bad(void); 33extern int __put_kernel_bad(void);
37extern int __put_user_bad(void); 34extern int __put_user_bad(void);
38 35
39 36static inline long access_ok(int type, const void __user * addr,
40/* 37 unsigned long size)
41 * Test whether a block of memory is a valid user space address.
42 * Returns 0 if the range is valid, nonzero otherwise.
43 */
44static inline int __range_not_ok(unsigned long addr, unsigned long size,
45 unsigned long limit)
46{ 38{
47 unsigned long __newaddr = addr + size; 39 return 1;
48 return (__newaddr < addr || __newaddr > limit || size > limit);
49} 40}
50 41
51/**
52 * access_ok: - Checks if a user space pointer is valid
53 * @type: Type of access: %VERIFY_READ or %VERIFY_WRITE. Note that
54 * %VERIFY_WRITE is a superset of %VERIFY_READ - if it is safe
55 * to write to a block, it is always safe to read from it.
56 * @addr: User space pointer to start of block to check
57 * @size: Size of block to check
58 *
59 * Context: User context only. This function may sleep.
60 *
61 * Checks if a pointer to a block of memory in user space is valid.
62 *
63 * Returns true (nonzero) if the memory block may be valid, false (zero)
64 * if it is definitely invalid.
65 *
66 * Note that, depending on architecture, this function probably just
67 * checks that the pointer is in the user space range - after calling
68 * this function, memory access functions may still return -EFAULT.
69 */
70#define access_ok(type, addr, size) \
71( __chk_user_ptr(addr), \
72 !__range_not_ok((unsigned long) (__force void *) (addr), \
73 size, user_addr_max()) \
74)
75
76#define put_user __put_user 42#define put_user __put_user
77#define get_user __get_user 43#define get_user __get_user
78 44
@@ -253,11 +219,7 @@ extern long lstrnlen_user(const char __user *,long);
253/* 219/*
254 * Complex access routines -- macros 220 * Complex access routines -- macros
255 */ 221 */
256#ifdef CONFIG_COMPAT 222#define user_addr_max() (~0UL)
257#define user_addr_max() (TASK_SIZE)
258#else
259#define user_addr_max() (DEFAULT_TASK_SIZE)
260#endif
261 223
262#define strnlen_user lstrnlen_user 224#define strnlen_user lstrnlen_user
263#define strlen_user(str) lstrnlen_user(str, 0x7fffffffL) 225#define strlen_user(str) lstrnlen_user(str, 0x7fffffffL)
diff --git a/arch/parisc/include/uapi/asm/socket.h b/arch/parisc/include/uapi/asm/socket.h
index 7c614d01f1fa..f33113a6141e 100644
--- a/arch/parisc/include/uapi/asm/socket.h
+++ b/arch/parisc/include/uapi/asm/socket.h
@@ -1,5 +1,5 @@
1#ifndef _ASM_SOCKET_H 1#ifndef _UAPI_ASM_SOCKET_H
2#define _ASM_SOCKET_H 2#define _UAPI_ASM_SOCKET_H
3 3
4#include <asm/sockios.h> 4#include <asm/sockios.h>
5 5
@@ -77,9 +77,4 @@
77 77
78#define SO_MAX_PACING_RATE 0x4048 78#define SO_MAX_PACING_RATE 0x4048
79 79
80/* O_NONBLOCK clashes with the bits used for socket types. Therefore we 80#endif /* _UAPI_ASM_SOCKET_H */
81 * have to define SOCK_NONBLOCK to a different value here.
82 */
83#define SOCK_NONBLOCK 0x40000000
84
85#endif /* _ASM_SOCKET_H */
diff --git a/arch/parisc/lib/memcpy.c b/arch/parisc/lib/memcpy.c
index b5507ec06b84..413dc1769299 100644
--- a/arch/parisc/lib/memcpy.c
+++ b/arch/parisc/lib/memcpy.c
@@ -161,7 +161,7 @@ static inline void prefetch_dst(const void *addr)
161/* Copy from a not-aligned src to an aligned dst, using shifts. Handles 4 words 161/* Copy from a not-aligned src to an aligned dst, using shifts. Handles 4 words
162 * per loop. This code is derived from glibc. 162 * per loop. This code is derived from glibc.
163 */ 163 */
164static inline unsigned long copy_dstaligned(unsigned long dst, 164static noinline unsigned long copy_dstaligned(unsigned long dst,
165 unsigned long src, unsigned long len) 165 unsigned long src, unsigned long len)
166{ 166{
167 /* gcc complains that a2 and a3 may be uninitialized, but actually 167 /* gcc complains that a2 and a3 may be uninitialized, but actually
@@ -276,7 +276,7 @@ handle_store_error:
276/* Returns PA_MEMCPY_OK, PA_MEMCPY_LOAD_ERROR or PA_MEMCPY_STORE_ERROR. 276/* Returns PA_MEMCPY_OK, PA_MEMCPY_LOAD_ERROR or PA_MEMCPY_STORE_ERROR.
277 * In case of an access fault the faulty address can be read from the per_cpu 277 * In case of an access fault the faulty address can be read from the per_cpu
278 * exception data struct. */ 278 * exception data struct. */
279static unsigned long pa_memcpy_internal(void *dstp, const void *srcp, 279static noinline unsigned long pa_memcpy_internal(void *dstp, const void *srcp,
280 unsigned long len) 280 unsigned long len)
281{ 281{
282 register unsigned long src, dst, t1, t2, t3; 282 register unsigned long src, dst, t1, t2, t3;
@@ -529,7 +529,7 @@ long probe_kernel_read(void *dst, const void *src, size_t size)
529{ 529{
530 unsigned long addr = (unsigned long)src; 530 unsigned long addr = (unsigned long)src;
531 531
532 if (size < 0 || addr < PAGE_SIZE) 532 if (addr < PAGE_SIZE)
533 return -EFAULT; 533 return -EFAULT;
534 534
535 /* check for I/O space F_EXTEND(0xfff00000) access as well? */ 535 /* check for I/O space F_EXTEND(0xfff00000) access as well? */
diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c
index 7584a5df0fa4..9d08c71a967e 100644
--- a/arch/parisc/mm/fault.c
+++ b/arch/parisc/mm/fault.c
@@ -282,16 +282,34 @@ bad_area:
282#endif 282#endif
283 switch (code) { 283 switch (code) {
284 case 15: /* Data TLB miss fault/Data page fault */ 284 case 15: /* Data TLB miss fault/Data page fault */
285 /* send SIGSEGV when outside of vma */
286 if (!vma ||
287 address < vma->vm_start || address > vma->vm_end) {
288 si.si_signo = SIGSEGV;
289 si.si_code = SEGV_MAPERR;
290 break;
291 }
292
293 /* send SIGSEGV for wrong permissions */
294 if ((vma->vm_flags & acc_type) != acc_type) {
295 si.si_signo = SIGSEGV;
296 si.si_code = SEGV_ACCERR;
297 break;
298 }
299
300 /* probably address is outside of mapped file */
301 /* fall through */
285 case 17: /* NA data TLB miss / page fault */ 302 case 17: /* NA data TLB miss / page fault */
286 case 18: /* Unaligned access - PCXS only */ 303 case 18: /* Unaligned access - PCXS only */
287 si.si_signo = SIGBUS; 304 si.si_signo = SIGBUS;
288 si.si_code = BUS_ADRERR; 305 si.si_code = (code == 18) ? BUS_ADRALN : BUS_ADRERR;
289 break; 306 break;
290 case 16: /* Non-access instruction TLB miss fault */ 307 case 16: /* Non-access instruction TLB miss fault */
291 case 26: /* PCXL: Data memory access rights trap */ 308 case 26: /* PCXL: Data memory access rights trap */
292 default: 309 default:
293 si.si_signo = SIGSEGV; 310 si.si_signo = SIGSEGV;
294 si.si_code = SEGV_MAPERR; 311 si.si_code = (code == 26) ? SEGV_ACCERR : SEGV_MAPERR;
312 break;
295 } 313 }
296 si.si_errno = 0; 314 si.si_errno = 0;
297 si.si_addr = (void __user *) address; 315 si.si_addr = (void __user *) address;