[SSI] openssi/kernel/arch/x86_64/kernel sys_x86_64.c,1.1,1.2

John Hughes <[email protected]> Mon, 26 Apr 2010 18:52:38 +0000
Newsgroups gmane.linux.cluster.ssic.cvs
Message-ID <[email protected]>
Update of /cvsroot/ssic-linux/openssi/kernel/arch/x86_64/kernel
In directory sfp-cvsdas-3.v30.ch3.sourceforge.com:/tmp/cvs-serv5601

Modified Files:
      Tag: 1
	sys_x86_64.c 
Log Message:
Lost changes from x86_64 2.4 port

Index: sys_x86_64.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/arch/x86_64/kernel/sys_x86_64.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- sys_x86_64.c	12 Apr 2005 22:34:43 -0000	1.1
+++ sys_x86_64.c	26 Apr 2010 18:52:36 -0000	1.2
@@ -4,6 +4,7 @@
 
 #include <linux/errno.h>
 #include <linux/sched.h>
+#include <linux/syscalls.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
@@ -18,12 +19,13 @@
 
 #include <asm/uaccess.h>
 #include <asm/ipc.h>
+#include <asm/ia32.h>
 
 /*
  * sys_pipe() is the normal C calling standard for creating
  * a pipe. It's not the way Unix traditionally does this, though.
  */
-asmlinkage long sys_pipe(unsigned long * fildes)
+asmlinkage long sys_pipe(int __user *fildes)
 {
 	int fd[2];
 	int error;
@@ -49,12 +51,14 @@
 	error = -EBADF;
 	file = NULL;
 	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+#ifdef CONFIG_SSI
+	flags &= ~MAP_MIGRATE;
+#endif
 	if (!(flags & MAP_ANONYMOUS)) {
 		file = fget(fd);
 		if (!file)
 			goto out;
 	}
-
 	down_write(&current->mm->mmap_sem);
 	error = do_mmap_pgoff(file, addr, len, prot, flags, off >> PAGE_SHIFT);
 	up_write(&current->mm->mmap_sem);
@@ -65,60 +69,109 @@
 	return error;
 }
 
-
-unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags)
+static void find_start_end(unsigned long flags, unsigned long *begin,
+			   unsigned long *end)
 {
-	struct vm_area_struct *vma;
-	unsigned long end = TASK_SIZE;
-
-	if (current->thread.flags & THREAD_IA32) {
-		if (!addr) 
-			addr = TASK_UNMAPPED_32;
-		end = 0xffff0000;
-	} else if (flags & MAP_32BIT) { 
+#ifdef CONFIG_IA32_EMULATION
+	if (test_thread_flag(TIF_IA32)) { 
+		*begin = TASK_UNMAPPED_32;
+		*end = IA32_PAGE_OFFSET; 
+	} else 
+#endif
+	if (flags & MAP_32BIT) { 
 		/* This is usually used needed to map code in small
-		   model: it needs to be in the first 31bit. Limit it
-		   to that.  This means we need to move the unmapped
-		   base down for this case.  This may give conflicts
-		   with the heap, but we assume that malloc falls back
-		   to mmap. Give it 1GB of playground for now. -AK */ 
-		if (!addr) 
-			addr = 0x40000000; 
-		end = 0x80000000;		
+		   model, so it needs to be in the first 31bit. Limit
+		   it to that.  This means we need to move the
+		   unmapped base down for this case. This can give
+		   conflicts with the heap, but we assume that glibc
+		   malloc knows how to fall back to mmap. Give it 1GB
+		   of playground for now. -AK */ 
+		*begin = 0x40000000; 
+		*end = 0x80000000;		
 	} else { 
-		if (!addr) 
-			addr = TASK_UNMAPPED_64; 
-		end = TASK_SIZE; 
+		*begin = TASK_UNMAPPED_64; 
+		*end = TASK_SIZE; 
 		}
+} 
+
+unsigned long
+arch_get_unmapped_area(struct file *filp, unsigned long addr,
+		unsigned long len, unsigned long pgoff, unsigned long flags)
+{
+	struct mm_struct *mm = current->mm;
+	struct vm_area_struct *vma;
+	unsigned long start_addr;
+	unsigned long begin, end;
+	
+	find_start_end(flags, &begin, &end); 
 
 	if (len > end)
 		return -ENOMEM;
-	addr = PAGE_ALIGN(addr);
 
-	for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) {
+	if (addr || (flags & MAP_MIGRATE)) {
+		addr = PAGE_ALIGN(addr);
+		vma = find_vma(mm, addr);
+		if (end - len >= addr &&
+		    (!vma || addr + len <= vma->vm_start))
+			return addr;
+	}
+	addr = mm->free_area_cache;
+	if (addr < begin) 
+		addr = begin; 
+	start_addr = addr;
+
+full_search:
+	for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
 		/* At this point:  (!vma || addr < vma->vm_end). */
-		if (end - len < addr)
+		if (end - len < addr) {
+			/*
+			 * Start a new search - just in case we missed
+			 * some holes.
+			 */
+			if (start_addr != begin) {
+				start_addr = addr = begin;
+				goto full_search;
+			}
 			return -ENOMEM;
-		if (!vma || addr + len <= vma->vm_start)
+		}
+		if (!vma || addr + len <= vma->vm_start) {
+			/*
+			 * Remember the place where we stopped the search:
+			 */
+			mm->free_area_cache = addr + len;
 			return addr;
+		}
 		addr = vma->vm_end;
 	}
 }
 
-asmlinkage long sys_uname(struct new_utsname * name)
+asmlinkage long sys_uname(struct new_utsname __user * name)
 {
 	int err;
 	down_read(&uts_sem);
-	err=copy_to_user(name, &system_utsname, sizeof (*name));
+	err = copy_to_user(name, &system_utsname, sizeof (*name));
 	up_read(&uts_sem);
-	if (personality(current->personality) == PER_LINUX32)
-		err = copy_to_user(name->machine, "i686", 5);
-	return err?-EFAULT:0;
+	if (personality(current->personality) == PER_LINUX32) 
+		err |= copy_to_user(&name->machine, "i686", 5); 		
+	return err ? -EFAULT : 0;
 }
 
-
-asmlinkage long wrap_sys_shmat(int shmid, char *shmaddr, int shmflg)
+asmlinkage long wrap_sys_shmat(int shmid, char __user *shmaddr, int shmflg)
 {
 	unsigned long raddr;
-	return sys_shmat(shmid,shmaddr,shmflg,&raddr) ?: raddr;
-} 
+	return do_shmat(shmid,shmaddr,shmflg,&raddr) ?: (long)raddr;
+}
+
+asmlinkage long sys_time64(long __user * tloc)
+{
+	struct timeval now; 
+	int i; 
+
+	do_gettimeofday(&now);
+	i = now.tv_sec;
+	if (tloc) {
+		if (put_user(i,tloc))
+			i = -EFAULT;
+	}
+	return i;
+}


------------------------------------------------------------------------------