#include "uname.h"
#include "qemu.h"
+#include "user-internals.h"
#include "strace.h"
#include "signal-common.h"
+#include "loader.h"
+#include "user-mmap.h"
+#include "user/safe-syscall.h"
#include "qemu/guest-random.h"
#include "qemu/selfmap.h"
#include "user/syscall-trace.h"
+#include "special-errno.h"
#include "qapi/error.h"
#include "fd-trans.h"
#include "tcg/tcg.h"
//#define DEBUG_ERESTARTSYS
//#include <linux/msdos_fs.h>
-#define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct linux_dirent [2])
-#define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct linux_dirent [2])
+#define VFAT_IOCTL_READDIR_BOTH \
+ _IOC(_IOC_READ, 'r', 1, (sizeof(struct linux_dirent) + 256) * 2)
+#define VFAT_IOCTL_READDIR_SHORT \
+ _IOC(_IOC_READ, 'r', 2, (sizeof(struct linux_dirent) + 256) * 2)
#undef _syscall0
#undef _syscall1
#if defined(__NR_futex_time64)
# define __NR_sys_futex_time64 __NR_futex_time64
#endif
-#define __NR_sys_inotify_init __NR_inotify_init
-#define __NR_sys_inotify_add_watch __NR_inotify_add_watch
-#define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
#define __NR_sys_statx __NR_statx
#if defined(__alpha__) || defined(__x86_64__) || defined(__s390x__)
#define __NR_sys_sched_setaffinity __NR_sched_setaffinity
_syscall3(int, sys_sched_setaffinity, pid_t, pid, unsigned int, len,
unsigned long *, user_mask_ptr);
+/* sched_attr is not defined in glibc */
+struct sched_attr {
+ uint32_t size;
+ uint32_t sched_policy;
+ uint64_t sched_flags;
+ int32_t sched_nice;
+ uint32_t sched_priority;
+ uint64_t sched_runtime;
+ uint64_t sched_deadline;
+ uint64_t sched_period;
+ uint32_t sched_util_min;
+ uint32_t sched_util_max;
+};
+#define __NR_sys_sched_getattr __NR_sched_getattr
+_syscall4(int, sys_sched_getattr, pid_t, pid, struct sched_attr *, attr,
+ unsigned int, size, unsigned int, flags);
+#define __NR_sys_sched_setattr __NR_sched_setattr
+_syscall3(int, sys_sched_setattr, pid_t, pid, struct sched_attr *, attr,
+ unsigned int, flags);
+#define __NR_sys_sched_getscheduler __NR_sched_getscheduler
+_syscall1(int, sys_sched_getscheduler, pid_t, pid);
+#define __NR_sys_sched_setscheduler __NR_sched_setscheduler
+_syscall3(int, sys_sched_setscheduler, pid_t, pid, int, policy,
+ const struct sched_param *, param);
+#define __NR_sys_sched_getparam __NR_sched_getparam
+_syscall2(int, sys_sched_getparam, pid_t, pid,
+ struct sched_param *, param);
+#define __NR_sys_sched_setparam __NR_sched_setparam
+_syscall2(int, sys_sched_setparam, pid_t, pid,
+ const struct sched_param *, param);
#define __NR_sys_getcpu __NR_getcpu
_syscall3(int, sys_getcpu, unsigned *, cpu, unsigned *, node, void *, tcache);
_syscall4(int, reboot, int, magic1, int, magic2, unsigned int, cmd,
#ifdef CONFIG_INOTIFY
#include <sys/inotify.h>
-
-#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
-static int sys_inotify_init(void)
-{
- return (inotify_init());
-}
-#endif
-#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
-static int sys_inotify_add_watch(int fd,const char *pathname, int32_t mask)
-{
- return (inotify_add_watch(fd, pathname, mask));
-}
-#endif
-#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
-static int sys_inotify_rm_watch(int fd, int32_t wd)
-{
- return (inotify_rm_watch(fd, wd));
-}
-#endif
-#ifdef CONFIG_INOTIFY1
-#if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
-static int sys_inotify_init1(int flags)
-{
- return (inotify_init1(flags));
-}
-#endif
-#endif
#else
/* Userspace can usually survive runtime without inotify */
#undef TARGET_NR_inotify_init
const char *target_strerror(int err)
{
- if (err == TARGET_ERESTARTSYS) {
+ if (err == QEMU_ERESTARTSYS) {
return "To be restarted";
}
- if (err == TARGET_QEMU_ESIGRETURN) {
+ if (err == QEMU_ESIGRETURN) {
return "Successful exit from sigreturn";
}
return strerror(target_to_host_errno(err));
}
+static int check_zeroed_user(abi_long addr, size_t ksize, size_t usize)
+{
+ int i;
+ uint8_t b;
+ if (usize <= ksize) {
+ return 1;
+ }
+ for (i = ksize; i < usize; i++) {
+ if (get_user_u8(b, addr + i)) {
+ return -TARGET_EFAULT;
+ }
+ if (b != 0) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
#define safe_syscall0(type, name) \
static type safe_##name(void) \
{ \
return RLIMIT_RSS;
case TARGET_RLIMIT_RTPRIO:
return RLIMIT_RTPRIO;
+ case TARGET_RLIMIT_RTTIME:
+ return RLIMIT_RTTIME;
case TARGET_RLIMIT_SIGPENDING:
return RLIMIT_SIGPENDING;
case TARGET_RLIMIT_STACK:
return -TARGET_EINVAL;
ip_mreq_source = lock_user(VERIFY_READ, optval_addr, optlen, 1);
+ if (!ip_mreq_source) {
+ return -TARGET_EFAULT;
+ }
ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq_source, optlen));
unlock_user (ip_mreq_source, optval_addr, 0);
break;
* We can't fit all the extents into the fixed size buffer.
* Allocate one that is large enough and use it instead.
*/
- host_ifconf = malloc(outbufsz);
+ host_ifconf = g_try_malloc(outbufsz);
if (!host_ifconf) {
return -TARGET_ENOMEM;
}
}
if (free_buf) {
- free(host_ifconf);
+ g_free(host_ifconf);
}
return ret;
return ret;
}
#endif /* defined(TARGET_ABI32 */
-
#endif /* defined(TARGET_I386) */
+/*
+ * These constants are generic. Supply any that are missing from the host.
+ */
+#ifndef PR_SET_NAME
+# define PR_SET_NAME 15
+# define PR_GET_NAME 16
+#endif
+#ifndef PR_SET_FP_MODE
+# define PR_SET_FP_MODE 45
+# define PR_GET_FP_MODE 46
+# define PR_FP_MODE_FR (1 << 0)
+# define PR_FP_MODE_FRE (1 << 1)
+#endif
+#ifndef PR_SVE_SET_VL
+# define PR_SVE_SET_VL 50
+# define PR_SVE_GET_VL 51
+# define PR_SVE_VL_LEN_MASK 0xffff
+# define PR_SVE_VL_INHERIT (1 << 17)
+#endif
+#ifndef PR_PAC_RESET_KEYS
+# define PR_PAC_RESET_KEYS 54
+# define PR_PAC_APIAKEY (1 << 0)
+# define PR_PAC_APIBKEY (1 << 1)
+# define PR_PAC_APDAKEY (1 << 2)
+# define PR_PAC_APDBKEY (1 << 3)
+# define PR_PAC_APGAKEY (1 << 4)
+#endif
+#ifndef PR_SET_TAGGED_ADDR_CTRL
+# define PR_SET_TAGGED_ADDR_CTRL 55
+# define PR_GET_TAGGED_ADDR_CTRL 56
+# define PR_TAGGED_ADDR_ENABLE (1UL << 0)
+#endif
+#ifndef PR_MTE_TCF_SHIFT
+# define PR_MTE_TCF_SHIFT 1
+# define PR_MTE_TCF_NONE (0UL << PR_MTE_TCF_SHIFT)
+# define PR_MTE_TCF_SYNC (1UL << PR_MTE_TCF_SHIFT)
+# define PR_MTE_TCF_ASYNC (2UL << PR_MTE_TCF_SHIFT)
+# define PR_MTE_TCF_MASK (3UL << PR_MTE_TCF_SHIFT)
+# define PR_MTE_TAG_SHIFT 3
+# define PR_MTE_TAG_MASK (0xffffUL << PR_MTE_TAG_SHIFT)
+#endif
+#ifndef PR_SET_IO_FLUSHER
+# define PR_SET_IO_FLUSHER 57
+# define PR_GET_IO_FLUSHER 58
+#endif
+#ifndef PR_SET_SYSCALL_USER_DISPATCH
+# define PR_SET_SYSCALL_USER_DISPATCH 59
+#endif
+
+#include "target_prctl.h"
+
+static abi_long do_prctl_inval0(CPUArchState *env)
+{
+ return -TARGET_EINVAL;
+}
+
+static abi_long do_prctl_inval1(CPUArchState *env, abi_long arg2)
+{
+ return -TARGET_EINVAL;
+}
+
+#ifndef do_prctl_get_fp_mode
+#define do_prctl_get_fp_mode do_prctl_inval0
+#endif
+#ifndef do_prctl_set_fp_mode
+#define do_prctl_set_fp_mode do_prctl_inval1
+#endif
+#ifndef do_prctl_get_vl
+#define do_prctl_get_vl do_prctl_inval0
+#endif
+#ifndef do_prctl_set_vl
+#define do_prctl_set_vl do_prctl_inval1
+#endif
+#ifndef do_prctl_reset_keys
+#define do_prctl_reset_keys do_prctl_inval1
+#endif
+#ifndef do_prctl_set_tagged_addr_ctrl
+#define do_prctl_set_tagged_addr_ctrl do_prctl_inval1
+#endif
+#ifndef do_prctl_get_tagged_addr_ctrl
+#define do_prctl_get_tagged_addr_ctrl do_prctl_inval0
+#endif
+#ifndef do_prctl_get_unalign
+#define do_prctl_get_unalign do_prctl_inval1
+#endif
+#ifndef do_prctl_set_unalign
+#define do_prctl_set_unalign do_prctl_inval1
+#endif
+
+static abi_long do_prctl(CPUArchState *env, abi_long option, abi_long arg2,
+ abi_long arg3, abi_long arg4, abi_long arg5)
+{
+ abi_long ret;
+
+ switch (option) {
+ case PR_GET_PDEATHSIG:
+ {
+ int deathsig;
+ ret = get_errno(prctl(PR_GET_PDEATHSIG, &deathsig,
+ arg3, arg4, arg5));
+ if (!is_error(ret) &&
+ put_user_s32(host_to_target_signal(deathsig), arg2)) {
+ return -TARGET_EFAULT;
+ }
+ return ret;
+ }
+ case PR_SET_PDEATHSIG:
+ return get_errno(prctl(PR_SET_PDEATHSIG, target_to_host_signal(arg2),
+ arg3, arg4, arg5));
+ case PR_GET_NAME:
+ {
+ void *name = lock_user(VERIFY_WRITE, arg2, 16, 1);
+ if (!name) {
+ return -TARGET_EFAULT;
+ }
+ ret = get_errno(prctl(PR_GET_NAME, (uintptr_t)name,
+ arg3, arg4, arg5));
+ unlock_user(name, arg2, 16);
+ return ret;
+ }
+ case PR_SET_NAME:
+ {
+ void *name = lock_user(VERIFY_READ, arg2, 16, 1);
+ if (!name) {
+ return -TARGET_EFAULT;
+ }
+ ret = get_errno(prctl(PR_SET_NAME, (uintptr_t)name,
+ arg3, arg4, arg5));
+ unlock_user(name, arg2, 0);
+ return ret;
+ }
+ case PR_GET_FP_MODE:
+ return do_prctl_get_fp_mode(env);
+ case PR_SET_FP_MODE:
+ return do_prctl_set_fp_mode(env, arg2);
+ case PR_SVE_GET_VL:
+ return do_prctl_get_vl(env);
+ case PR_SVE_SET_VL:
+ return do_prctl_set_vl(env, arg2);
+ case PR_PAC_RESET_KEYS:
+ if (arg3 || arg4 || arg5) {
+ return -TARGET_EINVAL;
+ }
+ return do_prctl_reset_keys(env, arg2);
+ case PR_SET_TAGGED_ADDR_CTRL:
+ if (arg3 || arg4 || arg5) {
+ return -TARGET_EINVAL;
+ }
+ return do_prctl_set_tagged_addr_ctrl(env, arg2);
+ case PR_GET_TAGGED_ADDR_CTRL:
+ if (arg2 || arg3 || arg4 || arg5) {
+ return -TARGET_EINVAL;
+ }
+ return do_prctl_get_tagged_addr_ctrl(env);
+
+ case PR_GET_UNALIGN:
+ return do_prctl_get_unalign(env, arg2);
+ case PR_SET_UNALIGN:
+ return do_prctl_set_unalign(env, arg2);
+
+ case PR_CAP_AMBIENT:
+ case PR_CAPBSET_READ:
+ case PR_CAPBSET_DROP:
+ case PR_GET_DUMPABLE:
+ case PR_SET_DUMPABLE:
+ case PR_GET_KEEPCAPS:
+ case PR_SET_KEEPCAPS:
+ case PR_GET_SECUREBITS:
+ case PR_SET_SECUREBITS:
+ case PR_GET_TIMING:
+ case PR_SET_TIMING:
+ case PR_GET_TIMERSLACK:
+ case PR_SET_TIMERSLACK:
+ case PR_MCE_KILL:
+ case PR_MCE_KILL_GET:
+ case PR_GET_NO_NEW_PRIVS:
+ case PR_SET_NO_NEW_PRIVS:
+ case PR_GET_IO_FLUSHER:
+ case PR_SET_IO_FLUSHER:
+ /* Some prctl options have no pointer arguments and we can pass on. */
+ return get_errno(prctl(option, arg2, arg3, arg4, arg5));
+
+ case PR_GET_CHILD_SUBREAPER:
+ case PR_SET_CHILD_SUBREAPER:
+ case PR_GET_SPECULATION_CTRL:
+ case PR_SET_SPECULATION_CTRL:
+ case PR_GET_TID_ADDRESS:
+ /* TODO */
+ return -TARGET_EINVAL;
+
+ case PR_GET_FPEXC:
+ case PR_SET_FPEXC:
+ /* Was used for SPE on PowerPC. */
+ return -TARGET_EINVAL;
+
+ case PR_GET_ENDIAN:
+ case PR_SET_ENDIAN:
+ case PR_GET_FPEMU:
+ case PR_SET_FPEMU:
+ case PR_SET_MM:
+ case PR_GET_SECCOMP:
+ case PR_SET_SECCOMP:
+ case PR_SET_SYSCALL_USER_DISPATCH:
+ case PR_GET_THP_DISABLE:
+ case PR_SET_THP_DISABLE:
+ case PR_GET_TSC:
+ case PR_SET_TSC:
+ /* Disable to prevent the target disabling stuff we need. */
+ return -TARGET_EINVAL;
+
+ default:
+ qemu_log_mask(LOG_UNIMP, "Unsupported prctl: " TARGET_ABI_FMT_ld "\n",
+ option);
+ return -TARGET_EINVAL;
+ }
+}
+
#define NEW_STACK_SIZE 0x40000
}
if (block_signals()) {
- return -TARGET_ERESTARTSYS;
+ return -QEMU_ERESTARTSYS;
}
fork_start();
typedef abi_long to_flock64_fn(abi_ulong target_addr, const struct flock64 *fl);
#if defined(TARGET_ARM) && TARGET_ABI_BITS == 32
+struct target_oabi_flock64 {
+ abi_short l_type;
+ abi_short l_whence;
+ abi_llong l_start;
+ abi_llong l_len;
+ abi_int l_pid;
+} QEMU_PACKED;
+
static inline abi_long copy_from_user_oabi_flock64(struct flock64 *fl,
abi_ulong target_flock_addr)
{
(flags & PAGE_READ) ? 'r' : '-',
(flags & PAGE_WRITE_ORG) ? 'w' : '-',
(flags & PAGE_EXEC) ? 'x' : '-',
- e->is_priv ? 'p' : '-',
+ e->is_priv ? 'p' : 's',
(uint64_t) e->offset, e->dev, e->inode);
if (path) {
dprintf(fd, "%*s%s\n", 73 - count, "", path);
} else if (i == 3) {
/* ppid */
g_string_printf(buf, FMT_pid " ", getppid());
+ } else if (i == 21) {
+ /* starttime */
+ g_string_printf(buf, "%" PRIu64 " ", ts->start_boottime);
} else if (i == 27) {
/* stack bottom */
g_string_printf(buf, TARGET_ABI_FMT_ld " ", ts->info->start_stack);
return 0;
}
+#ifdef TARGET_NR_getdents
+static int do_getdents(abi_long dirfd, abi_long arg2, abi_long count)
+{
+ g_autofree void *hdirp = NULL;
+ void *tdirp;
+ int hlen, hoff, toff;
+ int hreclen, treclen;
+ off64_t prev_diroff = 0;
+
+ hdirp = g_try_malloc(count);
+ if (!hdirp) {
+ return -TARGET_ENOMEM;
+ }
+
+#ifdef EMULATE_GETDENTS_WITH_GETDENTS
+ hlen = sys_getdents(dirfd, hdirp, count);
+#else
+ hlen = sys_getdents64(dirfd, hdirp, count);
+#endif
+
+ hlen = get_errno(hlen);
+ if (is_error(hlen)) {
+ return hlen;
+ }
+
+ tdirp = lock_user(VERIFY_WRITE, arg2, count, 0);
+ if (!tdirp) {
+ return -TARGET_EFAULT;
+ }
+
+ for (hoff = toff = 0; hoff < hlen; hoff += hreclen, toff += treclen) {
+#ifdef EMULATE_GETDENTS_WITH_GETDENTS
+ struct linux_dirent *hde = hdirp + hoff;
+#else
+ struct linux_dirent64 *hde = hdirp + hoff;
+#endif
+ struct target_dirent *tde = tdirp + toff;
+ int namelen;
+ uint8_t type;
+
+ namelen = strlen(hde->d_name);
+ hreclen = hde->d_reclen;
+ treclen = offsetof(struct target_dirent, d_name) + namelen + 2;
+ treclen = QEMU_ALIGN_UP(treclen, __alignof(struct target_dirent));
+
+ if (toff + treclen > count) {
+ /*
+ * If the host struct is smaller than the target struct, or
+ * requires less alignment and thus packs into less space,
+ * then the host can return more entries than we can pass
+ * on to the guest.
+ */
+ if (toff == 0) {
+ toff = -TARGET_EINVAL; /* result buffer is too small */
+ break;
+ }
+ /*
+ * Return what we have, resetting the file pointer to the
+ * location of the first record not returned.
+ */
+ lseek64(dirfd, prev_diroff, SEEK_SET);
+ break;
+ }
+
+ prev_diroff = hde->d_off;
+ tde->d_ino = tswapal(hde->d_ino);
+ tde->d_off = tswapal(hde->d_off);
+ tde->d_reclen = tswap16(treclen);
+ memcpy(tde->d_name, hde->d_name, namelen + 1);
+
+ /*
+ * The getdents type is in what was formerly a padding byte at the
+ * end of the structure.
+ */
+#ifdef EMULATE_GETDENTS_WITH_GETDENTS
+ type = *((uint8_t *)hde + hreclen - 1);
+#else
+ type = hde->d_type;
+#endif
+ *((uint8_t *)tde + treclen - 1) = type;
+ }
+
+ unlock_user(tdirp, arg2, toff);
+ return toff;
+}
+#endif /* TARGET_NR_getdents */
+
+#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
+static int do_getdents64(abi_long dirfd, abi_long arg2, abi_long count)
+{
+ g_autofree void *hdirp = NULL;
+ void *tdirp;
+ int hlen, hoff, toff;
+ int hreclen, treclen;
+ off64_t prev_diroff = 0;
+
+ hdirp = g_try_malloc(count);
+ if (!hdirp) {
+ return -TARGET_ENOMEM;
+ }
+
+ hlen = get_errno(sys_getdents64(dirfd, hdirp, count));
+ if (is_error(hlen)) {
+ return hlen;
+ }
+
+ tdirp = lock_user(VERIFY_WRITE, arg2, count, 0);
+ if (!tdirp) {
+ return -TARGET_EFAULT;
+ }
+
+ for (hoff = toff = 0; hoff < hlen; hoff += hreclen, toff += treclen) {
+ struct linux_dirent64 *hde = hdirp + hoff;
+ struct target_dirent64 *tde = tdirp + toff;
+ int namelen;
+
+ namelen = strlen(hde->d_name) + 1;
+ hreclen = hde->d_reclen;
+ treclen = offsetof(struct target_dirent64, d_name) + namelen;
+ treclen = QEMU_ALIGN_UP(treclen, __alignof(struct target_dirent64));
+
+ if (toff + treclen > count) {
+ /*
+ * If the host struct is smaller than the target struct, or
+ * requires less alignment and thus packs into less space,
+ * then the host can return more entries than we can pass
+ * on to the guest.
+ */
+ if (toff == 0) {
+ toff = -TARGET_EINVAL; /* result buffer is too small */
+ break;
+ }
+ /*
+ * Return what we have, resetting the file pointer to the
+ * location of the first record not returned.
+ */
+ lseek64(dirfd, prev_diroff, SEEK_SET);
+ break;
+ }
+
+ prev_diroff = hde->d_off;
+ tde->d_ino = tswap64(hde->d_ino);
+ tde->d_off = tswap64(hde->d_off);
+ tde->d_reclen = tswap16(treclen);
+ tde->d_type = hde->d_type;
+ memcpy(tde->d_name, hde->d_name, namelen);
+ }
+
+ unlock_user(tdirp, arg2, toff);
+ return toff;
+}
+#endif /* TARGET_NR_getdents64 */
+
#if defined(TARGET_NR_pivot_root) && defined(__NR_pivot_root)
_syscall2(int, pivot_root, const char *, new_root, const char *, put_old)
#endif
Do thread termination if we have more then one thread. */
if (block_signals()) {
- return -TARGET_ERESTARTSYS;
+ return -QEMU_ERESTARTSYS;
}
pthread_mutex_lock(&clone_lock);
int how;
if (arg2) {
+ p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1);
+ if (!p) {
+ return -TARGET_EFAULT;
+ }
+ target_to_host_old_sigset(&set, p);
+ unlock_user(p, arg2, 0);
+ set_ptr = &set;
switch (arg1) {
case TARGET_SIG_BLOCK:
how = SIG_BLOCK;
default:
return -TARGET_EINVAL;
}
- if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
- return -TARGET_EFAULT;
- target_to_host_old_sigset(&set, p);
- unlock_user(p, arg2, 0);
- set_ptr = &set;
} else {
how = 0;
set_ptr = NULL;
}
if (arg2) {
+ p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1);
+ if (!p) {
+ return -TARGET_EFAULT;
+ }
+ target_to_host_sigset(&set, p);
+ unlock_user(p, arg2, 0);
+ set_ptr = &set;
switch(how) {
case TARGET_SIG_BLOCK:
how = SIG_BLOCK;
default:
return -TARGET_EINVAL;
}
- if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
- return -TARGET_EFAULT;
- target_to_host_sigset(&set, p);
- unlock_user(p, arg2, 0);
- set_ptr = &set;
} else {
how = 0;
set_ptr = NULL;
#endif
ret = get_errno(safe_rt_sigsuspend(&ts->sigsuspend_mask,
SIGSET_T_SIZE));
- if (ret != -TARGET_ERESTARTSYS) {
+ if (ret != -QEMU_ERESTARTSYS) {
ts->in_sigsuspend = 1;
}
}
unlock_user(p, arg1, 0);
ret = get_errno(safe_rt_sigsuspend(&ts->sigsuspend_mask,
SIGSET_T_SIZE));
- if (ret != -TARGET_ERESTARTSYS) {
+ if (ret != -QEMU_ERESTARTSYS) {
ts->in_sigsuspend = 1;
}
}
#ifdef TARGET_NR_sigreturn
case TARGET_NR_sigreturn:
if (block_signals()) {
- return -TARGET_ERESTARTSYS;
+ return -QEMU_ERESTARTSYS;
}
return do_sigreturn(cpu_env);
#endif
case TARGET_NR_rt_sigreturn:
if (block_signals()) {
- return -TARGET_ERESTARTSYS;
+ return -QEMU_ERESTARTSYS;
}
return do_rt_sigreturn(cpu_env);
case TARGET_NR_sethostname:
#endif
#ifdef TARGET_NR_getdents
case TARGET_NR_getdents:
-#ifdef EMULATE_GETDENTS_WITH_GETDENTS
-#if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
- {
- struct target_dirent *target_dirp;
- struct linux_dirent *dirp;
- abi_long count = arg3;
-
- dirp = g_try_malloc(count);
- if (!dirp) {
- return -TARGET_ENOMEM;
- }
-
- ret = get_errno(sys_getdents(arg1, dirp, count));
- if (!is_error(ret)) {
- struct linux_dirent *de;
- struct target_dirent *tde;
- int len = ret;
- int reclen, treclen;
- int count1, tnamelen;
-
- count1 = 0;
- de = dirp;
- if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
- return -TARGET_EFAULT;
- tde = target_dirp;
- while (len > 0) {
- reclen = de->d_reclen;
- tnamelen = reclen - offsetof(struct linux_dirent, d_name);
- assert(tnamelen >= 0);
- treclen = tnamelen + offsetof(struct target_dirent, d_name);
- assert(count1 + treclen <= count);
- tde->d_reclen = tswap16(treclen);
- tde->d_ino = tswapal(de->d_ino);
- tde->d_off = tswapal(de->d_off);
- memcpy(tde->d_name, de->d_name, tnamelen);
- de = (struct linux_dirent *)((char *)de + reclen);
- len -= reclen;
- tde = (struct target_dirent *)((char *)tde + treclen);
- count1 += treclen;
- }
- ret = count1;
- unlock_user(target_dirp, arg2, ret);
- }
- g_free(dirp);
- }
-#else
- {
- struct linux_dirent *dirp;
- abi_long count = arg3;
-
- if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
- return -TARGET_EFAULT;
- ret = get_errno(sys_getdents(arg1, dirp, count));
- if (!is_error(ret)) {
- struct linux_dirent *de;
- int len = ret;
- int reclen;
- de = dirp;
- while (len > 0) {
- reclen = de->d_reclen;
- if (reclen > len)
- break;
- de->d_reclen = tswap16(reclen);
- tswapls(&de->d_ino);
- tswapls(&de->d_off);
- de = (struct linux_dirent *)((char *)de + reclen);
- len -= reclen;
- }
- }
- unlock_user(dirp, arg2, ret);
- }
-#endif
-#else
- /* Implement getdents in terms of getdents64 */
- {
- struct linux_dirent64 *dirp;
- abi_long count = arg3;
-
- dirp = lock_user(VERIFY_WRITE, arg2, count, 0);
- if (!dirp) {
- return -TARGET_EFAULT;
- }
- ret = get_errno(sys_getdents64(arg1, dirp, count));
- if (!is_error(ret)) {
- /* Convert the dirent64 structs to target dirent. We do this
- * in-place, since we can guarantee that a target_dirent is no
- * larger than a dirent64; however this means we have to be
- * careful to read everything before writing in the new format.
- */
- struct linux_dirent64 *de;
- struct target_dirent *tde;
- int len = ret;
- int tlen = 0;
-
- de = dirp;
- tde = (struct target_dirent *)dirp;
- while (len > 0) {
- int namelen, treclen;
- int reclen = de->d_reclen;
- uint64_t ino = de->d_ino;
- int64_t off = de->d_off;
- uint8_t type = de->d_type;
-
- namelen = strlen(de->d_name);
- treclen = offsetof(struct target_dirent, d_name)
- + namelen + 2;
- treclen = QEMU_ALIGN_UP(treclen, sizeof(abi_long));
-
- memmove(tde->d_name, de->d_name, namelen + 1);
- tde->d_ino = tswapal(ino);
- tde->d_off = tswapal(off);
- tde->d_reclen = tswap16(treclen);
- /* The target_dirent type is in what was formerly a padding
- * byte at the end of the structure:
- */
- *(((char *)tde) + treclen - 1) = type;
-
- de = (struct linux_dirent64 *)((char *)de + reclen);
- tde = (struct target_dirent *)((char *)tde + treclen);
- len -= reclen;
- tlen += treclen;
- }
- ret = tlen;
- }
- unlock_user(dirp, arg2, ret);
- }
-#endif
- return ret;
+ return do_getdents(arg1, arg2, arg3);
#endif /* TARGET_NR_getdents */
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
case TARGET_NR_getdents64:
- {
- struct linux_dirent64 *dirp;
- abi_long count = arg3;
- if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
- return -TARGET_EFAULT;
- ret = get_errno(sys_getdents64(arg1, dirp, count));
- if (!is_error(ret)) {
- struct linux_dirent64 *de;
- int len = ret;
- int reclen;
- de = dirp;
- while (len > 0) {
- reclen = de->d_reclen;
- if (reclen > len)
- break;
- de->d_reclen = tswap16(reclen);
- tswap64s((uint64_t *)&de->d_ino);
- tswap64s((uint64_t *)&de->d_off);
- de = (struct linux_dirent64 *)((char *)de + reclen);
- len -= reclen;
- }
- }
- unlock_user(dirp, arg2, ret);
- }
- return ret;
+ return do_getdents64(arg1, arg2, arg3);
#endif /* TARGET_NR_getdents64 */
#if defined(TARGET_NR__newselect)
case TARGET_NR__newselect:
return ret;
case TARGET_NR_sched_setparam:
{
- struct sched_param *target_schp;
+ struct target_sched_param *target_schp;
struct sched_param schp;
if (arg2 == 0) {
return -TARGET_EINVAL;
}
- if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
+ if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1)) {
return -TARGET_EFAULT;
+ }
schp.sched_priority = tswap32(target_schp->sched_priority);
unlock_user_struct(target_schp, arg2, 0);
- return get_errno(sched_setparam(arg1, &schp));
+ return get_errno(sys_sched_setparam(arg1, &schp));
}
case TARGET_NR_sched_getparam:
{
- struct sched_param *target_schp;
+ struct target_sched_param *target_schp;
struct sched_param schp;
if (arg2 == 0) {
return -TARGET_EINVAL;
}
- ret = get_errno(sched_getparam(arg1, &schp));
+ ret = get_errno(sys_sched_getparam(arg1, &schp));
if (!is_error(ret)) {
- if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
+ if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0)) {
return -TARGET_EFAULT;
+ }
target_schp->sched_priority = tswap32(schp.sched_priority);
unlock_user_struct(target_schp, arg2, 1);
}
return ret;
case TARGET_NR_sched_setscheduler:
{
- struct sched_param *target_schp;
+ struct target_sched_param *target_schp;
struct sched_param schp;
if (arg3 == 0) {
return -TARGET_EINVAL;
}
- if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
+ if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1)) {
return -TARGET_EFAULT;
+ }
schp.sched_priority = tswap32(target_schp->sched_priority);
unlock_user_struct(target_schp, arg3, 0);
- return get_errno(sched_setscheduler(arg1, arg2, &schp));
+ return get_errno(sys_sched_setscheduler(arg1, arg2, &schp));
}
case TARGET_NR_sched_getscheduler:
- return get_errno(sched_getscheduler(arg1));
+ return get_errno(sys_sched_getscheduler(arg1));
+ case TARGET_NR_sched_getattr:
+ {
+ struct target_sched_attr *target_scha;
+ struct sched_attr scha;
+ if (arg2 == 0) {
+ return -TARGET_EINVAL;
+ }
+ if (arg3 > sizeof(scha)) {
+ arg3 = sizeof(scha);
+ }
+ ret = get_errno(sys_sched_getattr(arg1, &scha, arg3, arg4));
+ if (!is_error(ret)) {
+ target_scha = lock_user(VERIFY_WRITE, arg2, arg3, 0);
+ if (!target_scha) {
+ return -TARGET_EFAULT;
+ }
+ target_scha->size = tswap32(scha.size);
+ target_scha->sched_policy = tswap32(scha.sched_policy);
+ target_scha->sched_flags = tswap64(scha.sched_flags);
+ target_scha->sched_nice = tswap32(scha.sched_nice);
+ target_scha->sched_priority = tswap32(scha.sched_priority);
+ target_scha->sched_runtime = tswap64(scha.sched_runtime);
+ target_scha->sched_deadline = tswap64(scha.sched_deadline);
+ target_scha->sched_period = tswap64(scha.sched_period);
+ if (scha.size > offsetof(struct sched_attr, sched_util_min)) {
+ target_scha->sched_util_min = tswap32(scha.sched_util_min);
+ target_scha->sched_util_max = tswap32(scha.sched_util_max);
+ }
+ unlock_user(target_scha, arg2, arg3);
+ }
+ return ret;
+ }
+ case TARGET_NR_sched_setattr:
+ {
+ struct target_sched_attr *target_scha;
+ struct sched_attr scha;
+ uint32_t size;
+ int zeroed;
+ if (arg2 == 0) {
+ return -TARGET_EINVAL;
+ }
+ if (get_user_u32(size, arg2)) {
+ return -TARGET_EFAULT;
+ }
+ if (!size) {
+ size = offsetof(struct target_sched_attr, sched_util_min);
+ }
+ if (size < offsetof(struct target_sched_attr, sched_util_min)) {
+ if (put_user_u32(sizeof(struct target_sched_attr), arg2)) {
+ return -TARGET_EFAULT;
+ }
+ return -TARGET_E2BIG;
+ }
+
+ zeroed = check_zeroed_user(arg2, sizeof(struct target_sched_attr), size);
+ if (zeroed < 0) {
+ return zeroed;
+ } else if (zeroed == 0) {
+ if (put_user_u32(sizeof(struct target_sched_attr), arg2)) {
+ return -TARGET_EFAULT;
+ }
+ return -TARGET_E2BIG;
+ }
+ if (size > sizeof(struct target_sched_attr)) {
+ size = sizeof(struct target_sched_attr);
+ }
+
+ target_scha = lock_user(VERIFY_READ, arg2, size, 1);
+ if (!target_scha) {
+ return -TARGET_EFAULT;
+ }
+ scha.size = size;
+ scha.sched_policy = tswap32(target_scha->sched_policy);
+ scha.sched_flags = tswap64(target_scha->sched_flags);
+ scha.sched_nice = tswap32(target_scha->sched_nice);
+ scha.sched_priority = tswap32(target_scha->sched_priority);
+ scha.sched_runtime = tswap64(target_scha->sched_runtime);
+ scha.sched_deadline = tswap64(target_scha->sched_deadline);
+ scha.sched_period = tswap64(target_scha->sched_period);
+ if (size > offsetof(struct target_sched_attr, sched_util_min)) {
+ scha.sched_util_min = tswap32(target_scha->sched_util_min);
+ scha.sched_util_max = tswap32(target_scha->sched_util_max);
+ }
+ unlock_user(target_scha, arg2, 0);
+ return get_errno(sys_sched_setattr(arg1, &scha, arg3));
+ }
case TARGET_NR_sched_yield:
return get_errno(sched_yield());
case TARGET_NR_sched_get_priority_max:
return ret;
#endif
case TARGET_NR_prctl:
- switch (arg1) {
- case PR_GET_PDEATHSIG:
- {
- int deathsig;
- ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
- if (!is_error(ret) && arg2
- && put_user_s32(deathsig, arg2)) {
- return -TARGET_EFAULT;
- }
- return ret;
- }
-#ifdef PR_GET_NAME
- case PR_GET_NAME:
- {
- void *name = lock_user(VERIFY_WRITE, arg2, 16, 1);
- if (!name) {
- return -TARGET_EFAULT;
- }
- ret = get_errno(prctl(arg1, (unsigned long)name,
- arg3, arg4, arg5));
- unlock_user(name, arg2, 16);
- return ret;
- }
- case PR_SET_NAME:
- {
- void *name = lock_user(VERIFY_READ, arg2, 16, 1);
- if (!name) {
- return -TARGET_EFAULT;
- }
- ret = get_errno(prctl(arg1, (unsigned long)name,
- arg3, arg4, arg5));
- unlock_user(name, arg2, 0);
- return ret;
- }
-#endif
-#ifdef TARGET_MIPS
- case TARGET_PR_GET_FP_MODE:
- {
- CPUMIPSState *env = ((CPUMIPSState *)cpu_env);
- ret = 0;
- if (env->CP0_Status & (1 << CP0St_FR)) {
- ret |= TARGET_PR_FP_MODE_FR;
- }
- if (env->CP0_Config5 & (1 << CP0C5_FRE)) {
- ret |= TARGET_PR_FP_MODE_FRE;
- }
- return ret;
- }
- case TARGET_PR_SET_FP_MODE:
- {
- CPUMIPSState *env = ((CPUMIPSState *)cpu_env);
- bool old_fr = env->CP0_Status & (1 << CP0St_FR);
- bool old_fre = env->CP0_Config5 & (1 << CP0C5_FRE);
- bool new_fr = arg2 & TARGET_PR_FP_MODE_FR;
- bool new_fre = arg2 & TARGET_PR_FP_MODE_FRE;
-
- const unsigned int known_bits = TARGET_PR_FP_MODE_FR |
- TARGET_PR_FP_MODE_FRE;
-
- /* If nothing to change, return right away, successfully. */
- if (old_fr == new_fr && old_fre == new_fre) {
- return 0;
- }
- /* Check the value is valid */
- if (arg2 & ~known_bits) {
- return -TARGET_EOPNOTSUPP;
- }
- /* Setting FRE without FR is not supported. */
- if (new_fre && !new_fr) {
- return -TARGET_EOPNOTSUPP;
- }
- if (new_fr && !(env->active_fpu.fcr0 & (1 << FCR0_F64))) {
- /* FR1 is not supported */
- return -TARGET_EOPNOTSUPP;
- }
- if (!new_fr && (env->active_fpu.fcr0 & (1 << FCR0_F64))
- && !(env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
- /* cannot set FR=0 */
- return -TARGET_EOPNOTSUPP;
- }
- if (new_fre && !(env->active_fpu.fcr0 & (1 << FCR0_FREP))) {
- /* Cannot set FRE=1 */
- return -TARGET_EOPNOTSUPP;
- }
-
- int i;
- fpr_t *fpr = env->active_fpu.fpr;
- for (i = 0; i < 32 ; i += 2) {
- if (!old_fr && new_fr) {
- fpr[i].w[!FP_ENDIAN_IDX] = fpr[i + 1].w[FP_ENDIAN_IDX];
- } else if (old_fr && !new_fr) {
- fpr[i + 1].w[FP_ENDIAN_IDX] = fpr[i].w[!FP_ENDIAN_IDX];
- }
- }
-
- if (new_fr) {
- env->CP0_Status |= (1 << CP0St_FR);
- env->hflags |= MIPS_HFLAG_F64;
- } else {
- env->CP0_Status &= ~(1 << CP0St_FR);
- env->hflags &= ~MIPS_HFLAG_F64;
- }
- if (new_fre) {
- env->CP0_Config5 |= (1 << CP0C5_FRE);
- if (env->active_fpu.fcr0 & (1 << FCR0_FREP)) {
- env->hflags |= MIPS_HFLAG_FRE;
- }
- } else {
- env->CP0_Config5 &= ~(1 << CP0C5_FRE);
- env->hflags &= ~MIPS_HFLAG_FRE;
- }
-
- return 0;
- }
-#endif /* MIPS */
-#ifdef TARGET_AARCH64
- case TARGET_PR_SVE_SET_VL:
- /*
- * We cannot support either PR_SVE_SET_VL_ONEXEC or
- * PR_SVE_VL_INHERIT. Note the kernel definition
- * of sve_vl_valid allows for VQ=512, i.e. VL=8192,
- * even though the current architectural maximum is VQ=16.
- */
- ret = -TARGET_EINVAL;
- if (cpu_isar_feature(aa64_sve, env_archcpu(cpu_env))
- && arg2 >= 0 && arg2 <= 512 * 16 && !(arg2 & 15)) {
- CPUARMState *env = cpu_env;
- ARMCPU *cpu = env_archcpu(env);
- uint32_t vq, old_vq;
-
- old_vq = (env->vfp.zcr_el[1] & 0xf) + 1;
- vq = MAX(arg2 / 16, 1);
- vq = MIN(vq, cpu->sve_max_vq);
-
- if (vq < old_vq) {
- aarch64_sve_narrow_vq(env, vq);
- }
- env->vfp.zcr_el[1] = vq - 1;
- arm_rebuild_hflags(env);
- ret = vq * 16;
- }
- return ret;
- case TARGET_PR_SVE_GET_VL:
- ret = -TARGET_EINVAL;
- {
- ARMCPU *cpu = env_archcpu(cpu_env);
- if (cpu_isar_feature(aa64_sve, cpu)) {
- ret = ((cpu->env.vfp.zcr_el[1] & 0xf) + 1) * 16;
- }
- }
- return ret;
- case TARGET_PR_PAC_RESET_KEYS:
- {
- CPUARMState *env = cpu_env;
- ARMCPU *cpu = env_archcpu(env);
-
- if (arg3 || arg4 || arg5) {
- return -TARGET_EINVAL;
- }
- if (cpu_isar_feature(aa64_pauth, cpu)) {
- int all = (TARGET_PR_PAC_APIAKEY | TARGET_PR_PAC_APIBKEY |
- TARGET_PR_PAC_APDAKEY | TARGET_PR_PAC_APDBKEY |
- TARGET_PR_PAC_APGAKEY);
- int ret = 0;
- Error *err = NULL;
-
- if (arg2 == 0) {
- arg2 = all;
- } else if (arg2 & ~all) {
- return -TARGET_EINVAL;
- }
- if (arg2 & TARGET_PR_PAC_APIAKEY) {
- ret |= qemu_guest_getrandom(&env->keys.apia,
- sizeof(ARMPACKey), &err);
- }
- if (arg2 & TARGET_PR_PAC_APIBKEY) {
- ret |= qemu_guest_getrandom(&env->keys.apib,
- sizeof(ARMPACKey), &err);
- }
- if (arg2 & TARGET_PR_PAC_APDAKEY) {
- ret |= qemu_guest_getrandom(&env->keys.apda,
- sizeof(ARMPACKey), &err);
- }
- if (arg2 & TARGET_PR_PAC_APDBKEY) {
- ret |= qemu_guest_getrandom(&env->keys.apdb,
- sizeof(ARMPACKey), &err);
- }
- if (arg2 & TARGET_PR_PAC_APGAKEY) {
- ret |= qemu_guest_getrandom(&env->keys.apga,
- sizeof(ARMPACKey), &err);
- }
- if (ret != 0) {
- /*
- * Some unknown failure in the crypto. The best
- * we can do is log it and fail the syscall.
- * The real syscall cannot fail this way.
- */
- qemu_log_mask(LOG_UNIMP,
- "PR_PAC_RESET_KEYS: Crypto failure: %s",
- error_get_pretty(err));
- error_free(err);
- return -TARGET_EIO;
- }
- return 0;
- }
- }
- return -TARGET_EINVAL;
- case TARGET_PR_SET_TAGGED_ADDR_CTRL:
- {
- abi_ulong valid_mask = TARGET_PR_TAGGED_ADDR_ENABLE;
- CPUARMState *env = cpu_env;
- ARMCPU *cpu = env_archcpu(env);
-
- if (cpu_isar_feature(aa64_mte, cpu)) {
- valid_mask |= TARGET_PR_MTE_TCF_MASK;
- valid_mask |= TARGET_PR_MTE_TAG_MASK;
- }
-
- if ((arg2 & ~valid_mask) || arg3 || arg4 || arg5) {
- return -TARGET_EINVAL;
- }
- env->tagged_addr_enable = arg2 & TARGET_PR_TAGGED_ADDR_ENABLE;
-
- if (cpu_isar_feature(aa64_mte, cpu)) {
- switch (arg2 & TARGET_PR_MTE_TCF_MASK) {
- case TARGET_PR_MTE_TCF_NONE:
- case TARGET_PR_MTE_TCF_SYNC:
- case TARGET_PR_MTE_TCF_ASYNC:
- break;
- default:
- return -EINVAL;
- }
-
- /*
- * Write PR_MTE_TCF to SCTLR_EL1[TCF0].
- * Note that the syscall values are consistent with hw.
- */
- env->cp15.sctlr_el[1] =
- deposit64(env->cp15.sctlr_el[1], 38, 2,
- arg2 >> TARGET_PR_MTE_TCF_SHIFT);
-
- /*
- * Write PR_MTE_TAG to GCR_EL1[Exclude].
- * Note that the syscall uses an include mask,
- * and hardware uses an exclude mask -- invert.
- */
- env->cp15.gcr_el1 =
- deposit64(env->cp15.gcr_el1, 0, 16,
- ~arg2 >> TARGET_PR_MTE_TAG_SHIFT);
- arm_rebuild_hflags(env);
- }
- return 0;
- }
- case TARGET_PR_GET_TAGGED_ADDR_CTRL:
- {
- abi_long ret = 0;
- CPUARMState *env = cpu_env;
- ARMCPU *cpu = env_archcpu(env);
-
- if (arg2 || arg3 || arg4 || arg5) {
- return -TARGET_EINVAL;
- }
- if (env->tagged_addr_enable) {
- ret |= TARGET_PR_TAGGED_ADDR_ENABLE;
- }
- if (cpu_isar_feature(aa64_mte, cpu)) {
- /* See above. */
- ret |= (extract64(env->cp15.sctlr_el[1], 38, 2)
- << TARGET_PR_MTE_TCF_SHIFT);
- ret = deposit64(ret, TARGET_PR_MTE_TAG_SHIFT, 16,
- ~env->cp15.gcr_el1);
- }
- return ret;
- }
-#endif /* AARCH64 */
- case PR_GET_SECCOMP:
- case PR_SET_SECCOMP:
- /* Disable seccomp to prevent the target disabling syscalls we
- * need. */
- return -TARGET_EINVAL;
- default:
- /* Most prctl options have no pointer arguments */
- return get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
- }
+ return do_prctl(cpu_env, arg1, arg2, arg3, arg4, arg5);
break;
#ifdef TARGET_NR_arch_prctl
case TARGET_NR_arch_prctl:
case TARGET_NR_futex_time64:
return do_futex_time64(cpu, arg1, arg2, arg3, arg4, arg5, arg6);
#endif
-#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
+#ifdef CONFIG_INOTIFY
+#if defined(TARGET_NR_inotify_init)
case TARGET_NR_inotify_init:
- ret = get_errno(sys_inotify_init());
+ ret = get_errno(inotify_init());
if (ret >= 0) {
fd_trans_register(ret, &target_inotify_trans);
}
return ret;
#endif
-#ifdef CONFIG_INOTIFY1
-#if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
+#if defined(TARGET_NR_inotify_init1) && defined(CONFIG_INOTIFY1)
case TARGET_NR_inotify_init1:
- ret = get_errno(sys_inotify_init1(target_to_host_bitmask(arg1,
+ ret = get_errno(inotify_init1(target_to_host_bitmask(arg1,
fcntl_flags_tbl)));
if (ret >= 0) {
fd_trans_register(ret, &target_inotify_trans);
}
return ret;
#endif
-#endif
-#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
+#if defined(TARGET_NR_inotify_add_watch)
case TARGET_NR_inotify_add_watch:
p = lock_user_string(arg2);
- ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
+ ret = get_errno(inotify_add_watch(arg1, path(p), arg3));
unlock_user(p, arg2, 0);
return ret;
#endif
-#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
+#if defined(TARGET_NR_inotify_rm_watch)
case TARGET_NR_inotify_rm_watch:
- return get_errno(sys_inotify_rm_watch(arg1, arg2));
+ return get_errno(inotify_rm_watch(arg1, arg2));
+#endif
#endif
#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
static bool flag;
flag = !flag;
if (flag) {
- return -TARGET_ERESTARTSYS;
+ return -QEMU_ERESTARTSYS;
}
}
#endif