diff options
-rwxr-xr-x | configure | 18 | ||||
-rw-r--r-- | linux-user/mmap.c | 79 | ||||
-rw-r--r-- | linux-user/signal.c | 382 | ||||
-rw-r--r-- | linux-user/syscall.c | 83 | ||||
-rw-r--r-- | linux-user/syscall_defs.h | 7 |
5 files changed, 510 insertions, 59 deletions
@@ -1474,6 +1474,21 @@ if compile_prog "" "" ; then splice=yes fi +# check if eventfd is supported +eventfd=no +cat > $TMPC << EOF +#include <sys/eventfd.h> + +int main(void) +{ + int efd = eventfd(0, 0); + return 0; +} +EOF +if compile_prog "" "" ; then + eventfd=yes +fi + # Check if tools are available to build documentation. if test "$docs" != "no" ; then if test -x "`which texi2html 2>/dev/null`" -a \ @@ -1813,6 +1828,9 @@ fi if test "$splice" = "yes" ; then echo "CONFIG_SPLICE=y" >> $config_host_mak fi +if test "$eventfd" = "yes" ; then + echo "CONFIG_EVENTFD=y" >> $config_host_mak +fi if test "$inotify" = "yes" ; then echo "CONFIG_INOTIFY=y" >> $config_host_mak fi diff --git a/linux-user/mmap.c b/linux-user/mmap.c index 3d2c8b3073..6ce41677af 100644 --- a/linux-user/mmap.c +++ b/linux-user/mmap.c @@ -273,52 +273,59 @@ static abi_ulong mmap_next_start = 0x40000000; unsigned long last_brk; -/* find a free memory area of size 'size'. The search starts at - 'start'. If 'start' == 0, then a default start address is used. - Return -1 if error. -*/ -/* page_init() marks pages used by the host as reserved to be sure not - to use them. */ +/* + * Find and reserve a free memory area of size 'size'. The search + * starts at 'start'. + * It must be called with mmap_lock() held. + * Return -1 if error. + */ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size) { - abi_ulong addr, addr1, addr_start; - int prot; - unsigned long new_brk; - - new_brk = (unsigned long)sbrk(0); - if (last_brk && last_brk < new_brk && last_brk == (target_ulong)last_brk) { - /* This is a hack to catch the host allocating memory with brk(). - If it uses mmap then we loose. - FIXME: We really want to avoid the host allocating memory in - the first place, and maybe leave some slack to avoid switching - to mmap. */ - page_set_flags(last_brk & TARGET_PAGE_MASK, - TARGET_PAGE_ALIGN(new_brk), - PAGE_RESERVED); - } - last_brk = new_brk; + void *ptr; + abi_ulong addr; size = HOST_PAGE_ALIGN(size); - start = start & qemu_host_page_mask; + start &= qemu_host_page_mask; + + /* If 'start' == 0, then a default start address is used. */ + if (start == 0) + start = mmap_next_start; + addr = start; - if (addr == 0) - addr = mmap_next_start; - addr_start = addr; + for(;;) { - prot = 0; - for(addr1 = addr; addr1 < (addr + size); addr1 += TARGET_PAGE_SIZE) { - prot |= page_get_flags(addr1); - } - if (prot == 0) + /* + * Reserve needed memory area to avoid a race. + * It should be discarded using: + * - mmap() with MAP_FIXED flag + * - mremap() with MREMAP_FIXED flag + * - shmat() with SHM_REMAP flag + */ + ptr = mmap((void *)(unsigned long)addr, size, PROT_NONE, + MAP_ANONYMOUS|MAP_PRIVATE|MAP_NORESERVE, -1, 0); + + /* ENOMEM, if host address space has no memory */ + if (ptr == MAP_FAILED) + return (abi_ulong)-1; + + /* If address fits target address space we've found what we need */ + if ((unsigned long)ptr + size - 1 <= (abi_ulong)-1) break; + + /* Unmap and try again with new page */ + munmap(ptr, size); addr += qemu_host_page_size; - /* we found nothing */ - if (addr == addr_start) + + /* ENOMEM if we check whole of target address space */ + if (addr == start) return (abi_ulong)-1; } - if (start == 0) - mmap_next_start = addr + size; - return addr; + + /* Update default start address */ + if (start == mmap_next_start) + mmap_next_start = (unsigned long)ptr + size; + + return h2g(ptr); } /* NOTE: all the constants are the HOST ones */ diff --git a/linux-user/signal.c b/linux-user/signal.c index b2c0623a44..2df17aa21b 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -4028,6 +4028,388 @@ sigsegv: return 0; } +#elif defined(TARGET_M68K) + +struct target_sigcontext { + abi_ulong sc_mask; + abi_ulong sc_usp; + abi_ulong sc_d0; + abi_ulong sc_d1; + abi_ulong sc_a0; + abi_ulong sc_a1; + unsigned short sc_sr; + abi_ulong sc_pc; +}; + +struct target_sigframe +{ + abi_ulong pretcode; + int sig; + int code; + abi_ulong psc; + char retcode[8]; + abi_ulong extramask[TARGET_NSIG_WORDS-1]; + struct target_sigcontext sc; +}; + +typedef int target_greg_t; +#define TARGET_NGREG 18 +typedef target_greg_t target_gregset_t[TARGET_NGREG]; + +typedef struct target_fpregset { + int f_fpcntl[3]; + int f_fpregs[8*3]; +} target_fpregset_t; + +struct target_mcontext { + int version; + target_gregset_t gregs; + target_fpregset_t fpregs; +}; + +#define TARGET_MCONTEXT_VERSION 2 + +struct target_ucontext { + abi_ulong uc_flags; + abi_ulong uc_link; + target_stack_t uc_stack; + struct target_mcontext uc_mcontext; + abi_long uc_filler[80]; + target_sigset_t uc_sigmask; +}; + +struct target_rt_sigframe +{ + abi_ulong pretcode; + int sig; + abi_ulong pinfo; + abi_ulong puc; + char retcode[8]; + struct target_siginfo info; + struct target_ucontext uc; +}; + +static int +setup_sigcontext(struct target_sigcontext *sc, CPUState *env, abi_ulong mask) +{ + int err = 0; + + err |= __put_user(mask, &sc->sc_mask); + err |= __put_user(env->aregs[7], &sc->sc_usp); + err |= __put_user(env->dregs[0], &sc->sc_d0); + err |= __put_user(env->dregs[1], &sc->sc_d1); + err |= __put_user(env->aregs[0], &sc->sc_a0); + err |= __put_user(env->aregs[1], &sc->sc_a1); + err |= __put_user(env->sr, &sc->sc_sr); + err |= __put_user(env->pc, &sc->sc_pc); + + return err; +} + +static int +restore_sigcontext(CPUState *env, struct target_sigcontext *sc, int *pd0) +{ + int err = 0; + int temp; + + err |= __get_user(env->aregs[7], &sc->sc_usp); + err |= __get_user(env->dregs[1], &sc->sc_d1); + err |= __get_user(env->aregs[0], &sc->sc_a0); + err |= __get_user(env->aregs[1], &sc->sc_a1); + err |= __get_user(env->pc, &sc->sc_pc); + err |= __get_user(temp, &sc->sc_sr); + env->sr = (env->sr & 0xff00) | (temp & 0xff); + + *pd0 = tswapl(sc->sc_d0); + + return err; +} + +/* + * Determine which stack to use.. + */ +static inline abi_ulong +get_sigframe(struct target_sigaction *ka, CPUState *regs, size_t frame_size) +{ + unsigned long sp; + + sp = regs->aregs[7]; + + /* This is the X/Open sanctioned signal stack switching. */ + if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) { + sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size; + } + + return ((sp - frame_size) & -8UL); +} + +static void setup_frame(int sig, struct target_sigaction *ka, + target_sigset_t *set, CPUState *env) +{ + struct target_sigframe *frame; + abi_ulong frame_addr; + abi_ulong retcode_addr; + abi_ulong sc_addr; + int err = 0; + int i; + + frame_addr = get_sigframe(ka, env, sizeof *frame); + if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) + goto give_sigsegv; + + err |= __put_user(sig, &frame->sig); + + sc_addr = frame_addr + offsetof(struct target_sigframe, sc); + err |= __put_user(sc_addr, &frame->psc); + + err |= setup_sigcontext(&frame->sc, env, set->sig[0]); + if (err) + goto give_sigsegv; + + for(i = 1; i < TARGET_NSIG_WORDS; i++) { + if (__put_user(set->sig[i], &frame->extramask[i - 1])) + goto give_sigsegv; + } + + /* Set up to return from userspace. */ + + retcode_addr = frame_addr + offsetof(struct target_sigframe, retcode); + err |= __put_user(retcode_addr, &frame->pretcode); + + /* moveq #,d0; trap #0 */ + + err |= __put_user(0x70004e40 + (TARGET_NR_sigreturn << 16), + (long *)(frame->retcode)); + + if (err) + goto give_sigsegv; + + /* Set up to return from userspace */ + + env->aregs[7] = frame_addr; + env->pc = ka->_sa_handler; + + unlock_user_struct(frame, frame_addr, 1); + return; + +give_sigsegv: + unlock_user_struct(frame, frame_addr, 1); + force_sig(SIGSEGV); +} + +static inline int target_rt_setup_ucontext(struct target_ucontext *uc, + CPUState *env) +{ + target_greg_t *gregs = uc->uc_mcontext.gregs; + int err; + + err = __put_user(TARGET_MCONTEXT_VERSION, &uc->uc_mcontext.version); + err |= __put_user(env->dregs[0], &gregs[0]); + err |= __put_user(env->dregs[1], &gregs[1]); + err |= __put_user(env->dregs[2], &gregs[2]); + err |= __put_user(env->dregs[3], &gregs[3]); + err |= __put_user(env->dregs[4], &gregs[4]); + err |= __put_user(env->dregs[5], &gregs[5]); + err |= __put_user(env->dregs[6], &gregs[6]); + err |= __put_user(env->dregs[7], &gregs[7]); + err |= __put_user(env->aregs[0], &gregs[8]); + err |= __put_user(env->aregs[1], &gregs[9]); + err |= __put_user(env->aregs[2], &gregs[10]); + err |= __put_user(env->aregs[3], &gregs[11]); + err |= __put_user(env->aregs[4], &gregs[12]); + err |= __put_user(env->aregs[5], &gregs[13]); + err |= __put_user(env->aregs[6], &gregs[14]); + err |= __put_user(env->aregs[7], &gregs[15]); + err |= __put_user(env->pc, &gregs[16]); + err |= __put_user(env->sr, &gregs[17]); + + return err; +} + +static inline int target_rt_restore_ucontext(CPUState *env, + struct target_ucontext *uc, + int *pd0) +{ + int temp; + int err; + target_greg_t *gregs = uc->uc_mcontext.gregs; + + err = __get_user(temp, &uc->uc_mcontext.version); + if (temp != TARGET_MCONTEXT_VERSION) + goto badframe; + + /* restore passed registers */ + err |= __get_user(env->dregs[0], &gregs[0]); + err |= __get_user(env->dregs[1], &gregs[1]); + err |= __get_user(env->dregs[2], &gregs[2]); + err |= __get_user(env->dregs[3], &gregs[3]); + err |= __get_user(env->dregs[4], &gregs[4]); + err |= __get_user(env->dregs[5], &gregs[5]); + err |= __get_user(env->dregs[6], &gregs[6]); + err |= __get_user(env->dregs[7], &gregs[7]); + err |= __get_user(env->aregs[0], &gregs[8]); + err |= __get_user(env->aregs[1], &gregs[9]); + err |= __get_user(env->aregs[2], &gregs[10]); + err |= __get_user(env->aregs[3], &gregs[11]); + err |= __get_user(env->aregs[4], &gregs[12]); + err |= __get_user(env->aregs[5], &gregs[13]); + err |= __get_user(env->aregs[6], &gregs[14]); + err |= __get_user(env->aregs[7], &gregs[15]); + err |= __get_user(env->pc, &gregs[16]); + err |= __get_user(temp, &gregs[17]); + env->sr = (env->sr & 0xff00) | (temp & 0xff); + + *pd0 = env->dregs[0]; + return err; + +badframe: + return 1; +} + +static void setup_rt_frame(int sig, struct target_sigaction *ka, + target_siginfo_t *info, + target_sigset_t *set, CPUState *env) +{ + struct target_rt_sigframe *frame; + abi_ulong frame_addr; + abi_ulong retcode_addr; + abi_ulong info_addr; + abi_ulong uc_addr; + int err = 0; + int i; + + frame_addr = get_sigframe(ka, env, sizeof *frame); + if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) + goto give_sigsegv; + + err |= __put_user(sig, &frame->sig); + + info_addr = frame_addr + offsetof(struct target_rt_sigframe, info); + err |= __put_user(info_addr, &frame->pinfo); + + uc_addr = frame_addr + offsetof(struct target_rt_sigframe, uc); + err |= __put_user(uc_addr, &frame->puc); + + err |= copy_siginfo_to_user(&frame->info, info); + + /* Create the ucontext */ + + err |= __put_user(0, &frame->uc.uc_flags); + err |= __put_user(0, &frame->uc.uc_link); + err |= __put_user(target_sigaltstack_used.ss_sp, + &frame->uc.uc_stack.ss_sp); + err |= __put_user(sas_ss_flags(env->aregs[7]), + &frame->uc.uc_stack.ss_flags); + err |= __put_user(target_sigaltstack_used.ss_size, + &frame->uc.uc_stack.ss_size); + err |= target_rt_setup_ucontext(&frame->uc, env); + + if (err) + goto give_sigsegv; + + for(i = 0; i < TARGET_NSIG_WORDS; i++) { + if (__put_user(set->sig[i], &frame->uc.uc_sigmask.sig[i])) + goto give_sigsegv; + } + + /* Set up to return from userspace. */ + + retcode_addr = frame_addr + offsetof(struct target_sigframe, retcode); + err |= __put_user(retcode_addr, &frame->pretcode); + + /* moveq #,d0; notb d0; trap #0 */ + + err |= __put_user(0x70004600 + ((TARGET_NR_rt_sigreturn ^ 0xff) << 16), + (long *)(frame->retcode + 0)); + err |= __put_user(0x4e40, (short *)(frame->retcode + 4)); + + if (err) + goto give_sigsegv; + + /* Set up to return from userspace */ + + env->aregs[7] = frame_addr; + env->pc = ka->_sa_handler; + + unlock_user_struct(frame, frame_addr, 1); + return; + +give_sigsegv: + unlock_user_struct(frame, frame_addr, 1); + force_sig(SIGSEGV); +} + +long do_sigreturn(CPUState *env) +{ + struct target_sigframe *frame; + abi_ulong frame_addr = env->aregs[7] - 4; + target_sigset_t target_set; + sigset_t set; + int d0, i; + + if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) + goto badframe; + + /* set blocked signals */ + + if (__get_user(target_set.sig[0], &frame->sc.sc_mask)) + goto badframe; + + for(i = 1; i < TARGET_NSIG_WORDS; i++) { + if (__get_user(target_set.sig[i], &frame->extramask[i - 1])) + goto badframe; + } + + target_to_host_sigset_internal(&set, &target_set); + sigprocmask(SIG_SETMASK, &set, NULL); + + /* restore registers */ + + if (restore_sigcontext(env, &frame->sc, &d0)) + goto badframe; + + unlock_user_struct(frame, frame_addr, 0); + return d0; + +badframe: + unlock_user_struct(frame, frame_addr, 0); + force_sig(TARGET_SIGSEGV); + return 0; +} + +long do_rt_sigreturn(CPUState *env) +{ + struct target_rt_sigframe *frame; + abi_ulong frame_addr = env->aregs[7] - 4; + target_sigset_t target_set; + sigset_t set; + int d0; + + if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) + goto badframe; + + target_to_host_sigset_internal(&set, &target_set); + sigprocmask(SIG_SETMASK, &set, NULL); + + /* restore registers */ + + if (target_rt_restore_ucontext(env, &frame->uc, &d0)) + goto badframe; + + if (do_sigaltstack(frame_addr + + offsetof(struct target_rt_sigframe, uc.uc_stack), + 0, get_sp_from_cpustate(env)) == -EFAULT) + goto badframe; + + unlock_user_struct(frame, frame_addr, 0); + return d0; + +badframe: + unlock_user_struct(frame, frame_addr, 0); + force_sig(TARGET_SIGSEGV); + return 0; +} + #else static void setup_frame(int sig, struct target_sigaction *ka, 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); diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index ac5dbc5be7..c018165bf3 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -1772,6 +1772,13 @@ struct target_statfs64 { #define TARGET_F_SETLK64 13 #define TARGET_F_SETLKW64 14 #endif + +#define TARGET_F_LINUX_SPECIFIC_BASE 1024 +#define TARGET_F_SETLEASE (TARGET_F_LINUX_SPECIFIC_BASE + 0) +#define TARGET_F_GETLEASE (TARGET_F_LINUX_SPECIFIC_BASE + 1) +#define TARGET_F_DUPFD_CLOEXEC (TARGET_F_LINUX_SPECIFIC_BASE + 6) +#define TARGET_F_NOTIFY (TARGET_F_LINUX_SPECIFIC_BASE+2) + #if defined (TARGET_ARM) #define TARGET_O_ACCMODE 0003 #define TARGET_O_RDONLY 00 |