aboutsummaryrefslogtreecommitdiff
path: root/linux-user/syscall.c
diff options
context:
space:
mode:
Diffstat (limited to 'linux-user/syscall.c')
-rw-r--r--linux-user/syscall.c83
1 files changed, 60 insertions, 23 deletions
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 673eed4ece..25b95ea05a 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -28,7 +28,6 @@
#include <fcntl.h>
#include <time.h>
#include <limits.h>
-#include <mqueue.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
@@ -60,6 +59,9 @@
#ifdef TARGET_GPROF
#include <sys/gmon.h>
#endif
+#ifdef CONFIG_EVENTFD
+#include <sys/eventfd.h>
+#endif
#define termios host_termios
#define winsize host_winsize
@@ -194,9 +196,7 @@ static int gettid(void) {
return -ENOSYS;
}
#endif
-#if TARGET_ABI_BITS == 32
_syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
-#endif
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
_syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
#endif
@@ -847,6 +847,9 @@ static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
return 0;
}
+#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
+#include <mqueue.h>
+
static inline abi_long copy_from_user_mq_attr(struct mq_attr *attr,
abi_ulong target_mq_attr_addr)
{
@@ -884,6 +887,7 @@ static inline abi_long copy_to_user_mq_attr(abi_ulong target_mq_attr_addr,
return 0;
}
+#endif
/* do_select() must return target values and target errnos. */
static abi_long do_select(int n,
@@ -3677,6 +3681,14 @@ static int target_to_host_fcntl_cmd(int cmd)
case TARGET_F_SETLKW64:
return F_SETLKW64;
#endif
+ case TARGET_F_SETLEASE:
+ return F_SETLEASE;
+ case TARGET_F_GETLEASE:
+ return F_GETLEASE;
+ case TARGET_F_DUPFD_CLOEXEC:
+ return F_DUPFD_CLOEXEC;
+ case TARGET_F_NOTIFY:
+ return F_NOTIFY;
default:
return -TARGET_EINVAL;
}
@@ -3703,7 +3715,7 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
fl.l_whence = tswap16(target_fl->l_whence);
fl.l_start = tswapl(target_fl->l_start);
fl.l_len = tswapl(target_fl->l_len);
- fl.l_pid = tswapl(target_fl->l_pid);
+ fl.l_pid = tswap32(target_fl->l_pid);
unlock_user_struct(target_fl, arg, 0);
ret = get_errno(fcntl(fd, host_cmd, &fl));
if (ret == 0) {
@@ -3713,7 +3725,7 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
target_fl->l_whence = tswap16(fl.l_whence);
target_fl->l_start = tswapl(fl.l_start);
target_fl->l_len = tswapl(fl.l_len);
- target_fl->l_pid = tswapl(fl.l_pid);
+ target_fl->l_pid = tswap32(fl.l_pid);
unlock_user_struct(target_fl, arg, 1);
}
break;
@@ -3726,7 +3738,7 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
fl.l_whence = tswap16(target_fl->l_whence);
fl.l_start = tswapl(target_fl->l_start);
fl.l_len = tswapl(target_fl->l_len);
- fl.l_pid = tswapl(target_fl->l_pid);
+ fl.l_pid = tswap32(target_fl->l_pid);
unlock_user_struct(target_fl, arg, 0);
ret = get_errno(fcntl(fd, host_cmd, &fl));
break;
@@ -3738,7 +3750,7 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
fl64.l_whence = tswap16(target_fl64->l_whence);
fl64.l_start = tswapl(target_fl64->l_start);
fl64.l_len = tswapl(target_fl64->l_len);
- fl64.l_pid = tswap16(target_fl64->l_pid);
+ fl64.l_pid = tswap32(target_fl64->l_pid);
unlock_user_struct(target_fl64, arg, 0);
ret = get_errno(fcntl(fd, host_cmd, &fl64));
if (ret == 0) {
@@ -3748,7 +3760,7 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
target_fl64->l_whence = tswap16(fl64.l_whence);
target_fl64->l_start = tswapl(fl64.l_start);
target_fl64->l_len = tswapl(fl64.l_len);
- target_fl64->l_pid = tswapl(fl64.l_pid);
+ target_fl64->l_pid = tswap32(fl64.l_pid);
unlock_user_struct(target_fl64, arg, 1);
}
break;
@@ -3760,7 +3772,7 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
fl64.l_whence = tswap16(target_fl64->l_whence);
fl64.l_start = tswapl(target_fl64->l_start);
fl64.l_len = tswapl(target_fl64->l_len);
- fl64.l_pid = tswap16(target_fl64->l_pid);
+ fl64.l_pid = tswap32(target_fl64->l_pid);
unlock_user_struct(target_fl64, arg, 0);
ret = get_errno(fcntl(fd, host_cmd, &fl64));
break;
@@ -3780,6 +3792,8 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
case TARGET_F_GETOWN:
case TARGET_F_SETSIG:
case TARGET_F_GETSIG:
+ case TARGET_F_SETLEASE:
+ case TARGET_F_GETLEASE:
ret = get_errno(fcntl(fd, host_cmd, arg));
break;
@@ -5515,6 +5529,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
goto efault;
+ memset(target_st, 0, sizeof(*target_st));
__put_user(st.st_dev, &target_st->st_dev);
__put_user(st.st_ino, &target_st->st_ino);
__put_user(st.st_mode, &target_st->st_mode);
@@ -5779,9 +5794,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
break;
#endif
case TARGET_NR_getdents:
-#if TARGET_ABI_BITS != 32
- goto unimplemented;
-#elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
+#if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
{
struct target_dirent *target_dirp;
struct linux_dirent *dirp;
@@ -6108,7 +6121,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
goto unimplemented;
case TARGET_NR_sigaltstack:
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
- defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA)
+ defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA) || \
+ defined(TARGET_M68K)
ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUState *)cpu_env));
break;
#else
@@ -6554,12 +6568,23 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
arg4 = temp;
}
#endif
-#if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64)
+#if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64) || defined(TARGET_NR_fadvise64)
#ifdef TARGET_NR_fadvise64_64
case TARGET_NR_fadvise64_64:
#endif
- /* This is a hint, so ignoring and returning success is ok. */
- ret = get_errno(0);
+#ifdef TARGET_NR_fadvise64
+ case TARGET_NR_fadvise64:
+#endif
+#ifdef TARGET_S390X
+ switch (arg4) {
+ case 4: arg4 = POSIX_FADV_NOREUSE + 1; break; /* make sure it's an invalid value */
+ case 5: arg4 = POSIX_FADV_NOREUSE + 2; break; /* ditto */
+ case 6: arg4 = POSIX_FADV_DONTNEED; break;
+ case 7: arg4 = POSIX_FADV_NOREUSE; break;
+ default: break;
+ }
+#endif
+ ret = -posix_fadvise(arg1, arg2, arg3, arg4);
break;
#endif
#ifdef TARGET_NR_madvise
@@ -6595,7 +6620,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
fl.l_whence = tswap16(target_efl->l_whence);
fl.l_start = tswap64(target_efl->l_start);
fl.l_len = tswap64(target_efl->l_len);
- fl.l_pid = tswapl(target_efl->l_pid);
+ fl.l_pid = tswap32(target_efl->l_pid);
unlock_user_struct(target_efl, arg3, 0);
} else
#endif
@@ -6606,7 +6631,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
fl.l_whence = tswap16(target_fl->l_whence);
fl.l_start = tswap64(target_fl->l_start);
fl.l_len = tswap64(target_fl->l_len);
- fl.l_pid = tswapl(target_fl->l_pid);
+ fl.l_pid = tswap32(target_fl->l_pid);
unlock_user_struct(target_fl, arg3, 0);
}
ret = get_errno(fcntl(arg1, cmd, &fl));
@@ -6619,7 +6644,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
target_efl->l_whence = tswap16(fl.l_whence);
target_efl->l_start = tswap64(fl.l_start);
target_efl->l_len = tswap64(fl.l_len);
- target_efl->l_pid = tswapl(fl.l_pid);
+ target_efl->l_pid = tswap32(fl.l_pid);
unlock_user_struct(target_efl, arg3, 1);
} else
#endif
@@ -6630,7 +6655,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
target_fl->l_whence = tswap16(fl.l_whence);
target_fl->l_start = tswap64(fl.l_start);
target_fl->l_len = tswap64(fl.l_len);
- target_fl->l_pid = tswapl(fl.l_pid);
+ target_fl->l_pid = tswap32(fl.l_pid);
unlock_user_struct(target_fl, arg3, 1);
}
}
@@ -6646,7 +6671,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
fl.l_whence = tswap16(target_efl->l_whence);
fl.l_start = tswap64(target_efl->l_start);
fl.l_len = tswap64(target_efl->l_len);
- fl.l_pid = tswapl(target_efl->l_pid);
+ fl.l_pid = tswap32(target_efl->l_pid);
unlock_user_struct(target_efl, arg3, 0);
} else
#endif
@@ -6657,7 +6682,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
fl.l_whence = tswap16(target_fl->l_whence);
fl.l_start = tswap64(target_fl->l_start);
fl.l_len = tswap64(target_fl->l_len);
- fl.l_pid = tswapl(target_fl->l_pid);
+ fl.l_pid = tswap32(target_fl->l_pid);
unlock_user_struct(target_fl, arg3, 0);
}
ret = get_errno(fcntl(arg1, cmd, &fl));
@@ -6859,7 +6884,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
break;
#endif
-#ifdef TARGET_NR_mq_open
+#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
case TARGET_NR_mq_open:
{
struct mq_attr posix_mq_attr;
@@ -6974,6 +6999,18 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
break;
#endif
#endif /* CONFIG_SPLICE */
+#ifdef CONFIG_EVENTFD
+#if defined(TARGET_NR_eventfd)
+ case TARGET_NR_eventfd:
+ ret = get_errno(eventfd(arg1, 0));
+ break;
+#endif
+#if defined(TARGET_NR_eventfd2)
+ case TARGET_NR_eventfd2:
+ ret = get_errno(eventfd(arg1, arg2));
+ break;
+#endif
+#endif /* CONFIG_EVENTFD */
default:
unimplemented:
gemu_log("qemu: Unsupported syscall: %d\n", num);