diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/exit.c | 9 | ||||
-rw-r--r-- | kernel/futex.c | 28 | ||||
-rw-r--r-- | kernel/hung_task.c | 14 | ||||
-rw-r--r-- | kernel/ptrace.c | 13 | ||||
-rw-r--r-- | kernel/signal.c | 2 | ||||
-rw-r--r-- | kernel/time/clockevents.c | 1 | ||||
-rw-r--r-- | kernel/tracepoint.c | 7 |
7 files changed, 54 insertions, 20 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index d0b7d988f873..e6e01b959a0e 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -1540,8 +1540,15 @@ static int wait_consider_task(struct wait_opts *wo, int ptrace, | |||
1540 | } | 1540 | } |
1541 | 1541 | ||
1542 | /* dead body doesn't have much to contribute */ | 1542 | /* dead body doesn't have much to contribute */ |
1543 | if (p->exit_state == EXIT_DEAD) | 1543 | if (unlikely(p->exit_state == EXIT_DEAD)) { |
1544 | /* | ||
1545 | * But do not ignore this task until the tracer does | ||
1546 | * wait_task_zombie()->do_notify_parent(). | ||
1547 | */ | ||
1548 | if (likely(!ptrace) && unlikely(ptrace_reparented(p))) | ||
1549 | wo->notask_error = 0; | ||
1544 | return 0; | 1550 | return 0; |
1551 | } | ||
1545 | 1552 | ||
1546 | /* slay zombie? */ | 1553 | /* slay zombie? */ |
1547 | if (p->exit_state == EXIT_ZOMBIE) { | 1554 | if (p->exit_state == EXIT_ZOMBIE) { |
diff --git a/kernel/futex.c b/kernel/futex.c index ea87f4d2f455..1614be20173d 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
@@ -314,17 +314,29 @@ again: | |||
314 | #endif | 314 | #endif |
315 | 315 | ||
316 | lock_page(page_head); | 316 | lock_page(page_head); |
317 | |||
318 | /* | ||
319 | * If page_head->mapping is NULL, then it cannot be a PageAnon | ||
320 | * page; but it might be the ZERO_PAGE or in the gate area or | ||
321 | * in a special mapping (all cases which we are happy to fail); | ||
322 | * or it may have been a good file page when get_user_pages_fast | ||
323 | * found it, but truncated or holepunched or subjected to | ||
324 | * invalidate_complete_page2 before we got the page lock (also | ||
325 | * cases which we are happy to fail). And we hold a reference, | ||
326 | * so refcount care in invalidate_complete_page's remove_mapping | ||
327 | * prevents drop_caches from setting mapping to NULL beneath us. | ||
328 | * | ||
329 | * The case we do have to guard against is when memory pressure made | ||
330 | * shmem_writepage move it from filecache to swapcache beneath us: | ||
331 | * an unlikely race, but we do need to retry for page_head->mapping. | ||
332 | */ | ||
317 | if (!page_head->mapping) { | 333 | if (!page_head->mapping) { |
334 | int shmem_swizzled = PageSwapCache(page_head); | ||
318 | unlock_page(page_head); | 335 | unlock_page(page_head); |
319 | put_page(page_head); | 336 | put_page(page_head); |
320 | /* | 337 | if (shmem_swizzled) |
321 | * ZERO_PAGE pages don't have a mapping. Avoid a busy loop | 338 | goto again; |
322 | * trying to find one. RW mapping would have COW'd (and thus | 339 | return -EFAULT; |
323 | * have a mapping) so this page is RO and won't ever change. | ||
324 | */ | ||
325 | if ((page_head == ZERO_PAGE(address))) | ||
326 | return -EFAULT; | ||
327 | goto again; | ||
328 | } | 340 | } |
329 | 341 | ||
330 | /* | 342 | /* |
diff --git a/kernel/hung_task.c b/kernel/hung_task.c index 8b1748d0172c..2e48ec0c2e91 100644 --- a/kernel/hung_task.c +++ b/kernel/hung_task.c | |||
@@ -74,11 +74,17 @@ static void check_hung_task(struct task_struct *t, unsigned long timeout) | |||
74 | 74 | ||
75 | /* | 75 | /* |
76 | * Ensure the task is not frozen. | 76 | * Ensure the task is not frozen. |
77 | * Also, when a freshly created task is scheduled once, changes | 77 | * Also, skip vfork and any other user process that freezer should skip. |
78 | * its state to TASK_UNINTERRUPTIBLE without having ever been | ||
79 | * switched out once, it musn't be checked. | ||
80 | */ | 78 | */ |
81 | if (unlikely(t->flags & PF_FROZEN || !switch_count)) | 79 | if (unlikely(t->flags & (PF_FROZEN | PF_FREEZER_SKIP))) |
80 | return; | ||
81 | |||
82 | /* | ||
83 | * When a freshly created task is scheduled once, changes its state to | ||
84 | * TASK_UNINTERRUPTIBLE without having ever been switched out once, it | ||
85 | * musn't be checked. | ||
86 | */ | ||
87 | if (unlikely(!switch_count)) | ||
82 | return; | 88 | return; |
83 | 89 | ||
84 | if (switch_count != t->last_switch_count) { | 90 | if (switch_count != t->last_switch_count) { |
diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 24d04477b257..78ab24a7b0e4 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c | |||
@@ -96,9 +96,20 @@ void __ptrace_unlink(struct task_struct *child) | |||
96 | */ | 96 | */ |
97 | if (!(child->flags & PF_EXITING) && | 97 | if (!(child->flags & PF_EXITING) && |
98 | (child->signal->flags & SIGNAL_STOP_STOPPED || | 98 | (child->signal->flags & SIGNAL_STOP_STOPPED || |
99 | child->signal->group_stop_count)) | 99 | child->signal->group_stop_count)) { |
100 | child->jobctl |= JOBCTL_STOP_PENDING; | 100 | child->jobctl |= JOBCTL_STOP_PENDING; |
101 | 101 | ||
102 | /* | ||
103 | * This is only possible if this thread was cloned by the | ||
104 | * traced task running in the stopped group, set the signal | ||
105 | * for the future reports. | ||
106 | * FIXME: we should change ptrace_init_task() to handle this | ||
107 | * case. | ||
108 | */ | ||
109 | if (!(child->jobctl & JOBCTL_STOP_SIGMASK)) | ||
110 | child->jobctl |= SIGSTOP; | ||
111 | } | ||
112 | |||
102 | /* | 113 | /* |
103 | * If transition to TASK_STOPPED is pending or in TASK_TRACED, kick | 114 | * If transition to TASK_STOPPED is pending or in TASK_TRACED, kick |
104 | * @child in the butt. Note that @resume should be used iff @child | 115 | * @child in the butt. Note that @resume should be used iff @child |
diff --git a/kernel/signal.c b/kernel/signal.c index b3f78d09a105..206551563cce 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -1994,8 +1994,6 @@ static bool do_signal_stop(int signr) | |||
1994 | */ | 1994 | */ |
1995 | if (!(sig->flags & SIGNAL_STOP_STOPPED)) | 1995 | if (!(sig->flags & SIGNAL_STOP_STOPPED)) |
1996 | sig->group_exit_code = signr; | 1996 | sig->group_exit_code = signr; |
1997 | else | ||
1998 | WARN_ON_ONCE(!current->ptrace); | ||
1999 | 1997 | ||
2000 | sig->group_stop_count = 0; | 1998 | sig->group_stop_count = 0; |
2001 | 1999 | ||
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c index c4eb71c8b2ea..1ecd6ba36d6c 100644 --- a/kernel/time/clockevents.c +++ b/kernel/time/clockevents.c | |||
@@ -387,7 +387,6 @@ void clockevents_exchange_device(struct clock_event_device *old, | |||
387 | * released list and do a notify add later. | 387 | * released list and do a notify add later. |
388 | */ | 388 | */ |
389 | if (old) { | 389 | if (old) { |
390 | old->event_handler = clockevents_handle_noop; | ||
391 | clockevents_set_mode(old, CLOCK_EVT_MODE_UNUSED); | 390 | clockevents_set_mode(old, CLOCK_EVT_MODE_UNUSED); |
392 | list_del(&old->list); | 391 | list_del(&old->list); |
393 | list_add(&old->list, &clockevents_released); | 392 | list_add(&old->list, &clockevents_released); |
diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c index db110b8ae030..f1539decd99d 100644 --- a/kernel/tracepoint.c +++ b/kernel/tracepoint.c | |||
@@ -634,10 +634,11 @@ static int tracepoint_module_coming(struct module *mod) | |||
634 | int ret = 0; | 634 | int ret = 0; |
635 | 635 | ||
636 | /* | 636 | /* |
637 | * We skip modules that tain the kernel, especially those with different | 637 | * We skip modules that taint the kernel, especially those with different |
638 | * module header (for forced load), to make sure we don't cause a crash. | 638 | * module headers (for forced load), to make sure we don't cause a crash. |
639 | * Staging and out-of-tree GPL modules are fine. | ||
639 | */ | 640 | */ |
640 | if (mod->taints) | 641 | if (mod->taints & ~((1 << TAINT_OOT_MODULE) | (1 << TAINT_CRAP))) |
641 | return 0; | 642 | return 0; |
642 | mutex_lock(&tracepoints_mutex); | 643 | mutex_lock(&tracepoints_mutex); |
643 | tp_mod = kmalloc(sizeof(struct tp_module), GFP_KERNEL); | 644 | tp_mod = kmalloc(sizeof(struct tp_module), GFP_KERNEL); |