parisc: sendfile and sendfile64 syscall cleanups
authorHelge Deller <deller@gmx.de>
Tue, 19 Feb 2013 21:55:17 +0000 (22:55 +0100)
committerHelge Deller <deller@gmx.de>
Wed, 20 Feb 2013 21:57:30 +0000 (22:57 +0100)
Utilize the existing compat_sys_sendfile function for 64bit kernel and add
wrappers for sendfile and sendfile64 to correctly handle the 32/64 bit sign
extension.

Signed-off-by: Helge Deller <deller@gmx.de>
arch/parisc/include/asm/unistd.h
arch/parisc/kernel/sys_parisc32.c
arch/parisc/kernel/syscall_table.S

index f2e390fe74cfa4f550d0cdfdf192f9194dca0756..74f801ebbe773926ae52e161e7342e1b3287d07d 100644 (file)
@@ -167,6 +167,7 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5)       \
 #define __ARCH_WANT_SYS_FORK
 #define __ARCH_WANT_SYS_VFORK
 #define __ARCH_WANT_SYS_CLONE
+#define __ARCH_WANT_COMPAT_SYS_SENDFILE
 
 #endif /* __ASSEMBLY__ */
 
index 0115eac76c391cd17b862b85a2de8bfc3cf2d541..eca69bb8ef5f48dd503dc986a9157444c86abc1e 100644 (file)
@@ -60,42 +60,23 @@ asmlinkage long sys32_unimplemented(int r26, int r25, int r24, int r23,
     return -ENOSYS;
 }
 
-asmlinkage int sys32_sendfile(int out_fd, int in_fd, compat_off_t __user *offset, s32 count)
+/* Note: it is necessary to treat out_fd and in_fd as unsigned ints, with the
+ * corresponding cast to a signed int to insure that the proper conversion
+ * (sign extension) between the register representation of a signed int (msr in
+ * 32-bit mode) and the register representation of a signed int (msr in 64-bit
+ * mode) is performed.
+ */
+asmlinkage long sys32_sendfile(u32 out_fd, u32 in_fd,
+                              compat_off_t __user *offset, compat_size_t count)
 {
-        mm_segment_t old_fs = get_fs();
-        int ret;
-        off_t of;
-
-        if (offset && get_user(of, offset))
-                return -EFAULT;
-
-        set_fs(KERNEL_DS);
-        ret = sys_sendfile(out_fd, in_fd, offset ? (off_t __user *)&of : NULL, count);
-        set_fs(old_fs);
-
-        if (offset && put_user(of, offset))
-                return -EFAULT;
-
-        return ret;
+       return compat_sys_sendfile((int)out_fd, (int)in_fd, offset, count);
 }
 
-asmlinkage int sys32_sendfile64(int out_fd, int in_fd, compat_loff_t __user *offset, s32 count)
+asmlinkage long sys32_sendfile64(u32 out_fd, u32 in_fd,
+                                compat_loff_t __user *offset, compat_size_t count)
 {
-       mm_segment_t old_fs = get_fs();
-       int ret;
-       loff_t lof;
-       
-       if (offset && get_user(lof, offset))
-               return -EFAULT;
-               
-       set_fs(KERNEL_DS);
-       ret = sys_sendfile64(out_fd, in_fd, offset ? (loff_t __user *)&lof : NULL, count);
-       set_fs(old_fs);
-       
-       if (offset && put_user(lof, offset))
-               return -EFAULT;
-               
-       return ret;
+       return sys_sendfile64((int)out_fd, (int)in_fd,
+                               (loff_t __user *)offset, count);
 }
 
 
index 9180719dad047a2a8684075ea6e60258b3e9f8b7..129fd472c471c9399832c39e66651dfc3d96a751 100644 (file)
        ENTRY_SAME(gettid)
        ENTRY_OURS(readahead)
        ENTRY_SAME(tkill)
-       ENTRY_SAME(sendfile64)
+       ENTRY_DIFF(sendfile64)
        ENTRY_COMP(futex)               /* 210 */
        ENTRY_COMP(sched_setaffinity)
        ENTRY_COMP(sched_getaffinity)