diff options
author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2007-02-20 14:13:30 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2007-02-20 14:13:30 -0500 |
commit | 5a84d159061d914c8dd4aa372ac6e9529c2be453 (patch) | |
tree | 9b08af78085334af44414adafe0096276f8fe0ff /kernel/signal.c | |
parent | e80a0e6e7ccdf64575d4384cb4172860422f5b81 (diff) | |
parent | 7d477a04a619e90ee08724e8f2d8803c6bdfcef8 (diff) |
Merge ARM fixes
Diffstat (limited to 'kernel/signal.c')
-rw-r--r-- | kernel/signal.c | 110 |
1 files changed, 55 insertions, 55 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index 5630255d2e2a..e2a7d4bf7d57 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -456,26 +456,50 @@ static int __dequeue_signal(struct sigpending *pending, sigset_t *mask, | |||
456 | int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info) | 456 | int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info) |
457 | { | 457 | { |
458 | int signr = __dequeue_signal(&tsk->pending, mask, info); | 458 | int signr = __dequeue_signal(&tsk->pending, mask, info); |
459 | if (!signr) | 459 | if (!signr) { |
460 | signr = __dequeue_signal(&tsk->signal->shared_pending, | 460 | signr = __dequeue_signal(&tsk->signal->shared_pending, |
461 | mask, info); | 461 | mask, info); |
462 | /* | ||
463 | * itimer signal ? | ||
464 | * | ||
465 | * itimers are process shared and we restart periodic | ||
466 | * itimers in the signal delivery path to prevent DoS | ||
467 | * attacks in the high resolution timer case. This is | ||
468 | * compliant with the old way of self restarting | ||
469 | * itimers, as the SIGALRM is a legacy signal and only | ||
470 | * queued once. Changing the restart behaviour to | ||
471 | * restart the timer in the signal dequeue path is | ||
472 | * reducing the timer noise on heavy loaded !highres | ||
473 | * systems too. | ||
474 | */ | ||
475 | if (unlikely(signr == SIGALRM)) { | ||
476 | struct hrtimer *tmr = &tsk->signal->real_timer; | ||
477 | |||
478 | if (!hrtimer_is_queued(tmr) && | ||
479 | tsk->signal->it_real_incr.tv64 != 0) { | ||
480 | hrtimer_forward(tmr, tmr->base->get_time(), | ||
481 | tsk->signal->it_real_incr); | ||
482 | hrtimer_restart(tmr); | ||
483 | } | ||
484 | } | ||
485 | } | ||
462 | recalc_sigpending_tsk(tsk); | 486 | recalc_sigpending_tsk(tsk); |
463 | if (signr && unlikely(sig_kernel_stop(signr))) { | 487 | if (signr && unlikely(sig_kernel_stop(signr))) { |
464 | /* | 488 | /* |
465 | * Set a marker that we have dequeued a stop signal. Our | 489 | * Set a marker that we have dequeued a stop signal. Our |
466 | * caller might release the siglock and then the pending | 490 | * caller might release the siglock and then the pending |
467 | * stop signal it is about to process is no longer in the | 491 | * stop signal it is about to process is no longer in the |
468 | * pending bitmasks, but must still be cleared by a SIGCONT | 492 | * pending bitmasks, but must still be cleared by a SIGCONT |
469 | * (and overruled by a SIGKILL). So those cases clear this | 493 | * (and overruled by a SIGKILL). So those cases clear this |
470 | * shared flag after we've set it. Note that this flag may | 494 | * shared flag after we've set it. Note that this flag may |
471 | * remain set after the signal we return is ignored or | 495 | * remain set after the signal we return is ignored or |
472 | * handled. That doesn't matter because its only purpose | 496 | * handled. That doesn't matter because its only purpose |
473 | * is to alert stop-signal processing code when another | 497 | * is to alert stop-signal processing code when another |
474 | * processor has come along and cleared the flag. | 498 | * processor has come along and cleared the flag. |
475 | */ | 499 | */ |
476 | if (!(tsk->signal->flags & SIGNAL_GROUP_EXIT)) | 500 | if (!(tsk->signal->flags & SIGNAL_GROUP_EXIT)) |
477 | tsk->signal->flags |= SIGNAL_STOP_DEQUEUED; | 501 | tsk->signal->flags |= SIGNAL_STOP_DEQUEUED; |
478 | } | 502 | } |
479 | if ( signr && | 503 | if ( signr && |
480 | ((info->si_code & __SI_MASK) == __SI_TIMER) && | 504 | ((info->si_code & __SI_MASK) == __SI_TIMER) && |
481 | info->si_sys_private){ | 505 | info->si_sys_private){ |
@@ -1096,42 +1120,21 @@ int kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp) | |||
1096 | return retval; | 1120 | return retval; |
1097 | } | 1121 | } |
1098 | 1122 | ||
1099 | int __kill_pg_info(int sig, struct siginfo *info, pid_t pgrp) | ||
1100 | { | ||
1101 | if (pgrp <= 0) | ||
1102 | return -EINVAL; | ||
1103 | |||
1104 | return __kill_pgrp_info(sig, info, find_pid(pgrp)); | ||
1105 | } | ||
1106 | |||
1107 | int | ||
1108 | kill_pg_info(int sig, struct siginfo *info, pid_t pgrp) | ||
1109 | { | ||
1110 | int retval; | ||
1111 | |||
1112 | read_lock(&tasklist_lock); | ||
1113 | retval = __kill_pg_info(sig, info, pgrp); | ||
1114 | read_unlock(&tasklist_lock); | ||
1115 | |||
1116 | return retval; | ||
1117 | } | ||
1118 | |||
1119 | int kill_pid_info(int sig, struct siginfo *info, struct pid *pid) | 1123 | int kill_pid_info(int sig, struct siginfo *info, struct pid *pid) |
1120 | { | 1124 | { |
1121 | int error; | 1125 | int error; |
1122 | int acquired_tasklist_lock = 0; | ||
1123 | struct task_struct *p; | 1126 | struct task_struct *p; |
1124 | 1127 | ||
1125 | rcu_read_lock(); | 1128 | rcu_read_lock(); |
1126 | if (unlikely(sig_needs_tasklist(sig))) { | 1129 | if (unlikely(sig_needs_tasklist(sig))) |
1127 | read_lock(&tasklist_lock); | 1130 | read_lock(&tasklist_lock); |
1128 | acquired_tasklist_lock = 1; | 1131 | |
1129 | } | ||
1130 | p = pid_task(pid, PIDTYPE_PID); | 1132 | p = pid_task(pid, PIDTYPE_PID); |
1131 | error = -ESRCH; | 1133 | error = -ESRCH; |
1132 | if (p) | 1134 | if (p) |
1133 | error = group_send_sig_info(sig, info, p); | 1135 | error = group_send_sig_info(sig, info, p); |
1134 | if (unlikely(acquired_tasklist_lock)) | 1136 | |
1137 | if (unlikely(sig_needs_tasklist(sig))) | ||
1135 | read_unlock(&tasklist_lock); | 1138 | read_unlock(&tasklist_lock); |
1136 | rcu_read_unlock(); | 1139 | rcu_read_unlock(); |
1137 | return error; | 1140 | return error; |
@@ -1192,8 +1195,10 @@ EXPORT_SYMBOL_GPL(kill_pid_info_as_uid); | |||
1192 | 1195 | ||
1193 | static int kill_something_info(int sig, struct siginfo *info, int pid) | 1196 | static int kill_something_info(int sig, struct siginfo *info, int pid) |
1194 | { | 1197 | { |
1198 | int ret; | ||
1199 | rcu_read_lock(); | ||
1195 | if (!pid) { | 1200 | if (!pid) { |
1196 | return kill_pg_info(sig, info, process_group(current)); | 1201 | ret = kill_pgrp_info(sig, info, task_pgrp(current)); |
1197 | } else if (pid == -1) { | 1202 | } else if (pid == -1) { |
1198 | int retval = 0, count = 0; | 1203 | int retval = 0, count = 0; |
1199 | struct task_struct * p; | 1204 | struct task_struct * p; |
@@ -1208,12 +1213,14 @@ static int kill_something_info(int sig, struct siginfo *info, int pid) | |||
1208 | } | 1213 | } |
1209 | } | 1214 | } |
1210 | read_unlock(&tasklist_lock); | 1215 | read_unlock(&tasklist_lock); |
1211 | return count ? retval : -ESRCH; | 1216 | ret = count ? retval : -ESRCH; |
1212 | } else if (pid < 0) { | 1217 | } else if (pid < 0) { |
1213 | return kill_pg_info(sig, info, -pid); | 1218 | ret = kill_pgrp_info(sig, info, find_pid(-pid)); |
1214 | } else { | 1219 | } else { |
1215 | return kill_proc_info(sig, info, pid); | 1220 | ret = kill_pid_info(sig, info, find_pid(pid)); |
1216 | } | 1221 | } |
1222 | rcu_read_unlock(); | ||
1223 | return ret; | ||
1217 | } | 1224 | } |
1218 | 1225 | ||
1219 | /* | 1226 | /* |
@@ -1312,12 +1319,6 @@ int kill_pid(struct pid *pid, int sig, int priv) | |||
1312 | EXPORT_SYMBOL(kill_pid); | 1319 | EXPORT_SYMBOL(kill_pid); |
1313 | 1320 | ||
1314 | int | 1321 | int |
1315 | kill_pg(pid_t pgrp, int sig, int priv) | ||
1316 | { | ||
1317 | return kill_pg_info(sig, __si_special(priv), pgrp); | ||
1318 | } | ||
1319 | |||
1320 | int | ||
1321 | kill_proc(pid_t pid, int sig, int priv) | 1322 | kill_proc(pid_t pid, int sig, int priv) |
1322 | { | 1323 | { |
1323 | return kill_proc_info(sig, __si_special(priv), pid); | 1324 | return kill_proc_info(sig, __si_special(priv), pid); |
@@ -1906,7 +1907,7 @@ relock: | |||
1906 | 1907 | ||
1907 | /* signals can be posted during this window */ | 1908 | /* signals can be posted during this window */ |
1908 | 1909 | ||
1909 | if (is_orphaned_pgrp(process_group(current))) | 1910 | if (is_current_pgrp_orphaned()) |
1910 | goto relock; | 1911 | goto relock; |
1911 | 1912 | ||
1912 | spin_lock_irq(¤t->sighand->siglock); | 1913 | spin_lock_irq(¤t->sighand->siglock); |
@@ -1956,7 +1957,6 @@ EXPORT_SYMBOL(recalc_sigpending); | |||
1956 | EXPORT_SYMBOL_GPL(dequeue_signal); | 1957 | EXPORT_SYMBOL_GPL(dequeue_signal); |
1957 | EXPORT_SYMBOL(flush_signals); | 1958 | EXPORT_SYMBOL(flush_signals); |
1958 | EXPORT_SYMBOL(force_sig); | 1959 | EXPORT_SYMBOL(force_sig); |
1959 | EXPORT_SYMBOL(kill_pg); | ||
1960 | EXPORT_SYMBOL(kill_proc); | 1960 | EXPORT_SYMBOL(kill_proc); |
1961 | EXPORT_SYMBOL(ptrace_notify); | 1961 | EXPORT_SYMBOL(ptrace_notify); |
1962 | EXPORT_SYMBOL(send_sig); | 1962 | EXPORT_SYMBOL(send_sig); |
@@ -2283,7 +2283,7 @@ static int do_tkill(int tgid, int pid, int sig) | |||
2283 | * @pid: the PID of the thread | 2283 | * @pid: the PID of the thread |
2284 | * @sig: signal to be sent | 2284 | * @sig: signal to be sent |
2285 | * | 2285 | * |
2286 | * This syscall also checks the tgid and returns -ESRCH even if the PID | 2286 | * This syscall also checks the @tgid and returns -ESRCH even if the PID |
2287 | * exists but it's not belonging to the target process anymore. This | 2287 | * exists but it's not belonging to the target process anymore. This |
2288 | * method solves the problem of threads exiting and PIDs getting reused. | 2288 | * method solves the problem of threads exiting and PIDs getting reused. |
2289 | */ | 2289 | */ |