aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorAneesh Kumar K.V2018-05-30 18:02:25 +0530
committerMichael Ellerman2018-06-02 01:48:11 +1000
commit667416f38554eef94485496f3a27b93feb5a9fbb (patch)
tree3d5991efde65334805a876fafb6ee8c7b862304b /arch
parent8af1da40669609707303eecdb857f48a5ba5792d (diff)
powerpc/mm: Fix kernel crash on page table free
Fix the below crash on Book3E 64. pgtable_page_dtor expects struct page *arg. Also call the destructor on non book3s platforms correctly. This frees up the split PTL locks correctly if we had allocated them before. Call Trace: .kmem_cache_free+0x9c/0x44c (unreliable) .ptlock_free+0x1c/0x30 .tlb_remove_table+0xdc/0x224 .free_pgd_range+0x298/0x500 .shift_arg_pages+0x10c/0x1e0 .setup_arg_pages+0x200/0x25c .load_elf_binary+0x450/0x16c8 .search_binary_handler.part.11+0x9c/0x248 .do_execveat_common.isra.13+0x868/0xc18 .run_init_process+0x34/0x4c .try_to_run_init_process+0x1c/0x68 .kernel_init+0xdc/0x130 .ret_from_kernel_thread+0x58/0x7c Fixes: 702346768 ("powerpc/mm/nohash: Remove pte fragment dependency from nohash") Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/include/asm/book3s/32/pgalloc.h1
-rw-r--r--arch/powerpc/include/asm/nohash/32/pgalloc.h1
-rw-r--r--arch/powerpc/include/asm/nohash/64/pgalloc.h2
3 files changed, 3 insertions, 1 deletions
diff --git a/arch/powerpc/include/asm/book3s/32/pgalloc.h b/arch/powerpc/include/asm/book3s/32/pgalloc.h
index 5073cc75f1c8..6a6673907e45 100644
--- a/arch/powerpc/include/asm/book3s/32/pgalloc.h
+++ b/arch/powerpc/include/asm/book3s/32/pgalloc.h
@@ -99,6 +99,7 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t ptepage)
static inline void pgtable_free(void *table, unsigned index_size)
{
if (!index_size) {
+ pgtable_page_dtor(virt_to_page(table));
free_page((unsigned long)table);
} else {
BUG_ON(index_size > MAX_PGTABLE_INDEX_SIZE);
diff --git a/arch/powerpc/include/asm/nohash/32/pgalloc.h b/arch/powerpc/include/asm/nohash/32/pgalloc.h
index 29d37bd1f3b3..1707781d2f20 100644
--- a/arch/powerpc/include/asm/nohash/32/pgalloc.h
+++ b/arch/powerpc/include/asm/nohash/32/pgalloc.h
@@ -100,6 +100,7 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t ptepage)
static inline void pgtable_free(void *table, unsigned index_size)
{
if (!index_size) {
+ pgtable_page_dtor(virt_to_page(table));
free_page((unsigned long)table);
} else {
BUG_ON(index_size > MAX_PGTABLE_INDEX_SIZE);
diff --git a/arch/powerpc/include/asm/nohash/64/pgalloc.h b/arch/powerpc/include/asm/nohash/64/pgalloc.h
index 21624ff1f065..0e693f322cb2 100644
--- a/arch/powerpc/include/asm/nohash/64/pgalloc.h
+++ b/arch/powerpc/include/asm/nohash/64/pgalloc.h
@@ -133,7 +133,7 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t ptepage)
static inline void pgtable_free(void *table, int shift)
{
if (!shift) {
- pgtable_page_dtor(table);
+ pgtable_page_dtor(virt_to_page(table));
free_page((unsigned long)table);
} else {
BUG_ON(shift > MAX_PGTABLE_INDEX_SIZE);