???????????????????????do_notify_resume()?????????????е???????????????????sighand_struct???ж???????????????do_notify_resume()(arch/arm/kernel/signal.c)????????????£?

asmlinkage void
do_notify_resume(struct pt_regs *regs?? unsigned int thread_flags?? int syscall)
{
 if (thread_flags & _TIF_SIGPENDING)
  do_signal(&current->blocked?? regs?? syscall);
}

????_TIF_SIGPENDING???????signal_wake_up()??????????????????????????????do_signal()????????????????do_signal()(arch/arm/kernel/signal.c)????嶨?壺

/*
 * Note that 'init' is a special process: it doesn't get signals it doesn't
 * want to handle. Thus you cannot kill init even with a SIGKILL even by
 * mistake.
 *
 * Note that we go through the signals twice: once to check the signals that
 * the kernel can handle?? and then we build all the user-level signal handling
 * stack-frames in one go after that.
 */
static int do_signal(sigset_t *oldset?? struct pt_regs *regs?? int syscall)
{
 struct k_sigaction ka;
 siginfo_t info;
 int signr;

 /*
  * We want the common case to go fast?? which
  * is why we may in certain cases get here from
  * kernel mode. Just return without doing anything
  * if so.
  */
 if (!user_mode(regs))//regs?????????????????????????????????????????????????
  return 0;

 if (try_to_freeze())
  goto no_signal;

 if (current->ptrace & PT_SINGLESTEP)
  ptrace_cancel_bpt(current);//????????????????????????л???????

 signr = get_signal_to_deliver(&info?? &ka?? regs?? NULL);//??????????????
 if (signr > 0) {
  handle_signal(signr?? &ka?? &info?? oldset?? regs?? syscall);//???????
  if (current->ptrace & PT_SINGLESTEP)
   ptrace_set_bpt(current);
  return 1;
 }

 no_signal:
 /*
  * No signal to deliver to the process - restart the syscall.
  */
 if (syscall) {
  if (regs->ARM_r0 == -ERESTART_RESTARTBLOCK) {
   if (thumb_mode(regs)) {
    regs->ARM_r7 = __NR_restart_syscall;
    regs->ARM_pc -= 2;
   } else {
    u32 __user *usp;

    regs->ARM_sp -= 12;
    usp = (u32 __user *)regs->ARM_sp;

    put_user(regs->ARM_pc?? &usp[0]);
    /* swi __NR_restart_syscall */
    put_user(0xef000000 | __NR_restart_syscall?? &usp[1]);
    /* ldr pc?? [sp]?? #12 */
    put_user(0xe49df00c?? &usp[2]);

    flush_icache_range((unsigned long)usp??
         (unsigned long)(usp + 3));

    regs->ARM_pc = regs->ARM_sp + 4;
   }
  }
  if (regs->ARM_r0 == -ERESTARTNOHAND ||
      regs->ARM_r0 == -ERESTARTSYS ||
      regs->ARM_r0 == -ERESTARTNOINTR) {
   restart_syscall(regs);
  }
 }
 if (current->ptrace & PT_SINGLESTEP)
  ptrace_set_bpt(current);
 return 0;
}

???????do_signal()?????????????????????????????????????ж?????????ò???????????regs????????????????ж?????????user_mode()????regs?е?cpsr????????ж????ж??????????????????????????????????????????????????κδ????????do_signal()?????????

???????user_mode()????????regs?????????????????ζ??????????????????????????????????ж????????????????ж????(???????????ù????з??????ж?)????????????·????????????????????????????????????????????????ж??????????????(???user_mode(regs)????1????ζ???ж????????????)????????ж????????????????????????????ж??????CPU?????и??????????????(???user_mode(regs)????0????ζ???ж????????????)????????????ж?????????????????????????????????????????????????ж????????????????????£?????????????????????????ж???????????????Windows????????????linux?????????????????????????????????е???????????????????linux????Windows?????????????????????????????????????ж?->????????ж?->???ж?(????Windows???е?DPC)->???(????Windows????е?APC)->???????С?