diff options
| -rw-r--r-- | arch/parisc/include/asm/socket.h | 11 | ||||
| -rw-r--r-- | arch/parisc/include/asm/uaccess.h | 46 | ||||
| -rw-r--r-- | arch/parisc/include/uapi/asm/socket.h | 11 | ||||
| -rw-r--r-- | arch/parisc/lib/memcpy.c | 6 | ||||
| -rw-r--r-- | arch/parisc/mm/fault.c | 22 |
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); | |||
| 36 | extern int __put_kernel_bad(void); | 33 | extern int __put_kernel_bad(void); |
| 37 | extern int __put_user_bad(void); | 34 | extern int __put_user_bad(void); |
| 38 | 35 | ||
| 39 | 36 | static 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 | */ | ||
| 44 | static 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 | */ |
| 164 | static inline unsigned long copy_dstaligned(unsigned long dst, | 164 | static 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. */ |
| 279 | static unsigned long pa_memcpy_internal(void *dstp, const void *srcp, | 279 | static 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; |
