aboutsummaryrefslogtreecommitdiffstats
path: root/arch/parisc
diff options
context:
space:
mode:
authorHelge Deller <deller@gmx.de>2013-02-19 16:55:17 -0500
committerHelge Deller <deller@gmx.de>2013-02-20 16:57:30 -0500
commitf03d70a7fc952a7fd01c678ad409c932a925637b (patch)
tree8865eacae776eaddfd3d05416995e052de11853b /arch/parisc
parente27da28a565e2a4d82a2d1adc9e0ba4aadd61e97 (diff)
parisc: sendfile and sendfile64 syscall cleanups
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>
Diffstat (limited to 'arch/parisc')
-rw-r--r--arch/parisc/include/asm/unistd.h1
-rw-r--r--arch/parisc/kernel/sys_parisc32.c45
-rw-r--r--arch/parisc/kernel/syscall_table.S2
3 files changed, 15 insertions, 33 deletions
diff --git a/arch/parisc/include/asm/unistd.h b/arch/parisc/include/asm/unistd.h
index f2e390fe74cf..74f801ebbe77 100644
--- a/arch/parisc/include/asm/unistd.h
+++ b/arch/parisc/include/asm/unistd.h
@@ -167,6 +167,7 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \
167#define __ARCH_WANT_SYS_FORK 167#define __ARCH_WANT_SYS_FORK
168#define __ARCH_WANT_SYS_VFORK 168#define __ARCH_WANT_SYS_VFORK
169#define __ARCH_WANT_SYS_CLONE 169#define __ARCH_WANT_SYS_CLONE
170#define __ARCH_WANT_COMPAT_SYS_SENDFILE
170 171
171#endif /* __ASSEMBLY__ */ 172#endif /* __ASSEMBLY__ */
172 173
diff --git a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c
index 0115eac76c39..eca69bb8ef5f 100644
--- a/arch/parisc/kernel/sys_parisc32.c
+++ b/arch/parisc/kernel/sys_parisc32.c
@@ -60,42 +60,23 @@ asmlinkage long sys32_unimplemented(int r26, int r25, int r24, int r23,
60 return -ENOSYS; 60 return -ENOSYS;
61} 61}
62 62
63asmlinkage int sys32_sendfile(int out_fd, int in_fd, compat_off_t __user *offset, s32 count) 63/* Note: it is necessary to treat out_fd and in_fd as unsigned ints, with the
64 * corresponding cast to a signed int to insure that the proper conversion
65 * (sign extension) between the register representation of a signed int (msr in
66 * 32-bit mode) and the register representation of a signed int (msr in 64-bit
67 * mode) is performed.
68 */
69asmlinkage long sys32_sendfile(u32 out_fd, u32 in_fd,
70 compat_off_t __user *offset, compat_size_t count)
64{ 71{
65 mm_segment_t old_fs = get_fs(); 72 return compat_sys_sendfile((int)out_fd, (int)in_fd, offset, count);
66 int ret;
67 off_t of;
68
69 if (offset && get_user(of, offset))
70 return -EFAULT;
71
72 set_fs(KERNEL_DS);
73 ret = sys_sendfile(out_fd, in_fd, offset ? (off_t __user *)&of : NULL, count);
74 set_fs(old_fs);
75
76 if (offset && put_user(of, offset))
77 return -EFAULT;
78
79 return ret;
80} 73}
81 74
82asmlinkage int sys32_sendfile64(int out_fd, int in_fd, compat_loff_t __user *offset, s32 count) 75asmlinkage long sys32_sendfile64(u32 out_fd, u32 in_fd,
76 compat_loff_t __user *offset, compat_size_t count)
83{ 77{
84 mm_segment_t old_fs = get_fs(); 78 return sys_sendfile64((int)out_fd, (int)in_fd,
85 int ret; 79 (loff_t __user *)offset, count);
86 loff_t lof;
87
88 if (offset && get_user(lof, offset))
89 return -EFAULT;
90
91 set_fs(KERNEL_DS);
92 ret = sys_sendfile64(out_fd, in_fd, offset ? (loff_t __user *)&lof : NULL, count);
93 set_fs(old_fs);
94
95 if (offset && put_user(lof, offset))
96 return -EFAULT;
97
98 return ret;
99} 80}
100 81
101 82
diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S
index 9180719dad04..129fd472c471 100644
--- a/arch/parisc/kernel/syscall_table.S
+++ b/arch/parisc/kernel/syscall_table.S
@@ -304,7 +304,7 @@
304 ENTRY_SAME(gettid) 304 ENTRY_SAME(gettid)
305 ENTRY_OURS(readahead) 305 ENTRY_OURS(readahead)
306 ENTRY_SAME(tkill) 306 ENTRY_SAME(tkill)
307 ENTRY_SAME(sendfile64) 307 ENTRY_DIFF(sendfile64)
308 ENTRY_COMP(futex) /* 210 */ 308 ENTRY_COMP(futex) /* 210 */
309 ENTRY_COMP(sched_setaffinity) 309 ENTRY_COMP(sched_setaffinity)
310 ENTRY_COMP(sched_getaffinity) 310 ENTRY_COMP(sched_getaffinity)