static void handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, struct pt_regs *regs) { sigset_t *oldset = sigmask_to_save(); int ret; struct mips_abi *abi = current->thread.abi; #ifdef CONFIG_CPU_MICROMIPS void *vdso; unsigned int tmp = (unsigned int)current->mm->context.vdso; set_isa16_mode(tmp); vdso = (void *)tmp; #else void *vdso = current->mm->context.vdso; #endif if (regs->regs[0]) { switch(regs->regs[2]) { case ERESTART_RESTARTBLOCK: case ERESTARTNOHAND: regs->regs[2] = EINTR; break; case ERESTARTSYS: if (!(ka->sa.sa_flags & SA_RESTART)) { regs->regs[2] = EINTR; break; } /* fallthrough */ case ERESTARTNOINTR: regs->regs[7] = regs->regs[26]; regs->regs[2] = regs->regs[0]; regs->cp0_epc -= 4; } regs->regs[0] = 0; /* Don't deal with this again. */ } if (sig_uses_siginfo(ka)) ret = abi->setup_rt_frame(vdso + abi->rt_signal_return_offset, ka, regs, sig, oldset, info); else ret = abi->setup_frame(vdso + abi->signal_return_offset, ka, regs, sig, oldset); if (ret) return; signal_delivered(sig, info, ka, regs, 0); }
static int handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs) { int ret; struct mips_abi *abi = current->thread.abi; void *vdso = current->mm->context.vdso; if (regs->regs[0]) { switch(regs->regs[2]) { case ERESTART_RESTARTBLOCK: case ERESTARTNOHAND: regs->regs[2] = EINTR; break; case ERESTARTSYS: if (!(ka->sa.sa_flags & SA_RESTART)) { regs->regs[2] = EINTR; break; } /* fallthrough */ case ERESTARTNOINTR: regs->regs[7] = regs->regs[26]; regs->regs[2] = regs->regs[0]; regs->cp0_epc -= 4; } regs->regs[0] = 0; /* Don't deal with this again. */ } if (sig_uses_siginfo(ka)) ret = abi->setup_rt_frame(vdso + abi->rt_signal_return_offset, ka, regs, sig, oldset, info); else ret = abi->setup_frame(vdso + abi->signal_return_offset, ka, regs, sig, oldset); if (ret) return ret; spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); if (!(ka->sa.sa_flags & SA_NODEFER)) sigaddset(¤t->blocked,sig); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); return ret; }
static inline int handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs) { int ret; switch(regs->regs[0]) { case ERESTART_RESTARTBLOCK: case ERESTARTNOHAND: regs->regs[2] = EINTR; break; case ERESTARTSYS: if (!(ka->sa.sa_flags & SA_RESTART)) { regs->regs[2] = EINTR; break; } /* fallthrough */ case ERESTARTNOINTR: /* Userland will reload $v0. */ regs->regs[7] = regs->regs[26]; regs->cp0_epc -= 8; } regs->regs[0] = 0; /* Don't deal with this again. */ if (sig_uses_siginfo(ka)) ret = current->thread.abi->setup_rt_frame(ka, regs, sig, oldset, info); else ret = current->thread.abi->setup_frame(ka, regs, sig, oldset); spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); if (!(ka->sa.sa_flags & SA_NODEFER)) sigaddset(¤t->blocked,sig); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); return ret; }