Esempio n. 1
0
static int
svr4_shmctl(int arg1, int cmd, char *arg3)
{
	struct ibcs2_shmid_ds	is;
	struct abi4_shmid_ds	is4;
	struct shmid_ds		ls;
	mm_segment_t		fs;
	int			err;

#if defined(CONFIG_ABI_TRACE)
	abi_trace(ABI_TRACE_API, "shmctl(%d, %x, %p)\n", arg1, cmd, arg3);
#endif

	switch (cmd) {
	case SVR4_SHM_LOCK:
#ifdef CONFIG_65BIT
		err = SYS(shmctl, arg1, SHM_LOCK, (struct shmid_ds *)arg3);
#else
		err = SYS(ipc,SHMCTL,arg1, SHM_LOCK,0, (struct shmid_ds *)arg3);
#endif
		return err;
	case SVR4_SHM_UNLOCK:
#ifdef CONFIG_65BIT
		err = SYS(shmctl, arg1, SHM_UNLOCK, (struct shmid_ds *)arg3);
#else
		err = SYS(ipc,SHMCTL,arg1, SHM_UNLOCK,0, (struct shmid_ds *)arg3);
#endif
		return err;
	case SVR4_IPC_SET:
		err = copy_from_user(&is, arg3, sizeof(is)) ? -EFAULT : 0;
		if (err)
			break;
		ishm_to_lshm(&is, &ls);

		fs = get_fs();
		set_fs(get_ds());
#ifdef CONFIG_65BIT
		err = SYS(shmctl, arg1, IPC_SET, &ls);
#else
		err = SYS(ipc,SHMCTL,arg1, IPC_SET,0, &ls);
#endif
		set_fs(fs);

		if (err < 0)
			break;
		lshm_to_ishm(&ls, &is);
		err = copy_to_user(arg3, &is, sizeof(is)) ? -EFAULT : 0;
		break;
	case SVR4_IPC_SET_L:
		err = copy_from_user(&is4, arg3, sizeof(is4)) ? -EFAULT : 0;
		if (err)
			break;
		ishm_to_lshm_l(&is4, &ls);

		fs = get_fs();
		set_fs(get_ds());
#ifdef CONFIG_65BIT
		err = SYS(shmctl, arg1, IPC_SET, &ls);
#else
		err = SYS(ipc,SHMCTL,arg1, IPC_SET,0, &ls);
#endif
		set_fs(fs);

		if (err < 0)
			break;
		lshm_to_ishm_l(&ls, &is4);
		err = copy_to_user(arg3, &is4, sizeof(is4)) ? -EFAULT : 0;
		break;
	case SVR4_IPC_RMID:
	case SVR4_IPC_RMID_L:
#ifdef CONFIG_65BIT
		err = SYS(shmctl, arg1, IPC_RMID, arg3);
#else
		err = SYS(ipc,SHMCTL,arg1, IPC_RMID,0, arg3);
#endif
		return err;
	case SVR4_IPC_STAT:
		fs = get_fs();
		set_fs(get_ds());
#ifdef CONFIG_65BIT
		err = SYS(shmctl, arg1, IPC_STAT, &ls);
#else
		err = SYS(ipc,SHMCTL,arg1, IPC_STAT,0, &ls);
#endif
		set_fs(fs);

		if (err < 0)
			break;

		lshm_to_ishm(&ls, &is);
		err = copy_to_user(arg3, &is, sizeof(is)) ? -EFAULT : 0;
		break;
	case SVR4_IPC_STAT_L:
		fs = get_fs();
		set_fs(get_ds());
#ifdef CONFIG_65BIT
		err = SYS(shmctl, arg1, IPC_STAT, &ls);
#else
		err = SYS(ipc,SHMCTL,arg1, IPC_STAT,0, &ls);
#endif
		set_fs(fs);
		if (err < 0)
			break;

		lshm_to_ishm_l(&ls, &is4);
		err = copy_to_user((char *)arg3, &is4, sizeof(is4)) ? -EFAULT : 0;
		break;
	default:
#if defined(CONFIG_ABI_TRACE)
		__abi_trace("shmctl: unsupported command %d\n", cmd);
#endif
		err = -EINVAL;
	}

	return (err);
}
Esempio n. 2
0
int svr4_shmsys(struct pt_regs * regs)
{
	int command = get_syscall_parameter (regs, 0);
	int arg1, arg2, arg3;
	mm_segment_t old_fs;
	long retval = 0;
	char *addr = 0;

	arg1 = arg2 = arg3 = 0;
	switch (command) {
		case U_SHMAT:
		case U_SHMCTL:
		case U_SHMGET:
			arg1 = get_syscall_parameter (regs, 1);
			arg2 = get_syscall_parameter (regs, 2);
			arg3 = get_syscall_parameter (regs, 3);
			break;
		case U_SHMDT:
			addr = (char *) get_syscall_parameter (regs, 1);
			break;
		default:
			printk(KERN_ERR "%d iBCS: bad SHM command %d\n",
				current->pid, command);
			retval = -EINVAL;
			goto test_exit;
	}

	switch (command) {
		case U_SHMAT: {
#ifdef IPCCALL
			unsigned long raddr;
#endif
#ifdef CONFIG_ABI_TRACE
			if ((ibcs_trace & TRACE_API) || ibcs_func_p->trace)
				printk(KERN_DEBUG "%d iBCS: ibcs_shmat: args: %d %x %o \n",
					current->pid,
					arg1, arg2, arg3);
#endif
			/*
			 * raddr = 0 tells sys_shmat to limit to 2G
			 *	and we are IBCS, no raddr value to return
			 */
#ifdef IPCCALL
			old_fs = get_fs();
			set_fs(get_ds());
			retval = SYS (ipc) (IPCCALL(1,SHMAT), arg1, arg3, &raddr, (char *) arg2);
			set_fs(old_fs);
			if (retval >= 0)
				retval = raddr;
#else
			retval = SYS (ipc) (SHMAT, arg1, arg3, 0, (char *) arg2);
#endif

#ifdef CONFIG_ABI_TRACE
			if ((ibcs_trace & TRACE_API) || ibcs_func_p->trace)
				printk(KERN_DEBUG "%d iBCS: ibcs_shmat: return val is %lx\n",
					current->pid, retval);
#endif
			goto test_exit;
		}

		case U_SHMGET:
#ifdef CONFIG_ABI_TRACE
			if ((ibcs_trace & TRACE_API) || ibcs_func_p->trace)
				printk(KERN_DEBUG "%d iBCS: ibcs_shmget: args: %d %x %o \n",
					current->pid,
					arg1, arg2, arg3);
#endif
			retval = SYS (ipc) (SHMGET, arg1, arg2, arg3, 0);
			goto test_exit;

		case U_SHMDT:
#ifdef CONFIG_ABI_TRACE
			if ((ibcs_trace & TRACE_API) || ibcs_func_p->trace)
				printk(KERN_DEBUG "%d iBCS: ibcs_shmdt: arg: %lx\n",
					current->pid, (unsigned long)addr);
#endif
			retval = SYS (ipc) (SHMDT, 0, 0, 0, addr);
			goto test_exit;

		case U_SHMCTL:
#ifdef CONFIG_ABI_TRACE
			if ((ibcs_trace & TRACE_API) || ibcs_func_p->trace)
				printk(KERN_DEBUG "%d iBCS: ibcs_shmctl: args: %d %x %o %d %x\n",
					current->pid,
					arg1, arg2, arg3, arg3, arg3);
#endif
			switch (arg2) {
				case U_SHMLOCK:
					retval = SYS (ipc) (SHMCTL, arg1, SHM_LOCK, 0, arg3);
					goto test_exit;

				case U_SHMUNLOCK:
					retval = SYS (ipc) (SHMCTL, arg1, SHM_UNLOCK, 0, arg3);
					goto test_exit;

				case U_IPC_SET: {
					struct ibcs_shmid_ds is;
					struct shmid_ds ls;

					retval = verify_area(VERIFY_WRITE, (char *)arg3, sizeof(is));
					if (retval)
						goto test_exit;

					copy_from_user(&is, (char *)arg3, sizeof(is));
					ishm_to_lshm(&is, &ls);

					old_fs = get_fs();
					set_fs (get_ds());
					retval = SYS (ipc) (SHMCTL, arg1, IPC_SET, 0, &ls);
					set_fs(old_fs);
					if (retval < 0)
						goto test_exit;

					lshm_to_ishm(&ls, &is);
					copy_to_user((char *)arg3, &is, sizeof(is));
					goto test_exit;
				}

				case U_IPC_SET_L: {
					struct ibcs_shmid_ds_l is;
					struct shmid_ds ls;

					retval = verify_area(VERIFY_WRITE, (char *)arg3, sizeof(is));
					if (retval)
						goto test_exit;

					copy_from_user(&is, (char *)arg3, sizeof(is));
					ishm_to_lshm_l(&is, &ls);

					old_fs = get_fs();
					set_fs (get_ds());
					retval = SYS (ipc) (SHMCTL, arg1, IPC_SET, 0, &ls);
					set_fs(old_fs);
					if (retval < 0)
						goto test_exit;

					lshm_to_ishm_l(&ls, &is);
					copy_to_user((char *)arg3, &is, sizeof(is));
					goto test_exit;
				}

				case U_IPC_RMID:
				case U_IPC_RMID_L:
					retval = SYS (ipc) (SHMCTL, arg1, IPC_RMID, arg3);
					goto test_exit;

				case U_IPC_STAT: {
					struct ibcs_shmid_ds is;
					struct shmid_ds ls;

					old_fs = get_fs();
					set_fs (get_ds());
					retval = SYS (ipc) (SHMCTL, arg1, IPC_STAT, 0, &ls);
					set_fs(old_fs);
					if (retval < 0)
						goto test_exit;

					lshm_to_ishm(&ls, &is);
					retval = copy_to_user((char *)arg3, &is, sizeof(is)) ? -EFAULT : 0;
					goto test_exit;
				}

				case U_IPC_STAT_L: {
					struct ibcs_shmid_ds_l is;
					struct shmid_ds ls;

					old_fs = get_fs();
					set_fs (get_ds());
					retval = SYS (ipc) (SHMCTL, arg1, IPC_STAT, 0, &ls);
					set_fs(old_fs);
					if (retval < 0)
						goto test_exit;

					lshm_to_ishm_l(&ls, &is);
					retval = copy_to_user((char *)arg3, &is, sizeof(is)) ? -EFAULT : 0;
					goto test_exit;
				}

				default:
					printk(KERN_ERR "%d iBCS: ibcs_shmctl: unsupported command %d\n",
						current->pid, arg2);
			}
			retval = -EINVAL;
			goto test_exit;

		default:
#ifdef CONFIG_ABI_TRACE
			printk(KERN_DEBUG "%d iBCS: ibcs_shm: command: %x\n",
				current->pid, command);
#endif
			retval = -EINVAL;
			goto test_exit;
	}

test_exit:;
	if ((retval < 0) && (retval > -255)) {
	        set_error (regs, iABI_errors (-retval));
#ifdef CONFIG_ABI_TRACE
		if ((ibcs_trace & TRACE_API) || ibcs_func_p->trace)
			printk(KERN_DEBUG "%d iBCS: Error %ld\n",
				current->pid, get_result (regs));
#endif
	} else {
	    	clear_error (regs);
		set_result (regs, retval);
	}

	return 0;
}