[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 27/33] linux-user: Split out ioctl
From: |
Richard Henderson |
Subject: |
[Qemu-devel] [PATCH 27/33] linux-user: Split out ioctl |
Date: |
Fri, 1 Jun 2018 00:30:44 -0700 |
At the same time, merge do_ioctl into the new function.
Signed-off-by: Richard Henderson <address@hidden>
---
linux-user/syscall.c | 190 ++++++++++++++++++++++---------------------
1 file changed, 97 insertions(+), 93 deletions(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index bde1f9872f..4be71367fc 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5759,97 +5759,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 defined(DEBUG)
- gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
-#endif
- 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 },
@@ -8231,6 +8140,102 @@ 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 defined(DEBUG)
+ gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
+#endif
+ 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)));
@@ -8900,8 +8905,6 @@ IMPL(everything_else)
char *fn;
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);
@@ -12990,6 +12993,7 @@ static impl_fn * const syscall_table[] = {
#if defined(TARGET_NR_getxpid) && defined(TARGET_ALPHA)
[TARGET_NR_getxpid] = impl_getxpid,
#endif
+ [TARGET_NR_ioctl] = impl_ioctl,
[TARGET_NR_kill] = impl_kill,
#ifdef TARGET_NR_link
[TARGET_NR_link] = impl_link,
--
2.17.0
- [Qemu-devel] [PATCH 17/33] linux-user: Split out unlink, unlinkat, (continued)
- [Qemu-devel] [PATCH 17/33] linux-user: Split out unlink, unlinkat, Richard Henderson, 2018/06/01
- [Qemu-devel] [PATCH 18/33] linux-user: Split out chdir, mknod, mknodat, time, chmod, Richard Henderson, 2018/06/01
- [Qemu-devel] [PATCH 19/33] linux-user: Remove all unimplemented entries, Richard Henderson, 2018/06/01
- [Qemu-devel] [PATCH 20/33] linux-user: Split out getpid, getxpid, lseek, Richard Henderson, 2018/06/01
- [Qemu-devel] [PATCH 21/33] linux-user: Split out mount, umount, Richard Henderson, 2018/06/01
- [Qemu-devel] [PATCH 22/33] linux-user: Split out alarm, pause, stime, utime, utimes, Richard Henderson, 2018/06/01
- [Qemu-devel] [PATCH 23/33] linux-user: Split out access, faccessat, futimesat, kill, nice, sync, syncfs, Richard Henderson, 2018/06/01
- [Qemu-devel] [PATCH 26/33] linux-user: Split out acct, pipe, pipe2, times, umount2, Richard Henderson, 2018/06/01
- [Qemu-devel] [PATCH 25/33] linux-user: Split out dup, mkdir, mkdirat, rmdir, Richard Henderson, 2018/06/01
- [Qemu-devel] [PATCH 24/33] linux-user: Split out rename, renameat, renameat2, Richard Henderson, 2018/06/01
- [Qemu-devel] [PATCH 27/33] linux-user: Split out ioctl,
Richard Henderson <=
- [Qemu-devel] [PATCH 28/33] linux-user: Split out chroot, dup2, dup3, fcntl, setpgid, umask, Richard Henderson, 2018/06/01
- [Qemu-devel] [PATCH 29/33] linux-user: Split out getpgrp, getppid, setsid, Richard Henderson, 2018/06/01
- [Qemu-devel] [PATCH 32/33] linux-user: Split out rt_sigpending, rt_sigsuspend, sigpending, sigsuspend, Richard Henderson, 2018/06/01
- [Qemu-devel] [PATCH 31/33] linux-user: Split out rt_sigprocmask, sgetmask, sigprocmask, ssetmask, Richard Henderson, 2018/06/01
- [Qemu-devel] [PATCH 30/33] linux-user: Split out rt_sigaction, sigaction, Richard Henderson, 2018/06/01
- [Qemu-devel] [PATCH 33/33] linux-user: Split out rt_sigqueueinfo, rt_sigtimedwait, rt_tgsigqueueinfo, Richard Henderson, 2018/06/01
- Re: [Qemu-devel] [PATCH 00/33] linux-user: Begin splitting do_syscall, Richard Henderson, 2018/06/01
- Re: [Qemu-devel] [PATCH 00/33] linux-user: Begin splitting do_syscall, no-reply, 2018/06/01
- Prev by Date:
[Qemu-devel] [PATCH 24/33] linux-user: Split out rename, renameat, renameat2
- Next by Date:
[Qemu-devel] [PATCH 28/33] linux-user: Split out chroot, dup2, dup3, fcntl, setpgid, umask
- Previous by thread:
[Qemu-devel] [PATCH 24/33] linux-user: Split out rename, renameat, renameat2
- Next by thread:
[Qemu-devel] [PATCH 28/33] linux-user: Split out chroot, dup2, dup3, fcntl, setpgid, umask
- Index(es):