Re: __access_ok

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Just to be nit-picking, the end point should be (addr + size - 1).

Jun

Carsten Langgaard wrote:

> 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
> 
> 
> 
> 



[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux