Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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()"

+41 -55
+11
arch/parisc/include/asm/socket.h
··· 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 */
+4 -42
arch/parisc/include/asm/uaccess.h
··· 4 4 /* 5 5 * User space memory access functions 6 6 */ 7 - #include <asm/processor.h> 8 7 #include <asm/page.h> 9 8 #include <asm/cache.h> 10 9 #include <asm/errno.h> 11 10 #include <asm-generic/uaccess-unaligned.h> 12 - 13 - #include <linux/sched.h> 14 11 15 12 #define VERIFY_READ 0 16 13 #define VERIFY_WRITE 1 ··· 33 36 extern int __put_kernel_bad(void); 34 37 extern int __put_user_bad(void); 35 38 36 - 37 - /* 38 - * Test whether a block of memory is a valid user space address. 39 - * Returns 0 if the range is valid, nonzero otherwise. 40 - */ 41 - static inline int __range_not_ok(unsigned long addr, unsigned long size, 42 - unsigned long limit) 39 + static inline long access_ok(int type, const void __user * addr, 40 + unsigned long size) 43 41 { 44 - unsigned long __newaddr = addr + size; 45 - return (__newaddr < addr || __newaddr > limit || size > limit); 42 + return 1; 46 43 } 47 - 48 - /** 49 - * access_ok: - Checks if a user space pointer is valid 50 - * @type: Type of access: %VERIFY_READ or %VERIFY_WRITE. Note that 51 - * %VERIFY_WRITE is a superset of %VERIFY_READ - if it is safe 52 - * to write to a block, it is always safe to read from it. 53 - * @addr: User space pointer to start of block to check 54 - * @size: Size of block to check 55 - * 56 - * Context: User context only. This function may sleep. 57 - * 58 - * Checks if a pointer to a block of memory in user space is valid. 59 - * 60 - * Returns true (nonzero) if the memory block may be valid, false (zero) 61 - * if it is definitely invalid. 62 - * 63 - * Note that, depending on architecture, this function probably just 64 - * checks that the pointer is in the user space range - after calling 65 - * this function, memory access functions may still return -EFAULT. 66 - */ 67 - #define access_ok(type, addr, size) \ 68 - ( __chk_user_ptr(addr), \ 69 - !__range_not_ok((unsigned long) (__force void *) (addr), \ 70 - size, user_addr_max()) \ 71 - ) 72 44 73 45 #define put_user __put_user 74 46 #define get_user __get_user ··· 219 253 /* 220 254 * Complex access routines -- macros 221 255 */ 222 - #ifdef CONFIG_COMPAT 223 - #define user_addr_max() (TASK_SIZE) 224 - #else 225 - #define user_addr_max() (DEFAULT_TASK_SIZE) 226 - #endif 256 + #define user_addr_max() (~0UL) 227 257 228 258 #define strnlen_user lstrnlen_user 229 259 #define strlen_user(str) lstrnlen_user(str, 0x7fffffffL)
+3 -8
arch/parisc/include/uapi/asm/socket.h
··· 1 - #ifndef _ASM_SOCKET_H 2 - #define _ASM_SOCKET_H 1 + #ifndef _UAPI_ASM_SOCKET_H 2 + #define _UAPI_ASM_SOCKET_H 3 3 4 4 #include <asm/sockios.h> 5 5 ··· 77 77 78 78 #define SO_MAX_PACING_RATE 0x4048 79 79 80 - /* O_NONBLOCK clashes with the bits used for socket types. Therefore we 81 - * have to define SOCK_NONBLOCK to a different value here. 82 - */ 83 - #define SOCK_NONBLOCK 0x40000000 84 - 85 - #endif /* _ASM_SOCKET_H */ 80 + #endif /* _UAPI_ASM_SOCKET_H */
+3 -3
arch/parisc/lib/memcpy.c
··· 161 161 /* Copy from a not-aligned src to an aligned dst, using shifts. Handles 4 words 162 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 165 unsigned long src, unsigned long len) 166 166 { 167 167 /* gcc complains that a2 and a3 may be uninitialized, but actually ··· 276 276 /* Returns PA_MEMCPY_OK, PA_MEMCPY_LOAD_ERROR or PA_MEMCPY_STORE_ERROR. 277 277 * In case of an access fault the faulty address can be read from the per_cpu 278 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 280 unsigned long len) 281 281 { 282 282 register unsigned long src, dst, t1, t2, t3; ··· 529 529 { 530 530 unsigned long addr = (unsigned long)src; 531 531 532 - if (size < 0 || addr < PAGE_SIZE) 532 + if (addr < PAGE_SIZE) 533 533 return -EFAULT; 534 534 535 535 /* check for I/O space F_EXTEND(0xfff00000) access as well? */
+20 -2
arch/parisc/mm/fault.c
··· 282 282 #endif 283 283 switch (code) { 284 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 302 case 17: /* NA data TLB miss / page fault */ 286 303 case 18: /* Unaligned access - PCXS only */ 287 304 si.si_signo = SIGBUS; 288 - si.si_code = BUS_ADRERR; 305 + si.si_code = (code == 18) ? BUS_ADRALN : BUS_ADRERR; 289 306 break; 290 307 case 16: /* Non-access instruction TLB miss fault */ 291 308 case 26: /* PCXL: Data memory access rights trap */ 292 309 default: 293 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 314 si.si_errno = 0; 297 315 si.si_addr = (void __user *) address;