The __access_ok macro in include/asm-mips64/uaccess.h need to be changed in order to work correctly, it's a copy from the 32-bit kernel. It's not good enough to simply check for the "sign bit" of the address. The area between USEG (XUSEG) and KSEG0 will in 64-bit addressing mode generate an address error, if accessed. The size of the area depend on the number of virtual addressing bits, implemented in the CPU. I have tried to come up with a patch, please see below. Any thought ? I also changed the macro in arch/mips64/kernel/unaligned.c /Carsten Index: include/asm-mips64//uaccess.h =================================================================== RCS file: /home/repository/sw/linux-2.4.18/include/asm-mips64/uaccess.h,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 uaccess.h --- include/asm-mips64//uaccess.h 4 Mar 2002 11:13:26 -0000 1.1.1.1 +++ include/asm-mips64//uaccess.h 17 Jun 2002 11:35:32 -0000 @@ -12,6 +12,8 @@ #include <linux/errno.h> #include <linux/sched.h> +#include <asm/addrspace.h> + #define STR(x) __STR(x) #define __STR(x) #x @@ -40,16 +42,23 @@ * than tests. * * Address valid if: - * - "addr" doesn't have any high-bits set - * - AND "size" doesn't have any high-bits set - * - AND "addr+size" doesn't have any high-bits set - * - OR we are in kernel mode. + * - In user mode and "addr" and "addr+size" in USEG (or XUSEG). + * - OR we are in kernel mode and "addr" and "addr+size" isn't in the + * area between USEG (XUSEG) and KSEG0. */ #define __ua_size(size) \ (__builtin_constant_p(size) && (signed long) (size) > 0 ? 0 : (size)) -#define __access_ok(addr,size,mask) \ - (((signed long)((mask)&(addr | (addr + size) | __ua_size(size)))) >= 0) +static inline int +__access_ok(unsigned long addr, unsigned long size, long mask) +{ + if (((mask) && ((addr | (addr+size)) >= KUSIZE)) || + (((addr | (addr+size)) < K0BASE) && + ((addr | (addr+size)) >= KUSIZE))) + return 0; + else + return 1; +} #define __access_mask ((long)(get_fs().seg)) Index: arch/mips64/kernel/unaligned.c =================================================================== RCS file: /home/repository/sw/linux-2.4.18/arch/mips64/kernel/unaligned.c,v retrieving revision 1.2 diff -u -r1.2 unaligned.c --- arch/mips64/kernel/unaligned.c 23 May 2002 11:11:45 -0000 1.2 +++ arch/mips64/kernel/unaligned.c 17 Jun 2002 11:51:30 -0000 @@ -89,11 +89,14 @@ #define __STR(x) #x /* - * User code may only access USEG; kernel code may access the - * entire address space. + * User code may only access USEG; + * Kernel code may access the entire address space, except the area between + * USEG (XUSEG) and KSEG0. */ -#define check_axs(pc,a,s) \ - if ((long)(~(pc) & ((a) | ((a)+(s)))) < 0) \ +#define check_axs(pc,a,s) \ + if (((pc < KUSIZE) && (((a) | ((a)+(s))) >= KUSIZE)) || \ + ((((a) | ((a)+(s))) < K0BASE) && \ + (((a) | ((a)+(s))) >= KUSIZE))) \ goto sigbus; -- _ _ ____ ___ Carsten Langgaard Mailto:carstenl@mips.com |\ /|||___)(___ MIPS Denmark Direct: +45 4486 5527 | \/ ||| ____) Lautrupvang 4B Switch: +45 4486 5555 TECHNOLOGIES 2750 Ballerup Fax...: +45 4486 5556 Denmark http://www.mips.com