UML - Runtime detection of host VMSPLIT on i386
PATCH 1/20 UML - Runtime detection of host VMSPLIT on i386
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.
--- 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(-)
arch/um/kernel/um_arch.c +14 -2
@@ -224,6 +224,11 @@ static void __init uml_postsetup(void) }/* 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);
@@ -250,6 +255,13 @@ int __init linux_main(int argc, char **aif (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 ();
@@ -286,7 +298,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,
@@ -318,7 +330,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;
include/asm-um/processor-generic.h +3 -2
@@ -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"
@@ -94,7 +93,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.
arch/um/include/os.h +4 -1
@@ -302,6 +302,9 @@ extern void sig_handler_common_skas(intextern int os_arch_prctl (int pid,int code,unsigned long *addr);/* tty.c */ -int get_pty (void ); +extern int get_pty (void ); + +/* sys-$ARCH/task_size.c */ +extern unsigned long os_get_task_size (void );#endif
arch/um/os-Linux/sys-i386/Makefile +1 -1
@@ -3,7 +3,7 @@ # Licensed under the GPL # -obj-y = registers.o signal.o tls.o +obj-y = registers.o signal.o task_size.o tls.o USER_OBJS := $(obj-y)
arch/um/os-Linux/sys-i386/task_size.c new file +120 -0
120 lines not on this page · raw message
arch/um/os-Linux/sys-x86_64/Makefile +1 -1
@@ -3,7 +3,7 @@ # Licensed under the GPL # -obj-y = registers.o prctl.o signal.o +obj-y = registers.o prctl.o signal.o task_size.o USER_OBJS := $(obj-y)
arch/um/os-Linux/sys-x86_64/task_size.c new file +5 -0
@@ -0,0 +1,5 @@ +unsigned long os_get_task_size (unsigned long shift) +{ +/* The old value of CONFIG_TOP_ADDR */ +return 0x7fc0000000 ; +}
arch/um/Kconfig +0 -11
@@ -216,17 +216,6 @@ config NR_CPUS depends on SMP default "32" -config NEST_LEVEL - int "Nesting level" - default "0" - help - This is set to the number of layers of UMLs that this UML will be run - in. Normally, this is zero, meaning that it will run directly on the - host. Setting it to one will build a UML that can run inside a UML - that is running on the host. Generally, if you intend this UML to run - inside another UML, set CONFIG_NEST_LEVEL to one more than the host - UML. - config HIGHMEM bool "Highmem support (EXPERIMENTAL)" depends on !64BIT && EXPERIMENTAL
arch/um/Kconfig.i386 +0 -37
@@ -23,43 +23,6 @@ config SEMAPHORE_SLEEPERS bool default y -choice - prompt "Host memory split" - default HOST_VMSPLIT_3G - help - This is needed when the host kernel on which you run has a non-default - (like 2G/2G) memory split, instead of the customary 3G/1G. If you did - not recompile your own kernel but use the default distro's one, you can - safely accept the "Default split" option. - - It can be enabled on recent (>=2.6.16-rc2) vanilla kernels via - CONFIG_VM_SPLIT_*, or on previous kernels with special patches (-ck - patchset by Con Kolivas, or other ones) - option names match closely the - host CONFIG_VM_SPLIT_* ones. - - A lower setting (where 1G/3G is lowest and 3G/1G is higher) will - tolerate even more "normal" host kernels, but an higher setting will be - stricter. - - So, if you do not know what to do here, say 'Default split'. - -config HOST_VMSPLIT_3G - bool "Default split (3G/1G user/kernel host split)" -config HOST_VMSPLIT_3G_OPT - bool "3G/1G user/kernel host split (for full 1G low memory)" -config HOST_VMSPLIT_2G - bool "2G/2G user/kernel host split" -config HOST_VMSPLIT_1G - bool "1G/3G user/kernel host split" -endchoice - -config TOP_ADDR - hex - default 0xB0000000 if HOST_VMSPLIT_3G_OPT - default 0x78000000 if HOST_VMSPLIT_2G - default 0x40000000 if HOST_VMSPLIT_1G - default 0xC0000000 - config 3_LEVEL_PGTABLES bool "Three-level pagetables (EXPERIMENTAL)" default n
arch/um/Kconfig.x86_64 +0 -4
@@ -15,10 +15,6 @@ config SEMAPHORE_SLEEPERS bool default y -config TOP_ADDR - hex - default 0x7fc0000000 - config 3_LEVEL_PGTABLES bool default y
arch/um/Makefile +0 -11
@@ -79,13 +79,6 @@ KERNEL_DEFINES = $(strip -Derrno=kernel_ KBUILD_CFLAGS += $(KERNEL_DEFINES) KBUILD_CFLAGS += $(call cc-option,-fno-unit-at-a-time,) -# These are needed for clean and mrproper, since in that case .config is not -# included; the values here are meaningless - -CONFIG_NEST_LEVEL ?= 0 - -SIZE = ($(CONFIG_NEST_LEVEL) * 0x20000000) - PHONY += linux all: linux
@@ -120,10 +113,6 @@ CFLAGS_NO_HARDENING := $(call cc-option, CONFIG_KERNEL_STACK_ORDER ?= 2 STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] ) -ifndef START - START = $(shell echo $$[ $(TOP_ADDR) - $(SIZE) ] ) -endif - CPPFLAGS_vmlinux.lds = -U$(SUBARCH) -DSTART=$(START) -DELF_ARCH=$(ELF_ARCH) \ -DELF_FORMAT="$(ELF_FORMAT)" -DKERNEL_STACK_SIZE=$(STACK_SIZE)
arch/um/defconfig +0 -3
@@ -56,8 +56,6 @@ CONFIG_X86_TSC=y CONFIG_UML_X86=y # CONFIG_64BIT is not set CONFIG_SEMAPHORE_SLEEPERS=y -# CONFIG_HOST_2G_2G is not set -CONFIG_TOP_ADDR=0xc0000000 # CONFIG_3_LEVEL_PGTABLES is not set CONFIG_ARCH_HAS_SC_SIGNALS=y CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA=y
@@ -81,7 +79,6 @@ CONFIG_BINFMT_MISC=m # CONFIG_HPPFS is not set CONFIG_MCONSOLE=y CONFIG_MAGIC_SYSRQ=y -CONFIG_NEST_LEVEL=0 # CONFIG_HIGHMEM is not set CONFIG_KERNEL_STACK_ORDER=0
include/asm-um/fixmap.h +2 -1
@@ -1,6 +1,7 @@#ifndef __UM_FIXMAP_H#define __UM_FIXMAP_H +#include <asm/processor.h> #include <asm/system.h> #include <asm/kmap_types.h> #include <asm/archparam.h>
@@ -57,7 +58,7 @@ extern void __set_fixmap (enum fixed_add* at the top of mem.. */ -#define FIXADDR_TOP (CONFIG_TOP_ADDR - 2 * PAGE_SIZE) +#define FIXADDR_TOP (TASK_SIZE - 2 * PAGE_SIZE)#define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE)
arch/um/include/as-layout.h +2 -0
@@ -57,6 +57,8 @@ extern unsigned long _stext, _etext, _sdextern unsigned long _unprotected_end;extern unsigned long brk_start; +extern unsigned long host_task_size; +extern int linux_main (int argc,char **argv);extern void (*sig_info[])(int ,struct uml_pt_regs *);
arch/um/kernel/exec.c +1 -1
@@ -25,7 +25,7 @@ void flush_thread(void) ret =unmap (¤t->mm->context.id,0 ,STUB_START ,0 , &data); ret = ret ||unmap (¤t->mm->context.id,STUB_END , -TASK_SIZE -STUB_END ,1 , &data); + host_task_size -STUB_END ,1 , &data);if (ret) {printk (KERN_ERR "flush_thread - clearing address space failed, " "err = %d\n" , ret);
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
User-mode-linux-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel