|
@@ -588,104 +588,3 @@ ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall)
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
-
|
|
|
-/* Set a delayed signal that was detected in MCA/INIT/NMI/PMI context where it
|
|
|
- * could not be delivered. It is important that the target process is not
|
|
|
- * allowed to do any more work in user space. Possible cases for the target
|
|
|
- * process:
|
|
|
- *
|
|
|
- * - It is sleeping and will wake up soon. Store the data in the current task,
|
|
|
- * the signal will be sent when the current task returns from the next
|
|
|
- * interrupt.
|
|
|
- *
|
|
|
- * - It is running in user context. Store the data in the current task, the
|
|
|
- * signal will be sent when the current task returns from the next interrupt.
|
|
|
- *
|
|
|
- * - It is running in kernel context on this or another cpu and will return to
|
|
|
- * user context. Store the data in the target task, the signal will be sent
|
|
|
- * to itself when the target task returns to user space.
|
|
|
- *
|
|
|
- * - It is running in kernel context on this cpu and will sleep before
|
|
|
- * returning to user context. Because this is also the current task, the
|
|
|
- * signal will not get delivered and the task could sleep indefinitely.
|
|
|
- * Store the data in the idle task for this cpu, the signal will be sent
|
|
|
- * after the idle task processes its next interrupt.
|
|
|
- *
|
|
|
- * To cover all cases, store the data in the target task, the current task and
|
|
|
- * the idle task on this cpu. Whatever happens, the signal will be delivered
|
|
|
- * to the target task before it can do any useful user space work. Multiple
|
|
|
- * deliveries have no unwanted side effects.
|
|
|
- *
|
|
|
- * Note: This code is executed in MCA/INIT/NMI/PMI context, with interrupts
|
|
|
- * disabled. It must not take any locks nor use kernel structures or services
|
|
|
- * that require locks.
|
|
|
- */
|
|
|
-
|
|
|
-/* To ensure that we get the right pid, check its start time. To avoid extra
|
|
|
- * include files in thread_info.h, convert the task start_time to unsigned long,
|
|
|
- * giving us a cycle time of > 580 years.
|
|
|
- */
|
|
|
-static inline unsigned long
|
|
|
-start_time_ul(const struct task_struct *t)
|
|
|
-{
|
|
|
- return t->start_time.tv_sec * NSEC_PER_SEC + t->start_time.tv_nsec;
|
|
|
-}
|
|
|
-
|
|
|
-void
|
|
|
-set_sigdelayed(pid_t pid, int signo, int code, void __user *addr)
|
|
|
-{
|
|
|
- struct task_struct *t;
|
|
|
- unsigned long start_time = 0;
|
|
|
- int i;
|
|
|
-
|
|
|
- for (i = 1; i <= 3; ++i) {
|
|
|
- switch (i) {
|
|
|
- case 1:
|
|
|
- t = find_task_by_pid(pid);
|
|
|
- if (t)
|
|
|
- start_time = start_time_ul(t);
|
|
|
- break;
|
|
|
- case 2:
|
|
|
- t = current;
|
|
|
- break;
|
|
|
- default:
|
|
|
- t = idle_task(smp_processor_id());
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- if (!t)
|
|
|
- return;
|
|
|
- task_thread_info(t)->sigdelayed.signo = signo;
|
|
|
- task_thread_info(t)->sigdelayed.code = code;
|
|
|
- task_thread_info(t)->sigdelayed.addr = addr;
|
|
|
- task_thread_info(t)->sigdelayed.start_time = start_time;
|
|
|
- task_thread_info(t)->sigdelayed.pid = pid;
|
|
|
- wmb();
|
|
|
- set_tsk_thread_flag(t, TIF_SIGDELAYED);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-/* Called from entry.S when it detects TIF_SIGDELAYED, a delayed signal that
|
|
|
- * was detected in MCA/INIT/NMI/PMI context where it could not be delivered.
|
|
|
- */
|
|
|
-
|
|
|
-void
|
|
|
-do_sigdelayed(void)
|
|
|
-{
|
|
|
- struct siginfo siginfo;
|
|
|
- pid_t pid;
|
|
|
- struct task_struct *t;
|
|
|
-
|
|
|
- clear_thread_flag(TIF_SIGDELAYED);
|
|
|
- memset(&siginfo, 0, sizeof(siginfo));
|
|
|
- siginfo.si_signo = current_thread_info()->sigdelayed.signo;
|
|
|
- siginfo.si_code = current_thread_info()->sigdelayed.code;
|
|
|
- siginfo.si_addr = current_thread_info()->sigdelayed.addr;
|
|
|
- pid = current_thread_info()->sigdelayed.pid;
|
|
|
- t = find_task_by_pid(pid);
|
|
|
- if (!t)
|
|
|
- return;
|
|
|
- if (current_thread_info()->sigdelayed.start_time != start_time_ul(t))
|
|
|
- return;
|
|
|
- force_sig_info(siginfo.si_signo, &siginfo, t);
|
|
|
-}
|