Patchwork sh4 linux-user: Save/restore fpu registers to signal context.

login
register
mail settings
Submitter takasi-y@ops.dti.ne.jp
Date Feb. 17, 2010, 3:46 p.m.
Message ID <201002171546.o1HFkjhW009910@smtp09.dti.ne.jp>
Download mbox | patch
Permalink /patch/45640/
State New
Headers show

Comments

takasi-y@ops.dti.ne.jp - Feb. 17, 2010, 3:46 p.m.
As "todo" comment in source code.
And modify restore_sigcontext() to have three args as kernel's does.

Signed-off-by: Takashi YOSHII <takasi-y@ops.dti.ne.jp>
---
 linux-user/signal.c |   27 +++++++++++++++++++--------
 1 files changed, 19 insertions(+), 8 deletions(-)
Aurelien Jarno - March 6, 2010, 6:39 p.m.
On Thu, Feb 18, 2010 at 12:46:45AM +0900, takasi-y@ops.dti.ne.jp wrote:
> As "todo" comment in source code.
> And modify restore_sigcontext() to have three args as kernel's does.
> 
> Signed-off-by: Takashi YOSHII <takasi-y@ops.dti.ne.jp>

Thanks, applied.

> ---
>  linux-user/signal.c |   27 +++++++++++++++++++--------
>  1 files changed, 19 insertions(+), 8 deletions(-)
> 
> diff --git a/linux-user/signal.c b/linux-user/signal.c
> index b0faf2e..8697511 100644
> --- a/linux-user/signal.c
> +++ b/linux-user/signal.c
> @@ -2812,6 +2812,7 @@ static int setup_sigcontext(struct target_sigcontext *sc,
>  			    CPUState *regs, unsigned long mask)
>  {
>      int err = 0;
> +    int i;
>  
>  #define COPY(x)         err |= __put_user(regs->x, &sc->sc_##x)
>      COPY(gregs[0]); COPY(gregs[1]);
> @@ -2827,7 +2828,10 @@ static int setup_sigcontext(struct target_sigcontext *sc,
>      COPY(sr); COPY(pc);
>  #undef COPY
>  
> -    /* todo: save FPU registers here */
> +    for (i=0; i<16; i++)
> +        err |= __put_user(regs->fregs[i], &sc->sc_fpregs[i]);
> +    err |= __put_user(regs->fpscr, &sc->sc_fpscr);
> +    err |= __put_user(regs->fpul, &sc->sc_fpul);
>  
>      /* non-iBCS2 extensions.. */
>      err |= __put_user(mask, &sc->oldmask);
> @@ -2835,10 +2839,11 @@ static int setup_sigcontext(struct target_sigcontext *sc,
>      return err;
>  }
>  
> -static int restore_sigcontext(CPUState *regs,
> -			      struct target_sigcontext *sc)
> +static int restore_sigcontext(CPUState *regs, struct target_sigcontext *sc,
> +                              target_ulong *r0_p)
>  {
>      unsigned int err = 0;
> +    int i;
>  
>  #define COPY(x)         err |= __get_user(regs->x, &sc->sc_##x)
>      COPY(gregs[1]);
> @@ -2854,9 +2859,13 @@ static int restore_sigcontext(CPUState *regs,
>      COPY(sr); COPY(pc);
>  #undef COPY
>  
> -    /* todo: restore FPU registers here */
> +    for (i=0; i<16; i++)
> +        err |= __get_user(regs->fregs[i], &sc->sc_fpregs[i]);
> +    err |= __get_user(regs->fpscr, &sc->sc_fpscr);
> +    err |= __get_user(regs->fpul, &sc->sc_fpul);
>  
>      regs->tra = -1;         /* disable syscall checks */
> +    err |= __get_user(*r0_p, &sc->sc_gregs[0]);
>      return err;
>  }
>  
> @@ -2980,6 +2989,7 @@ long do_sigreturn(CPUState *regs)
>      abi_ulong frame_addr;
>      sigset_t blocked;
>      target_sigset_t target_set;
> +    target_ulong r0;
>      int i;
>      int err = 0;
>  
> @@ -3001,11 +3011,11 @@ long do_sigreturn(CPUState *regs)
>      target_to_host_sigset_internal(&blocked, &target_set);
>      sigprocmask(SIG_SETMASK, &blocked, NULL);
>  
> -    if (restore_sigcontext(regs, &frame->sc))
> +    if (restore_sigcontext(regs, &frame->sc, &r0))
>          goto badframe;
>  
>      unlock_user_struct(frame, frame_addr, 0);
> -    return regs->gregs[0];
> +    return r0;
>  
>  badframe:
>      unlock_user_struct(frame, frame_addr, 0);
> @@ -3018,6 +3028,7 @@ long do_rt_sigreturn(CPUState *regs)
>      struct target_rt_sigframe *frame;
>      abi_ulong frame_addr;
>      sigset_t blocked;
> +    target_ulong r0;
>  
>  #if defined(DEBUG_SIGNAL)
>      fprintf(stderr, "do_rt_sigreturn\n");
> @@ -3029,7 +3040,7 @@ long do_rt_sigreturn(CPUState *regs)
>      target_to_host_sigset(&blocked, &frame->uc.uc_sigmask);
>      sigprocmask(SIG_SETMASK, &blocked, NULL);
>  
> -    if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
> +    if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0))
>          goto badframe;
>  
>      if (do_sigaltstack(frame_addr +
> @@ -3038,7 +3049,7 @@ long do_rt_sigreturn(CPUState *regs)
>          goto badframe;
>  
>      unlock_user_struct(frame, frame_addr, 0);
> -    return regs->gregs[0];
> +    return r0;
>  
>  badframe:
>      unlock_user_struct(frame, frame_addr, 0);
> -- 
> 1.6.5
> 
> 
> 
>

Patch

diff --git a/linux-user/signal.c b/linux-user/signal.c
index b0faf2e..8697511 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -2812,6 +2812,7 @@  static int setup_sigcontext(struct target_sigcontext *sc,
 			    CPUState *regs, unsigned long mask)
 {
     int err = 0;
+    int i;
 
 #define COPY(x)         err |= __put_user(regs->x, &sc->sc_##x)
     COPY(gregs[0]); COPY(gregs[1]);
@@ -2827,7 +2828,10 @@  static int setup_sigcontext(struct target_sigcontext *sc,
     COPY(sr); COPY(pc);
 #undef COPY
 
-    /* todo: save FPU registers here */
+    for (i=0; i<16; i++)
+        err |= __put_user(regs->fregs[i], &sc->sc_fpregs[i]);
+    err |= __put_user(regs->fpscr, &sc->sc_fpscr);
+    err |= __put_user(regs->fpul, &sc->sc_fpul);
 
     /* non-iBCS2 extensions.. */
     err |= __put_user(mask, &sc->oldmask);
@@ -2835,10 +2839,11 @@  static int setup_sigcontext(struct target_sigcontext *sc,
     return err;
 }
 
-static int restore_sigcontext(CPUState *regs,
-			      struct target_sigcontext *sc)
+static int restore_sigcontext(CPUState *regs, struct target_sigcontext *sc,
+                              target_ulong *r0_p)
 {
     unsigned int err = 0;
+    int i;
 
 #define COPY(x)         err |= __get_user(regs->x, &sc->sc_##x)
     COPY(gregs[1]);
@@ -2854,9 +2859,13 @@  static int restore_sigcontext(CPUState *regs,
     COPY(sr); COPY(pc);
 #undef COPY
 
-    /* todo: restore FPU registers here */
+    for (i=0; i<16; i++)
+        err |= __get_user(regs->fregs[i], &sc->sc_fpregs[i]);
+    err |= __get_user(regs->fpscr, &sc->sc_fpscr);
+    err |= __get_user(regs->fpul, &sc->sc_fpul);
 
     regs->tra = -1;         /* disable syscall checks */
+    err |= __get_user(*r0_p, &sc->sc_gregs[0]);
     return err;
 }
 
@@ -2980,6 +2989,7 @@  long do_sigreturn(CPUState *regs)
     abi_ulong frame_addr;
     sigset_t blocked;
     target_sigset_t target_set;
+    target_ulong r0;
     int i;
     int err = 0;
 
@@ -3001,11 +3011,11 @@  long do_sigreturn(CPUState *regs)
     target_to_host_sigset_internal(&blocked, &target_set);
     sigprocmask(SIG_SETMASK, &blocked, NULL);
 
-    if (restore_sigcontext(regs, &frame->sc))
+    if (restore_sigcontext(regs, &frame->sc, &r0))
         goto badframe;
 
     unlock_user_struct(frame, frame_addr, 0);
-    return regs->gregs[0];
+    return r0;
 
 badframe:
     unlock_user_struct(frame, frame_addr, 0);
@@ -3018,6 +3028,7 @@  long do_rt_sigreturn(CPUState *regs)
     struct target_rt_sigframe *frame;
     abi_ulong frame_addr;
     sigset_t blocked;
+    target_ulong r0;
 
 #if defined(DEBUG_SIGNAL)
     fprintf(stderr, "do_rt_sigreturn\n");
@@ -3029,7 +3040,7 @@  long do_rt_sigreturn(CPUState *regs)
     target_to_host_sigset(&blocked, &frame->uc.uc_sigmask);
     sigprocmask(SIG_SETMASK, &blocked, NULL);
 
-    if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
+    if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0))
         goto badframe;
 
     if (do_sigaltstack(frame_addr +
@@ -3038,7 +3049,7 @@  long do_rt_sigreturn(CPUState *regs)
         goto badframe;
 
     unlock_user_struct(frame, frame_addr, 0);
-    return regs->gregs[0];
+    return r0;
 
 badframe:
     unlock_user_struct(frame, frame_addr, 0);