VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   32 Branches   54 Tags
author: Greg Ungerer <gerg@snapgear.com> 2007-02-07 12:03:08 +1000 committer: Linus Torvalds <torvalds@woody.linux-foundation.org> 2007-02-09 10:45:33 -0800 commit: 72613e5f44adf2fe2684a5f1c1b62c2ee9984f40 parent: c051b01129560ea02ea2cebdf00db0721cc9a618
Commit Summary:
[PATCH] uclinux: correctly remap bin_fmtflat exe allocated mem regions
Diffstat:
1 file changed, 24 insertions, 7 deletions
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
index ae8595d49856..7b0265d7f3a8 100644
--- a/fs/binfmt_flat.c
+++ b/fs/binfmt_flat.c
@@ -419,7 +419,7 @@ static int load_flat_file(struct linux_binprm * bprm,
 	unsigned long textpos = 0, datapos = 0, result;
 	unsigned long realdatastart = 0;
 	unsigned long text_len, data_len, bss_len, stack_len, flags;
-	unsigned long memp = 0; /* for finding the brk area */
+	unsigned long len, reallen, memp = 0;
 	unsigned long extra, rlim;
 	unsigned long *reloc = 0, *rp;
 	struct inode *inode;
@@ -540,10 +540,18 @@ static int load_flat_file(struct linux_binprm * bprm,
 			goto err;
 		}
 
+		len = data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long);
 		down_write(&current->mm->mmap_sem);
-		realdatastart = do_mmap(0, 0, data_len + extra +
-				MAX_SHARED_LIBS * sizeof(unsigned long),
-				PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0);
+		realdatastart = do_mmap(0, 0, len,
+			PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0);
+		/* Remap to use all availabe slack region space */
+		if (realdatastart && (realdatastart < (unsigned long)-4096)) {
+			reallen = ksize(realdatastart);
+			if (reallen > len) {
+				realdatastart = do_mremap(realdatastart, len,
+					reallen, MREMAP_FIXED, realdatastart);
+			}
+		}
 		up_write(&current->mm->mmap_sem);
 
 		if (realdatastart == 0 || realdatastart >= (unsigned long)-4096) {
@@ -584,11 +592,20 @@ static int load_flat_file(struct linux_binprm * bprm,
 
 	} else {
 
+		len = text_len + data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long);
 		down_write(&current->mm->mmap_sem);
-		textpos = do_mmap(0, 0, text_len + data_len + extra +
-					MAX_SHARED_LIBS * sizeof(unsigned long),
-				PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0);
+		textpos = do_mmap(0, 0, len,
+			PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0);
+		/* Remap to use all availabe slack region space */
+		if (textpos && (textpos < (unsigned long) -4096)) {
+			reallen = ksize(textpos);
+			if (reallen > len) {
+				textpos = do_mremap(textpos, len, reallen,
+					MREMAP_FIXED, textpos);
+			}
+		}
 		up_write(&current->mm->mmap_sem);
+
 		if (!textpos  || textpos >= (unsigned long) -4096) {
 			if (!textpos)
 				textpos = (unsigned long) -ENOMEM;