@@ -447,7 +447,7 @@ static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs)
447447
448448 if (CPU_IS_060 ? sc -> sc_fpstate [2 ] : sc -> sc_fpstate [0 ]) {
449449 fpu_version = sc -> sc_fpstate [0 ];
450- if (CPU_IS_020_OR_030 &&
450+ if (CPU_IS_020_OR_030 && ! regs -> stkadj &&
451451 regs -> vector >= (VEC_FPBRUC * 4 ) &&
452452 regs -> vector <= (VEC_FPNAN * 4 )) {
453453 /* Clear pending exception in 68882 idle frame */
@@ -510,7 +510,7 @@ static inline int rt_save_fpu_state(struct ucontext __user *uc, struct pt_regs *
510510 if (!(CPU_IS_060 || CPU_IS_COLDFIRE ))
511511 context_size = fpstate [1 ];
512512 fpu_version = fpstate [0 ];
513- if (CPU_IS_020_OR_030 &&
513+ if (CPU_IS_020_OR_030 && ! regs -> stkadj &&
514514 regs -> vector >= (VEC_FPBRUC * 4 ) &&
515515 regs -> vector <= (VEC_FPNAN * 4 )) {
516516 /* Clear pending exception in 68882 idle frame */
@@ -828,25 +828,32 @@ asmlinkage int do_rt_sigreturn(struct pt_regs *regs, struct switch_stack *sw)
828828 return 0 ;
829829}
830830
831+ static inline struct pt_regs * rte_regs (struct pt_regs * regs )
832+ {
833+ return (void * )regs + regs -> stkadj ;
834+ }
835+
831836static void setup_sigcontext (struct sigcontext * sc , struct pt_regs * regs ,
832837 unsigned long mask )
833838{
839+ struct pt_regs * tregs = rte_regs (regs );
834840 sc -> sc_mask = mask ;
835841 sc -> sc_usp = rdusp ();
836842 sc -> sc_d0 = regs -> d0 ;
837843 sc -> sc_d1 = regs -> d1 ;
838844 sc -> sc_a0 = regs -> a0 ;
839845 sc -> sc_a1 = regs -> a1 ;
840- sc -> sc_sr = regs -> sr ;
841- sc -> sc_pc = regs -> pc ;
842- sc -> sc_formatvec = regs -> format << 12 | regs -> vector ;
846+ sc -> sc_sr = tregs -> sr ;
847+ sc -> sc_pc = tregs -> pc ;
848+ sc -> sc_formatvec = tregs -> format << 12 | tregs -> vector ;
843849 save_a5_state (sc , regs );
844850 save_fpu_state (sc , regs );
845851}
846852
847853static inline int rt_setup_ucontext (struct ucontext __user * uc , struct pt_regs * regs )
848854{
849855 struct switch_stack * sw = (struct switch_stack * )regs - 1 ;
856+ struct pt_regs * tregs = rte_regs (regs );
850857 greg_t __user * gregs = uc -> uc_mcontext .gregs ;
851858 int err = 0 ;
852859
@@ -867,9 +874,9 @@ static inline int rt_setup_ucontext(struct ucontext __user *uc, struct pt_regs *
867874 err |= __put_user (sw -> a5 , & gregs [13 ]);
868875 err |= __put_user (sw -> a6 , & gregs [14 ]);
869876 err |= __put_user (rdusp (), & gregs [15 ]);
870- err |= __put_user (regs -> pc , & gregs [16 ]);
871- err |= __put_user (regs -> sr , & gregs [17 ]);
872- err |= __put_user ((regs -> format << 12 ) | regs -> vector , & uc -> uc_formatvec );
877+ err |= __put_user (tregs -> pc , & gregs [16 ]);
878+ err |= __put_user (tregs -> sr , & gregs [17 ]);
879+ err |= __put_user ((tregs -> format << 12 ) | tregs -> vector , & uc -> uc_formatvec );
873880 err |= rt_save_fpu_state (uc , regs );
874881 return err ;
875882}
@@ -886,13 +893,14 @@ static int setup_frame(struct ksignal *ksig, sigset_t *set,
886893 struct pt_regs * regs )
887894{
888895 struct sigframe __user * frame ;
889- int fsize = frame_extra_sizes (regs -> format );
896+ struct pt_regs * tregs = rte_regs (regs );
897+ int fsize = frame_extra_sizes (tregs -> format );
890898 struct sigcontext context ;
891899 int err = 0 , sig = ksig -> sig ;
892900
893901 if (fsize < 0 ) {
894902 pr_debug ("setup_frame: Unknown frame format %#x\n" ,
895- regs -> format );
903+ tregs -> format );
896904 return - EFAULT ;
897905 }
898906
@@ -903,7 +911,7 @@ static int setup_frame(struct ksignal *ksig, sigset_t *set,
903911
904912 err |= __put_user (sig , & frame -> sig );
905913
906- err |= __put_user (regs -> vector , & frame -> code );
914+ err |= __put_user (tregs -> vector , & frame -> code );
907915 err |= __put_user (& frame -> sc , & frame -> psc );
908916
909917 if (_NSIG_WORDS > 1 )
@@ -929,42 +937,37 @@ static int setup_frame(struct ksignal *ksig, sigset_t *set,
929937
930938 push_cache ((unsigned long ) & frame -> retcode );
931939
932- /*
933- * Set up registers for signal handler. All the state we are about
934- * to destroy is successfully copied to sigframe.
935- */
936- wrusp ((unsigned long ) frame );
937- regs -> pc = (unsigned long ) ksig -> ka .sa .sa_handler ;
938- adjustformat (regs );
939-
940940 /*
941941 * This is subtle; if we build more than one sigframe, all but the
942942 * first one will see frame format 0 and have fsize == 0, so we won't
943943 * screw stkadj.
944944 */
945- if (fsize )
945+ if (fsize ) {
946946 regs -> stkadj = fsize ;
947-
948- /* Prepare to skip over the extra stuff in the exception frame. */
949- if (regs -> stkadj ) {
950- struct pt_regs * tregs =
951- (struct pt_regs * )((ulong )regs + regs -> stkadj );
947+ tregs = rte_regs (regs );
952948 pr_debug ("Performing stackadjust=%04lx\n" , regs -> stkadj );
953- /* This must be copied with decreasing addresses to
954- handle overlaps. */
955949 tregs -> vector = 0 ;
956950 tregs -> format = 0 ;
957- tregs -> pc = regs -> pc ;
958951 tregs -> sr = regs -> sr ;
959952 }
953+
954+ /*
955+ * Set up registers for signal handler. All the state we are about
956+ * to destroy is successfully copied to sigframe.
957+ */
958+ wrusp ((unsigned long ) frame );
959+ tregs -> pc = (unsigned long ) ksig -> ka .sa .sa_handler ;
960+ adjustformat (regs );
961+
960962 return 0 ;
961963}
962964
963965static int setup_rt_frame (struct ksignal * ksig , sigset_t * set ,
964966 struct pt_regs * regs )
965967{
966968 struct rt_sigframe __user * frame ;
967- int fsize = frame_extra_sizes (regs -> format );
969+ struct pt_regs * tregs = rte_regs (regs );
970+ int fsize = frame_extra_sizes (tregs -> format );
968971 int err = 0 , sig = ksig -> sig ;
969972
970973 if (fsize < 0 ) {
@@ -1014,34 +1017,27 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
10141017
10151018 push_cache ((unsigned long ) & frame -> retcode );
10161019
1017- /*
1018- * Set up registers for signal handler. All the state we are about
1019- * to destroy is successfully copied to sigframe.
1020- */
1021- wrusp ((unsigned long ) frame );
1022- regs -> pc = (unsigned long ) ksig -> ka .sa .sa_handler ;
1023- adjustformat (regs );
1024-
10251020 /*
10261021 * This is subtle; if we build more than one sigframe, all but the
10271022 * first one will see frame format 0 and have fsize == 0, so we won't
10281023 * screw stkadj.
10291024 */
1030- if (fsize )
1025+ if (fsize ) {
10311026 regs -> stkadj = fsize ;
1032-
1033- /* Prepare to skip over the extra stuff in the exception frame. */
1034- if (regs -> stkadj ) {
1035- struct pt_regs * tregs =
1036- (struct pt_regs * )((ulong )regs + regs -> stkadj );
1027+ tregs = rte_regs (regs );
10371028 pr_debug ("Performing stackadjust=%04lx\n" , regs -> stkadj );
1038- /* This must be copied with decreasing addresses to
1039- handle overlaps. */
10401029 tregs -> vector = 0 ;
10411030 tregs -> format = 0 ;
1042- tregs -> pc = regs -> pc ;
10431031 tregs -> sr = regs -> sr ;
10441032 }
1033+
1034+ /*
1035+ * Set up registers for signal handler. All the state we are about
1036+ * to destroy is successfully copied to sigframe.
1037+ */
1038+ wrusp ((unsigned long ) frame );
1039+ tregs -> pc = (unsigned long ) ksig -> ka .sa .sa_handler ;
1040+ adjustformat (regs );
10451041 return 0 ;
10461042}
10471043
0 commit comments