[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v2 026/108] linux-user: Split out ioctl
From: |
Richard Henderson |
Subject: |
[Qemu-devel] [PATCH v2 026/108] linux-user: Split out ioctl |
Date: |
Sat, 9 Jun 2018 17:00:58 -1000 |
At the same time, merge do_ioctl into the new function.
Signed-off-by: Richard Henderson <address@hidden>
---
linux-user/syscall.c | 184 ++++++++++++++++++++++---------------------
1 file changed, 94 insertions(+), 90 deletions(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 81e142f091..ebe57d86aa 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5754,94 +5754,6 @@ static IOCTLEntry ioctl_entries[] = {
{ 0, 0, },
};
-/* ??? Implement proper locking for ioctls. */
-/* do_ioctl() Must return target values and target errnos. */
-static abi_long do_ioctl(int fd, int cmd, abi_long arg)
-{
- const IOCTLEntry *ie;
- const argtype *arg_type;
- abi_long ret;
- uint8_t buf_temp[MAX_STRUCT_SIZE];
- int target_size;
- void *argptr;
-
- ie = ioctl_entries;
- for(;;) {
- if (ie->target_cmd == 0) {
- gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
- return -TARGET_ENOSYS;
- }
- if (ie->target_cmd == cmd)
- break;
- ie++;
- }
- arg_type = ie->arg_type;
- if (ie->do_ioctl) {
- return ie->do_ioctl(ie, buf_temp, fd, cmd, arg);
- } else if (!ie->host_cmd) {
- /* Some architectures define BSD ioctls in their headers
- that are not implemented in Linux. */
- return -TARGET_ENOSYS;
- }
-
- switch(arg_type[0]) {
- case TYPE_NULL:
- /* no argument */
- ret = get_errno(safe_ioctl(fd, ie->host_cmd));
- break;
- case TYPE_PTRVOID:
- case TYPE_INT:
- ret = get_errno(safe_ioctl(fd, ie->host_cmd, arg));
- break;
- case TYPE_PTR:
- arg_type++;
- target_size = thunk_type_size(arg_type, 0);
- switch(ie->access) {
- case IOC_R:
- ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
- if (!is_error(ret)) {
- argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
- if (!argptr)
- return -TARGET_EFAULT;
- thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
- unlock_user(argptr, arg, target_size);
- }
- break;
- case IOC_W:
- argptr = lock_user(VERIFY_READ, arg, target_size, 1);
- if (!argptr)
- return -TARGET_EFAULT;
- thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
- unlock_user(argptr, arg, 0);
- ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
- break;
- default:
- case IOC_RW:
- argptr = lock_user(VERIFY_READ, arg, target_size, 1);
- if (!argptr)
- return -TARGET_EFAULT;
- thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
- unlock_user(argptr, arg, 0);
- ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
- if (!is_error(ret)) {
- argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
- if (!argptr)
- return -TARGET_EFAULT;
- thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
- unlock_user(argptr, arg, target_size);
- }
- break;
- }
- break;
- default:
- gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
- (long)cmd, arg_type[0]);
- ret = -TARGET_ENOSYS;
- break;
- }
- return ret;
-}
-
static const bitmask_transtbl iflag_tbl[] = {
{ TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
{ TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
@@ -8179,6 +8091,99 @@ IMPL(getxpid)
}
#endif
+/* ??? Implement proper locking for ioctls. */
+IMPL(ioctl)
+{
+ abi_long fd = arg1;
+ abi_long cmd = arg2;
+ abi_long arg = arg3;
+ const IOCTLEntry *ie;
+ const argtype *arg_type;
+ abi_long ret;
+ uint8_t buf_temp[MAX_STRUCT_SIZE];
+ int target_size;
+ void *argptr;
+
+ for (ie = ioctl_entries; ; ie++) {
+ if (ie->target_cmd == 0) {
+ gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
+ return -TARGET_ENOSYS;
+ }
+ if (ie->target_cmd == cmd) {
+ break;
+ }
+ }
+ arg_type = ie->arg_type;
+ if (ie->do_ioctl) {
+ return ie->do_ioctl(ie, buf_temp, fd, cmd, arg);
+ } else if (!ie->host_cmd) {
+ /* Some architectures define BSD ioctls in their headers
+ that are not implemented in Linux. */
+ return -TARGET_ENOSYS;
+ }
+
+ switch (arg_type[0]) {
+ case TYPE_NULL:
+ /* no argument */
+ ret = get_errno(safe_ioctl(fd, ie->host_cmd));
+ break;
+ case TYPE_PTRVOID:
+ case TYPE_INT:
+ ret = get_errno(safe_ioctl(fd, ie->host_cmd, arg));
+ break;
+ case TYPE_PTR:
+ arg_type++;
+ target_size = thunk_type_size(arg_type, 0);
+ switch (ie->access) {
+ case IOC_R:
+ ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
+ if (!is_error(ret)) {
+ argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
+ if (!argptr) {
+ return -TARGET_EFAULT;
+ }
+ thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
+ unlock_user(argptr, arg, target_size);
+ }
+ break;
+ case IOC_W:
+ argptr = lock_user(VERIFY_READ, arg, target_size, 1);
+ if (!argptr) {
+ return -TARGET_EFAULT;
+ }
+ thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
+ unlock_user(argptr, arg, 0);
+ ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
+ break;
+ default:
+ case IOC_RW:
+ argptr = lock_user(VERIFY_READ, arg, target_size, 1);
+ if (!argptr) {
+ return -TARGET_EFAULT;
+ }
+ thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
+ unlock_user(argptr, arg, 0);
+ ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
+ if (!is_error(ret)) {
+ argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
+ if (!argptr) {
+ return -TARGET_EFAULT;
+ }
+ thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
+ unlock_user(argptr, arg, target_size);
+ }
+ break;
+ }
+ break;
+ default:
+ gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
+ (long)cmd, arg_type[0]);
+ ret = -TARGET_ENOSYS;
+ break;
+ }
+ return ret;
+}
+
IMPL(kill)
{
return get_errno(safe_kill(arg1, target_to_host_signal(arg2)));
@@ -8784,8 +8789,6 @@ static abi_long do_syscall1(void *cpu_env, unsigned num,
abi_long arg1,
void *p;
switch(num) {
- case TARGET_NR_ioctl:
- return do_ioctl(arg1, arg2, arg3);
#ifdef TARGET_NR_fcntl
case TARGET_NR_fcntl:
return do_fcntl(arg1, arg2, arg3);
@@ -12641,6 +12644,7 @@ static impl_fn *syscall_table(unsigned num)
#if defined(TARGET_NR_getxpid) && defined(TARGET_ALPHA)
SYSCALL(getxpid);
#endif
+ SYSCALL(ioctl);
SYSCALL(kill);
#ifdef TARGET_NR_link
SYSCALL(link);
--
2.17.1
- [Qemu-devel] [PATCH v2 017/108] linux-user: Split out unlink, unlinkat, (continued)
- [Qemu-devel] [PATCH v2 017/108] linux-user: Split out unlink, unlinkat, Richard Henderson, 2018/06/09
- [Qemu-devel] [PATCH v2 018/108] linux-user: Split out chdir, mknod, mknodat, time, chmod, Richard Henderson, 2018/06/09
- [Qemu-devel] [PATCH v2 019/108] linux-user: Split out getpid, getxpid, lseek, Richard Henderson, 2018/06/09
- [Qemu-devel] [PATCH v2 020/108] linux-user: Split out mount, umount, Richard Henderson, 2018/06/09
- [Qemu-devel] [PATCH v2 021/108] linux-user: Split out alarm, pause, stime, utime, utimes, Richard Henderson, 2018/06/09
- [Qemu-devel] [PATCH v2 022/108] linux-user: Split out access, faccessat, futimesat, kill, nice, sync, syncfs, Richard Henderson, 2018/06/09
- [Qemu-devel] [PATCH v2 023/108] linux-user: Split out rename, renameat, renameat2, Richard Henderson, 2018/06/09
- [Qemu-devel] [PATCH v2 024/108] linux-user: Split out dup, mkdir, mkdirat, rmdir, Richard Henderson, 2018/06/09
- [Qemu-devel] [PATCH v2 025/108] linux-user: Split out acct, pipe, pipe2, times, umount2, Richard Henderson, 2018/06/09
- [Qemu-devel] [PATCH v2 027/108] linux-user: Split out chroot, dup2, dup3, fcntl, setpgid, umask, Richard Henderson, 2018/06/09
- [Qemu-devel] [PATCH v2 026/108] linux-user: Split out ioctl,
Richard Henderson <=
- [Qemu-devel] [PATCH v2 028/108] linux-user: Split out getpgrp, getppid, setsid, Richard Henderson, 2018/06/09
- [Qemu-devel] [PATCH v2 029/108] linux-user: Split out rt_sigaction, sigaction, Richard Henderson, 2018/06/09
- [Qemu-devel] [PATCH v2 030/108] linux-user: Split out rt_sigprocmask, sgetmask, sigprocmask, ssetmask, Richard Henderson, 2018/06/09
- [Qemu-devel] [PATCH v2 031/108] linux-user: Split out rt_sigpending, rt_sigsuspend, sigpending, sigsuspend, Richard Henderson, 2018/06/09
- [Qemu-devel] [PATCH v2 032/108] linux-user: Split out rt_sigqueueinfo, rt_sigtimedwait, rt_tgsigqueueinfo, Richard Henderson, 2018/06/09
- [Qemu-devel] [PATCH v2 033/108] linux-user: Split out rt_sigreturn, sethostname, setrlimit, sigreturn, Richard Henderson, 2018/06/09
- [Qemu-devel] [PATCH v2 036/108] linux-user: Split out symlink, symlinkat, Richard Henderson, 2018/06/09
- [Qemu-devel] [PATCH v2 035/108] linux-user: Split out select, pselect6, newselect, Richard Henderson, 2018/06/09
- [Qemu-devel] [PATCH v2 034/108] linux-user: Split out getrlimit, getrusage, gettimeofday, settimeofday, Richard Henderson, 2018/06/09
- [Qemu-devel] [PATCH v2 037/108] linux-user: Split out readlink, readlinkat, Richard Henderson, 2018/06/09
- Prev by Date:
[Qemu-devel] [PATCH v2 027/108] linux-user: Split out chroot, dup2, dup3, fcntl, setpgid, umask
- Next by Date:
[Qemu-devel] [PATCH v2 028/108] linux-user: Split out getpgrp, getppid, setsid
- Previous by thread:
[Qemu-devel] [PATCH v2 027/108] linux-user: Split out chroot, dup2, dup3, fcntl, setpgid, umask
- Next by thread:
[Qemu-devel] [PATCH v2 028/108] linux-user: Split out getpgrp, getppid, setsid
- Index(es):