xref: /linux/arch/sparc/kernel/sys_sparc32.c (revision a88b5ba8bd8ac18aad65ee6c6a254e2e74876db3)
1*a88b5ba8SSam Ravnborg /* sys_sparc32.c: Conversion between 32bit and 64bit native syscalls.
2*a88b5ba8SSam Ravnborg  *
3*a88b5ba8SSam Ravnborg  * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
4*a88b5ba8SSam Ravnborg  * Copyright (C) 1997, 2007 David S. Miller (davem@davemloft.net)
5*a88b5ba8SSam Ravnborg  *
6*a88b5ba8SSam Ravnborg  * These routines maintain argument size conversion between 32bit and 64bit
7*a88b5ba8SSam Ravnborg  * environment.
8*a88b5ba8SSam Ravnborg  */
9*a88b5ba8SSam Ravnborg 
10*a88b5ba8SSam Ravnborg #include <linux/kernel.h>
11*a88b5ba8SSam Ravnborg #include <linux/sched.h>
12*a88b5ba8SSam Ravnborg #include <linux/capability.h>
13*a88b5ba8SSam Ravnborg #include <linux/fs.h>
14*a88b5ba8SSam Ravnborg #include <linux/mm.h>
15*a88b5ba8SSam Ravnborg #include <linux/file.h>
16*a88b5ba8SSam Ravnborg #include <linux/signal.h>
17*a88b5ba8SSam Ravnborg #include <linux/resource.h>
18*a88b5ba8SSam Ravnborg #include <linux/times.h>
19*a88b5ba8SSam Ravnborg #include <linux/utsname.h>
20*a88b5ba8SSam Ravnborg #include <linux/smp.h>
21*a88b5ba8SSam Ravnborg #include <linux/smp_lock.h>
22*a88b5ba8SSam Ravnborg #include <linux/sem.h>
23*a88b5ba8SSam Ravnborg #include <linux/msg.h>
24*a88b5ba8SSam Ravnborg #include <linux/shm.h>
25*a88b5ba8SSam Ravnborg #include <linux/slab.h>
26*a88b5ba8SSam Ravnborg #include <linux/uio.h>
27*a88b5ba8SSam Ravnborg #include <linux/nfs_fs.h>
28*a88b5ba8SSam Ravnborg #include <linux/quota.h>
29*a88b5ba8SSam Ravnborg #include <linux/module.h>
30*a88b5ba8SSam Ravnborg #include <linux/sunrpc/svc.h>
31*a88b5ba8SSam Ravnborg #include <linux/nfsd/nfsd.h>
32*a88b5ba8SSam Ravnborg #include <linux/nfsd/cache.h>
33*a88b5ba8SSam Ravnborg #include <linux/nfsd/xdr.h>
34*a88b5ba8SSam Ravnborg #include <linux/nfsd/syscall.h>
35*a88b5ba8SSam Ravnborg #include <linux/poll.h>
36*a88b5ba8SSam Ravnborg #include <linux/personality.h>
37*a88b5ba8SSam Ravnborg #include <linux/stat.h>
38*a88b5ba8SSam Ravnborg #include <linux/filter.h>
39*a88b5ba8SSam Ravnborg #include <linux/highmem.h>
40*a88b5ba8SSam Ravnborg #include <linux/highuid.h>
41*a88b5ba8SSam Ravnborg #include <linux/mman.h>
42*a88b5ba8SSam Ravnborg #include <linux/ipv6.h>
43*a88b5ba8SSam Ravnborg #include <linux/in.h>
44*a88b5ba8SSam Ravnborg #include <linux/icmpv6.h>
45*a88b5ba8SSam Ravnborg #include <linux/syscalls.h>
46*a88b5ba8SSam Ravnborg #include <linux/sysctl.h>
47*a88b5ba8SSam Ravnborg #include <linux/binfmts.h>
48*a88b5ba8SSam Ravnborg #include <linux/dnotify.h>
49*a88b5ba8SSam Ravnborg #include <linux/security.h>
50*a88b5ba8SSam Ravnborg #include <linux/compat.h>
51*a88b5ba8SSam Ravnborg #include <linux/vfs.h>
52*a88b5ba8SSam Ravnborg #include <linux/netfilter_ipv4/ip_tables.h>
53*a88b5ba8SSam Ravnborg #include <linux/ptrace.h>
54*a88b5ba8SSam Ravnborg 
55*a88b5ba8SSam Ravnborg #include <asm/types.h>
56*a88b5ba8SSam Ravnborg #include <asm/uaccess.h>
57*a88b5ba8SSam Ravnborg #include <asm/fpumacro.h>
58*a88b5ba8SSam Ravnborg #include <asm/mmu_context.h>
59*a88b5ba8SSam Ravnborg #include <asm/compat_signal.h>
60*a88b5ba8SSam Ravnborg 
61*a88b5ba8SSam Ravnborg #ifdef CONFIG_SYSVIPC
62*a88b5ba8SSam Ravnborg asmlinkage long compat_sys_ipc(u32 call, u32 first, u32 second, u32 third, compat_uptr_t ptr, u32 fifth)
63*a88b5ba8SSam Ravnborg {
64*a88b5ba8SSam Ravnborg 	int version;
65*a88b5ba8SSam Ravnborg 
66*a88b5ba8SSam Ravnborg 	version = call >> 16; /* hack for backward compatibility */
67*a88b5ba8SSam Ravnborg 	call &= 0xffff;
68*a88b5ba8SSam Ravnborg 
69*a88b5ba8SSam Ravnborg 	switch (call) {
70*a88b5ba8SSam Ravnborg 	case SEMTIMEDOP:
71*a88b5ba8SSam Ravnborg 		if (fifth)
72*a88b5ba8SSam Ravnborg 			/* sign extend semid */
73*a88b5ba8SSam Ravnborg 			return compat_sys_semtimedop((int)first,
74*a88b5ba8SSam Ravnborg 						     compat_ptr(ptr), second,
75*a88b5ba8SSam Ravnborg 						     compat_ptr(fifth));
76*a88b5ba8SSam Ravnborg 		/* else fall through for normal semop() */
77*a88b5ba8SSam Ravnborg 	case SEMOP:
78*a88b5ba8SSam Ravnborg 		/* struct sembuf is the same on 32 and 64bit :)) */
79*a88b5ba8SSam Ravnborg 		/* sign extend semid */
80*a88b5ba8SSam Ravnborg 		return sys_semtimedop((int)first, compat_ptr(ptr), second,
81*a88b5ba8SSam Ravnborg 				      NULL);
82*a88b5ba8SSam Ravnborg 	case SEMGET:
83*a88b5ba8SSam Ravnborg 		/* sign extend key, nsems */
84*a88b5ba8SSam Ravnborg 		return sys_semget((int)first, (int)second, third);
85*a88b5ba8SSam Ravnborg 	case SEMCTL:
86*a88b5ba8SSam Ravnborg 		/* sign extend semid, semnum */
87*a88b5ba8SSam Ravnborg 		return compat_sys_semctl((int)first, (int)second, third,
88*a88b5ba8SSam Ravnborg 					 compat_ptr(ptr));
89*a88b5ba8SSam Ravnborg 
90*a88b5ba8SSam Ravnborg 	case MSGSND:
91*a88b5ba8SSam Ravnborg 		/* sign extend msqid */
92*a88b5ba8SSam Ravnborg 		return compat_sys_msgsnd((int)first, (int)second, third,
93*a88b5ba8SSam Ravnborg 					 compat_ptr(ptr));
94*a88b5ba8SSam Ravnborg 	case MSGRCV:
95*a88b5ba8SSam Ravnborg 		/* sign extend msqid, msgtyp */
96*a88b5ba8SSam Ravnborg 		return compat_sys_msgrcv((int)first, second, (int)fifth,
97*a88b5ba8SSam Ravnborg 					 third, version, compat_ptr(ptr));
98*a88b5ba8SSam Ravnborg 	case MSGGET:
99*a88b5ba8SSam Ravnborg 		/* sign extend key */
100*a88b5ba8SSam Ravnborg 		return sys_msgget((int)first, second);
101*a88b5ba8SSam Ravnborg 	case MSGCTL:
102*a88b5ba8SSam Ravnborg 		/* sign extend msqid */
103*a88b5ba8SSam Ravnborg 		return compat_sys_msgctl((int)first, second, compat_ptr(ptr));
104*a88b5ba8SSam Ravnborg 
105*a88b5ba8SSam Ravnborg 	case SHMAT:
106*a88b5ba8SSam Ravnborg 		/* sign extend shmid */
107*a88b5ba8SSam Ravnborg 		return compat_sys_shmat((int)first, second, third, version,
108*a88b5ba8SSam Ravnborg 					compat_ptr(ptr));
109*a88b5ba8SSam Ravnborg 	case SHMDT:
110*a88b5ba8SSam Ravnborg 		return sys_shmdt(compat_ptr(ptr));
111*a88b5ba8SSam Ravnborg 	case SHMGET:
112*a88b5ba8SSam Ravnborg 		/* sign extend key_t */
113*a88b5ba8SSam Ravnborg 		return sys_shmget((int)first, second, third);
114*a88b5ba8SSam Ravnborg 	case SHMCTL:
115*a88b5ba8SSam Ravnborg 		/* sign extend shmid */
116*a88b5ba8SSam Ravnborg 		return compat_sys_shmctl((int)first, second, compat_ptr(ptr));
117*a88b5ba8SSam Ravnborg 
118*a88b5ba8SSam Ravnborg 	default:
119*a88b5ba8SSam Ravnborg 		return -ENOSYS;
120*a88b5ba8SSam Ravnborg 	};
121*a88b5ba8SSam Ravnborg 
122*a88b5ba8SSam Ravnborg 	return -ENOSYS;
123*a88b5ba8SSam Ravnborg }
124*a88b5ba8SSam Ravnborg #endif
125*a88b5ba8SSam Ravnborg 
126*a88b5ba8SSam Ravnborg asmlinkage long sys32_truncate64(const char __user * path, unsigned long high, unsigned long low)
127*a88b5ba8SSam Ravnborg {
128*a88b5ba8SSam Ravnborg 	if ((int)high < 0)
129*a88b5ba8SSam Ravnborg 		return -EINVAL;
130*a88b5ba8SSam Ravnborg 	else
131*a88b5ba8SSam Ravnborg 		return sys_truncate(path, (high << 32) | low);
132*a88b5ba8SSam Ravnborg }
133*a88b5ba8SSam Ravnborg 
134*a88b5ba8SSam Ravnborg asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned long low)
135*a88b5ba8SSam Ravnborg {
136*a88b5ba8SSam Ravnborg 	if ((int)high < 0)
137*a88b5ba8SSam Ravnborg 		return -EINVAL;
138*a88b5ba8SSam Ravnborg 	else
139*a88b5ba8SSam Ravnborg 		return sys_ftruncate(fd, (high << 32) | low);
140*a88b5ba8SSam Ravnborg }
141*a88b5ba8SSam Ravnborg 
142*a88b5ba8SSam Ravnborg static int cp_compat_stat64(struct kstat *stat,
143*a88b5ba8SSam Ravnborg 			    struct compat_stat64 __user *statbuf)
144*a88b5ba8SSam Ravnborg {
145*a88b5ba8SSam Ravnborg 	int err;
146*a88b5ba8SSam Ravnborg 
147*a88b5ba8SSam Ravnborg 	err  = put_user(huge_encode_dev(stat->dev), &statbuf->st_dev);
148*a88b5ba8SSam Ravnborg 	err |= put_user(stat->ino, &statbuf->st_ino);
149*a88b5ba8SSam Ravnborg 	err |= put_user(stat->mode, &statbuf->st_mode);
150*a88b5ba8SSam Ravnborg 	err |= put_user(stat->nlink, &statbuf->st_nlink);
151*a88b5ba8SSam Ravnborg 	err |= put_user(stat->uid, &statbuf->st_uid);
152*a88b5ba8SSam Ravnborg 	err |= put_user(stat->gid, &statbuf->st_gid);
153*a88b5ba8SSam Ravnborg 	err |= put_user(huge_encode_dev(stat->rdev), &statbuf->st_rdev);
154*a88b5ba8SSam Ravnborg 	err |= put_user(0, (unsigned long __user *) &statbuf->__pad3[0]);
155*a88b5ba8SSam Ravnborg 	err |= put_user(stat->size, &statbuf->st_size);
156*a88b5ba8SSam Ravnborg 	err |= put_user(stat->blksize, &statbuf->st_blksize);
157*a88b5ba8SSam Ravnborg 	err |= put_user(0, (unsigned int __user *) &statbuf->__pad4[0]);
158*a88b5ba8SSam Ravnborg 	err |= put_user(0, (unsigned int __user *) &statbuf->__pad4[4]);
159*a88b5ba8SSam Ravnborg 	err |= put_user(stat->blocks, &statbuf->st_blocks);
160*a88b5ba8SSam Ravnborg 	err |= put_user(stat->atime.tv_sec, &statbuf->st_atime);
161*a88b5ba8SSam Ravnborg 	err |= put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec);
162*a88b5ba8SSam Ravnborg 	err |= put_user(stat->mtime.tv_sec, &statbuf->st_mtime);
163*a88b5ba8SSam Ravnborg 	err |= put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec);
164*a88b5ba8SSam Ravnborg 	err |= put_user(stat->ctime.tv_sec, &statbuf->st_ctime);
165*a88b5ba8SSam Ravnborg 	err |= put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec);
166*a88b5ba8SSam Ravnborg 	err |= put_user(0, &statbuf->__unused4);
167*a88b5ba8SSam Ravnborg 	err |= put_user(0, &statbuf->__unused5);
168*a88b5ba8SSam Ravnborg 
169*a88b5ba8SSam Ravnborg 	return err;
170*a88b5ba8SSam Ravnborg }
171*a88b5ba8SSam Ravnborg 
172*a88b5ba8SSam Ravnborg asmlinkage long compat_sys_stat64(char __user * filename,
173*a88b5ba8SSam Ravnborg 		struct compat_stat64 __user *statbuf)
174*a88b5ba8SSam Ravnborg {
175*a88b5ba8SSam Ravnborg 	struct kstat stat;
176*a88b5ba8SSam Ravnborg 	int error = vfs_stat(filename, &stat);
177*a88b5ba8SSam Ravnborg 
178*a88b5ba8SSam Ravnborg 	if (!error)
179*a88b5ba8SSam Ravnborg 		error = cp_compat_stat64(&stat, statbuf);
180*a88b5ba8SSam Ravnborg 	return error;
181*a88b5ba8SSam Ravnborg }
182*a88b5ba8SSam Ravnborg 
183*a88b5ba8SSam Ravnborg asmlinkage long compat_sys_lstat64(char __user * filename,
184*a88b5ba8SSam Ravnborg 		struct compat_stat64 __user *statbuf)
185*a88b5ba8SSam Ravnborg {
186*a88b5ba8SSam Ravnborg 	struct kstat stat;
187*a88b5ba8SSam Ravnborg 	int error = vfs_lstat(filename, &stat);
188*a88b5ba8SSam Ravnborg 
189*a88b5ba8SSam Ravnborg 	if (!error)
190*a88b5ba8SSam Ravnborg 		error = cp_compat_stat64(&stat, statbuf);
191*a88b5ba8SSam Ravnborg 	return error;
192*a88b5ba8SSam Ravnborg }
193*a88b5ba8SSam Ravnborg 
194*a88b5ba8SSam Ravnborg asmlinkage long compat_sys_fstat64(unsigned int fd,
195*a88b5ba8SSam Ravnborg 		struct compat_stat64 __user * statbuf)
196*a88b5ba8SSam Ravnborg {
197*a88b5ba8SSam Ravnborg 	struct kstat stat;
198*a88b5ba8SSam Ravnborg 	int error = vfs_fstat(fd, &stat);
199*a88b5ba8SSam Ravnborg 
200*a88b5ba8SSam Ravnborg 	if (!error)
201*a88b5ba8SSam Ravnborg 		error = cp_compat_stat64(&stat, statbuf);
202*a88b5ba8SSam Ravnborg 	return error;
203*a88b5ba8SSam Ravnborg }
204*a88b5ba8SSam Ravnborg 
205*a88b5ba8SSam Ravnborg asmlinkage long compat_sys_fstatat64(unsigned int dfd, char __user *filename,
206*a88b5ba8SSam Ravnborg 		struct compat_stat64 __user * statbuf, int flag)
207*a88b5ba8SSam Ravnborg {
208*a88b5ba8SSam Ravnborg 	struct kstat stat;
209*a88b5ba8SSam Ravnborg 	int error = -EINVAL;
210*a88b5ba8SSam Ravnborg 
211*a88b5ba8SSam Ravnborg 	if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
212*a88b5ba8SSam Ravnborg 		goto out;
213*a88b5ba8SSam Ravnborg 
214*a88b5ba8SSam Ravnborg 	if (flag & AT_SYMLINK_NOFOLLOW)
215*a88b5ba8SSam Ravnborg 		error = vfs_lstat_fd(dfd, filename, &stat);
216*a88b5ba8SSam Ravnborg 	else
217*a88b5ba8SSam Ravnborg 		error = vfs_stat_fd(dfd, filename, &stat);
218*a88b5ba8SSam Ravnborg 
219*a88b5ba8SSam Ravnborg 	if (!error)
220*a88b5ba8SSam Ravnborg 		error = cp_compat_stat64(&stat, statbuf);
221*a88b5ba8SSam Ravnborg 
222*a88b5ba8SSam Ravnborg out:
223*a88b5ba8SSam Ravnborg 	return error;
224*a88b5ba8SSam Ravnborg }
225*a88b5ba8SSam Ravnborg 
226*a88b5ba8SSam Ravnborg asmlinkage long compat_sys_sysfs(int option, u32 arg1, u32 arg2)
227*a88b5ba8SSam Ravnborg {
228*a88b5ba8SSam Ravnborg 	return sys_sysfs(option, arg1, arg2);
229*a88b5ba8SSam Ravnborg }
230*a88b5ba8SSam Ravnborg 
231*a88b5ba8SSam Ravnborg asmlinkage long compat_sys_sched_rr_get_interval(compat_pid_t pid, struct compat_timespec __user *interval)
232*a88b5ba8SSam Ravnborg {
233*a88b5ba8SSam Ravnborg 	struct timespec t;
234*a88b5ba8SSam Ravnborg 	int ret;
235*a88b5ba8SSam Ravnborg 	mm_segment_t old_fs = get_fs ();
236*a88b5ba8SSam Ravnborg 
237*a88b5ba8SSam Ravnborg 	set_fs (KERNEL_DS);
238*a88b5ba8SSam Ravnborg 	ret = sys_sched_rr_get_interval(pid, (struct timespec __user *) &t);
239*a88b5ba8SSam Ravnborg 	set_fs (old_fs);
240*a88b5ba8SSam Ravnborg 	if (put_compat_timespec(&t, interval))
241*a88b5ba8SSam Ravnborg 		return -EFAULT;
242*a88b5ba8SSam Ravnborg 	return ret;
243*a88b5ba8SSam Ravnborg }
244*a88b5ba8SSam Ravnborg 
245*a88b5ba8SSam Ravnborg asmlinkage long compat_sys_rt_sigprocmask(int how,
246*a88b5ba8SSam Ravnborg 					  compat_sigset_t __user *set,
247*a88b5ba8SSam Ravnborg 					  compat_sigset_t __user *oset,
248*a88b5ba8SSam Ravnborg 					  compat_size_t sigsetsize)
249*a88b5ba8SSam Ravnborg {
250*a88b5ba8SSam Ravnborg 	sigset_t s;
251*a88b5ba8SSam Ravnborg 	compat_sigset_t s32;
252*a88b5ba8SSam Ravnborg 	int ret;
253*a88b5ba8SSam Ravnborg 	mm_segment_t old_fs = get_fs();
254*a88b5ba8SSam Ravnborg 
255*a88b5ba8SSam Ravnborg 	if (set) {
256*a88b5ba8SSam Ravnborg 		if (copy_from_user (&s32, set, sizeof(compat_sigset_t)))
257*a88b5ba8SSam Ravnborg 			return -EFAULT;
258*a88b5ba8SSam Ravnborg 		switch (_NSIG_WORDS) {
259*a88b5ba8SSam Ravnborg 		case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32);
260*a88b5ba8SSam Ravnborg 		case 3: s.sig[2] = s32.sig[4] | (((long)s32.sig[5]) << 32);
261*a88b5ba8SSam Ravnborg 		case 2: s.sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32);
262*a88b5ba8SSam Ravnborg 		case 1: s.sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32);
263*a88b5ba8SSam Ravnborg 		}
264*a88b5ba8SSam Ravnborg 	}
265*a88b5ba8SSam Ravnborg 	set_fs (KERNEL_DS);
266*a88b5ba8SSam Ravnborg 	ret = sys_rt_sigprocmask(how,
267*a88b5ba8SSam Ravnborg 				 set ? (sigset_t __user *) &s : NULL,
268*a88b5ba8SSam Ravnborg 				 oset ? (sigset_t __user *) &s : NULL,
269*a88b5ba8SSam Ravnborg 				 sigsetsize);
270*a88b5ba8SSam Ravnborg 	set_fs (old_fs);
271*a88b5ba8SSam Ravnborg 	if (ret) return ret;
272*a88b5ba8SSam Ravnborg 	if (oset) {
273*a88b5ba8SSam Ravnborg 		switch (_NSIG_WORDS) {
274*a88b5ba8SSam Ravnborg 		case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3];
275*a88b5ba8SSam Ravnborg 		case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2];
276*a88b5ba8SSam Ravnborg 		case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
277*a88b5ba8SSam Ravnborg 		case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
278*a88b5ba8SSam Ravnborg 		}
279*a88b5ba8SSam Ravnborg 		if (copy_to_user (oset, &s32, sizeof(compat_sigset_t)))
280*a88b5ba8SSam Ravnborg 			return -EFAULT;
281*a88b5ba8SSam Ravnborg 	}
282*a88b5ba8SSam Ravnborg 	return 0;
283*a88b5ba8SSam Ravnborg }
284*a88b5ba8SSam Ravnborg 
285*a88b5ba8SSam Ravnborg asmlinkage long sys32_rt_sigpending(compat_sigset_t __user *set,
286*a88b5ba8SSam Ravnborg 				    compat_size_t sigsetsize)
287*a88b5ba8SSam Ravnborg {
288*a88b5ba8SSam Ravnborg 	sigset_t s;
289*a88b5ba8SSam Ravnborg 	compat_sigset_t s32;
290*a88b5ba8SSam Ravnborg 	int ret;
291*a88b5ba8SSam Ravnborg 	mm_segment_t old_fs = get_fs();
292*a88b5ba8SSam Ravnborg 
293*a88b5ba8SSam Ravnborg 	set_fs (KERNEL_DS);
294*a88b5ba8SSam Ravnborg 	ret = sys_rt_sigpending((sigset_t __user *) &s, sigsetsize);
295*a88b5ba8SSam Ravnborg 	set_fs (old_fs);
296*a88b5ba8SSam Ravnborg 	if (!ret) {
297*a88b5ba8SSam Ravnborg 		switch (_NSIG_WORDS) {
298*a88b5ba8SSam Ravnborg 		case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3];
299*a88b5ba8SSam Ravnborg 		case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2];
300*a88b5ba8SSam Ravnborg 		case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
301*a88b5ba8SSam Ravnborg 		case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
302*a88b5ba8SSam Ravnborg 		}
303*a88b5ba8SSam Ravnborg 		if (copy_to_user (set, &s32, sizeof(compat_sigset_t)))
304*a88b5ba8SSam Ravnborg 			return -EFAULT;
305*a88b5ba8SSam Ravnborg 	}
306*a88b5ba8SSam Ravnborg 	return ret;
307*a88b5ba8SSam Ravnborg }
308*a88b5ba8SSam Ravnborg 
309*a88b5ba8SSam Ravnborg asmlinkage long compat_sys_rt_sigqueueinfo(int pid, int sig,
310*a88b5ba8SSam Ravnborg 					   struct compat_siginfo __user *uinfo)
311*a88b5ba8SSam Ravnborg {
312*a88b5ba8SSam Ravnborg 	siginfo_t info;
313*a88b5ba8SSam Ravnborg 	int ret;
314*a88b5ba8SSam Ravnborg 	mm_segment_t old_fs = get_fs();
315*a88b5ba8SSam Ravnborg 
316*a88b5ba8SSam Ravnborg 	if (copy_siginfo_from_user32(&info, uinfo))
317*a88b5ba8SSam Ravnborg 		return -EFAULT;
318*a88b5ba8SSam Ravnborg 
319*a88b5ba8SSam Ravnborg 	set_fs (KERNEL_DS);
320*a88b5ba8SSam Ravnborg 	ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *) &info);
321*a88b5ba8SSam Ravnborg 	set_fs (old_fs);
322*a88b5ba8SSam Ravnborg 	return ret;
323*a88b5ba8SSam Ravnborg }
324*a88b5ba8SSam Ravnborg 
325*a88b5ba8SSam Ravnborg asmlinkage long compat_sys_sigaction(int sig, struct old_sigaction32 __user *act,
326*a88b5ba8SSam Ravnborg 				     struct old_sigaction32 __user *oact)
327*a88b5ba8SSam Ravnborg {
328*a88b5ba8SSam Ravnborg         struct k_sigaction new_ka, old_ka;
329*a88b5ba8SSam Ravnborg         int ret;
330*a88b5ba8SSam Ravnborg 
331*a88b5ba8SSam Ravnborg 	WARN_ON_ONCE(sig >= 0);
332*a88b5ba8SSam Ravnborg 	sig = -sig;
333*a88b5ba8SSam Ravnborg 
334*a88b5ba8SSam Ravnborg         if (act) {
335*a88b5ba8SSam Ravnborg 		compat_old_sigset_t mask;
336*a88b5ba8SSam Ravnborg 		u32 u_handler, u_restorer;
337*a88b5ba8SSam Ravnborg 
338*a88b5ba8SSam Ravnborg 		ret = get_user(u_handler, &act->sa_handler);
339*a88b5ba8SSam Ravnborg 		new_ka.sa.sa_handler =  compat_ptr(u_handler);
340*a88b5ba8SSam Ravnborg 		ret |= __get_user(u_restorer, &act->sa_restorer);
341*a88b5ba8SSam Ravnborg 		new_ka.sa.sa_restorer = compat_ptr(u_restorer);
342*a88b5ba8SSam Ravnborg 		ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
343*a88b5ba8SSam Ravnborg 		ret |= __get_user(mask, &act->sa_mask);
344*a88b5ba8SSam Ravnborg 		if (ret)
345*a88b5ba8SSam Ravnborg 			return ret;
346*a88b5ba8SSam Ravnborg 		new_ka.ka_restorer = NULL;
347*a88b5ba8SSam Ravnborg 		siginitset(&new_ka.sa.sa_mask, mask);
348*a88b5ba8SSam Ravnborg         }
349*a88b5ba8SSam Ravnborg 
350*a88b5ba8SSam Ravnborg         ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
351*a88b5ba8SSam Ravnborg 
352*a88b5ba8SSam Ravnborg 	if (!ret && oact) {
353*a88b5ba8SSam Ravnborg 		ret = put_user(ptr_to_compat(old_ka.sa.sa_handler), &oact->sa_handler);
354*a88b5ba8SSam Ravnborg 		ret |= __put_user(ptr_to_compat(old_ka.sa.sa_restorer), &oact->sa_restorer);
355*a88b5ba8SSam Ravnborg 		ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
356*a88b5ba8SSam Ravnborg 		ret |= __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
357*a88b5ba8SSam Ravnborg         }
358*a88b5ba8SSam Ravnborg 
359*a88b5ba8SSam Ravnborg 	return ret;
360*a88b5ba8SSam Ravnborg }
361*a88b5ba8SSam Ravnborg 
362*a88b5ba8SSam Ravnborg asmlinkage long compat_sys_rt_sigaction(int sig,
363*a88b5ba8SSam Ravnborg 					struct sigaction32 __user *act,
364*a88b5ba8SSam Ravnborg 					struct sigaction32 __user *oact,
365*a88b5ba8SSam Ravnborg 					void __user *restorer,
366*a88b5ba8SSam Ravnborg 					compat_size_t sigsetsize)
367*a88b5ba8SSam Ravnborg {
368*a88b5ba8SSam Ravnborg         struct k_sigaction new_ka, old_ka;
369*a88b5ba8SSam Ravnborg         int ret;
370*a88b5ba8SSam Ravnborg 	compat_sigset_t set32;
371*a88b5ba8SSam Ravnborg 
372*a88b5ba8SSam Ravnborg         /* XXX: Don't preclude handling different sized sigset_t's.  */
373*a88b5ba8SSam Ravnborg         if (sigsetsize != sizeof(compat_sigset_t))
374*a88b5ba8SSam Ravnborg                 return -EINVAL;
375*a88b5ba8SSam Ravnborg 
376*a88b5ba8SSam Ravnborg         if (act) {
377*a88b5ba8SSam Ravnborg 		u32 u_handler, u_restorer;
378*a88b5ba8SSam Ravnborg 
379*a88b5ba8SSam Ravnborg 		new_ka.ka_restorer = restorer;
380*a88b5ba8SSam Ravnborg 		ret = get_user(u_handler, &act->sa_handler);
381*a88b5ba8SSam Ravnborg 		new_ka.sa.sa_handler =  compat_ptr(u_handler);
382*a88b5ba8SSam Ravnborg 		ret |= __copy_from_user(&set32, &act->sa_mask, sizeof(compat_sigset_t));
383*a88b5ba8SSam Ravnborg 		switch (_NSIG_WORDS) {
384*a88b5ba8SSam Ravnborg 		case 4: new_ka.sa.sa_mask.sig[3] = set32.sig[6] | (((long)set32.sig[7]) << 32);
385*a88b5ba8SSam Ravnborg 		case 3: new_ka.sa.sa_mask.sig[2] = set32.sig[4] | (((long)set32.sig[5]) << 32);
386*a88b5ba8SSam Ravnborg 		case 2: new_ka.sa.sa_mask.sig[1] = set32.sig[2] | (((long)set32.sig[3]) << 32);
387*a88b5ba8SSam Ravnborg 		case 1: new_ka.sa.sa_mask.sig[0] = set32.sig[0] | (((long)set32.sig[1]) << 32);
388*a88b5ba8SSam Ravnborg 		}
389*a88b5ba8SSam Ravnborg 		ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
390*a88b5ba8SSam Ravnborg 		ret |= __get_user(u_restorer, &act->sa_restorer);
391*a88b5ba8SSam Ravnborg 		new_ka.sa.sa_restorer = compat_ptr(u_restorer);
392*a88b5ba8SSam Ravnborg                 if (ret)
393*a88b5ba8SSam Ravnborg                 	return -EFAULT;
394*a88b5ba8SSam Ravnborg 	}
395*a88b5ba8SSam Ravnborg 
396*a88b5ba8SSam Ravnborg 	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
397*a88b5ba8SSam Ravnborg 
398*a88b5ba8SSam Ravnborg 	if (!ret && oact) {
399*a88b5ba8SSam Ravnborg 		switch (_NSIG_WORDS) {
400*a88b5ba8SSam Ravnborg 		case 4: set32.sig[7] = (old_ka.sa.sa_mask.sig[3] >> 32); set32.sig[6] = old_ka.sa.sa_mask.sig[3];
401*a88b5ba8SSam Ravnborg 		case 3: set32.sig[5] = (old_ka.sa.sa_mask.sig[2] >> 32); set32.sig[4] = old_ka.sa.sa_mask.sig[2];
402*a88b5ba8SSam Ravnborg 		case 2: set32.sig[3] = (old_ka.sa.sa_mask.sig[1] >> 32); set32.sig[2] = old_ka.sa.sa_mask.sig[1];
403*a88b5ba8SSam Ravnborg 		case 1: set32.sig[1] = (old_ka.sa.sa_mask.sig[0] >> 32); set32.sig[0] = old_ka.sa.sa_mask.sig[0];
404*a88b5ba8SSam Ravnborg 		}
405*a88b5ba8SSam Ravnborg 		ret = put_user(ptr_to_compat(old_ka.sa.sa_handler), &oact->sa_handler);
406*a88b5ba8SSam Ravnborg 		ret |= __copy_to_user(&oact->sa_mask, &set32, sizeof(compat_sigset_t));
407*a88b5ba8SSam Ravnborg 		ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
408*a88b5ba8SSam Ravnborg 		ret |= __put_user(ptr_to_compat(old_ka.sa.sa_restorer), &oact->sa_restorer);
409*a88b5ba8SSam Ravnborg 		if (ret)
410*a88b5ba8SSam Ravnborg 			ret = -EFAULT;
411*a88b5ba8SSam Ravnborg         }
412*a88b5ba8SSam Ravnborg 
413*a88b5ba8SSam Ravnborg         return ret;
414*a88b5ba8SSam Ravnborg }
415*a88b5ba8SSam Ravnborg 
416*a88b5ba8SSam Ravnborg /*
417*a88b5ba8SSam Ravnborg  * sparc32_execve() executes a new program after the asm stub has set
418*a88b5ba8SSam Ravnborg  * things up for us.  This should basically do what I want it to.
419*a88b5ba8SSam Ravnborg  */
420*a88b5ba8SSam Ravnborg asmlinkage long sparc32_execve(struct pt_regs *regs)
421*a88b5ba8SSam Ravnborg {
422*a88b5ba8SSam Ravnborg 	int error, base = 0;
423*a88b5ba8SSam Ravnborg 	char *filename;
424*a88b5ba8SSam Ravnborg 
425*a88b5ba8SSam Ravnborg 	/* User register window flush is done by entry.S */
426*a88b5ba8SSam Ravnborg 
427*a88b5ba8SSam Ravnborg 	/* Check for indirect call. */
428*a88b5ba8SSam Ravnborg 	if ((u32)regs->u_regs[UREG_G1] == 0)
429*a88b5ba8SSam Ravnborg 		base = 1;
430*a88b5ba8SSam Ravnborg 
431*a88b5ba8SSam Ravnborg 	filename = getname(compat_ptr(regs->u_regs[base + UREG_I0]));
432*a88b5ba8SSam Ravnborg 	error = PTR_ERR(filename);
433*a88b5ba8SSam Ravnborg 	if (IS_ERR(filename))
434*a88b5ba8SSam Ravnborg 		goto out;
435*a88b5ba8SSam Ravnborg 
436*a88b5ba8SSam Ravnborg 	error = compat_do_execve(filename,
437*a88b5ba8SSam Ravnborg 				 compat_ptr(regs->u_regs[base + UREG_I1]),
438*a88b5ba8SSam Ravnborg 				 compat_ptr(regs->u_regs[base + UREG_I2]), regs);
439*a88b5ba8SSam Ravnborg 
440*a88b5ba8SSam Ravnborg 	putname(filename);
441*a88b5ba8SSam Ravnborg 
442*a88b5ba8SSam Ravnborg 	if (!error) {
443*a88b5ba8SSam Ravnborg 		fprs_write(0);
444*a88b5ba8SSam Ravnborg 		current_thread_info()->xfsr[0] = 0;
445*a88b5ba8SSam Ravnborg 		current_thread_info()->fpsaved[0] = 0;
446*a88b5ba8SSam Ravnborg 		regs->tstate &= ~TSTATE_PEF;
447*a88b5ba8SSam Ravnborg 	}
448*a88b5ba8SSam Ravnborg out:
449*a88b5ba8SSam Ravnborg 	return error;
450*a88b5ba8SSam Ravnborg }
451*a88b5ba8SSam Ravnborg 
452*a88b5ba8SSam Ravnborg #ifdef CONFIG_MODULES
453*a88b5ba8SSam Ravnborg 
454*a88b5ba8SSam Ravnborg asmlinkage long sys32_init_module(void __user *umod, u32 len,
455*a88b5ba8SSam Ravnborg 				  const char __user *uargs)
456*a88b5ba8SSam Ravnborg {
457*a88b5ba8SSam Ravnborg 	return sys_init_module(umod, len, uargs);
458*a88b5ba8SSam Ravnborg }
459*a88b5ba8SSam Ravnborg 
460*a88b5ba8SSam Ravnborg asmlinkage long sys32_delete_module(const char __user *name_user,
461*a88b5ba8SSam Ravnborg 				    unsigned int flags)
462*a88b5ba8SSam Ravnborg {
463*a88b5ba8SSam Ravnborg 	return sys_delete_module(name_user, flags);
464*a88b5ba8SSam Ravnborg }
465*a88b5ba8SSam Ravnborg 
466*a88b5ba8SSam Ravnborg #else /* CONFIG_MODULES */
467*a88b5ba8SSam Ravnborg 
468*a88b5ba8SSam Ravnborg asmlinkage long sys32_init_module(const char __user *name_user,
469*a88b5ba8SSam Ravnborg 				  struct module __user *mod_user)
470*a88b5ba8SSam Ravnborg {
471*a88b5ba8SSam Ravnborg 	return -ENOSYS;
472*a88b5ba8SSam Ravnborg }
473*a88b5ba8SSam Ravnborg 
474*a88b5ba8SSam Ravnborg asmlinkage long sys32_delete_module(const char __user *name_user)
475*a88b5ba8SSam Ravnborg {
476*a88b5ba8SSam Ravnborg 	return -ENOSYS;
477*a88b5ba8SSam Ravnborg }
478*a88b5ba8SSam Ravnborg 
479*a88b5ba8SSam Ravnborg #endif  /* CONFIG_MODULES */
480*a88b5ba8SSam Ravnborg 
481*a88b5ba8SSam Ravnborg asmlinkage compat_ssize_t sys32_pread64(unsigned int fd,
482*a88b5ba8SSam Ravnborg 					char __user *ubuf,
483*a88b5ba8SSam Ravnborg 					compat_size_t count,
484*a88b5ba8SSam Ravnborg 					unsigned long poshi,
485*a88b5ba8SSam Ravnborg 					unsigned long poslo)
486*a88b5ba8SSam Ravnborg {
487*a88b5ba8SSam Ravnborg 	return sys_pread64(fd, ubuf, count, (poshi << 32) | poslo);
488*a88b5ba8SSam Ravnborg }
489*a88b5ba8SSam Ravnborg 
490*a88b5ba8SSam Ravnborg asmlinkage compat_ssize_t sys32_pwrite64(unsigned int fd,
491*a88b5ba8SSam Ravnborg 					 char __user *ubuf,
492*a88b5ba8SSam Ravnborg 					 compat_size_t count,
493*a88b5ba8SSam Ravnborg 					 unsigned long poshi,
494*a88b5ba8SSam Ravnborg 					 unsigned long poslo)
495*a88b5ba8SSam Ravnborg {
496*a88b5ba8SSam Ravnborg 	return sys_pwrite64(fd, ubuf, count, (poshi << 32) | poslo);
497*a88b5ba8SSam Ravnborg }
498*a88b5ba8SSam Ravnborg 
499*a88b5ba8SSam Ravnborg asmlinkage long compat_sys_readahead(int fd,
500*a88b5ba8SSam Ravnborg 				     unsigned long offhi,
501*a88b5ba8SSam Ravnborg 				     unsigned long offlo,
502*a88b5ba8SSam Ravnborg 				     compat_size_t count)
503*a88b5ba8SSam Ravnborg {
504*a88b5ba8SSam Ravnborg 	return sys_readahead(fd, (offhi << 32) | offlo, count);
505*a88b5ba8SSam Ravnborg }
506*a88b5ba8SSam Ravnborg 
507*a88b5ba8SSam Ravnborg long compat_sys_fadvise64(int fd,
508*a88b5ba8SSam Ravnborg 			  unsigned long offhi,
509*a88b5ba8SSam Ravnborg 			  unsigned long offlo,
510*a88b5ba8SSam Ravnborg 			  compat_size_t len, int advice)
511*a88b5ba8SSam Ravnborg {
512*a88b5ba8SSam Ravnborg 	return sys_fadvise64_64(fd, (offhi << 32) | offlo, len, advice);
513*a88b5ba8SSam Ravnborg }
514*a88b5ba8SSam Ravnborg 
515*a88b5ba8SSam Ravnborg long compat_sys_fadvise64_64(int fd,
516*a88b5ba8SSam Ravnborg 			     unsigned long offhi, unsigned long offlo,
517*a88b5ba8SSam Ravnborg 			     unsigned long lenhi, unsigned long lenlo,
518*a88b5ba8SSam Ravnborg 			     int advice)
519*a88b5ba8SSam Ravnborg {
520*a88b5ba8SSam Ravnborg 	return sys_fadvise64_64(fd,
521*a88b5ba8SSam Ravnborg 				(offhi << 32) | offlo,
522*a88b5ba8SSam Ravnborg 				(lenhi << 32) | lenlo,
523*a88b5ba8SSam Ravnborg 				advice);
524*a88b5ba8SSam Ravnborg }
525*a88b5ba8SSam Ravnborg 
526*a88b5ba8SSam Ravnborg asmlinkage long compat_sys_sendfile(int out_fd, int in_fd,
527*a88b5ba8SSam Ravnborg 				    compat_off_t __user *offset,
528*a88b5ba8SSam Ravnborg 				    compat_size_t count)
529*a88b5ba8SSam Ravnborg {
530*a88b5ba8SSam Ravnborg 	mm_segment_t old_fs = get_fs();
531*a88b5ba8SSam Ravnborg 	int ret;
532*a88b5ba8SSam Ravnborg 	off_t of;
533*a88b5ba8SSam Ravnborg 
534*a88b5ba8SSam Ravnborg 	if (offset && get_user(of, offset))
535*a88b5ba8SSam Ravnborg 		return -EFAULT;
536*a88b5ba8SSam Ravnborg 
537*a88b5ba8SSam Ravnborg 	set_fs(KERNEL_DS);
538*a88b5ba8SSam Ravnborg 	ret = sys_sendfile(out_fd, in_fd,
539*a88b5ba8SSam Ravnborg 			   offset ? (off_t __user *) &of : NULL,
540*a88b5ba8SSam Ravnborg 			   count);
541*a88b5ba8SSam Ravnborg 	set_fs(old_fs);
542*a88b5ba8SSam Ravnborg 
543*a88b5ba8SSam Ravnborg 	if (offset && put_user(of, offset))
544*a88b5ba8SSam Ravnborg 		return -EFAULT;
545*a88b5ba8SSam Ravnborg 
546*a88b5ba8SSam Ravnborg 	return ret;
547*a88b5ba8SSam Ravnborg }
548*a88b5ba8SSam Ravnborg 
549*a88b5ba8SSam Ravnborg asmlinkage long compat_sys_sendfile64(int out_fd, int in_fd,
550*a88b5ba8SSam Ravnborg 				      compat_loff_t __user *offset,
551*a88b5ba8SSam Ravnborg 				      compat_size_t count)
552*a88b5ba8SSam Ravnborg {
553*a88b5ba8SSam Ravnborg 	mm_segment_t old_fs = get_fs();
554*a88b5ba8SSam Ravnborg 	int ret;
555*a88b5ba8SSam Ravnborg 	loff_t lof;
556*a88b5ba8SSam Ravnborg 
557*a88b5ba8SSam Ravnborg 	if (offset && get_user(lof, offset))
558*a88b5ba8SSam Ravnborg 		return -EFAULT;
559*a88b5ba8SSam Ravnborg 
560*a88b5ba8SSam Ravnborg 	set_fs(KERNEL_DS);
561*a88b5ba8SSam Ravnborg 	ret = sys_sendfile64(out_fd, in_fd,
562*a88b5ba8SSam Ravnborg 			     offset ? (loff_t __user *) &lof : NULL,
563*a88b5ba8SSam Ravnborg 			     count);
564*a88b5ba8SSam Ravnborg 	set_fs(old_fs);
565*a88b5ba8SSam Ravnborg 
566*a88b5ba8SSam Ravnborg 	if (offset && put_user(lof, offset))
567*a88b5ba8SSam Ravnborg 		return -EFAULT;
568*a88b5ba8SSam Ravnborg 
569*a88b5ba8SSam Ravnborg 	return ret;
570*a88b5ba8SSam Ravnborg }
571*a88b5ba8SSam Ravnborg 
572*a88b5ba8SSam Ravnborg /* This is just a version for 32-bit applications which does
573*a88b5ba8SSam Ravnborg  * not force O_LARGEFILE on.
574*a88b5ba8SSam Ravnborg  */
575*a88b5ba8SSam Ravnborg 
576*a88b5ba8SSam Ravnborg asmlinkage long sparc32_open(const char __user *filename,
577*a88b5ba8SSam Ravnborg 			     int flags, int mode)
578*a88b5ba8SSam Ravnborg {
579*a88b5ba8SSam Ravnborg 	return do_sys_open(AT_FDCWD, filename, flags, mode);
580*a88b5ba8SSam Ravnborg }
581*a88b5ba8SSam Ravnborg 
582*a88b5ba8SSam Ravnborg extern unsigned long do_mremap(unsigned long addr,
583*a88b5ba8SSam Ravnborg 	unsigned long old_len, unsigned long new_len,
584*a88b5ba8SSam Ravnborg 	unsigned long flags, unsigned long new_addr);
585*a88b5ba8SSam Ravnborg 
586*a88b5ba8SSam Ravnborg asmlinkage unsigned long sys32_mremap(unsigned long addr,
587*a88b5ba8SSam Ravnborg 	unsigned long old_len, unsigned long new_len,
588*a88b5ba8SSam Ravnborg 	unsigned long flags, u32 __new_addr)
589*a88b5ba8SSam Ravnborg {
590*a88b5ba8SSam Ravnborg 	unsigned long ret = -EINVAL;
591*a88b5ba8SSam Ravnborg 	unsigned long new_addr = __new_addr;
592*a88b5ba8SSam Ravnborg 
593*a88b5ba8SSam Ravnborg 	if (unlikely(sparc_mmap_check(addr, old_len)))
594*a88b5ba8SSam Ravnborg 		goto out;
595*a88b5ba8SSam Ravnborg 	if (unlikely(sparc_mmap_check(new_addr, new_len)))
596*a88b5ba8SSam Ravnborg 		goto out;
597*a88b5ba8SSam Ravnborg 	down_write(&current->mm->mmap_sem);
598*a88b5ba8SSam Ravnborg 	ret = do_mremap(addr, old_len, new_len, flags, new_addr);
599*a88b5ba8SSam Ravnborg 	up_write(&current->mm->mmap_sem);
600*a88b5ba8SSam Ravnborg out:
601*a88b5ba8SSam Ravnborg 	return ret;
602*a88b5ba8SSam Ravnborg }
603*a88b5ba8SSam Ravnborg 
604*a88b5ba8SSam Ravnborg struct __sysctl_args32 {
605*a88b5ba8SSam Ravnborg 	u32 name;
606*a88b5ba8SSam Ravnborg 	int nlen;
607*a88b5ba8SSam Ravnborg 	u32 oldval;
608*a88b5ba8SSam Ravnborg 	u32 oldlenp;
609*a88b5ba8SSam Ravnborg 	u32 newval;
610*a88b5ba8SSam Ravnborg 	u32 newlen;
611*a88b5ba8SSam Ravnborg 	u32 __unused[4];
612*a88b5ba8SSam Ravnborg };
613*a88b5ba8SSam Ravnborg 
614*a88b5ba8SSam Ravnborg asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args)
615*a88b5ba8SSam Ravnborg {
616*a88b5ba8SSam Ravnborg #ifndef CONFIG_SYSCTL_SYSCALL
617*a88b5ba8SSam Ravnborg 	return -ENOSYS;
618*a88b5ba8SSam Ravnborg #else
619*a88b5ba8SSam Ravnborg 	struct __sysctl_args32 tmp;
620*a88b5ba8SSam Ravnborg 	int error;
621*a88b5ba8SSam Ravnborg 	size_t oldlen, __user *oldlenp = NULL;
622*a88b5ba8SSam Ravnborg 	unsigned long addr = (((unsigned long)&args->__unused[0]) + 7UL) & ~7UL;
623*a88b5ba8SSam Ravnborg 
624*a88b5ba8SSam Ravnborg 	if (copy_from_user(&tmp, args, sizeof(tmp)))
625*a88b5ba8SSam Ravnborg 		return -EFAULT;
626*a88b5ba8SSam Ravnborg 
627*a88b5ba8SSam Ravnborg 	if (tmp.oldval && tmp.oldlenp) {
628*a88b5ba8SSam Ravnborg 		/* Duh, this is ugly and might not work if sysctl_args
629*a88b5ba8SSam Ravnborg 		   is in read-only memory, but do_sysctl does indirectly
630*a88b5ba8SSam Ravnborg 		   a lot of uaccess in both directions and we'd have to
631*a88b5ba8SSam Ravnborg 		   basically copy the whole sysctl.c here, and
632*a88b5ba8SSam Ravnborg 		   glibc's __sysctl uses rw memory for the structure
633*a88b5ba8SSam Ravnborg 		   anyway.  */
634*a88b5ba8SSam Ravnborg 		if (get_user(oldlen, (u32 __user *)(unsigned long)tmp.oldlenp) ||
635*a88b5ba8SSam Ravnborg 		    put_user(oldlen, (size_t __user *)addr))
636*a88b5ba8SSam Ravnborg 			return -EFAULT;
637*a88b5ba8SSam Ravnborg 		oldlenp = (size_t __user *)addr;
638*a88b5ba8SSam Ravnborg 	}
639*a88b5ba8SSam Ravnborg 
640*a88b5ba8SSam Ravnborg 	lock_kernel();
641*a88b5ba8SSam Ravnborg 	error = do_sysctl((int __user *)(unsigned long) tmp.name,
642*a88b5ba8SSam Ravnborg 			  tmp.nlen,
643*a88b5ba8SSam Ravnborg 			  (void __user *)(unsigned long) tmp.oldval,
644*a88b5ba8SSam Ravnborg 			  oldlenp,
645*a88b5ba8SSam Ravnborg 			  (void __user *)(unsigned long) tmp.newval,
646*a88b5ba8SSam Ravnborg 			  tmp.newlen);
647*a88b5ba8SSam Ravnborg 	unlock_kernel();
648*a88b5ba8SSam Ravnborg 	if (oldlenp) {
649*a88b5ba8SSam Ravnborg 		if (!error) {
650*a88b5ba8SSam Ravnborg 			if (get_user(oldlen, (size_t __user *)addr) ||
651*a88b5ba8SSam Ravnborg 			    put_user(oldlen, (u32 __user *)(unsigned long) tmp.oldlenp))
652*a88b5ba8SSam Ravnborg 				error = -EFAULT;
653*a88b5ba8SSam Ravnborg 		}
654*a88b5ba8SSam Ravnborg 		if (copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused)))
655*a88b5ba8SSam Ravnborg 			error = -EFAULT;
656*a88b5ba8SSam Ravnborg 	}
657*a88b5ba8SSam Ravnborg 	return error;
658*a88b5ba8SSam Ravnborg #endif
659*a88b5ba8SSam Ravnborg }
660*a88b5ba8SSam Ravnborg 
661*a88b5ba8SSam Ravnborg long sys32_lookup_dcookie(unsigned long cookie_high,
662*a88b5ba8SSam Ravnborg 			  unsigned long cookie_low,
663*a88b5ba8SSam Ravnborg 			  char __user *buf, size_t len)
664*a88b5ba8SSam Ravnborg {
665*a88b5ba8SSam Ravnborg 	return sys_lookup_dcookie((cookie_high << 32) | cookie_low,
666*a88b5ba8SSam Ravnborg 				  buf, len);
667*a88b5ba8SSam Ravnborg }
668*a88b5ba8SSam Ravnborg 
669*a88b5ba8SSam Ravnborg long compat_sync_file_range(int fd, unsigned long off_high, unsigned long off_low, unsigned long nb_high, unsigned long nb_low, int flags)
670*a88b5ba8SSam Ravnborg {
671*a88b5ba8SSam Ravnborg 	return sys_sync_file_range(fd,
672*a88b5ba8SSam Ravnborg 				   (off_high << 32) | off_low,
673*a88b5ba8SSam Ravnborg 				   (nb_high << 32) | nb_low,
674*a88b5ba8SSam Ravnborg 				   flags);
675*a88b5ba8SSam Ravnborg }
676*a88b5ba8SSam Ravnborg 
677*a88b5ba8SSam Ravnborg asmlinkage long compat_sys_fallocate(int fd, int mode, u32 offhi, u32 offlo,
678*a88b5ba8SSam Ravnborg 				     u32 lenhi, u32 lenlo)
679*a88b5ba8SSam Ravnborg {
680*a88b5ba8SSam Ravnborg 	return sys_fallocate(fd, mode, ((loff_t)offhi << 32) | offlo,
681*a88b5ba8SSam Ravnborg 			     ((loff_t)lenhi << 32) | lenlo);
682*a88b5ba8SSam Ravnborg }
683