summaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2011-01-31 11:30:04 +0100
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>2011-01-31 11:30:20 +0100
commitf1be77bb21120b5306b56d6854db1f8eb5c3678b (patch)
treeaef2f02074095935a21e2d57c9b21859016d8a8c /arch/s390
parentf602f6d694a99a0141c066c8f0b360a0b3c16915 (diff)
downloadlinux-f1be77bb21120b5306b56d6854db1f8eb5c3678b.tar.gz
linux-f1be77bb21120b5306b56d6854db1f8eb5c3678b.tar.bz2
linux-f1be77bb21120b5306b56d6854db1f8eb5c3678b.zip
[S390] pgtable_list corruption
After page_table_free_rcu removed a page from the pgtable_list page_table_free better not add it again. Otherwise a page_table_alloc can reuse a page table fragment that is still in the rcu process. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/mm/pgtable.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c
index 0c719c61972e..e1850c28cd68 100644
--- a/arch/s390/mm/pgtable.c
+++ b/arch/s390/mm/pgtable.c
@@ -336,7 +336,8 @@ void page_table_free(struct mm_struct *mm, unsigned long *table)
page->flags ^= bits;
if (page->flags & FRAG_MASK) {
/* Page now has some free pgtable fragments. */
- list_move(&page->lru, &mm->context.pgtable_list);
+ if (!list_empty(&page->lru))
+ list_move(&page->lru, &mm->context.pgtable_list);
page = NULL;
} else
/* All fragments of the 4K page have been freed. */