xref: /openbmc/linux/ipc/syscall.c (revision baed7fc9b580bd3fb8252ff1d9b36eaf1f86b670)
1*baed7fc9SChristoph Hellwig /*
2*baed7fc9SChristoph Hellwig  * sys_ipc() is the old de-multiplexer for the SysV IPC calls.
3*baed7fc9SChristoph Hellwig  *
4*baed7fc9SChristoph Hellwig  * This is really horribly ugly, and new architectures should just wire up
5*baed7fc9SChristoph Hellwig  * the individual syscalls instead.
6*baed7fc9SChristoph Hellwig  */
7*baed7fc9SChristoph Hellwig #include <linux/unistd.h>
8*baed7fc9SChristoph Hellwig 
9*baed7fc9SChristoph Hellwig #ifdef __ARCH_WANT_SYS_IPC
10*baed7fc9SChristoph Hellwig #include <linux/errno.h>
11*baed7fc9SChristoph Hellwig #include <linux/ipc.h>
12*baed7fc9SChristoph Hellwig #include <linux/shm.h>
13*baed7fc9SChristoph Hellwig #include <linux/syscalls.h>
14*baed7fc9SChristoph Hellwig #include <linux/uaccess.h>
15*baed7fc9SChristoph Hellwig 
16*baed7fc9SChristoph Hellwig SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, int, second,
17*baed7fc9SChristoph Hellwig 		unsigned long, third, void __user *, ptr, long, fifth)
18*baed7fc9SChristoph Hellwig {
19*baed7fc9SChristoph Hellwig 	int version, ret;
20*baed7fc9SChristoph Hellwig 
21*baed7fc9SChristoph Hellwig 	version = call >> 16; /* hack for backward compatibility */
22*baed7fc9SChristoph Hellwig 	call &= 0xffff;
23*baed7fc9SChristoph Hellwig 
24*baed7fc9SChristoph Hellwig 	switch (call) {
25*baed7fc9SChristoph Hellwig 	case SEMOP:
26*baed7fc9SChristoph Hellwig 		return sys_semtimedop(first, (struct sembuf __user *)ptr,
27*baed7fc9SChristoph Hellwig 				      second, NULL);
28*baed7fc9SChristoph Hellwig 	case SEMTIMEDOP:
29*baed7fc9SChristoph Hellwig 		return sys_semtimedop(first, (struct sembuf __user *)ptr,
30*baed7fc9SChristoph Hellwig 				      second,
31*baed7fc9SChristoph Hellwig 				      (const struct timespec __user *)fifth);
32*baed7fc9SChristoph Hellwig 
33*baed7fc9SChristoph Hellwig 	case SEMGET:
34*baed7fc9SChristoph Hellwig 		return sys_semget(first, second, third);
35*baed7fc9SChristoph Hellwig 	case SEMCTL: {
36*baed7fc9SChristoph Hellwig 		union semun fourth;
37*baed7fc9SChristoph Hellwig 		if (!ptr)
38*baed7fc9SChristoph Hellwig 			return -EINVAL;
39*baed7fc9SChristoph Hellwig 		if (get_user(fourth.__pad, (void __user * __user *) ptr))
40*baed7fc9SChristoph Hellwig 			return -EFAULT;
41*baed7fc9SChristoph Hellwig 		return sys_semctl(first, second, third, fourth);
42*baed7fc9SChristoph Hellwig 	}
43*baed7fc9SChristoph Hellwig 
44*baed7fc9SChristoph Hellwig 	case MSGSND:
45*baed7fc9SChristoph Hellwig 		return sys_msgsnd(first, (struct msgbuf __user *) ptr,
46*baed7fc9SChristoph Hellwig 				  second, third);
47*baed7fc9SChristoph Hellwig 	case MSGRCV:
48*baed7fc9SChristoph Hellwig 		switch (version) {
49*baed7fc9SChristoph Hellwig 		case 0: {
50*baed7fc9SChristoph Hellwig 			struct ipc_kludge tmp;
51*baed7fc9SChristoph Hellwig 			if (!ptr)
52*baed7fc9SChristoph Hellwig 				return -EINVAL;
53*baed7fc9SChristoph Hellwig 
54*baed7fc9SChristoph Hellwig 			if (copy_from_user(&tmp,
55*baed7fc9SChristoph Hellwig 					   (struct ipc_kludge __user *) ptr,
56*baed7fc9SChristoph Hellwig 					   sizeof(tmp)))
57*baed7fc9SChristoph Hellwig 				return -EFAULT;
58*baed7fc9SChristoph Hellwig 			return sys_msgrcv(first, tmp.msgp, second,
59*baed7fc9SChristoph Hellwig 					   tmp.msgtyp, third);
60*baed7fc9SChristoph Hellwig 		}
61*baed7fc9SChristoph Hellwig 		default:
62*baed7fc9SChristoph Hellwig 			return sys_msgrcv(first,
63*baed7fc9SChristoph Hellwig 					   (struct msgbuf __user *) ptr,
64*baed7fc9SChristoph Hellwig 					   second, fifth, third);
65*baed7fc9SChristoph Hellwig 		}
66*baed7fc9SChristoph Hellwig 	case MSGGET:
67*baed7fc9SChristoph Hellwig 		return sys_msgget((key_t) first, second);
68*baed7fc9SChristoph Hellwig 	case MSGCTL:
69*baed7fc9SChristoph Hellwig 		return sys_msgctl(first, second, (struct msqid_ds __user *)ptr);
70*baed7fc9SChristoph Hellwig 
71*baed7fc9SChristoph Hellwig 	case SHMAT:
72*baed7fc9SChristoph Hellwig 		switch (version) {
73*baed7fc9SChristoph Hellwig 		default: {
74*baed7fc9SChristoph Hellwig 			unsigned long raddr;
75*baed7fc9SChristoph Hellwig 			ret = do_shmat(first, (char __user *)ptr,
76*baed7fc9SChristoph Hellwig 				       second, &raddr);
77*baed7fc9SChristoph Hellwig 			if (ret)
78*baed7fc9SChristoph Hellwig 				return ret;
79*baed7fc9SChristoph Hellwig 			return put_user(raddr, (unsigned long __user *) third);
80*baed7fc9SChristoph Hellwig 		}
81*baed7fc9SChristoph Hellwig 		case 1:
82*baed7fc9SChristoph Hellwig 			/*
83*baed7fc9SChristoph Hellwig 			 * This was the entry point for kernel-originating calls
84*baed7fc9SChristoph Hellwig 			 * from iBCS2 in 2.2 days.
85*baed7fc9SChristoph Hellwig 			 */
86*baed7fc9SChristoph Hellwig 			return -EINVAL;
87*baed7fc9SChristoph Hellwig 		}
88*baed7fc9SChristoph Hellwig 	case SHMDT:
89*baed7fc9SChristoph Hellwig 		return sys_shmdt((char __user *)ptr);
90*baed7fc9SChristoph Hellwig 	case SHMGET:
91*baed7fc9SChristoph Hellwig 		return sys_shmget(first, second, third);
92*baed7fc9SChristoph Hellwig 	case SHMCTL:
93*baed7fc9SChristoph Hellwig 		return sys_shmctl(first, second,
94*baed7fc9SChristoph Hellwig 				   (struct shmid_ds __user *) ptr);
95*baed7fc9SChristoph Hellwig 	default:
96*baed7fc9SChristoph Hellwig 		return -ENOSYS;
97*baed7fc9SChristoph Hellwig 	}
98*baed7fc9SChristoph Hellwig }
99*baed7fc9SChristoph Hellwig #endif
100