Commit 667416f3 authored by Aneesh Kumar K.V's avatar Aneesh Kumar K.V Committed by Michael Ellerman

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: 70234676 ("powerpc/mm/nohash: Remove pte fragment dependency from nohash")
Signed-off-by: default avatarAneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent 8af1da40
...@@ -99,6 +99,7 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t ptepage) ...@@ -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) static inline void pgtable_free(void *table, unsigned index_size)
{ {
if (!index_size) { if (!index_size) {
pgtable_page_dtor(virt_to_page(table));
free_page((unsigned long)table); free_page((unsigned long)table);
} else { } else {
BUG_ON(index_size > MAX_PGTABLE_INDEX_SIZE); BUG_ON(index_size > MAX_PGTABLE_INDEX_SIZE);
......
...@@ -100,6 +100,7 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t ptepage) ...@@ -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) static inline void pgtable_free(void *table, unsigned index_size)
{ {
if (!index_size) { if (!index_size) {
pgtable_page_dtor(virt_to_page(table));
free_page((unsigned long)table); free_page((unsigned long)table);
} else { } else {
BUG_ON(index_size > MAX_PGTABLE_INDEX_SIZE); BUG_ON(index_size > MAX_PGTABLE_INDEX_SIZE);
......
...@@ -133,7 +133,7 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t ptepage) ...@@ -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) static inline void pgtable_free(void *table, int shift)
{ {
if (!shift) { if (!shift) {
pgtable_page_dtor(table); pgtable_page_dtor(virt_to_page(table));
free_page((unsigned long)table); free_page((unsigned long)table);
} else { } else {
BUG_ON(shift > MAX_PGTABLE_INDEX_SIZE); BUG_ON(shift > MAX_PGTABLE_INDEX_SIZE);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment