From 970d032fec3f9687446595ee2569fb70b858a69f Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 18 Oct 2012 13:54:15 +0200 Subject: MIPS: Transparent Huge Pages support Signed-off-by: Ralf Baechle --- arch/mips/mm/pgtable-64.c | 31 +++++++++++++++++++++++++++++++ arch/mips/mm/tlb-r4k.c | 20 ++++++++++++++++++++ arch/mips/mm/tlbex.c | 3 ++- 3 files changed, 53 insertions(+), 1 deletion(-) (limited to 'arch/mips/mm') diff --git a/arch/mips/mm/pgtable-64.c b/arch/mips/mm/pgtable-64.c index 25407794edb4..ee331bbd8f8a 100644 --- a/arch/mips/mm/pgtable-64.c +++ b/arch/mips/mm/pgtable-64.c @@ -11,6 +11,7 @@ #include #include #include +#include void pgd_init(unsigned long page) { @@ -61,6 +62,36 @@ void pmd_init(unsigned long addr, unsigned long pagetable) } #endif +#ifdef CONFIG_TRANSPARENT_HUGEPAGE + +void pmdp_splitting_flush(struct vm_area_struct *vma, + unsigned long address, + pmd_t *pmdp) +{ + if (!pmd_trans_splitting(*pmdp)) { + pmd_t pmd = pmd_mksplitting(*pmdp); + set_pmd_at(vma->vm_mm, address, pmdp, pmd); + } +} + +#endif + +pmd_t mk_pmd(struct page *page, pgprot_t prot) +{ + pmd_t pmd; + + pmd_val(pmd) = (page_to_pfn(page) << _PFN_SHIFT) | pgprot_val(prot); + + return pmd; +} + +void set_pmd_at(struct mm_struct *mm, unsigned long addr, + pmd_t *pmdp, pmd_t pmd) +{ + *pmdp = pmd; + flush_tlb_all(); +} + void __init pagetable_init(void) { unsigned long vaddr; diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index 936165d167e1..94ad86d055c5 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c @@ -377,6 +377,26 @@ void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, EXIT_CRITICAL(flags); } +#ifdef CONFIG_TRANSPARENT_HUGEPAGE + +int __init has_transparent_hugepage(void) +{ + unsigned int mask; + unsigned long flags; + + ENTER_CRITICAL(flags); + write_c0_pagemask(PM_HUGE_MASK); + back_to_back_c0_hazard(); + mask = read_c0_pagemask(); + write_c0_pagemask(PM_DEFAULT_MASK); + + EXIT_CRITICAL(flags); + + return mask == PM_HUGE_MASK; +} + +#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ + static int __cpuinitdata ntlb; static int __init set_ntlb(char *str) { diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 98b2b732005a..6af62a2fec21 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -225,8 +225,9 @@ static void output_pgtable_bits_defines(void) pr_define("_PAGE_WRITE_SHIFT %d\n", _PAGE_WRITE_SHIFT); pr_define("_PAGE_ACCESSED_SHIFT %d\n", _PAGE_ACCESSED_SHIFT); pr_define("_PAGE_MODIFIED_SHIFT %d\n", _PAGE_MODIFIED_SHIFT); -#ifdef _PAGE_HUGE_SHIFT +#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT pr_define("_PAGE_HUGE_SHIFT %d\n", _PAGE_HUGE_SHIFT); + pr_define("_PAGE_SPLITTING_SHIFT %d\n", _PAGE_SPLITTING_SHIFT); #endif if (cpu_has_rixi) { #ifdef _PAGE_NO_EXEC_SHIFT -- cgit v1.2.3-55-g7522