[PATCH 1/5] UML - Runtime host VMSPLIT detection

2008-02-06 Thread Jeff Dike
Calculate TASK_SIZE at run-time by figuring out the host's VMSPLIT -
this is needed on i386 if UML is to run on hosts with varying VMSPLITs
without recompilation.

TASK_SIZE is now defined in terms of a variable, task_size.  This gets
rid of an include of pgtable.h from processor.h, which can cause
include loops.

On i386, task_size is calculated early in boot by probing the address
space in a binary search to figure out where the boundary between
usable and non-usable memory is.  This tries to make sure that a page
that is considered to be in userspace is, or can be made, read-write.
I'm concerned about a system-global VDSO page in kernel memory being
hit and considered to be a userspace page.

On x86_64, task_size is just the old value of CONFIG_TOP_ADDR.

A bunch of config variable are gone now.  CONFIG_TOP_ADDR is directly
replaced by TASK_SIZE.  NEST_LEVEL is gone since the relocation of
the stubs makes it irrelevant.  All the HOST_VMSPLIT stuff is gone.
All references to these in arch/um/Makefile are also gone.

I noticed and fixed a missing extern in os.h when adding
os_get_task_size.

Note: This has been revised to fix the 32-bit UML on 64-bit host bug
that Miklos ran into.

Signed-off-by: Jeff Dike <[EMAIL PROTECTED]>
---
 arch/um/Kconfig |   11 --
 arch/um/Kconfig.i386|   37 -
 arch/um/Kconfig.x86_64  |4 -
 arch/um/Makefile|   11 --
 arch/um/defconfig   |3 
 arch/um/include/as-layout.h |2 
 arch/um/include/os.h|5 +
 arch/um/kernel/exec.c   |2 
 arch/um/kernel/um_arch.c|   16 +++-
 arch/um/os-Linux/sys-i386/Makefile  |2 
 arch/um/os-Linux/sys-i386/task_size.c   |  120 
 arch/um/os-Linux/sys-x86_64/Makefile|2 
 arch/um/os-Linux/sys-x86_64/task_size.c |5 +
 include/asm-um/fixmap.h |3 
 include/asm-um/processor-generic.h  |5 -
 15 files changed, 153 insertions(+), 75 deletions(-)

Index: linux-2.6-git/arch/um/kernel/um_arch.c
===
--- linux-2.6-git.orig/arch/um/kernel/um_arch.c 2008-02-06 11:19:07.0 
-0500
+++ linux-2.6-git/arch/um/kernel/um_arch.c  2008-02-06 11:31:53.0 
-0500
@@ -241,6 +241,11 @@ static struct notifier_block panic_exit_
 };
 
 /* Set during early boot */
+unsigned long task_size;
+EXPORT_SYMBOL(task_size);
+
+unsigned long host_task_size;
+
 unsigned long brk_start;
 unsigned long end_iomem;
 EXPORT_SYMBOL(end_iomem);
@@ -267,6 +272,13 @@ int __init linux_main(int argc, char **a
if (have_root == 0)
add_arg(DEFAULT_COMMAND_LINE);
 
+   host_task_size = os_get_task_size();
+   /*
+* TASK_SIZE needs to be PGDIR_SIZE aligned or else exit_mmap craps
+* out
+*/
+   task_size = host_task_size & PGDIR_MASK;
+
/* OS sanity checks that need to happen before the kernel runs */
os_early_checks();
 
@@ -303,7 +315,7 @@ int __init linux_main(int argc, char **a
 
highmem = 0;
iomem_size = (iomem_size + PAGE_SIZE - 1) & PAGE_MASK;
-   max_physmem = CONFIG_TOP_ADDR - uml_physmem - iomem_size - MIN_VMALLOC;
+   max_physmem = TASK_SIZE - uml_physmem - iomem_size - MIN_VMALLOC;
 
/*
 * Zones have to begin on a 1 << MAX_ORDER page boundary,
@@ -335,7 +347,7 @@ int __init linux_main(int argc, char **a
}
 
virtmem_size = physmem_size;
-   avail = CONFIG_TOP_ADDR - start_vm;
+   avail = TASK_SIZE - start_vm;
if (physmem_size > avail)
virtmem_size = avail;
end_vm = start_vm + virtmem_size;
Index: linux-2.6-git/include/asm-um/processor-generic.h
===
--- linux-2.6-git.orig/include/asm-um/processor-generic.h   2008-02-06 
11:19:09.0 -0500
+++ linux-2.6-git/include/asm-um/processor-generic.h2008-02-06 
11:31:53.0 -0500
@@ -11,7 +11,6 @@ struct pt_regs;
 struct task_struct;
 
 #include "asm/ptrace.h"
-#include "asm/pgtable.h"
 #include "registers.h"
 #include "sysdep/archsetjmp.h"
 
@@ -92,7 +91,9 @@ static inline void mm_copy_segments(stru
 /*
  * User space process size: 3GB (default).
  */
-#define TASK_SIZE (CONFIG_TOP_ADDR & PGDIR_MASK)
+extern unsigned long task_size;
+
+#define TASK_SIZE (task_size)
 
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
Index: linux-2.6-git/arch/um/include/os.h
===
--- linux-2.6-git.orig/arch/um/include/os.h 2008-02-06 11:19:07.0 
-0500
+++ linux-2.6-git/arch/um/include/os.h  2008-02-06 11:31:53.0 -0500
@@ -295,6 +295,9 @@ extern void maybe_sigio_broken(int fd, i
 extern int os_arch_prctl(int pid, int code, unsigned long *addr);
 
 /* tty.c 

[PATCH 1/5] UML - Runtime host VMSPLIT detection

2008-02-06 Thread Jeff Dike
Calculate TASK_SIZE at run-time by figuring out the host's VMSPLIT -
this is needed on i386 if UML is to run on hosts with varying VMSPLITs
without recompilation.

TASK_SIZE is now defined in terms of a variable, task_size.  This gets
rid of an include of pgtable.h from processor.h, which can cause
include loops.

On i386, task_size is calculated early in boot by probing the address
space in a binary search to figure out where the boundary between
usable and non-usable memory is.  This tries to make sure that a page
that is considered to be in userspace is, or can be made, read-write.
I'm concerned about a system-global VDSO page in kernel memory being
hit and considered to be a userspace page.

On x86_64, task_size is just the old value of CONFIG_TOP_ADDR.

A bunch of config variable are gone now.  CONFIG_TOP_ADDR is directly
replaced by TASK_SIZE.  NEST_LEVEL is gone since the relocation of
the stubs makes it irrelevant.  All the HOST_VMSPLIT stuff is gone.
All references to these in arch/um/Makefile are also gone.

I noticed and fixed a missing extern in os.h when adding
os_get_task_size.

Note: This has been revised to fix the 32-bit UML on 64-bit host bug
that Miklos ran into.

Signed-off-by: Jeff Dike [EMAIL PROTECTED]
---
 arch/um/Kconfig |   11 --
 arch/um/Kconfig.i386|   37 -
 arch/um/Kconfig.x86_64  |4 -
 arch/um/Makefile|   11 --
 arch/um/defconfig   |3 
 arch/um/include/as-layout.h |2 
 arch/um/include/os.h|5 +
 arch/um/kernel/exec.c   |2 
 arch/um/kernel/um_arch.c|   16 +++-
 arch/um/os-Linux/sys-i386/Makefile  |2 
 arch/um/os-Linux/sys-i386/task_size.c   |  120 
 arch/um/os-Linux/sys-x86_64/Makefile|2 
 arch/um/os-Linux/sys-x86_64/task_size.c |5 +
 include/asm-um/fixmap.h |3 
 include/asm-um/processor-generic.h  |5 -
 15 files changed, 153 insertions(+), 75 deletions(-)

Index: linux-2.6-git/arch/um/kernel/um_arch.c
===
--- linux-2.6-git.orig/arch/um/kernel/um_arch.c 2008-02-06 11:19:07.0 
-0500
+++ linux-2.6-git/arch/um/kernel/um_arch.c  2008-02-06 11:31:53.0 
-0500
@@ -241,6 +241,11 @@ static struct notifier_block panic_exit_
 };
 
 /* Set during early boot */
+unsigned long task_size;
+EXPORT_SYMBOL(task_size);
+
+unsigned long host_task_size;
+
 unsigned long brk_start;
 unsigned long end_iomem;
 EXPORT_SYMBOL(end_iomem);
@@ -267,6 +272,13 @@ int __init linux_main(int argc, char **a
if (have_root == 0)
add_arg(DEFAULT_COMMAND_LINE);
 
+   host_task_size = os_get_task_size();
+   /*
+* TASK_SIZE needs to be PGDIR_SIZE aligned or else exit_mmap craps
+* out
+*/
+   task_size = host_task_size  PGDIR_MASK;
+
/* OS sanity checks that need to happen before the kernel runs */
os_early_checks();
 
@@ -303,7 +315,7 @@ int __init linux_main(int argc, char **a
 
highmem = 0;
iomem_size = (iomem_size + PAGE_SIZE - 1)  PAGE_MASK;
-   max_physmem = CONFIG_TOP_ADDR - uml_physmem - iomem_size - MIN_VMALLOC;
+   max_physmem = TASK_SIZE - uml_physmem - iomem_size - MIN_VMALLOC;
 
/*
 * Zones have to begin on a 1  MAX_ORDER page boundary,
@@ -335,7 +347,7 @@ int __init linux_main(int argc, char **a
}
 
virtmem_size = physmem_size;
-   avail = CONFIG_TOP_ADDR - start_vm;
+   avail = TASK_SIZE - start_vm;
if (physmem_size  avail)
virtmem_size = avail;
end_vm = start_vm + virtmem_size;
Index: linux-2.6-git/include/asm-um/processor-generic.h
===
--- linux-2.6-git.orig/include/asm-um/processor-generic.h   2008-02-06 
11:19:09.0 -0500
+++ linux-2.6-git/include/asm-um/processor-generic.h2008-02-06 
11:31:53.0 -0500
@@ -11,7 +11,6 @@ struct pt_regs;
 struct task_struct;
 
 #include asm/ptrace.h
-#include asm/pgtable.h
 #include registers.h
 #include sysdep/archsetjmp.h
 
@@ -92,7 +91,9 @@ static inline void mm_copy_segments(stru
 /*
  * User space process size: 3GB (default).
  */
-#define TASK_SIZE (CONFIG_TOP_ADDR  PGDIR_MASK)
+extern unsigned long task_size;
+
+#define TASK_SIZE (task_size)
 
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
Index: linux-2.6-git/arch/um/include/os.h
===
--- linux-2.6-git.orig/arch/um/include/os.h 2008-02-06 11:19:07.0 
-0500
+++ linux-2.6-git/arch/um/include/os.h  2008-02-06 11:31:53.0 -0500
@@ -295,6 +295,9 @@ extern void maybe_sigio_broken(int fd, i
 extern int os_arch_prctl(int pid, int code, unsigned long *addr);
 
 /* tty.c */
-int