diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2012-05-10 08:47:21 (GMT) |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2012-05-16 12:42:43 (GMT) |
commit | d49f47f83d15f3142d482a29de76f45360e34082 (patch) | |
tree | 255724f1f3d0e6b395c14ca91829ed6141be7964 /arch/s390/mm | |
parent | 0a16ba7866fd5cd802d49801a099f4c558ce99c7 (diff) | |
download | linux-d49f47f83d15f3142d482a29de76f45360e34082.tar.xz |
s390/pfault: add sanity check
If the task that was found on an initial interrupt doesn't match the
current task execute a WARN_ON_ONCE() and don't put the task to sleep.
When this happened something went wrong between the interface of the
hypervisor and the kernel. In such a case keep the tasks alive to
avoid a hanging system.
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/mm')
-rw-r--r-- | arch/s390/mm/fault.c | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index a9c11aa..72cec9e 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -584,6 +584,8 @@ static void pfault_interrupt(struct ext_code ext_code, } } else { /* signal bit not set -> a real page is missing. */ + if (WARN_ON_ONCE(tsk != current)) + goto out; if (tsk->thread.pfault_wait == 1) { /* Already on the list with a reference: put to sleep */ __set_task_state(tsk, TASK_UNINTERRUPTIBLE); @@ -606,6 +608,7 @@ static void pfault_interrupt(struct ext_code ext_code, set_tsk_need_resched(tsk); } } +out: spin_unlock(&pfault_lock); put_task_struct(tsk); } |