diff -urNp --exclude CVS --exclude BitKeeper --exclude {arch} --exclude .arch-ids x-ref/arch/s390x/kernel/binfmt_elf32.c x/arch/s390x/kernel/binfmt_elf32.c --- x-ref/arch/s390x/kernel/binfmt_elf32.c 2003-11-28 23:12:33.000000000 +0100 +++ x/arch/s390x/kernel/binfmt_elf32.c 2004-05-31 16:02:45.529156584 +0200 @@ -198,7 +198,7 @@ elf_map32 (struct file *filep, unsigned unsigned long map_addr; if(!addr) - addr = 0x40000000; + addr = current->map_base; down_write(¤t->mm->mmap_sem); map_addr = do_mmap(filep, ELF_PAGESTART(addr), diff -urNp --exclude CVS --exclude BitKeeper --exclude {arch} --exclude .arch-ids x-ref/fs/proc/base.c x/fs/proc/base.c --- x-ref/fs/proc/base.c 2003-11-28 23:12:44.000000000 +0100 +++ x/fs/proc/base.c 2004-05-31 16:02:45.521157800 +0200 @@ -499,6 +499,58 @@ static struct file_operations proc_mem_o open: mem_open, }; +#ifdef __HAS_ARCH_PROC_MAPPED_BASE +static ssize_t mapbase_read(struct file * file, char * buf, + size_t count, loff_t *ppos) +{ + struct task_struct *task = file->f_dentry->d_inode->u.proc_i.task; + char buffer[64]; + size_t len; + + sprintf(buffer, "%li", task->map_base); + len=strlen(buffer)+1; + *ppos += len; + if (copy_to_user(buf, buffer, len)) + len = -EFAULT; + + return (len<*ppos)?0:len; +} + +static ssize_t mapbase_write(struct file * file, const char * buf, + size_t count, loff_t *ppos) +{ + struct task_struct *task = file->f_dentry->d_inode->u.proc_i.task; + char buffer[64]; + int len; + unsigned long newbase; + if (!capable(CAP_SYS_ADMIN)) return -EPERM; + memset(buffer, 0, 64); + len = count; + if (len>63) + len = 63; + if (copy_from_user(buffer, buf, len)) + return -EFAULT; + + for (len = 0; len < 64; len++) + if (!buffer[len]) + break; + if (len>60) + return -EFAULT; + + newbase = simple_strtoul(buffer, NULL, 0); + + if (newbase > 0) + task->map_base = newbase; + + return len; +} + +static struct file_operations proc_mapbase_operations = { + read: mapbase_read, + write: mapbase_write, +}; +#endif /* __HAS_ARCH_PROC_MAPPED_BASE */ + static struct inode_operations proc_mem_inode_operations = { permission: proc_permission, }; @@ -599,6 +651,7 @@ enum pid_directory_inos { PROC_PID_MAPS, PROC_PID_CPU, PROC_PID_MOUNTS, + PROC_PID_MAPBASE, PROC_PID_FD_DIR = 0x8000, /* 0x8000-0xffff */ }; @@ -619,6 +672,9 @@ static struct pid_entry base_stuff[] = { E(PROC_PID_ROOT, "root", S_IFLNK|S_IRWXUGO), E(PROC_PID_EXE, "exe", S_IFLNK|S_IRWXUGO), E(PROC_PID_MOUNTS, "mounts", S_IFREG|S_IRUGO), +#ifdef __HAS_ARCH_PROC_MAPPED_BASE + E(PROC_PID_MAPBASE, "mapped_base", S_IFREG|S_IRUSR|S_IWUSR), +#endif {0,0,NULL,0} }; #undef E @@ -971,6 +1027,11 @@ static struct dentry *proc_base_lookup(s inode->i_fop = &proc_info_file_operations; inode->u.proc_i.op.proc_read = proc_pid_statm; break; +#ifdef __HAS_ARCH_PROC_MAPPED_BASE + case PROC_PID_MAPBASE: + inode->i_fop = &proc_mapbase_operations; + break; +#endif case PROC_PID_MAPS: inode->i_fop = &proc_maps_operations; break; diff -urNp --exclude CVS --exclude BitKeeper --exclude {arch} --exclude .arch-ids x-ref/include/asm-i386/processor.h x/include/asm-i386/processor.h --- x-ref/include/asm-i386/processor.h 2004-05-31 16:02:39.799027696 +0200 +++ x/include/asm-i386/processor.h 2004-05-31 16:02:45.523157496 +0200 @@ -265,10 +265,12 @@ extern unsigned int mca_pentium_flag; /* This decides where the kernel will search for a free chunk of vm * space during mmap's. */ +#define TASK_UNMAPPED_BASE (current->map_base) + #ifndef CONFIG_05GB -#define TASK_UNMAPPED_BASE (TASK_SIZE / 3) +#define __TASK_UNMAPPED_BASE (TASK_SIZE / 3) #else -#define TASK_UNMAPPED_BASE (TASK_SIZE / 16) +#define __TASK_UNMAPPED_BASE (TASK_SIZE / 16) #endif /* diff -urNp --exclude CVS --exclude BitKeeper --exclude {arch} --exclude .arch-ids x-ref/include/asm-s390/processor.h x/include/asm-s390/processor.h --- x-ref/include/asm-s390/processor.h 2003-06-13 22:07:41.000000000 +0200 +++ x/include/asm-s390/processor.h 2004-05-31 16:02:45.523157496 +0200 @@ -60,7 +60,8 @@ extern struct task_struct *last_task_use /* This decides where the kernel will search for a free chunk of vm * space during mmap's. */ -#define TASK_UNMAPPED_BASE (TASK_SIZE / 2) +#define __TASK_UNMAPPED_BASE (TASK_SIZE / 2) +#define TASK_UNMAPPED_BASE (current->map_base) #define THREAD_SIZE (2*PAGE_SIZE) diff -urNp --exclude CVS --exclude BitKeeper --exclude {arch} --exclude .arch-ids x-ref/include/asm-s390x/processor.h x/include/asm-s390x/processor.h --- x-ref/include/asm-s390x/processor.h 2003-06-13 22:07:42.000000000 +0200 +++ x/include/asm-s390x/processor.h 2004-05-31 16:02:45.524157344 +0200 @@ -62,12 +62,13 @@ extern struct task_struct *last_task_use */ #define TASK_SIZE (0x20000000000UL) #define TASK31_SIZE (0x80000000UL) +#define __TASK_UNMAPPED_BASE (TASK31_SIZE/2) /* This decides where the kernel will search for a free chunk of vm * space during mmap's. */ #define TASK_UNMAPPED_BASE ((current->thread.flags & S390_FLAG_31BIT) ? \ - (TASK31_SIZE / 2) : (TASK_SIZE / 2)) + (current->map_base) : (TASK_SIZE / 2)) #define THREAD_SIZE (4*PAGE_SIZE) diff -urNp --exclude CVS --exclude BitKeeper --exclude {arch} --exclude .arch-ids x-ref/include/asm-um/processor-generic.h x/include/asm-um/processor-generic.h --- x-ref/include/asm-um/processor-generic.h 2004-05-31 16:02:41.449776744 +0200 +++ x/include/asm-um/processor-generic.h 2004-05-31 16:02:45.524157344 +0200 @@ -139,7 +139,8 @@ extern unsigned long task_size; /* This decides where the kernel will search for a free chunk of vm * space during mmap's. */ -#define TASK_UNMAPPED_BASE (0x40000000) +#define __TASK_UNMAPPED_BASE (0x40000000) +#define TASK_UNMAPPED_BASE (current->map_base) extern void start_thread(struct pt_regs *regs, unsigned long entry, unsigned long stack); diff -urNp --exclude CVS --exclude BitKeeper --exclude {arch} --exclude .arch-ids x-ref/include/asm-x86_64/processor.h x/include/asm-x86_64/processor.h --- x-ref/include/asm-x86_64/processor.h 2003-11-28 23:12:46.000000000 +0100 +++ x/include/asm-x86_64/processor.h 2004-05-31 16:03:52.260011952 +0200 @@ -250,11 +250,12 @@ static inline void clear_in_cr4 (unsigne * space during mmap's. */ +#define __TASK_UNMAPPED_BASE TASK_UNMAPPED_32 #define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? 0xc0000000 : 0xFFFFe000) #define TASK_UNMAPPED_32 (IA32_PAGE_OFFSET / 3) #define TASK_UNMAPPED_64 (TASK_SIZE/3) #define TASK_UNMAPPED_BASE \ - ((current->thread.flags & THREAD_IA32) ? TASK_UNMAPPED_32 : TASK_UNMAPPED_64) + ((current->thread.flags & THREAD_IA32) ? (current->map_base) : TASK_UNMAPPED_64) /* * Size of io_bitmap in longwords: 32 is ports 0-0x3ff. diff -urNp --exclude CVS --exclude BitKeeper --exclude {arch} --exclude .arch-ids x-ref/include/linux/sched.h x/include/linux/sched.h --- x-ref/include/linux/sched.h 2004-05-31 16:02:42.480620032 +0200 +++ x/include/linux/sched.h 2004-05-31 16:02:45.528156736 +0200 @@ -436,6 +436,9 @@ struct task_struct { /* journalling filesystem info */ void *journal_info; + +/* TASK_UNMAPPED_BASE value */ + unsigned long map_base; }; /* @@ -488,6 +491,12 @@ extern void yield(void); */ extern struct exec_domain default_exec_domain; +#ifndef __TASK_UNMAPPED_BASE +#define __TASK_UNMAPPED_BASE 0UL +#else +#define __HAS_ARCH_PROC_MAPPED_BASE +#endif + /* * INIT_TASK is used to set up the first task table, touch at * your own risk!. Base=0, limit=0x1fffff (=2MB) @@ -534,6 +543,7 @@ extern struct exec_domain default_exec_d alloc_lock: SPIN_LOCK_UNLOCKED, \ switch_lock: SPIN_LOCK_UNLOCKED, \ journal_info: NULL, \ + map_base: __TASK_UNMAPPED_BASE, \ }