qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/7] alpha-linux syscall fixes
@ 2010-05-03 17:07 Richard Henderson
  2010-05-03 17:07 ` [Qemu-devel] [PATCH 1/7] alpha-linux-user: Fix brk error return Richard Henderson
  2010-05-21 16:27 ` [Qemu-devel] [PATCH 0/7] alpha-linux syscall fixes Aurelien Jarno
  0 siblings, 2 replies; 9+ messages in thread
From: Richard Henderson @ 2010-05-03 17:07 UTC (permalink / raw)
  To: qemu-devel

I've been doing a bit of testing of the alpha TCG port by running
QEMU compiled for alpha on QEMU compiled for x86-64.  Which is an
interesting challenge for the linux-user code, and has found a 
few bugs.


r~


Richard Henderson (7):
  alpha-linux-user: Fix brk error return.
  alpha-linux-user: Fix siginfo.si_addr for SIGSEGV and SIGBUS.
  alpha-linux-user: Add correct sigaction constants.
  alpha-linux-user: Fix pipe return mechanism.
  alpha-linux-user: Fix getxpid.
  alpha-linux-user: Fix sigsuspend parameters.
  alpha-linux-user: Fix sigprocmask.

 linux-user/main.c         |   15 +++++--
 linux-user/syscall.c      |   95 +++++++++++++++++++++++++++++++++++---------
 linux-user/syscall_defs.h |    8 ++++
 3 files changed, 94 insertions(+), 24 deletions(-)

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

* [Qemu-devel] [PATCH 1/7] alpha-linux-user: Fix brk error return.
  2010-05-03 17:07 [Qemu-devel] [PATCH 0/7] alpha-linux syscall fixes Richard Henderson
@ 2010-05-03 17:07 ` Richard Henderson
  2010-05-03 17:07   ` [Qemu-devel] [PATCH 2/7] alpha-linux-user: Fix siginfo.si_addr for SIGSEGV and SIGBUS Richard Henderson
  2010-05-21 16:27 ` [Qemu-devel] [PATCH 0/7] alpha-linux syscall fixes Aurelien Jarno
  1 sibling, 1 reply; 9+ messages in thread
From: Richard Henderson @ 2010-05-03 17:07 UTC (permalink / raw)
  To: qemu-devel

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 linux-user/syscall.c |   12 ++++++++++--
 1 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 17599eb..81e09b3 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -718,9 +718,17 @@ abi_long do_brk(abi_ulong new_brk)
                                         PROT_READ|PROT_WRITE,
                                         MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
 
-    if (!is_error(mapped_addr))
+#if defined(TARGET_ALPHA)
+    /* We (partially) emulate OSF/1 on Alpha, which requires we
+       return a proper errno, not an unchanged brk value.  */
+    if (is_error(mapped_addr)) {
+        return -TARGET_ENOMEM;
+    }
+#endif
+
+    if (!is_error(mapped_addr)) {
 	target_brk = new_brk;
-    
+    }
     return target_brk;
 }
 
-- 
1.6.6.1

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

* [Qemu-devel] [PATCH 2/7] alpha-linux-user: Fix siginfo.si_addr for SIGSEGV and SIGBUS.
  2010-05-03 17:07 ` [Qemu-devel] [PATCH 1/7] alpha-linux-user: Fix brk error return Richard Henderson
@ 2010-05-03 17:07   ` Richard Henderson
  2010-05-03 17:07     ` [Qemu-devel] [PATCH 3/7] alpha-linux-user: Add correct sigaction constants Richard Henderson
  0 siblings, 1 reply; 9+ messages in thread
From: Richard Henderson @ 2010-05-03 17:07 UTC (permalink / raw)
  To: qemu-devel

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 linux-user/main.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index 18b52c0..e35c124 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -2434,7 +2434,7 @@ void cpu_loop (CPUState *env)
             info.si_signo = TARGET_SIGSEGV;
             info.si_errno = 0;
             info.si_code = 0;  /* ??? SEGV_MAPERR vs SEGV_ACCERR.  */
-            info._sifields._sigfault._addr = env->pc;
+            info._sifields._sigfault._addr = env->ipr[IPR_EXC_ADDR];
             queue_signal(env, info.si_signo, &info);
             break;
         case EXCP_DTB_MISS_PAL:
@@ -2458,7 +2458,7 @@ void cpu_loop (CPUState *env)
             info.si_signo = TARGET_SIGBUS;
             info.si_errno = 0;
             info.si_code = TARGET_BUS_ADRALN;
-            info._sifields._sigfault._addr = env->pc;
+            info._sifields._sigfault._addr = env->ipr[IPR_EXC_ADDR];
             queue_signal(env, info.si_signo, &info);
             break;
         case EXCP_OPCDEC:
-- 
1.6.6.1

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

* [Qemu-devel] [PATCH 3/7] alpha-linux-user: Add correct sigaction constants.
  2010-05-03 17:07   ` [Qemu-devel] [PATCH 2/7] alpha-linux-user: Fix siginfo.si_addr for SIGSEGV and SIGBUS Richard Henderson
@ 2010-05-03 17:07     ` Richard Henderson
  2010-05-03 17:07       ` [Qemu-devel] [PATCH 4/7] alpha-linux-user: Fix pipe return mechanism Richard Henderson
  0 siblings, 1 reply; 9+ messages in thread
From: Richard Henderson @ 2010-05-03 17:07 UTC (permalink / raw)
  To: qemu-devel

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 linux-user/syscall_defs.h |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 63c2bc3..e41b6b9 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -336,6 +336,14 @@ int do_sigaction(int sig, const struct target_sigaction *act,
 #if !defined(TARGET_ABI_MIPSN32) && !defined(TARGET_ABI_MIPSN64)
 #define TARGET_SA_RESTORER	0x04000000	/* Only for O32 */
 #endif
+#elif defined(TARGET_ALPHA)
+#define TARGET_SA_ONSTACK	0x00000001
+#define TARGET_SA_RESTART	0x00000002
+#define TARGET_SA_NOCLDSTOP	0x00000004
+#define TARGET_SA_NODEFER	0x00000008
+#define TARGET_SA_RESETHAND	0x00000010
+#define TARGET_SA_NOCLDWAIT	0x00000020 /* not supported yet */
+#define TARGET_SA_SIGINFO	0x00000040
 #else
 #define TARGET_SA_NOCLDSTOP	0x00000001
 #define TARGET_SA_NOCLDWAIT	0x00000002 /* not supported yet */
-- 
1.6.6.1

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

* [Qemu-devel] [PATCH 4/7] alpha-linux-user: Fix pipe return mechanism.
  2010-05-03 17:07     ` [Qemu-devel] [PATCH 3/7] alpha-linux-user: Add correct sigaction constants Richard Henderson
@ 2010-05-03 17:07       ` Richard Henderson
  2010-05-03 17:07         ` [Qemu-devel] [PATCH 5/7] alpha-linux-user: Fix getxpid Richard Henderson
  0 siblings, 1 reply; 9+ messages in thread
From: Richard Henderson @ 2010-05-03 17:07 UTC (permalink / raw)
  To: qemu-devel

At the same time, tidy the code wrt MIPS and SH4 which have the
same two register return mechanism.  Fix confusion between pipe
and pipe2 with an explicit flags=0, when the guest will not be
using the two register return mechanism.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 linux-user/syscall.c |   30 ++++++++++++++++++------------
 1 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 81e09b3..3b0e169 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -979,7 +979,8 @@ static abi_long do_pipe2(int host_pipe[], int flags)
 #endif
 }
 
-static abi_long do_pipe(void *cpu_env, abi_ulong pipedes, int flags)
+static abi_long do_pipe(void *cpu_env, abi_ulong pipedes,
+                        int flags, int is_pipe2)
 {
     int host_pipe[2];
     abi_long ret;
@@ -987,20 +988,25 @@ static abi_long do_pipe(void *cpu_env, abi_ulong pipedes, int flags)
 
     if (is_error(ret))
         return get_errno(ret);
-#if defined(TARGET_MIPS)
-    ((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = host_pipe[1];
-    ret = host_pipe[0];
-#else
-#if defined(TARGET_SH4)
-    if (!flags) {
+
+    /* Several targets have special calling conventions for the original
+       pipe syscall, but didn't replicate this into the pipe2 syscall.  */
+    if (!is_pipe2) {
+#if defined(TARGET_ALPHA)
+        ((CPUAlphaState *)cpu_env)->ir[IR_A4] = host_pipe[1];
+        return host_pipe[0];
+#elif defined(TARGET_MIPS)
+        ((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = host_pipe[1];
+        return host_pipe[0];
+#elif defined(TARGET_SH4)
         ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
-        ret = host_pipe[0];
-    } else
+        return host_pipe[0];
 #endif
+    }
+
     if (put_user_s32(host_pipe[0], pipedes)
         || put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0])))
         return -TARGET_EFAULT;
-#endif
     return get_errno(ret);
 }
 
@@ -4690,11 +4696,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         ret = get_errno(dup(arg1));
         break;
     case TARGET_NR_pipe:
-        ret = do_pipe(cpu_env, arg1, 0);
+        ret = do_pipe(cpu_env, arg1, 0, 0);
         break;
 #ifdef TARGET_NR_pipe2
     case TARGET_NR_pipe2:
-        ret = do_pipe(cpu_env, arg1, arg2);
+        ret = do_pipe(cpu_env, arg1, arg2, 1);
         break;
 #endif
     case TARGET_NR_times:
-- 
1.6.6.1

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

* [Qemu-devel] [PATCH 5/7] alpha-linux-user: Fix getxpid.
  2010-05-03 17:07       ` [Qemu-devel] [PATCH 4/7] alpha-linux-user: Fix pipe return mechanism Richard Henderson
@ 2010-05-03 17:07         ` Richard Henderson
  2010-05-03 17:07           ` [Qemu-devel] [PATCH 6/7] alpha-linux-user: Fix sigsuspend parameters Richard Henderson
  0 siblings, 1 reply; 9+ messages in thread
From: Richard Henderson @ 2010-05-03 17:07 UTC (permalink / raw)
  To: qemu-devel

Put ppid in the second return register.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 linux-user/syscall.c |   11 ++++++++---
 1 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 3b0e169..8a6cbaf 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4481,13 +4481,18 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
     case TARGET_NR_lseek:
         ret = get_errno(lseek(arg1, arg2, arg3));
         break;
-#ifdef TARGET_NR_getxpid
+#if defined(TARGET_NR_getxpid) && defined(TARGET_ALPHA)
+    /* Alpha specific */
     case TARGET_NR_getxpid:
-#else
-    case TARGET_NR_getpid:
+        ((CPUAlphaState *)cpu_env)->ir[IR_A4] = getppid();
+        ret = get_errno(getpid());
+        break;
 #endif
+#ifdef TARGET_NR_getpid
+    case TARGET_NR_getpid:
         ret = get_errno(getpid());
         break;
+#endif
     case TARGET_NR_mount:
 		{
 			/* need to look at the data field */
-- 
1.6.6.1

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

* [Qemu-devel] [PATCH 6/7] alpha-linux-user: Fix sigsuspend parameters.
  2010-05-03 17:07         ` [Qemu-devel] [PATCH 5/7] alpha-linux-user: Fix getxpid Richard Henderson
@ 2010-05-03 17:07           ` Richard Henderson
  2010-05-03 17:07             ` [Qemu-devel] [PATCH 7/7] alpha-linux-user: Fix sigprocmask Richard Henderson
  0 siblings, 1 reply; 9+ messages in thread
From: Richard Henderson @ 2010-05-03 17:07 UTC (permalink / raw)
  To: qemu-devel

Alpha passes the signal set in a register, not by reference.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 linux-user/syscall.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 8a6cbaf..899b76f 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5072,10 +5072,15 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
     case TARGET_NR_sigsuspend:
         {
             sigset_t set;
+#if defined(TARGET_ALPHA)
+            abi_ulong mask = arg1;
+            target_to_host_old_sigset(&set, &mask);
+#else
             if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
                 goto efault;
             target_to_host_old_sigset(&set, p);
             unlock_user(p, arg1, 0);
+#endif
             ret = get_errno(sigsuspend(&set));
         }
         break;
-- 
1.6.6.1

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

* [Qemu-devel] [PATCH 7/7] alpha-linux-user: Fix sigprocmask.
  2010-05-03 17:07           ` [Qemu-devel] [PATCH 6/7] alpha-linux-user: Fix sigsuspend parameters Richard Henderson
@ 2010-05-03 17:07             ` Richard Henderson
  0 siblings, 0 replies; 9+ messages in thread
From: Richard Henderson @ 2010-05-03 17:07 UTC (permalink / raw)
  To: qemu-devel

Alpha passes oldset by value in a register, and returns the newset
as the return value; as compared to the standard implementation in
which both are passed by reference.  This requires being able to
distinguish negative return values that are not errors.  Do this in
the same way as the Alpha Linux kernel, by storing a zero in V0 in
the implementation of the syscall.

At the same time, fix a think-o in the regular sigprocmask path in
which we passed the target, rather than the host, HOW value.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 linux-user/main.c    |   11 +++++++++--
 linux-user/syscall.c |   37 ++++++++++++++++++++++++++++++++++---
 2 files changed, 43 insertions(+), 5 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index e35c124..2862355 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -2499,8 +2499,15 @@ void cpu_loop (CPUState *env)
                                     env->ir[IR_A0], env->ir[IR_A1],
                                     env->ir[IR_A2], env->ir[IR_A3],
                                     env->ir[IR_A4], env->ir[IR_A5]);
-                if (trapnr != TARGET_NR_sigreturn
-                    && trapnr != TARGET_NR_rt_sigreturn) {
+                if (trapnr == TARGET_NR_sigreturn
+                    || trapnr == TARGET_NR_rt_sigreturn) {
+                    break;
+                }
+                /* Syscall writes 0 to V0 to bypass error check, similar
+                   to how this is handled internal to Linux kernel.  */
+                if (env->ir[IR_V0] == 0) {
+                    env->ir[IR_V0] = sysret;
+                } else {
                     env->ir[IR_V0] = (sysret < 0 ? -sysret : sysret);
                     env->ir[IR_A3] = (sysret < 0);
                 }
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 899b76f..6f88943 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4967,11 +4967,41 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 #ifdef TARGET_NR_sigprocmask
     case TARGET_NR_sigprocmask:
         {
-            int how = arg1;
+#if defined(TARGET_ALPHA)
+            sigset_t set, oldset;
+            abi_ulong mask;
+            int how;
+
+            switch (arg1) {
+            case TARGET_SIG_BLOCK:
+                how = SIG_BLOCK;
+                break;
+            case TARGET_SIG_UNBLOCK:
+                how = SIG_UNBLOCK;
+                break;
+            case TARGET_SIG_SETMASK:
+                how = SIG_SETMASK;
+                break;
+            default:
+                ret = -TARGET_EINVAL;
+                goto fail;
+            }
+            mask = arg2;
+            target_to_host_old_sigset(&set, &mask);
+
+            ret = get_errno(sigprocmask(how, &set, &oldset));
+
+            if (!is_error(ret)) {
+                host_to_target_old_sigset(&mask, &oldset);
+                ret = mask;
+                ((CPUAlphaState *)cpu_env)->[IR_V0] = 0; /* force no error */
+            }
+#else
             sigset_t set, oldset, *set_ptr;
+            int how;
 
             if (arg2) {
-                switch(how) {
+                switch (arg1) {
                 case TARGET_SIG_BLOCK:
                     how = SIG_BLOCK;
                     break;
@@ -4994,13 +5024,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
                 how = 0;
                 set_ptr = NULL;
             }
-            ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
+            ret = get_errno(sigprocmask(how, set_ptr, &oldset));
             if (!is_error(ret) && arg3) {
                 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
                     goto efault;
                 host_to_target_old_sigset(p, &oldset);
                 unlock_user(p, arg3, sizeof(target_sigset_t));
             }
+#endif
         }
         break;
 #endif
-- 
1.6.6.1

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

* Re: [Qemu-devel] [PATCH 0/7] alpha-linux syscall fixes
  2010-05-03 17:07 [Qemu-devel] [PATCH 0/7] alpha-linux syscall fixes Richard Henderson
  2010-05-03 17:07 ` [Qemu-devel] [PATCH 1/7] alpha-linux-user: Fix brk error return Richard Henderson
@ 2010-05-21 16:27 ` Aurelien Jarno
  1 sibling, 0 replies; 9+ messages in thread
From: Aurelien Jarno @ 2010-05-21 16:27 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel

On Mon, May 03, 2010 at 10:07:48AM -0700, Richard Henderson wrote:
> I've been doing a bit of testing of the alpha TCG port by running
> QEMU compiled for alpha on QEMU compiled for x86-64.  Which is an
> interesting challenge for the linux-user code, and has found a 
> few bugs.
> 
> 
> r~
> 
> 
> Richard Henderson (7):
>   alpha-linux-user: Fix brk error return.
>   alpha-linux-user: Fix siginfo.si_addr for SIGSEGV and SIGBUS.
>   alpha-linux-user: Add correct sigaction constants.
>   alpha-linux-user: Fix pipe return mechanism.
>   alpha-linux-user: Fix getxpid.
>   alpha-linux-user: Fix sigsuspend parameters.
>   alpha-linux-user: Fix sigprocmask.
> 
>  linux-user/main.c         |   15 +++++--
>  linux-user/syscall.c      |   95 +++++++++++++++++++++++++++++++++++---------
>  linux-user/syscall_defs.h |    8 ++++
>  3 files changed, 94 insertions(+), 24 deletions(-)
> 

Thanks, all applied.

-- 
Aurelien Jarno                          GPG: 1024D/F1BCDB73
aurelien@aurel32.net                 http://www.aurel32.net

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

end of thread, other threads:[~2010-05-21 16:28 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-05-03 17:07 [Qemu-devel] [PATCH 0/7] alpha-linux syscall fixes Richard Henderson
2010-05-03 17:07 ` [Qemu-devel] [PATCH 1/7] alpha-linux-user: Fix brk error return Richard Henderson
2010-05-03 17:07   ` [Qemu-devel] [PATCH 2/7] alpha-linux-user: Fix siginfo.si_addr for SIGSEGV and SIGBUS Richard Henderson
2010-05-03 17:07     ` [Qemu-devel] [PATCH 3/7] alpha-linux-user: Add correct sigaction constants Richard Henderson
2010-05-03 17:07       ` [Qemu-devel] [PATCH 4/7] alpha-linux-user: Fix pipe return mechanism Richard Henderson
2010-05-03 17:07         ` [Qemu-devel] [PATCH 5/7] alpha-linux-user: Fix getxpid Richard Henderson
2010-05-03 17:07           ` [Qemu-devel] [PATCH 6/7] alpha-linux-user: Fix sigsuspend parameters Richard Henderson
2010-05-03 17:07             ` [Qemu-devel] [PATCH 7/7] alpha-linux-user: Fix sigprocmask Richard Henderson
2010-05-21 16:27 ` [Qemu-devel] [PATCH 0/7] alpha-linux syscall fixes Aurelien Jarno

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).