Subject: [PATCH] Add 3GB personality for x86-64
From: Andi Kleen <[email-masked]>
To: [email-masked]
Cc: [email-masked]
Date: Sat, 23 Aug 2003 15:12:35 +0200

As discussed earlier: some important 32bit programs only work with exactly 3GB 
of address space. x86-64 uses 4GB by default for 32bit programs.
Allow to overwrite this using a personality flag.

-Andi

diff -burpN -X ../KDIFX linux/include/asm-x86_64/ia32.h linux-2.6.0test4-amd64/include/asm-x86_64/ia32.h
--- linux/include/asm-x86_64/ia32.h	2003-05-27 03:00:56.000000000 +0200
+++ linux-2.6.0test4-amd64/include/asm-x86_64/ia32.h	2003-08-20 22:53:38.000000000 +0200
@@ -160,7 +160,6 @@ struct ustat32 {
 	char			f_fpack[6];
 };
 
-#define IA32_PAGE_OFFSET 0xffffe000
 #define IA32_STACK_TOP IA32_PAGE_OFFSET
 
 #ifdef __KERNEL__
diff -burpN -X ../KDIFX linux/include/asm-x86_64/processor.h linux-2.6.0test4-amd64/include/asm-x86_64/processor.h
--- linux/include/asm-x86_64/processor.h	2003-08-23 13:03:22.000000000 +0200
+++ linux-2.6.0test4-amd64/include/asm-x86_64/processor.h	2003-08-23 13:12:33.000000000 +0200
@@ -18,6 +18,7 @@
 #include <asm/current.h>
 #include <asm/system.h>
 #include <asm/mmsegment.h>
+#include <linux/personality.h>
 
 #define TF_MASK		0x00000100
 #define IF_MASK		0x00000200
@@ -172,7 +173,8 @@ static inline void clear_in_cr4 (unsigne
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
  */
-#define TASK_UNMAPPED_32 0xa0000000
+#define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? 0xc0000000 : 0xFFFFe000)
+#define TASK_UNMAPPED_32 (IA32_PAGE_OFFSET / 3)
 #define TASK_UNMAPPED_64 PAGE_ALIGN(TASK_SIZE/3) 
 #define TASK_UNMAPPED_BASE	\
 	(test_thread_flag(TIF_IA32) ? TASK_UNMAPPED_32 : TASK_UNMAPPED_64)  
diff -burpN -X ../KDIFX linux/include/linux/personality.h linux-2.6.0test4-amd64/include/linux/personality.h
--- linux/include/linux/personality.h	2003-05-27 03:00:40.000000000 +0200
+++ linux-2.6.0test4-amd64/include/linux/personality.h	2003-08-20 22:55:54.000000000 +0200
@@ -34,6 +34,7 @@ enum {
 	SHORT_INODE =		0x1000000,
 	WHOLE_SECONDS =		0x2000000,
 	STICKY_TIMEOUTS	=	0x4000000,
+	ADDR_LIMIT_3GB = 	0x8000000,
 };
 
 /*
@@ -56,6 +57,7 @@ enum {
 	PER_SUNOS =		0x0006 | STICKY_TIMEOUTS,
 	PER_XENIX =		0x0007 | STICKY_TIMEOUTS | SHORT_INODE,
 	PER_LINUX32 =		0x0008,
+	PER_LINUX32_3GB =	0x0008 | ADDR_LIMIT_3GB,
 	PER_IRIX32 =		0x0009 | STICKY_TIMEOUTS,/* IRIX5 32-bit */
 	PER_IRIXN32 =		0x000a | STICKY_TIMEOUTS,/* IRIX6 new 32-bit */
 	PER_IRIX64 =		0x000b | STICKY_TIMEOUTS,/* IRIX6 64-bit */