All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] MIPS: Make TASK_SIZE reflect proper size for both 32 and 64 bit processes.
@ 2010-10-13 17:53 David Daney
  2010-10-13 21:46 ` David Daney
  0 siblings, 1 reply; 2+ messages in thread
From: David Daney @ 2010-10-13 17:53 UTC (permalink / raw)
  To: linux-mips, ralf; +Cc: David Daney

The TASK_SIZE macro should reflect the size of a user process virtual
address space.  Previously for 64-bit kernels, this was not the case.
The immediate cause of pain was in
hugetlbfs/inode.c:hugetlb_get_unmapped_area() where 32-bit processes
trying to mmap a huge page would be served a page with an address
outside of the 32-bit address range.  But there are other uses of
TASK_SIZE in the kernel as well that would like an accurate value.

The new definition is nice because it now makes TASK_SIZE and
TASK_SIZE_OF() yield the same value for any given process.

For 32-bit kernels there should be no change, although I did factor
out some code in asm/processor.h that became identical for the 32-bit and
64-bit cases.

__UA_LIMIT is set to 1 << 63 for 64-bit kernels on the theory that the
TLB handlers cause a fault on all illegal accesses in the bottom half
of the address space.  This allows for more efficient code generation.

With the patch applied, I can still run o32, n32 and n64 processes,
and have an o32 shell fork/exec both n32 and n64 processes.

Signed-off-by: David Daney <ddaney@caviumnetworks.com>
---

This second version reworks the __UA_LIMIT part.

 arch/mips/include/asm/pgtable-64.h |    4 +-
 arch/mips/include/asm/processor.h  |   40 +++++++++++++++++------------------
 arch/mips/include/asm/uaccess.h    |    2 +-
 3 files changed, 22 insertions(+), 24 deletions(-)

diff --git a/arch/mips/include/asm/pgtable-64.h b/arch/mips/include/asm/pgtable-64.h
index 1be4b0f..82d881a 100644
--- a/arch/mips/include/asm/pgtable-64.h
+++ b/arch/mips/include/asm/pgtable-64.h
@@ -113,10 +113,10 @@
 #endif
 #define PTRS_PER_PTE	((PAGE_SIZE << PTE_ORDER) / sizeof(pte_t))
 
-#if PGDIR_SIZE >= TASK_SIZE
+#if PGDIR_SIZE >= TASK_SIZE64
 #define USER_PTRS_PER_PGD       (1)
 #else
-#define USER_PTRS_PER_PGD	(TASK_SIZE / PGDIR_SIZE)
+#define USER_PTRS_PER_PGD	(TASK_SIZE64 / PGDIR_SIZE)
 #endif
 #define FIRST_USER_ADDRESS	0UL
 
diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h
index 0d629bb..ead6928 100644
--- a/arch/mips/include/asm/processor.h
+++ b/arch/mips/include/asm/processor.h
@@ -50,13 +50,10 @@ extern unsigned int vced_count, vcei_count;
  * so don't change it unless you know what you are doing.
  */
 #define TASK_SIZE	0x7fff8000UL
-#define STACK_TOP	((TASK_SIZE & PAGE_MASK) - SPECIAL_PAGES_SIZE)
 
-/*
- * This decides where the kernel will search for a free chunk of vm
- * space during mmap's.
- */
-#define TASK_UNMAPPED_BASE	((TASK_SIZE / 3) & ~(PAGE_SIZE))
+#ifdef __KERNEL__
+#define STACK_TOP_MAX	TASK_SIZE
+#endif
 
 #define TASK_IS_32BIT_ADDR 1
 
@@ -71,28 +68,29 @@ extern unsigned int vced_count, vcei_count;
  * 8192EB ...
  */
 #define TASK_SIZE32	0x7fff8000UL
-#define TASK_SIZE	0x10000000000UL
-#define STACK_TOP	\
-	(((test_thread_flag(TIF_32BIT_ADDR) ?				\
-	   TASK_SIZE32 : TASK_SIZE) & PAGE_MASK) - SPECIAL_PAGES_SIZE)
+#define TASK_SIZE64	0x10000000000UL
+#define TASK_SIZE (test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE64)
+
+#ifdef __KERNEL__
+#define STACK_TOP_MAX	TASK_SIZE64
+#endif
+
 
-/*
- * This decides where the kernel will search for a free chunk of vm
- * space during mmap's.
- */
-#define TASK_UNMAPPED_BASE						\
-	(test_thread_flag(TIF_32BIT_ADDR) ?				\
-		PAGE_ALIGN(TASK_SIZE32 / 3) : PAGE_ALIGN(TASK_SIZE / 3))
 #define TASK_SIZE_OF(tsk)						\
-	(test_tsk_thread_flag(tsk, TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE)
+	(test_tsk_thread_flag(tsk, TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE64)
 
 #define TASK_IS_32BIT_ADDR test_thread_flag(TIF_32BIT_ADDR)
 
 #endif
 
-#ifdef __KERNEL__
-#define STACK_TOP_MAX	TASK_SIZE
-#endif
+#define STACK_TOP	((TASK_SIZE & PAGE_MASK) - SPECIAL_PAGES_SIZE)
+
+/*
+ * This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE PAGE_ALIGN(TASK_SIZE / 3)
+
 
 #define NUM_FPU_REGS	32
 
diff --git a/arch/mips/include/asm/uaccess.h b/arch/mips/include/asm/uaccess.h
index c2d53c1..476348f 100644
--- a/arch/mips/include/asm/uaccess.h
+++ b/arch/mips/include/asm/uaccess.h
@@ -35,7 +35,7 @@
 
 #ifdef CONFIG_64BIT
 
-#define __UA_LIMIT	(- TASK_SIZE)
+#define __UA_LIMIT	(1ul << 63)
 
 #define __UA_ADDR	".dword"
 #define __UA_LA		"dla"
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH v2] MIPS: Make TASK_SIZE reflect proper size for both 32 and 64 bit processes.
  2010-10-13 17:53 [PATCH v2] MIPS: Make TASK_SIZE reflect proper size for both 32 and 64 bit processes David Daney
@ 2010-10-13 21:46 ` David Daney
  0 siblings, 0 replies; 2+ messages in thread
From: David Daney @ 2010-10-13 21:46 UTC (permalink / raw)
  To: ralf; +Cc: linux-mips

On 10/13/2010 10:53 AM, David Daney wrote:
[...]
>
> -#define __UA_LIMIT	(- TASK_SIZE)
> +#define __UA_LIMIT	(1ul<<  63)
>

This doesn't work:

Unhandled kernel unaligned access[#1]:
Cpu 7
$ 0   : 0000000000000000 10c38ca810c38c78 0000000000000000 0000000000000000
$ 4   : ffffffff811238ac 10c38ca810c38c68 0000000010108ce3 10c38ca810c38c68
$ 8   : 0000000000000000 10c38ca810c38c68 10c38ca810c38c68 10c38ca810c38c68
$12   : 0000000010108ce1 000000001000001e ffffffff8117aa08 ffffffff815905c8
$16   : ffffffffdca80000 a80000009271bcd0 8000000000000000 00000001208d0094
$20   : 10c38ca810c38c68 0000005558776460 ffffffffffffffa7 0000005558776428
$24   : 0000000000000000 0000005558aace60
$28   : a800000092718000 a80000009271bca0 0000005558776420 ffffffff81100880
Hi    : 0000000000000249
Lo    : 077c561f20000000
epc   : ffffffff811238c4 do_ade+0x1f4/0x490
     Not tainted
ra    : ffffffff81100880 ret_from_exception+0x0/0x8
Status: 10108ce3    KX SX UX KERNEL EXL IE
Cause : 00800010
BadVA : 10c38ca810c38c68
PrId  : 000d0409 (Cavium Octeon+)
Modules linked in:
Process loop-3.exe (pid: 31583, threadinfo=a800000092718000, 
task=a8000000b6529fc8, tls=000000555c5ca880)
Stack : 0000000000000008 0000000000000080 10c38ca810c38c68 0000000000000008
         00000001208d0094 ffffffff81100880 0000000000000000 10c38ca810c38c78
         0000000000000000 8000000000000000 a80000009271be38 10c38ca810c38c68
         0000000000000010 10c38ca810c38c68 0000000000000000 10c38ca810c38c68
         10c38ca810c38c68 10c38ca810c38c68 0000000000000000 0000000000000000
         ffffffff8117aa08 ffffffff815905c8 0000000000000080 10c38ca810c38c68
         0000000000000008 00000001208d0094 10c38ca810c38c68 0000005558776460
         ffffffffffffffa7 0000005558776428 0000000000000000 0000005558aace60
         ffffffff814f8ba8 ffffffff81123f14 a800000092718000 a80000009271be30
         0000005558776420 ffffffff8117aae8 0000000010108ce3 0000000000000249
         ...
Call Trace:
[<ffffffff811238c4>] do_ade+0x1f4/0x490
[<ffffffff81100880>] ret_from_exception+0x0/0x8
[<ffffffff81100590>] less_than_4units+0xc/0x5c
[<ffffffff8117aae8>] SyS_futex+0xe0/0x1c0
[<ffffffff81102bc4>] handle_sys64+0x44/0x60



We are doing a copy_from_user(), with a bad address passed in from 
userspace.  The access_ok() says it is fine, but when we drop into the 
memcpy, we get the Address Error Exception because we exceeded SEGBITS.

Really we want to clamp things at the SEGBITS boundry.

David Daney

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2010-10-13 21:46 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-10-13 17:53 [PATCH v2] MIPS: Make TASK_SIZE reflect proper size for both 32 and 64 bit processes David Daney
2010-10-13 21:46 ` David Daney

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.