[parisc-linux-cvs] mmap2 syscall

Matthew Wilcox willy@ldl.fc.hp.com
Sun, 04 Mar 2001 20:26:05 -0700


Add an mmap2 syscall.  It allows 32-bit applications to mmap a chunk of
files up to 44-bits (16TB) long.  It's part of the LFS, and most of the
other ports have it.  Probably requires glibc to be rebuilt to use it.

Index: arch/parisc/kernel/sys_parisc.c
===================================================================
RCS file: /home/cvs/parisc/linux/arch/parisc/kernel/sys_parisc.c,v
retrieving revision 1.8
diff -u -p -r1.8 sys_parisc.c
--- sys_parisc.c	2001/03/04 04:48:53	1.8
+++ sys_parisc.c	2001/03/05 03:15:37
@@ -1,7 +1,7 @@
 /*
  * linux/arch/parisc/kernel/sys_parisc.c
  *
- * this implements the missing syscalls.
+ * this implements syscalls which are handled per-arch.
  */
 
 #include <asm/uaccess.h>
@@ -10,6 +10,7 @@
 #include <linux/linkage.h>
 #include <linux/mm.h>
 #include <linux/mman.h>
+#include <linux/shm.h>
 #include <linux/smp_lock.h>
 
 int sys_pipe(int *fildes)
@@ -32,22 +33,22 @@ int sys_pause(void)
 	return -ERESTARTNOHAND;
 }
 
-int sys_mmap(unsigned long addr, unsigned long len,
-		unsigned long prot, unsigned long flags, unsigned long fd,
-		unsigned long offset)
+static unsigned long do_mmap2(unsigned long addr, unsigned long len,
+	unsigned long prot, unsigned long flags, unsigned long fd,
+	unsigned long pgoff)
 {
 	struct file * file = NULL;
-	int error = -EBADF;
-
+	unsigned long error = -EBADF;
 	if (!(flags & MAP_ANONYMOUS)) {
 		file = fget(fd);
 		if (!file)
 			goto out;
 	}
+
 	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
 
 	down(&current->mm->mmap_sem);
-	error = do_mmap(file, addr, len, prot, flags, offset);
+	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
 	up(&current->mm->mmap_sem);
 
 	if (file != NULL)
@@ -55,11 +56,29 @@ int sys_mmap(unsigned long addr, unsigne
 out:
 	return error;
 }
+
+asmlinkage unsigned long sys_mmap2(unsigned long addr, unsigned long len,
+	unsigned long prot, unsigned long flags, unsigned long fd,
+	unsigned long pgoff)
+{
+	/* Make sure the shift for mmap2 is constant (12), no matter what PAGE_SIZE
+	   we have. */
+	return do_mmap2(addr, len, prot, flags, fd, pgoff >> (PAGE_SHIFT - 12));
+}
+
+asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len,
+		unsigned long prot, unsigned long flags, unsigned long fd,
+		unsigned long offset)
+{
+	if (!(offset & ~PAGE_MASK)) {
+		return do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
+	} else {
+		return -EINVAL;
+	}
+}
 
-long sys_shmat_wrapper(int shmid, void *shmaddr, int shmflag)
+long sys_shmat_wrapper(int shmid, char *shmaddr, int shmflag)
 {
-	extern int sys_shmat(int shmid, char *shmaddr, int shmflg,
-			     unsigned long * raddr);
 	unsigned long raddr;
 	int r;
 
Index: arch/parisc/kernel/syscall.S
===================================================================
RCS file: /home/cvs/parisc/linux/arch/parisc/kernel/syscall.S,v
retrieving revision 1.58
diff -u -p -r1.58 syscall.S
--- syscall.S	2001/03/01 17:07:10	1.58
+++ syscall.S	2001/03/05 03:15:37
@@ -418,8 +418,7 @@ sys_call_table:
 	ENTRY_UHOH(uselib)
 	ENTRY_SAME(swapon)
 	ENTRY_SAME(reboot)
-	ENTRY_SAME(ni_syscall)
-	/* I'm not certain about off_t... */
+	ENTRY_SAME(mmap2)
 	ENTRY_SAME(mmap)		/* 90 */
 	ENTRY_SAME(munmap)
 	ENTRY_SAME(truncate)
Index: include/asm-parisc/unistd.h
===================================================================
RCS file: /home/cvs/parisc/linux/include/asm-parisc/unistd.h,v
retrieving revision 1.18
diff -u -p -r1.18 unistd.h
--- unistd.h	2001/03/04 04:48:54	1.18
+++ unistd.h	2001/03/05 03:15:37
@@ -579,7 +579,7 @@
 #define __NR_uselib              (__NR_Linux + 86)
 #define __NR_swapon              (__NR_Linux + 87)
 #define __NR_reboot              (__NR_Linux + 88)
-/* #define __NR_readdir             (__NR_Linux + 89) */
+#define __NR_mmap2             (__NR_Linux + 89)
 #define __NR_mmap                (__NR_Linux + 90)
 #define __NR_munmap              (__NR_Linux + 91)
 #define __NR_truncate            (__NR_Linux + 92)
@@ -795,7 +795,7 @@ type name(type1 arg1, type2 arg2, type3 
 }
 
 
-/* mmap takes 6 arguments */
+/* mmap & mmap2 take 6 arguments */
 
 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \
 type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) \