Re: [Qemu-devel] [PATCH v4 2/5] aarch64-linux-user: Split out helpers for guest signal handling

2018-03-06 Thread Alex Bennée

Richard Henderson  writes:

> Split out helpers from target_setup_frame and target_restore_sigframe
> for dealing with general registers, fpsimd registers, and the end record.
>
> When we add support for sve registers, the relative positions of
> these will change.
>
> Reviewed-by: Peter Maydell 
> Signed-off-by: Richard Henderson 

Reviewed-by: Alex Bennée 

> ---
>  linux-user/signal.c | 120 
> ++--
>  1 file changed, 69 insertions(+), 51 deletions(-)
>
> diff --git a/linux-user/signal.c b/linux-user/signal.c
> index 9a380b9e31..25c9743aed 100644
> --- a/linux-user/signal.c
> +++ b/linux-user/signal.c
> @@ -1462,16 +1462,17 @@ struct target_rt_sigframe {
>  uint32_t tramp[2];
>  };
>
> -static int target_setup_sigframe(struct target_rt_sigframe *sf,
> - CPUARMState *env, target_sigset_t *set)
> +static void target_setup_general_frame(struct target_rt_sigframe *sf,
> +   CPUARMState *env, target_sigset_t 
> *set)
>  {
>  int i;
> -struct target_aux_context *aux =
> -(struct target_aux_context *)sf->uc.tuc_mcontext.__reserved;
>
> -/* set up the stack frame for unwinding */
> -__put_user(env->xregs[29], &sf->fp);
> -__put_user(env->xregs[30], &sf->lr);
> +__put_user(0, &sf->uc.tuc_flags);
> +__put_user(0, &sf->uc.tuc_link);
> +
> +__put_user(target_sigaltstack_used.ss_sp, &sf->uc.tuc_stack.ss_sp);
> +__put_user(sas_ss_flags(env->xregs[31]), &sf->uc.tuc_stack.ss_flags);
> +__put_user(target_sigaltstack_used.ss_size, &sf->uc.tuc_stack.ss_size);
>
>  for (i = 0; i < 31; i++) {
>  __put_user(env->xregs[i], &sf->uc.tuc_mcontext.regs[i]);
> @@ -1485,39 +1486,42 @@ static int target_setup_sigframe(struct 
> target_rt_sigframe *sf,
>  for (i = 0; i < TARGET_NSIG_WORDS; i++) {
>  __put_user(set->sig[i], &sf->uc.tuc_sigmask.sig[i]);
>  }
> +}
> +
> +static void target_setup_fpsimd_record(struct target_fpsimd_context *fpsimd,
> +   CPUARMState *env)
> +{
> +int i;
> +
> +__put_user(TARGET_FPSIMD_MAGIC, &fpsimd->head.magic);
> +__put_user(sizeof(struct target_fpsimd_context), &fpsimd->head.size);
> +__put_user(vfp_get_fpsr(env), &fpsimd->fpsr);
> +__put_user(vfp_get_fpcr(env), &fpsimd->fpcr);
>
>  for (i = 0; i < 32; i++) {
>  uint64_t *q = aa64_vfp_qreg(env, i);
>  #ifdef TARGET_WORDS_BIGENDIAN
> -__put_user(q[0], &aux->fpsimd.vregs[i * 2 + 1]);
> -__put_user(q[1], &aux->fpsimd.vregs[i * 2]);
> +__put_user(q[0], &fpsimd->vregs[i * 2 + 1]);
> +__put_user(q[1], &fpsimd->vregs[i * 2]);
>  #else
> -__put_user(q[0], &aux->fpsimd.vregs[i * 2]);
> -__put_user(q[1], &aux->fpsimd.vregs[i * 2 + 1]);
> +__put_user(q[0], &fpsimd->vregs[i * 2]);
> +__put_user(q[1], &fpsimd->vregs[i * 2 + 1]);
>  #endif
>  }
> -__put_user(vfp_get_fpsr(env), &aux->fpsimd.fpsr);
> -__put_user(vfp_get_fpcr(env), &aux->fpsimd.fpcr);
> -__put_user(TARGET_FPSIMD_MAGIC, &aux->fpsimd.head.magic);
> -__put_user(sizeof(struct target_fpsimd_context),
> -&aux->fpsimd.head.size);
> -
> -/* set the "end" magic */
> -__put_user(0, &aux->end.magic);
> -__put_user(0, &aux->end.size);
> -
> -return 0;
>  }
>
> -static int target_restore_sigframe(CPUARMState *env,
> -   struct target_rt_sigframe *sf)
> +static void target_setup_end_record(struct target_aarch64_ctx *end)
> +{
> +__put_user(0, &end->magic);
> +__put_user(0, &end->size);
> +}
> +
> +static void target_restore_general_frame(CPUARMState *env,
> + struct target_rt_sigframe *sf)
>  {
>  sigset_t set;
> -int i;
> -struct target_aux_context *aux =
> -(struct target_aux_context *)sf->uc.tuc_mcontext.__reserved;
> -uint32_t magic, size, fpsr, fpcr;
>  uint64_t pstate;
> +int i;
>
>  target_to_host_sigset(&set, &sf->uc.tuc_sigmask);
>  set_sigmask(&set);
> @@ -1530,30 +1534,48 @@ static int target_restore_sigframe(CPUARMState *env,
>  __get_user(env->pc, &sf->uc.tuc_mcontext.pc);
>  __get_user(pstate, &sf->uc.tuc_mcontext.pstate);
>  pstate_write(env, pstate);
> +}
>
> -__get_user(magic, &aux->fpsimd.head.magic);
> -__get_user(size, &aux->fpsimd.head.size);
> +static void target_restore_fpsimd_record(CPUARMState *env,
> + struct target_fpsimd_context 
> *fpsimd)
> +{
> +uint32_t fpsr, fpcr;
> +int i;
>
> -if (magic != TARGET_FPSIMD_MAGIC
> -|| size != sizeof(struct target_fpsimd_context)) {
> -return 1;
> -}
> +__get_user(fpsr, &fpsimd->fpsr);
> +vfp_set_fpsr(env, fpsr);
> +__get_user(fpcr, &fpsimd->fpcr);
> +vfp_set_fpcr(env, fpcr);
>
>  for (i = 0; i < 32; i++) {
>  uint64_t *q = aa64_vfp_qreg(env, i);
>

[Qemu-devel] [PATCH v4 2/5] aarch64-linux-user: Split out helpers for guest signal handling

2018-03-03 Thread Richard Henderson
Split out helpers from target_setup_frame and target_restore_sigframe
for dealing with general registers, fpsimd registers, and the end record.

When we add support for sve registers, the relative positions of
these will change.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 linux-user/signal.c | 120 ++--
 1 file changed, 69 insertions(+), 51 deletions(-)

diff --git a/linux-user/signal.c b/linux-user/signal.c
index 9a380b9e31..25c9743aed 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -1462,16 +1462,17 @@ struct target_rt_sigframe {
 uint32_t tramp[2];
 };
 
-static int target_setup_sigframe(struct target_rt_sigframe *sf,
- CPUARMState *env, target_sigset_t *set)
+static void target_setup_general_frame(struct target_rt_sigframe *sf,
+   CPUARMState *env, target_sigset_t *set)
 {
 int i;
-struct target_aux_context *aux =
-(struct target_aux_context *)sf->uc.tuc_mcontext.__reserved;
 
-/* set up the stack frame for unwinding */
-__put_user(env->xregs[29], &sf->fp);
-__put_user(env->xregs[30], &sf->lr);
+__put_user(0, &sf->uc.tuc_flags);
+__put_user(0, &sf->uc.tuc_link);
+
+__put_user(target_sigaltstack_used.ss_sp, &sf->uc.tuc_stack.ss_sp);
+__put_user(sas_ss_flags(env->xregs[31]), &sf->uc.tuc_stack.ss_flags);
+__put_user(target_sigaltstack_used.ss_size, &sf->uc.tuc_stack.ss_size);
 
 for (i = 0; i < 31; i++) {
 __put_user(env->xregs[i], &sf->uc.tuc_mcontext.regs[i]);
@@ -1485,39 +1486,42 @@ static int target_setup_sigframe(struct 
target_rt_sigframe *sf,
 for (i = 0; i < TARGET_NSIG_WORDS; i++) {
 __put_user(set->sig[i], &sf->uc.tuc_sigmask.sig[i]);
 }
+}
+
+static void target_setup_fpsimd_record(struct target_fpsimd_context *fpsimd,
+   CPUARMState *env)
+{
+int i;
+
+__put_user(TARGET_FPSIMD_MAGIC, &fpsimd->head.magic);
+__put_user(sizeof(struct target_fpsimd_context), &fpsimd->head.size);
+__put_user(vfp_get_fpsr(env), &fpsimd->fpsr);
+__put_user(vfp_get_fpcr(env), &fpsimd->fpcr);
 
 for (i = 0; i < 32; i++) {
 uint64_t *q = aa64_vfp_qreg(env, i);
 #ifdef TARGET_WORDS_BIGENDIAN
-__put_user(q[0], &aux->fpsimd.vregs[i * 2 + 1]);
-__put_user(q[1], &aux->fpsimd.vregs[i * 2]);
+__put_user(q[0], &fpsimd->vregs[i * 2 + 1]);
+__put_user(q[1], &fpsimd->vregs[i * 2]);
 #else
-__put_user(q[0], &aux->fpsimd.vregs[i * 2]);
-__put_user(q[1], &aux->fpsimd.vregs[i * 2 + 1]);
+__put_user(q[0], &fpsimd->vregs[i * 2]);
+__put_user(q[1], &fpsimd->vregs[i * 2 + 1]);
 #endif
 }
-__put_user(vfp_get_fpsr(env), &aux->fpsimd.fpsr);
-__put_user(vfp_get_fpcr(env), &aux->fpsimd.fpcr);
-__put_user(TARGET_FPSIMD_MAGIC, &aux->fpsimd.head.magic);
-__put_user(sizeof(struct target_fpsimd_context),
-&aux->fpsimd.head.size);
-
-/* set the "end" magic */
-__put_user(0, &aux->end.magic);
-__put_user(0, &aux->end.size);
-
-return 0;
 }
 
-static int target_restore_sigframe(CPUARMState *env,
-   struct target_rt_sigframe *sf)
+static void target_setup_end_record(struct target_aarch64_ctx *end)
+{
+__put_user(0, &end->magic);
+__put_user(0, &end->size);
+}
+
+static void target_restore_general_frame(CPUARMState *env,
+ struct target_rt_sigframe *sf)
 {
 sigset_t set;
-int i;
-struct target_aux_context *aux =
-(struct target_aux_context *)sf->uc.tuc_mcontext.__reserved;
-uint32_t magic, size, fpsr, fpcr;
 uint64_t pstate;
+int i;
 
 target_to_host_sigset(&set, &sf->uc.tuc_sigmask);
 set_sigmask(&set);
@@ -1530,30 +1534,48 @@ static int target_restore_sigframe(CPUARMState *env,
 __get_user(env->pc, &sf->uc.tuc_mcontext.pc);
 __get_user(pstate, &sf->uc.tuc_mcontext.pstate);
 pstate_write(env, pstate);
+}
 
-__get_user(magic, &aux->fpsimd.head.magic);
-__get_user(size, &aux->fpsimd.head.size);
+static void target_restore_fpsimd_record(CPUARMState *env,
+ struct target_fpsimd_context *fpsimd)
+{
+uint32_t fpsr, fpcr;
+int i;
 
-if (magic != TARGET_FPSIMD_MAGIC
-|| size != sizeof(struct target_fpsimd_context)) {
-return 1;
-}
+__get_user(fpsr, &fpsimd->fpsr);
+vfp_set_fpsr(env, fpsr);
+__get_user(fpcr, &fpsimd->fpcr);
+vfp_set_fpcr(env, fpcr);
 
 for (i = 0; i < 32; i++) {
 uint64_t *q = aa64_vfp_qreg(env, i);
 #ifdef TARGET_WORDS_BIGENDIAN
-__get_user(q[0], &aux->fpsimd.vregs[i * 2 + 1]);
-__get_user(q[1], &aux->fpsimd.vregs[i * 2]);
+__get_user(q[0], &fpsimd->vregs[i * 2 + 1]);
+__get_user(q[1], &fpsimd->vregs[i * 2]);
 #else
-__get_user(q[0], &aux->fpsimd.vregs[i * 2]);