??????????忴??sys_sigreturn()????壺

asmlinkage int sys_sigreturn(struct pt_regs *regs)
{
 struct sigframe __user *frame;
 sigset_t set;

 /* Always make any pending restarted system calls return -EINTR */
 current_thread_info()->restart_block.fn = do_no_restart_syscall;

 /*
  * Since we stacked the signal on a 64-bit boundary??
  * then 'sp' should be word aligned here.  If it's
  * not?? then the user is trying to mess with us.
  */
 if (regs->ARM_sp & 7)
  goto badframe;

 frame = (struct sigframe __user *)regs->ARM_sp;

 if (!access_ok(VERIFY_READ?? frame?? sizeof (*frame)))
  goto badframe;
 if (__get_user(set.sig[0]?? &frame->sc.oldmask)
     || (_NSIG_WORDS > 1
         && __copy_from_user(&set.sig[1]?? &frame->extramask??
        sizeof(frame->extramask))))
  goto badframe;

 sigdelsetmask(&set?? ~_BLOCKABLE);
 spin_lock_irq(&current->sighand->siglock);
 current->blocked = set;
 recalc_sigpending();
 spin_unlock_irq(&currentt->sighand->siglock);

 if (restore_sigcontext(regs?? &frame->sc?? &frame->aux))
  goto badframe;

 /* Send SIGTRAP if we're single-stepping */
 if (current->ptrace & PT_SINGLESTEP) {
  ptrace_cancel_bpt(current);
  send_sig(SIGTRAP?? current?? 1);
 }

 return regs->ARM_r0;

badframe:
 force_sig(SIGSEGV?? current);
 return 0;
}

??????????????????restore_sigcontext()???????????????sigframe??????pt_regs??

static int
restore_sigcontext(struct pt_regs *regs?? struct sigcontext __user *sc??
     struct aux_sigframe __user *aux)
{
 int err = 0;

 __get_user_error(regs->ARM_r0?? &sc->arm_r0?? err);
 __get_user_error(regs->ARM_r1?? &sc->arm_r1?? err);
 __get_user_error(regs->ARM_r2?? &sc->arm_r2?? err);
 __get_user_error(regs->ARM_r3?? &sc->arm_r3?? err);
 __get_user_error(regs->ARM_r4?? &sc->arm_r4?? err);
 __get_user_error(regs->ARM_r5?? &sc->arm_r5?? err);
 __get_user_error(regs->ARM_r6?? &sc->arm_r6?? err);
 __get_user_error(regs->ARM_r7?? &sc->arm_r7?? err);
 __get_user_error(regs->ARM_r8?? &sc->arm_r8?? err);
 __get_user_error(regs->ARM_r9?? &sc->arm_r9?? err);
 __get_user_error(regs->ARM_r10?? &sc->arm_r10?? err);
 __get_user_error(regs->ARM_fp?? &sc->arm_fp?? err);
 __get_user_error(regs->ARM_ip?? &sc->arm_ip?? err);
 __get_user_error(regs->ARM_sp?? &sc->arm_sp?? err);
 __get_user_error(regs->ARM_lr?? &sc->arm_lr?? err);
 __get_user_error(regs->ARM_pc?? &sc->arm_pc?? err);
 __get_user_error(regs->ARM_cpsr?? &sc->arm_cpsr?? err);

 err |= !valid_user_regs(regs);

#ifdef CONFIG_IWMMXT
 if (err == 0 && test_thread_flag(TIF_USING_IWMMXT))
  err |= restore_iwmmxt_context(&aux->iwmmxt);
#endif
#ifdef CONFIG_VFP
// if (err == 0)
//  err |= vfp_restore_state(&aux->vfp);
#endif

 return err;
}

????restore_sigcontext()?????????????????sys_sigreturn()???????????????pt_regs???????????????????????pt_regs????????sys_sigreturn()?????????????????????????????????