>>>>> On Fri, 2 Jan 2004 20:44:03 +0100, Ralf Baechle <ralf@linux-mips.org>
>>>>> said:
>> Does anybody know why TASK_SIZE is set to 0x7fff8000 and not
>> 0x80000000 ?
ralf> There is a weird special case were 32-bit code running on a
ralf> 64-bit kernel with c0_status.ux set will behave differently than
ralf> on a 32-bit processor or with c0_status.ux clear. The
ralf> workaround for 64-bit kernels is to leave the top 32kB of the
ralf> 2GB user virtual address space unused. For sake of symmetry we
ralf> do this on both 32-bit and 64-bit kernels.
Then, access_ok in 2.6 tree is broken, isn't it?
2.4 mips:
#define TASK_SIZE 0x7fff8000UL
#define USER_DS ((mm_segment_t) { (unsigned long) -1L })
2.4 mips64:
#define TASK_SIZE32 0x7fff8000UL
#define TASK_SIZE 0x10000000000UL
#define USER_DS ((mm_segment_t) { -TASK_SIZE })
2.6:
#ifdef CONFIG_MIPS32
#define TASK_SIZE 0x7fff8000UL
#else
#define TASK_SIZE32 0x7fff8000UL
#define TASK_SIZE 0x10000000000UL
#endif
#define USER_DS ((mm_segment_t) { -TASK_SIZE })
It seems there should be another definition of USER_DS for
CONFIG_MIPS32 in 2.6.
BTW, there are another problems in uaccess.h as I wrote in
http://www.linux-mips.org/archives/linux-mips/2003-09/msg00035.html.
First, 2.4 mips64 __ua_size is broken.
2.4 mips:
#define __ua_size(size) \
(__builtin_constant_p(size) && (signed long) (size) > 0 ? 0 : (size))
2.4 mips64:
#define __ua_size(size) \
((__builtin_constant_p(size) && (size)) > 0 ? 0 : (size))
2.6:
#define __ua_size(size) \
((__builtin_constant_p(size) && (signed long) (size) > 0) ? 0 : (size))
2.4 mips and 2.6 are identical except for parenthesis.
Second, __access_ok for 64bit kernel is broken both 2.4 and 2.6. It
returns 0 if 'addr' + 'size' == TASK_SIZE (which should be OK).
2.4 mips64:
#define __access_ok(addr, size, mask) \
(((mask) & ((addr) | ((addr) + (size)) | __ua_size(size))) == 0)
2.6:
#define __access_ok(addr, size, mask) \
(((signed long)((mask) & ((addr) | ((addr) + (size)) |
__ua_size(size)))) == 0)
I think these macros should be:
2.4 mips64:
#define __access_ok(addr, size, mask) \
(((mask) & ((addr) | ((addr) + (size) - 1) | __ua_size(size))) == 0)
2.6:
#define __access_ok(addr, size, mask) \
(((signed long)((mask) & ((addr) | ((addr) + (size) - 1) |
__ua_size(size)))) == 0)
---
Atsushi Nemoto
|