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); }
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; }