All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 00/11] linux-user patches for HEAD
@ 2009-08-13 20:06 riku.voipio
  2009-08-13 20:06 ` [Qemu-devel] [PATCH 01/11] linux-user: add eventfd support riku.voipio
                   ` (10 more replies)
  0 siblings, 11 replies; 14+ messages in thread
From: riku.voipio @ 2009-08-13 20:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: Riku Voipio

From: Riku Voipio <riku.voipio@iki.fi>

Again, the patches have been on the list before. I think they have
had time for comments already, but I'll give another chance before
sending this as a pull request to anthony.

If I have missed any patches, please resend or reply to the missed
patch and CC: me.

Kirill A. Shutemov (1):
  linux-user: Rewrite mmap_find_vma() to work fine on 64-bit hosts with
    32-bit targets

Laurent Vivier (3):
  m68k,linux-user: add setup_frame
  m68k, linux-user: add setup_rt_frame
  m68k, linux-user: enable sigaltstack()

Nathan Froyd (1):
  linux-user: fix mq_* compilation problems

Riku Voipio (1):
  linux-user: add eventfd support

Ulrich Hecht (5):
  linux-user: fcntl fixes for LTP
  linux-user: enable getdents for > 32-bit systems
  linux-user: define a couple of syscalls for non-uid16 targets
  linux-user: fadvise64 implementation
  linux-user: zero fstat buffer to initialize nsec fields

 configure                 |   18 ++
 linux-user/mmap.c         |   79 +++++-----
 linux-user/signal.c       |  382 +++++++++++++++++++++++++++++++++++++++++++++
 linux-user/syscall.c      |  206 +++++++++++++++++++-----
 linux-user/syscall_defs.h |    7 +
 5 files changed, 613 insertions(+), 79 deletions(-)

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 01/11] linux-user: add eventfd support
  2009-08-13 20:06 [Qemu-devel] [PATCH 00/11] linux-user patches for HEAD riku.voipio
@ 2009-08-13 20:06 ` riku.voipio
  2009-08-21 11:29   ` Kirill A. Shutemov
  2009-08-13 20:06 ` [Qemu-devel] [PATCH 02/11] m68k,linux-user: add setup_frame riku.voipio
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 14+ messages in thread
From: riku.voipio @ 2009-08-13 20:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: Riku Voipio

From: Riku Voipio <riku.voipio@iki.fi>

Straightforward implementation. This syscall is rare enough that we
don't need to support the odder cases, just disable it if host glibc
is too old.

Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
---
 configure            |   18 ++++++++++++++++++
 linux-user/syscall.c |   13 +++++++++++++
 2 files changed, 31 insertions(+), 0 deletions(-)

diff --git a/configure b/configure
index 0b2c721..c52f1cf 100755
--- a/configure
+++ b/configure
@@ -1345,6 +1345,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 "$build_docs" = "yes" -a \( ! -x "`which texi2html 2>/dev/null`" -o ! -x "`which pod2man 2>/dev/null`" \) ; then
   build_docs="no"
@@ -1684,6 +1699,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/syscall.c b/linux-user/syscall.c
index 673eed4..3b1ed60 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -6974,6 +6974,19 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         break;
 #endif
 #endif /* CONFIG_SPLICE */
+#ifdef CONFIG_EVENTFD
+#include <sys/eventfd.h>
+#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);
-- 
1.6.2.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 02/11] m68k,linux-user: add setup_frame
  2009-08-13 20:06 [Qemu-devel] [PATCH 00/11] linux-user patches for HEAD riku.voipio
  2009-08-13 20:06 ` [Qemu-devel] [PATCH 01/11] linux-user: add eventfd support riku.voipio
@ 2009-08-13 20:06 ` riku.voipio
  2009-08-13 20:06 ` [Qemu-devel] [PATCH 03/11] m68k, linux-user: add setup_rt_frame riku.voipio
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: riku.voipio @ 2009-08-13 20:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: Riku Voipio, Laurent Vivier

From: Laurent Vivier <laurent@vivier.eu>

This patch adds signals management for linux-user.

It implements setup_frame() which allows to call the user signal
handler.

setup_rt_frame() is always unimplemented.

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
---
 linux-user/signal.c |  183 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 183 insertions(+), 0 deletions(-)

diff --git a/linux-user/signal.c b/linux-user/signal.c
index b2c0623..0756380 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -4028,6 +4028,189 @@ 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;
+};
+
+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 void setup_rt_frame(int sig, struct target_sigaction *ka,
+                           target_siginfo_t *info,
+			   target_sigset_t *set, CPUState *env)
+{
+    fprintf(stderr, "setup_rt_frame: not implemented\n");
+}
+
+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)
+{
+    fprintf(stderr, "do_rt_sigreturn: not implemented\n");
+    return -TARGET_ENOSYS;
+}
+
 #else
 
 static void setup_frame(int sig, struct target_sigaction *ka,
-- 
1.6.2.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 03/11] m68k, linux-user: add setup_rt_frame
  2009-08-13 20:06 [Qemu-devel] [PATCH 00/11] linux-user patches for HEAD riku.voipio
  2009-08-13 20:06 ` [Qemu-devel] [PATCH 01/11] linux-user: add eventfd support riku.voipio
  2009-08-13 20:06 ` [Qemu-devel] [PATCH 02/11] m68k,linux-user: add setup_frame riku.voipio
@ 2009-08-13 20:06 ` riku.voipio
  2009-08-13 20:06 ` [Qemu-devel] [PATCH 04/11] m68k, linux-user: enable sigaltstack() riku.voipio
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: riku.voipio @ 2009-08-13 20:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: Riku Voipio, Laurent Vivier

From: Laurent Vivier <laurent@vivier.eu>

This patch implements setup_rt_frame().

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
---
 linux-user/signal.c |  205 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 202 insertions(+), 3 deletions(-)

diff --git a/linux-user/signal.c b/linux-user/signal.c
index 0756380..2df17aa 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -4051,6 +4051,43 @@ struct target_sigframe
     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)
@@ -4160,11 +4197,146 @@ give_sigsegv:
     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)
 {
-    fprintf(stderr, "setup_rt_frame: not implemented\n");
+    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)
@@ -4207,8 +4379,35 @@ badframe:
 
 long do_rt_sigreturn(CPUState *env)
 {
-    fprintf(stderr, "do_rt_sigreturn: not implemented\n");
-    return -TARGET_ENOSYS;
+    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
-- 
1.6.2.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 04/11] m68k, linux-user: enable sigaltstack()
  2009-08-13 20:06 [Qemu-devel] [PATCH 00/11] linux-user patches for HEAD riku.voipio
                   ` (2 preceding siblings ...)
  2009-08-13 20:06 ` [Qemu-devel] [PATCH 03/11] m68k, linux-user: add setup_rt_frame riku.voipio
@ 2009-08-13 20:06 ` riku.voipio
  2009-08-13 20:06 ` [Qemu-devel] [PATCH 05/11] linux-user: fix mq_* compilation problems riku.voipio
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: riku.voipio @ 2009-08-13 20:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: Riku Voipio, Laurent Vivier

From: Laurent Vivier <laurent@vivier.eu>

As setup_frame() and setup_rt_frame() are now implemented we can now
enable sigaltstack().

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
---
 linux-user/syscall.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 3b1ed60..fdd46ec 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -6108,7 +6108,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
-- 
1.6.2.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 05/11] linux-user: fix mq_* compilation problems
  2009-08-13 20:06 [Qemu-devel] [PATCH 00/11] linux-user patches for HEAD riku.voipio
                   ` (3 preceding siblings ...)
  2009-08-13 20:06 ` [Qemu-devel] [PATCH 04/11] m68k, linux-user: enable sigaltstack() riku.voipio
@ 2009-08-13 20:06 ` riku.voipio
  2009-08-13 20:06 ` [Qemu-devel] [PATCH 06/11] linux-user: fcntl fixes for LTP riku.voipio
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: riku.voipio @ 2009-08-13 20:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: Riku Voipio, Nathan Froyd

From: Nathan Froyd <froydnj@codesourcery.com>

mqueue.h is only available if __NR_mq_open is defined.  So don't include
it unconditionally.  Similarly, the mq_* family of syscalls depend on
__NR_mq_open.  Finally, the copy_{from,to}_user_mq_attr functions should
not be defined unconditionally, but only if we're going to use the mq_*
syscalls.

Signed-off-by: Nathan Froyd <froydnj@codesourcery.com
Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
---
 linux-user/syscall.c |    7 +++++--
 1 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index fdd46ec..c14a78a 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>
@@ -847,6 +846,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 +886,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,
@@ -6860,7 +6863,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;
-- 
1.6.2.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 06/11] linux-user: fcntl fixes for LTP
  2009-08-13 20:06 [Qemu-devel] [PATCH 00/11] linux-user patches for HEAD riku.voipio
                   ` (4 preceding siblings ...)
  2009-08-13 20:06 ` [Qemu-devel] [PATCH 05/11] linux-user: fix mq_* compilation problems riku.voipio
@ 2009-08-13 20:06 ` riku.voipio
  2009-08-13 20:06 ` [Qemu-devel] [PATCH 07/11] linux-user: enable getdents for > 32-bit systems riku.voipio
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: riku.voipio @ 2009-08-13 20:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: Riku Voipio

From: Ulrich Hecht <uli@suse.de>

Fixes swaps on l_pid which were pretty much of random size. Implements
F_SETLEASE, F_GETLEASE. Now passes all LTP fcntl tests.

Signed-off-by: Ulrich Hecht <uli@suse.de>
Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
---
 linux-user/syscall.c      |   34 ++++++++++++++++++++++------------
 linux-user/syscall_defs.h |    7 +++++++
 2 files changed, 29 insertions(+), 12 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index c14a78a..02fa987 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -3680,6 +3680,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;
     }
@@ -3706,7 +3714,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) {
@@ -3716,7 +3724,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;
@@ -3729,7 +3737,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;
@@ -3741,7 +3749,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) {
@@ -3751,7 +3759,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;
@@ -3763,7 +3771,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;
@@ -3783,6 +3791,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;
 
@@ -6599,7 +6609,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
@@ -6610,7 +6620,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));
@@ -6623,7 +6633,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
@@ -6634,7 +6644,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);
                 }
 	    }
@@ -6650,7 +6660,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
@@ -6661,7 +6671,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));
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index ac5dbc5..c018165 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
-- 
1.6.2.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 07/11] linux-user: enable getdents for > 32-bit systems
  2009-08-13 20:06 [Qemu-devel] [PATCH 00/11] linux-user patches for HEAD riku.voipio
                   ` (5 preceding siblings ...)
  2009-08-13 20:06 ` [Qemu-devel] [PATCH 06/11] linux-user: fcntl fixes for LTP riku.voipio
@ 2009-08-13 20:06 ` riku.voipio
  2009-08-13 20:06 ` [Qemu-devel] [PATCH 08/11] linux-user: define a couple of syscalls for non-uid16 targets riku.voipio
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: riku.voipio @ 2009-08-13 20:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: Riku Voipio

From: Ulrich Hecht <uli@suse.de>

works perfectly fine with the example from getdents(2) and passes the LTP
tests (tested with s390x on x86_64 emulation)

Signed-off-by: Ulrich Hecht <uli@suse.de>
Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
---
 linux-user/syscall.c |    6 +-----
 1 files changed, 1 insertions(+), 5 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 02fa987..0f5d8da 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -193,9 +193,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
@@ -5792,9 +5790,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;
-- 
1.6.2.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 08/11] linux-user: define a couple of syscalls for non-uid16 targets
  2009-08-13 20:06 [Qemu-devel] [PATCH 00/11] linux-user patches for HEAD riku.voipio
                   ` (6 preceding siblings ...)
  2009-08-13 20:06 ` [Qemu-devel] [PATCH 07/11] linux-user: enable getdents for > 32-bit systems riku.voipio
@ 2009-08-13 20:06 ` riku.voipio
  2009-08-13 20:06 ` [Qemu-devel] [PATCH 09/11] linux-user: fadvise64 implementation riku.voipio
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: riku.voipio @ 2009-08-13 20:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: Riku Voipio

From: Ulrich Hecht <uli@suse.de>

Quite a number of syscalls are only defined on systems with USE_UID16
defined; this patch defines them on other systems as well.

Fixes a large number of uid/gid-related testcases on the s390x target
(and most likely on other targets as well)

Signed-off-by: Ulrich Hecht <uli@suse.de>
Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
---
 linux-user/syscall.c |  125 ++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 105 insertions(+), 20 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 0f5d8da..58c1b29 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -304,7 +304,7 @@ static int sys_fchmodat(int dirfd, const char *pathname, mode_t mode)
   return (fchmodat(dirfd, pathname, mode, 0));
 }
 #endif
-#if defined(TARGET_NR_fchownat) && defined(USE_UID16)
+#if defined(TARGET_NR_fchownat)
 static int sys_fchownat(int dirfd, const char *pathname, uid_t owner,
     gid_t group, int flags)
 {
@@ -413,7 +413,7 @@ _syscall3(int,sys_faccessat,int,dirfd,const char *,pathname,int,mode)
 #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
 _syscall3(int,sys_fchmodat,int,dirfd,const char *,pathname, mode_t,mode)
 #endif
-#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) && defined(USE_UID16)
+#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
 _syscall5(int,sys_fchownat,int,dirfd,const char *,pathname,
           uid_t,owner,gid_t,group,int,flags)
 #endif
@@ -6351,18 +6351,35 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
     case TARGET_NR_setfsgid:
         ret = get_errno(setfsgid(arg1));
         break;
+#else /* USE_UID16 */
+#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
+    case TARGET_NR_fchownat:
+        if (!(p = lock_user_string(arg2))) 
+            goto efault;
+        ret = get_errno(sys_fchownat(arg1, p, arg3, arg4, arg5));
+        unlock_user(p, arg2, 0);
+        break;
+#endif
 #endif /* USE_UID16 */
 
-#ifdef TARGET_NR_lchown32
+#if defined(TARGET_NR_lchown32) || !defined(USE_UID16)
+#if defined(TARGET_NR_lchown32)
     case TARGET_NR_lchown32:
+#else
+    case TARGET_NR_lchown:
+#endif
         if (!(p = lock_user_string(arg1)))
             goto efault;
         ret = get_errno(lchown(p, arg2, arg3));
         unlock_user(p, arg1, 0);
         break;
 #endif
-#ifdef TARGET_NR_getuid32
+#if defined(TARGET_NR_getuid32) || (defined(TARGET_NR_getuid) && !defined(USE_UID16))
+#if defined(TARGET_NR_getuid32)
     case TARGET_NR_getuid32:
+#else
+    case TARGET_NR_getuid:
+#endif
         ret = get_errno(getuid());
         break;
 #endif
@@ -6390,33 +6407,57 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         break;
 #endif
 
-#ifdef TARGET_NR_getgid32
+#if defined(TARGET_NR_getgid32) || (defined(TARGET_NR_getgid) && !defined(USE_UID16))
+#if defined(TARGET_NR_getgid32)
     case TARGET_NR_getgid32:
+#else
+    case TARGET_NR_getgid:
+#endif
         ret = get_errno(getgid());
         break;
 #endif
-#ifdef TARGET_NR_geteuid32
+#if defined(TARGET_NR_geteuid32) || (defined(TARGET_NR_geteuid) && !defined(USE_UID16))
+#if defined(TARGET_NR_geteuid32)
     case TARGET_NR_geteuid32:
+#else
+    case TARGET_NR_geteuid:
+#endif
         ret = get_errno(geteuid());
         break;
 #endif
-#ifdef TARGET_NR_getegid32
+#if defined(TARGET_NR_getegid32) || (defined(TARGET_NR_getegid) && !defined(USE_UID16))
+#if defined(TARGET_NR_getegid32)
     case TARGET_NR_getegid32:
+#else
+    case TARGET_NR_getegid:
+#endif
         ret = get_errno(getegid());
         break;
 #endif
-#ifdef TARGET_NR_setreuid32
+#if defined(TARGET_NR_setreuid32) || !defined(USE_UID16)
+#if defined(TARGET_NR_setreuid32)
     case TARGET_NR_setreuid32:
+#else
+    case TARGET_NR_setreuid:
+#endif
         ret = get_errno(setreuid(arg1, arg2));
         break;
 #endif
-#ifdef TARGET_NR_setregid32
+#if defined(TARGET_NR_setregid32) || !defined(USE_UID16)
+#if defined(TARGET_NR_setregid32)
     case TARGET_NR_setregid32:
+#else
+    case TARGET_NR_setregid:
+#endif
         ret = get_errno(setregid(arg1, arg2));
         break;
 #endif
-#ifdef TARGET_NR_getgroups32
+#if defined(TARGET_NR_getgroups32) || !defined(USE_UID16)
+#if defined(TARGET_NR_getgroups32)
     case TARGET_NR_getgroups32:
+#else
+    case TARGET_NR_getgroups:
+#endif
         {
             int gidsetsize = arg1;
             uint32_t *target_grouplist;
@@ -6440,8 +6481,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         }
         break;
 #endif
-#ifdef TARGET_NR_setgroups32
+#if defined(TARGET_NR_setgroups32) || !defined(USE_UID16)
+#if defined(TARGET_NR_setgroups32)
     case TARGET_NR_setgroups32:
+#else
+    case TARGET_NR_setgroups:
+#endif
         {
             int gidsetsize = arg1;
             uint32_t *target_grouplist;
@@ -6461,18 +6506,30 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         }
         break;
 #endif
-#ifdef TARGET_NR_fchown32
+#if defined(TARGET_NR_fchown32) || !defined(USE_UID16)
+#if defined(TARGET_NR_fchown32)
     case TARGET_NR_fchown32:
+#else
+    case TARGET_NR_fchown:
+#endif
         ret = get_errno(fchown(arg1, arg2, arg3));
         break;
 #endif
-#ifdef TARGET_NR_setresuid32
+#if defined(TARGET_NR_setresuid32) || !defined(USE_UID16)
+#if defined(TARGET_NR_setresuid32)
     case TARGET_NR_setresuid32:
+#else
+    case TARGET_NR_setresuid:
+#endif
         ret = get_errno(setresuid(arg1, arg2, arg3));
         break;
 #endif
-#ifdef TARGET_NR_getresuid32
+#if defined(TARGET_NR_getresuid32) || !defined(USE_UID16)
+#if defined(TARGET_NR_getresuid32)
     case TARGET_NR_getresuid32:
+#else
+    case TARGET_NR_getresuid:
+#endif
         {
             uid_t ruid, euid, suid;
             ret = get_errno(getresuid(&ruid, &euid, &suid));
@@ -6485,13 +6542,21 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         }
         break;
 #endif
-#ifdef TARGET_NR_setresgid32
+#if defined(TARGET_NR_setresgid32) || !defined(USE_UID16)
+#if defined(TARGET_NR_setresgid32)
     case TARGET_NR_setresgid32:
+#else
+    case TARGET_NR_setresgid:
+#endif
         ret = get_errno(setresgid(arg1, arg2, arg3));
         break;
 #endif
+#if defined(TARGET_NR_getresgid32) || !defined(USE_UID16)
 #ifdef TARGET_NR_getresgid32
     case TARGET_NR_getresgid32:
+#else
+    case TARGET_NR_getresgid:
+#endif
         {
             gid_t rgid, egid, sgid;
             ret = get_errno(getresgid(&rgid, &egid, &sgid));
@@ -6504,31 +6569,51 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         }
         break;
 #endif
-#ifdef TARGET_NR_chown32
+#if defined(TARGET_NR_chown32) || !defined(USE_UID16)
+#if defined(TARGET_NR_chown32)
     case TARGET_NR_chown32:
+#else
+    case TARGET_NR_chown:
+#endif
         if (!(p = lock_user_string(arg1)))
             goto efault;
         ret = get_errno(chown(p, arg2, arg3));
         unlock_user(p, arg1, 0);
         break;
 #endif
-#ifdef TARGET_NR_setuid32
+#if defined(TARGET_NR_setuid32) || !defined(USE_UID16)
+#if defined(TARGET_NR_setuid32)
     case TARGET_NR_setuid32:
+#else
+    case TARGET_NR_setuid:
+#endif
         ret = get_errno(setuid(arg1));
         break;
 #endif
-#ifdef TARGET_NR_setgid32
+#if defined(TARGET_NR_setgid32) || !defined(USE_UID16)
+#if defined(TARGET_NR_setgid32)
     case TARGET_NR_setgid32:
+#else
+    case TARGET_NR_setgid:
+#endif
         ret = get_errno(setgid(arg1));
         break;
 #endif
-#ifdef TARGET_NR_setfsuid32
+#if defined(TARGET_NR_setfsuid32) || !defined(USE_UID16)
+#if defined(TARGET_NR_setfsuid32)
     case TARGET_NR_setfsuid32:
+#else
+    case TARGET_NR_setfsuid:
+#endif
         ret = get_errno(setfsuid(arg1));
         break;
 #endif
-#ifdef TARGET_NR_setfsgid32
+#if defined(TARGET_NR_setfsgid32) || !defined(USE_UID16)
+#if defined(TARGET_NR_setfsgid32)
     case TARGET_NR_setfsgid32:
+#else
+    case TARGET_NR_setfsgid:
+#endif
         ret = get_errno(setfsgid(arg1));
         break;
 #endif
-- 
1.6.2.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 09/11] linux-user: fadvise64 implementation
  2009-08-13 20:06 [Qemu-devel] [PATCH 00/11] linux-user patches for HEAD riku.voipio
                   ` (7 preceding siblings ...)
  2009-08-13 20:06 ` [Qemu-devel] [PATCH 08/11] linux-user: define a couple of syscalls for non-uid16 targets riku.voipio
@ 2009-08-13 20:06 ` riku.voipio
  2009-08-13 20:06 ` [Qemu-devel] [PATCH 10/11] linux-user: zero fstat buffer to initialize nsec fields riku.voipio
  2009-08-13 20:06 ` [Qemu-devel] [PATCH 11/11] linux-user: Rewrite mmap_find_vma() to work fine on 64-bit hosts with 32-bit targets riku.voipio
  10 siblings, 0 replies; 14+ messages in thread
From: riku.voipio @ 2009-08-13 20:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: Riku Voipio

From: Ulrich Hecht <uli@suse.de>

good enough to pass all LTP fadvise64 tests

Signed-off-by: Ulrich Hecht <uli@suse.de>
Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
---
 linux-user/syscall.c |   17 ++++++++++++++---
 1 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 58c1b29..f90be71 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -6649,12 +6649,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
-- 
1.6.2.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 10/11] linux-user: zero fstat buffer to initialize nsec fields
  2009-08-13 20:06 [Qemu-devel] [PATCH 00/11] linux-user patches for HEAD riku.voipio
                   ` (8 preceding siblings ...)
  2009-08-13 20:06 ` [Qemu-devel] [PATCH 09/11] linux-user: fadvise64 implementation riku.voipio
@ 2009-08-13 20:06 ` riku.voipio
  2009-08-13 20:06 ` [Qemu-devel] [PATCH 11/11] linux-user: Rewrite mmap_find_vma() to work fine on 64-bit hosts with 32-bit targets riku.voipio
  10 siblings, 0 replies; 14+ messages in thread
From: riku.voipio @ 2009-08-13 20:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: Riku Voipio

From: Ulrich Hecht <uli@suse.de>

The fstat implementation does not initialize the nanosecond fields in the
stat buffer; this caused funny values to turn up there, preventing, for
instance, cp -p from preserving timestamps because utimensat rejected
the out-of-bounds nanosecond values. Resetting the entire structure
to zero fixes that.

Signed-off-by: Ulrich Hecht <uli@suse.de>
Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
---
 linux-user/syscall.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index f90be71..66a25a0 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5526,6 +5526,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);
-- 
1.6.2.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 11/11] linux-user: Rewrite mmap_find_vma() to work fine on 64-bit hosts with 32-bit targets
  2009-08-13 20:06 [Qemu-devel] [PATCH 00/11] linux-user patches for HEAD riku.voipio
                   ` (9 preceding siblings ...)
  2009-08-13 20:06 ` [Qemu-devel] [PATCH 10/11] linux-user: zero fstat buffer to initialize nsec fields riku.voipio
@ 2009-08-13 20:06 ` riku.voipio
  10 siblings, 0 replies; 14+ messages in thread
From: riku.voipio @ 2009-08-13 20:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kirill A. Shutemov, Riku Voipio

From: Kirill A. Shutemov <kirill@shutemov.name>

qemu's page table can be incomple if /proc/self/maps is unavailable or
host allocating a memory with mmap(), so we can't use it to find free
memory area.

New version mmap_find_vma() uses mmap() without MAP_FIXED to find free
memory.

Tested-by: Martin Mohring <martin.mohring@opensuse.org> :

quite some time ago this patch had been sent by Kirill to the QEMU ml.
At that time, the patch was rejected. Now we found out why the current
user mode memory allocator sometimes fails:

- Kernel Bug  linux/fs/proc/task_mmu.c (fixed after 2.6.27)
http://bugzilla.kernel.org/attachment.cgi?id=17219
- use of proc file system to find memory mappings => bad idea

So I please apply the attached patch from Kirill to qemu to fix this
longstanding bug, because it causes all older linux distros (using
kernel 2.6.26 or older) to fail the QEMU memory allocator in user mode.

Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
---
 linux-user/mmap.c |   79 +++++++++++++++++++++++++++++------------------------
 1 files changed, 43 insertions(+), 36 deletions(-)

diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index 3d2c8b3..6ce4167 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 */
-- 
1.6.2.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PATCH 01/11] linux-user: add eventfd support
  2009-08-13 20:06 ` [Qemu-devel] [PATCH 01/11] linux-user: add eventfd support riku.voipio
@ 2009-08-21 11:29   ` Kirill A. Shutemov
  2009-08-26 13:23     ` Riku Voipio
  0 siblings, 1 reply; 14+ messages in thread
From: Kirill A. Shutemov @ 2009-08-21 11:29 UTC (permalink / raw)
  To: riku.voipio; +Cc: qemu-devel

On Thu, Aug 13, 2009 at 11:06 PM, <riku.voipio@iki.fi> wrote:
> From: Riku Voipio <riku.voipio@iki.fi>
>
> Straightforward implementation. This syscall is rare enough that we
> don't need to support the odder cases, just disable it if host glibc
> is too old.
>
> Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
> ---
>  configure            |   18 ++++++++++++++++++
>  linux-user/syscall.c |   13 +++++++++++++
>  2 files changed, 31 insertions(+), 0 deletions(-)
>
> diff --git a/configure b/configure
> index 0b2c721..c52f1cf 100755
> --- a/configure
> +++ b/configure
> @@ -1345,6 +1345,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 "$build_docs" = "yes" -a \( ! -x "`which texi2html 2>/dev/null`" -o ! -x "`which pod2man 2>/dev/null`" \) ; then
>   build_docs="no"
> @@ -1684,6 +1699,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/syscall.c b/linux-user/syscall.c
> index 673eed4..3b1ed60 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -6974,6 +6974,19 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
>         break;
>  #endif
>  #endif /* CONFIG_SPLICE */
> +#ifdef CONFIG_EVENTFD
> +#include <sys/eventfd.h>

I don't think that #include within function is a good idea.

> +#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);
> --
> 1.6.2.1
>
>
>
>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PATCH 01/11] linux-user: add eventfd support
  2009-08-21 11:29   ` Kirill A. Shutemov
@ 2009-08-26 13:23     ` Riku Voipio
  0 siblings, 0 replies; 14+ messages in thread
From: Riku Voipio @ 2009-08-26 13:23 UTC (permalink / raw)
  To: Kirill A. Shutemov; +Cc: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 275 bytes --]

On Fri, Aug 21, 2009 at 02:29:46PM +0300, Kirill A. Shutemov wrote:
> >  #endif /* CONFIG_SPLICE */
> > +#ifdef CONFIG_EVENTFD
> > +#include <sys/eventfd.h>

> I don't think that #include within function is a good idea.

You are right. Corrected version attached.


[-- Attachment #2: 0001-linux-user-add-eventfd-support.patch --]
[-- Type: text/x-diff, Size: 2499 bytes --]

>From c2882b96545eeabf16767c6effa836e6f9991018 Mon Sep 17 00:00:00 2001
Message-Id: <c2882b96545eeabf16767c6effa836e6f9991018.1251230665.git.riku.voipio@iki.fi>
In-Reply-To: <cover.1251230665.git.riku.voipio@iki.fi>
References: <cover.1251230665.git.riku.voipio@iki.fi>
From: Riku Voipio <riku.voipio@iki.fi>
Date: Wed, 12 Aug 2009 15:08:24 +0300
Subject: [PATCH 01/10] linux-user: add eventfd support

Straightforward implementation. This syscall is rare enough that we
don't need to support the odder cases, just disable it if host glibc
is too old.

Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
---
 configure            |   18 ++++++++++++++++++
 linux-user/syscall.c |   15 +++++++++++++++
 2 files changed, 33 insertions(+), 0 deletions(-)

diff --git a/configure b/configure
index 5c1065f..56dd489 100755
--- a/configure
+++ b/configure
@@ -1322,6 +1322,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 "$build_docs" = "yes" -a \( ! -x "`which texi2html 2>/dev/null`" -o ! -x "`which pod2man 2>/dev/null`" \) ; then
   build_docs="no"
@@ -1659,6 +1674,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/syscall.c b/linux-user/syscall.c
index 673eed4..603fec2 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -60,6 +60,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
@@ -6974,6 +6977,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);
-- 
1.6.2.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2009-08-26 13:23 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-08-13 20:06 [Qemu-devel] [PATCH 00/11] linux-user patches for HEAD riku.voipio
2009-08-13 20:06 ` [Qemu-devel] [PATCH 01/11] linux-user: add eventfd support riku.voipio
2009-08-21 11:29   ` Kirill A. Shutemov
2009-08-26 13:23     ` Riku Voipio
2009-08-13 20:06 ` [Qemu-devel] [PATCH 02/11] m68k,linux-user: add setup_frame riku.voipio
2009-08-13 20:06 ` [Qemu-devel] [PATCH 03/11] m68k, linux-user: add setup_rt_frame riku.voipio
2009-08-13 20:06 ` [Qemu-devel] [PATCH 04/11] m68k, linux-user: enable sigaltstack() riku.voipio
2009-08-13 20:06 ` [Qemu-devel] [PATCH 05/11] linux-user: fix mq_* compilation problems riku.voipio
2009-08-13 20:06 ` [Qemu-devel] [PATCH 06/11] linux-user: fcntl fixes for LTP riku.voipio
2009-08-13 20:06 ` [Qemu-devel] [PATCH 07/11] linux-user: enable getdents for > 32-bit systems riku.voipio
2009-08-13 20:06 ` [Qemu-devel] [PATCH 08/11] linux-user: define a couple of syscalls for non-uid16 targets riku.voipio
2009-08-13 20:06 ` [Qemu-devel] [PATCH 09/11] linux-user: fadvise64 implementation riku.voipio
2009-08-13 20:06 ` [Qemu-devel] [PATCH 10/11] linux-user: zero fstat buffer to initialize nsec fields riku.voipio
2009-08-13 20:06 ` [Qemu-devel] [PATCH 11/11] linux-user: Rewrite mmap_find_vma() to work fine on 64-bit hosts with 32-bit targets riku.voipio

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.