Skip to content

Commit

Permalink
powerpc/64/kexec: Fix MMU cleanup on radix
Browse files Browse the repository at this point in the history
Just using the hash ops won't work anymore since radix will have
NULL in there. Instead create an mmu_cleanup_all() function which
will do the right thing based on the MMU mode.

For Radix, for now I clear UPRT and the PTCR, effectively switching
back to Radix with no partition table setup.

Currently set it to NULL on BookE thought it might be a good idea
to wipe the TLB there (Scott ?)

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Acked-by: Balbir Singh <bsingharora@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
  • Loading branch information
Benjamin Herrenschmidt authored and Michael Ellerman committed Sep 22, 2016
1 parent fc48bad commit fe036a0
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 10 deletions.
3 changes: 3 additions & 0 deletions arch/powerpc/include/asm/mmu-book3e.h
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,9 @@ extern int book3e_htw_mode;
* return 1, indicating that the tlb requires preloading.
*/
#define HUGETLB_NEED_PRELOAD

#define mmu_cleanup_all NULL

#endif

#endif /* !__ASSEMBLY__ */
Expand Down
4 changes: 4 additions & 0 deletions arch/powerpc/include/asm/mmu.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,10 @@ extern unsigned int __start___mmu_ftr_fixup, __stop___mmu_ftr_fixup;
* make it match the size our of bolted TLB area
*/
extern u64 ppc64_rma_size;

/* Cleanup function used by kexec */
extern void mmu_cleanup_all(void);
extern void radix__mmu_cleanup_all(void);
#endif /* CONFIG_PPC64 */

struct mm_struct;
Expand Down
12 changes: 2 additions & 10 deletions arch/powerpc/kernel/machine_kexec_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,6 @@ int default_machine_kexec_prepare(struct kimage *image)
const unsigned long *basep;
const unsigned int *sizep;

if (!mmu_hash_ops.hpte_clear_all)
return -ENOENT;

/*
* Since we use the kernel fault handlers and paging code to
* handle the virtual mode, we must make sure no destination
Expand Down Expand Up @@ -379,13 +376,8 @@ void default_machine_kexec(struct kimage *image)
* a toc is easier in C, so pass in what we can.
*/
kexec_sequence(&kexec_stack, image->start, image,
page_address(image->control_code_page),
#ifdef CONFIG_PPC_STD_MMU
mmu_hash_ops.hpte_clear_all
#else
NULL
#endif
);
page_address(image->control_code_page),
mmu_cleanup_all);
/* NOTREACHED */
}

Expand Down
9 changes: 9 additions & 0 deletions arch/powerpc/mm/pgtable-book3s64.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,12 @@ void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr,
return;
}
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */

/* For use by kexec */
void mmu_cleanup_all(void)
{
if (radix_enabled())
radix__mmu_cleanup_all();
else if (mmu_hash_ops.hpte_clear_all)
mmu_hash_ops.hpte_clear_all();
}
12 changes: 12 additions & 0 deletions arch/powerpc/mm/pgtable-radix.c
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,18 @@ void radix__early_init_mmu_secondary(void)
}
}

void radix__mmu_cleanup_all(void)
{
unsigned long lpcr;

if (!firmware_has_feature(FW_FEATURE_LPAR)) {
lpcr = mfspr(SPRN_LPCR);
mtspr(SPRN_LPCR, lpcr & ~LPCR_UPRT);
mtspr(SPRN_PTCR, 0);
radix__flush_tlb_all();
}
}

void radix__setup_initial_memory_limit(phys_addr_t first_memblock_base,
phys_addr_t first_memblock_size)
{
Expand Down

0 comments on commit fe036a0

Please sign in to comment.