Hi Al,

Today's linux-next merge of the signal tree got conflicts in
arch/powerpc/kernel/signal_32.c and arch/powerpc/kernel/signal_64.c
between commit 2b0a576d15e0 ("powerpc: Add new transactional memory state
to the signal context") from the powerpc tree and commit 7cce246557bf
("powerpc: switch to generic sigaltstack") from the signal tree.

I fixed it up (I think - see below) and can carry the fix as necessary
(no action is required).

-- 
Cheers,
Stephen Rothwell                    s...@canb.auug.org.au

diff --cc arch/powerpc/kernel/signal_32.c
index e4a88d3,802ab5e..0000000
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@@ -817,223 -513,7 +742,140 @@@ static long restore_user_regs(struct pt
        return 0;
  }
  
 +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
 +/*
 + * Restore the current user register values from the user stack, except for
 + * MSR, and recheckpoint the original checkpointed register state for 
processes
 + * in transactions.
 + */
 +static long restore_tm_user_regs(struct pt_regs *regs,
 +                               struct mcontext __user *sr,
 +                               struct mcontext __user *tm_sr)
 +{
 +      long err;
 +      unsigned long msr;
 +#ifdef CONFIG_VSX
 +      int i;
 +#endif
 +
 +      /*
 +       * restore general registers but not including MSR or SOFTE. Also
 +       * take care of keeping r2 (TLS) intact if not a signal.
 +       * See comment in signal_64.c:restore_tm_sigcontexts();
 +       * TFHAR is restored from the checkpointed NIP; TEXASR and TFIAR
 +       * were set by the signal delivery.
 +       */
 +      err = restore_general_regs(regs, tm_sr);
 +      err |= restore_general_regs(&current->thread.ckpt_regs, sr);
 +
 +      err |= __get_user(current->thread.tm_tfhar, &sr->mc_gregs[PT_NIP]);
 +
 +      err |= __get_user(msr, &sr->mc_gregs[PT_MSR]);
 +      if (err)
 +              return 1;
 +
 +      /* Restore the previous little-endian mode */
 +      regs->msr = (regs->msr & ~MSR_LE) | (msr & MSR_LE);
 +
 +      /*
 +       * Do this before updating the thread state in
 +       * current->thread.fpr/vr/evr.  That way, if we get preempted
 +       * and another task grabs the FPU/Altivec/SPE, it won't be
 +       * tempted to save the current CPU state into the thread_struct
 +       * and corrupt what we are writing there.
 +       */
 +      discard_lazy_cpu_state();
 +
 +#ifdef CONFIG_ALTIVEC
 +      regs->msr &= ~MSR_VEC;
 +      if (msr & MSR_VEC) {
 +              /* restore altivec registers from the stack */
 +              if (__copy_from_user(current->thread.vr, &sr->mc_vregs,
 +                                   sizeof(sr->mc_vregs)) ||
 +                  __copy_from_user(current->thread.transact_vr,
 +                                   &tm_sr->mc_vregs,
 +                                   sizeof(sr->mc_vregs)))
 +                      return 1;
 +      } else if (current->thread.used_vr) {
 +              memset(current->thread.vr, 0, ELF_NVRREG * sizeof(vector128));
 +              memset(current->thread.transact_vr, 0,
 +                     ELF_NVRREG * sizeof(vector128));
 +      }
 +
 +      /* Always get VRSAVE back */
 +      if (__get_user(current->thread.vrsave,
 +                     (u32 __user *)&sr->mc_vregs[32]) ||
 +          __get_user(current->thread.transact_vrsave,
 +                     (u32 __user *)&tm_sr->mc_vregs[32]))
 +              return 1;
 +#endif /* CONFIG_ALTIVEC */
 +
 +      regs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1);
 +
 +      if (copy_fpr_from_user(current, &sr->mc_fregs) ||
 +          copy_transact_fpr_from_user(current, &tm_sr->mc_fregs))
 +              return 1;
 +
 +#ifdef CONFIG_VSX
 +      regs->msr &= ~MSR_VSX;
 +      if (msr & MSR_VSX) {
 +              /*
 +               * Restore altivec registers from the stack to a local
 +               * buffer, then write this out to the thread_struct
 +               */
 +              if (copy_vsx_from_user(current, &sr->mc_vsregs) ||
 +                  copy_transact_vsx_from_user(current, &tm_sr->mc_vsregs))
 +                      return 1;
 +      } else if (current->thread.used_vsr)
 +              for (i = 0; i < 32 ; i++) {
 +                      current->thread.fpr[i][TS_VSRLOWOFFSET] = 0;
 +                      current->thread.transact_fpr[i][TS_VSRLOWOFFSET] = 0;
 +              }
 +#endif /* CONFIG_VSX */
 +
 +#ifdef CONFIG_SPE
 +      /* SPE regs are not checkpointed with TM, so this section is
 +       * simply the same as in restore_user_regs().
 +       */
 +      regs->msr &= ~MSR_SPE;
 +      if (msr & MSR_SPE) {
 +              if (__copy_from_user(current->thread.evr, &sr->mc_vregs,
 +                                   ELF_NEVRREG * sizeof(u32)))
 +                      return 1;
 +      } else if (current->thread.used_spe)
 +              memset(current->thread.evr, 0, ELF_NEVRREG * sizeof(u32));
 +
 +      /* Always get SPEFSCR back */
 +      if (__get_user(current->thread.spefscr, (u32 __user *)&sr->mc_vregs
 +                     + ELF_NEVRREG))
 +              return 1;
 +#endif /* CONFIG_SPE */
 +
 +      /* Now, recheckpoint.  This loads up all of the checkpointed (older)
 +       * registers, including FP and V[S]Rs.  After recheckpointing, the
 +       * transactional versions should be loaded.
 +       */
 +      tm_enable();
 +      /* This loads the checkpointed FP/VEC state, if used */
 +      tm_recheckpoint(&current->thread, msr);
 +      /* The task has moved into TM state S, so ensure MSR reflects this */
 +      regs->msr = (regs->msr & ~MSR_TS_MASK) | MSR_TS_S;
 +
 +      /* This loads the speculative FP/VEC state, if used */
 +      if (msr & MSR_FP) {
 +              do_load_up_transact_fpu(&current->thread);
 +              regs->msr |= (MSR_FP | current->thread.fpexc_mode);
 +      }
 +      if (msr & MSR_VEC) {
 +              do_load_up_transact_altivec(&current->thread);
 +              regs->msr |= MSR_VEC;
 +      }
 +
 +      return 0;
 +}
 +#endif
 +
  #ifdef CONFIG_PPC64
- long compat_sys_rt_sigaction(int sig, const struct sigaction32 __user *act,
-               struct sigaction32 __user *oact, size_t sigsetsize)
- {
-       struct k_sigaction new_ka, old_ka;
-       int ret;
- 
-       /* XXX: Don't preclude handling different sized sigset_t's.  */
-       if (sigsetsize != sizeof(compat_sigset_t))
-               return -EINVAL;
- 
-       if (act) {
-               compat_uptr_t handler;
- 
-               ret = get_user(handler, &act->sa_handler);
-               new_ka.sa.sa_handler = compat_ptr(handler);
-               ret |= get_sigset_t(&new_ka.sa.sa_mask, &act->sa_mask);
-               ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
-               if (ret)
-                       return -EFAULT;
-       }
- 
-       ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
-       if (!ret && oact) {
-               ret = put_user(to_user_ptr(old_ka.sa.sa_handler), 
&oact->sa_handler);
-               ret |= put_sigset_t(&oact->sa_mask, &old_ka.sa.sa_mask);
-               ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
-       }
-       return ret;
- }
- 
- /*
-  * Note: it is necessary to treat how as an unsigned int, with the
-  * corresponding cast to a signed int to insure that the proper
-  * conversion (sign extension) between the register representation
-  * of a signed int (msr in 32-bit mode) and the register representation
-  * of a signed int (msr in 64-bit mode) is performed.
-  */
- long compat_sys_rt_sigprocmask(u32 how, compat_sigset_t __user *set,
-               compat_sigset_t __user *oset, size_t sigsetsize)
- {
-       sigset_t s;
-       sigset_t __user *up;
-       int ret;
-       mm_segment_t old_fs = get_fs();
- 
-       if (set) {
-               if (get_sigset_t(&s, set))
-                       return -EFAULT;
-       }
- 
-       set_fs(KERNEL_DS);
-       /* This is valid because of the set_fs() */
-       up = (sigset_t __user *) &s;
-       ret = sys_rt_sigprocmask((int)how, set ? up : NULL, oset ? up : NULL,
-                                sigsetsize);
-       set_fs(old_fs);
-       if (ret)
-               return ret;
-       if (oset) {
-               if (put_sigset_t(oset, &s))
-                       return -EFAULT;
-       }
-       return 0;
- }
- 
- long compat_sys_rt_sigpending(compat_sigset_t __user *set, compat_size_t 
sigsetsize)
- {
-       sigset_t s;
-       int ret;
-       mm_segment_t old_fs = get_fs();
- 
-       set_fs(KERNEL_DS);
-       /* The __user pointer cast is valid because of the set_fs() */
-       ret = sys_rt_sigpending((sigset_t __user *) &s, sigsetsize);
-       set_fs(old_fs);
-       if (!ret) {
-               if (put_sigset_t(set, &s))
-                       return -EFAULT;
-       }
-       return ret;
- }
- 
- 
  int copy_siginfo_to_user32(struct compat_siginfo __user *d, siginfo_t *s)
  {
        int err;
@@@ -1202,10 -607,8 +971,7 @@@ int handle_rt_signal32(unsigned long si
        /* Put the siginfo & fill in most of the ucontext */
        if (copy_siginfo_to_user(&rt_sf->info, info)
            || __put_user(0, &rt_sf->uc.uc_flags)
-           || __put_user(current->sas_ss_sp, &rt_sf->uc.uc_stack.ss_sp)
-           || __put_user(sas_ss_flags(regs->gpr[1]),
-                         &rt_sf->uc.uc_stack.ss_flags)
-           || __put_user(current->sas_ss_size, &rt_sf->uc.uc_stack.ss_size)
 -          || __put_user(0, &rt_sf->uc.uc_link)
+           || __save_altstack(&rt_sf->uc.uc_stack, regs->gpr[1])
            || __put_user(to_user_ptr(&rt_sf->uc.uc_mcontext),
                    &rt_sf->uc.uc_regs)
            || put_sigset_t(&rt_sf->uc.uc_sigmask, oldset))
diff --cc arch/powerpc/kernel/signal_64.c
index 7a76ee4,807b5b1..0000000
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@@ -723,29 -413,10 +721,26 @@@ int handle_rt_signal64(int signr, struc
  
        /* Create the ucontext.  */
        err |= __put_user(0, &frame->uc.uc_flags);
-       err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
-       err |= __put_user(sas_ss_flags(regs->gpr[1]),
-                         &frame->uc.uc_stack.ss_flags);
-       err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
 -      err |= __put_user(0, &frame->uc.uc_link);
+       err |= __save_altstack(&frame->uc.uc_stack, regs->gpr[1]);
 -      err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, signr, NULL,
 -                              (unsigned long)ka->sa.sa_handler, 1);
 +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
 +      if (MSR_TM_ACTIVE(regs->msr)) {
 +              /* The ucontext_t passed to userland points to the second
 +               * ucontext_t (for transactional state) with its uc_link ptr.
 +               */
 +              err |= __put_user(&frame->uc_transact, &frame->uc.uc_link);
 +              err |= setup_tm_sigcontexts(&frame->uc.uc_mcontext,
 +                                          &frame->uc_transact.uc_mcontext,
 +                                          regs, signr,
 +                                          NULL,
 +                                          (unsigned long)ka->sa.sa_handler);
 +      } else
 +#endif
 +      {
 +              err |= __put_user(0, &frame->uc.uc_link);
 +              err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, signr,
 +                                      NULL, (unsigned long)ka->sa.sa_handler,
 +                                      1);
 +      }
        err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
        if (err)
                goto badframe;

Attachment: pgp54LParMs1V.pgp
Description: PGP signature

_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Reply via email to