aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/mm
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2012-10-18 07:54:15 -0400
committerRalf Baechle <ralf@linux-mips.org>2012-12-12 10:48:52 -0500
commit970d032fec3f9687446595ee2569fb70b858a69f (patch)
tree18fdf6999d82569a14a41021328f459a7f4bbd97 /arch/mips/mm
parentf65aad41772f6a0022e9763fe06f47604449964c (diff)
MIPS: Transparent Huge Pages support
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/mm')
-rw-r--r--arch/mips/mm/pgtable-64.c31
-rw-r--r--arch/mips/mm/tlb-r4k.c20
-rw-r--r--arch/mips/mm/tlbex.c3
3 files changed, 53 insertions, 1 deletions
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 @@
11#include <asm/fixmap.h> 11#include <asm/fixmap.h>
12#include <asm/pgtable.h> 12#include <asm/pgtable.h>
13#include <asm/pgalloc.h> 13#include <asm/pgalloc.h>
14#include <asm/tlbflush.h>
14 15
15void pgd_init(unsigned long page) 16void pgd_init(unsigned long page)
16{ 17{
@@ -61,6 +62,36 @@ void pmd_init(unsigned long addr, unsigned long pagetable)
61} 62}
62#endif 63#endif
63 64
65#ifdef CONFIG_TRANSPARENT_HUGEPAGE
66
67void pmdp_splitting_flush(struct vm_area_struct *vma,
68 unsigned long address,
69 pmd_t *pmdp)
70{
71 if (!pmd_trans_splitting(*pmdp)) {
72 pmd_t pmd = pmd_mksplitting(*pmdp);
73 set_pmd_at(vma->vm_mm, address, pmdp, pmd);
74 }
75}
76
77#endif
78
79pmd_t mk_pmd(struct page *page, pgprot_t prot)
80{
81 pmd_t pmd;
82
83 pmd_val(pmd) = (page_to_pfn(page) << _PFN_SHIFT) | pgprot_val(prot);
84
85 return pmd;
86}
87
88void set_pmd_at(struct mm_struct *mm, unsigned long addr,
89 pmd_t *pmdp, pmd_t pmd)
90{
91 *pmdp = pmd;
92 flush_tlb_all();
93}
94
64void __init pagetable_init(void) 95void __init pagetable_init(void)
65{ 96{
66 unsigned long vaddr; 97 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,
377 EXIT_CRITICAL(flags); 377 EXIT_CRITICAL(flags);
378} 378}
379 379
380#ifdef CONFIG_TRANSPARENT_HUGEPAGE
381
382int __init has_transparent_hugepage(void)
383{
384 unsigned int mask;
385 unsigned long flags;
386
387 ENTER_CRITICAL(flags);
388 write_c0_pagemask(PM_HUGE_MASK);
389 back_to_back_c0_hazard();
390 mask = read_c0_pagemask();
391 write_c0_pagemask(PM_DEFAULT_MASK);
392
393 EXIT_CRITICAL(flags);
394
395 return mask == PM_HUGE_MASK;
396}
397
398#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
399
380static int __cpuinitdata ntlb; 400static int __cpuinitdata ntlb;
381static int __init set_ntlb(char *str) 401static int __init set_ntlb(char *str)
382{ 402{
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)
225 pr_define("_PAGE_WRITE_SHIFT %d\n", _PAGE_WRITE_SHIFT); 225 pr_define("_PAGE_WRITE_SHIFT %d\n", _PAGE_WRITE_SHIFT);
226 pr_define("_PAGE_ACCESSED_SHIFT %d\n", _PAGE_ACCESSED_SHIFT); 226 pr_define("_PAGE_ACCESSED_SHIFT %d\n", _PAGE_ACCESSED_SHIFT);
227 pr_define("_PAGE_MODIFIED_SHIFT %d\n", _PAGE_MODIFIED_SHIFT); 227 pr_define("_PAGE_MODIFIED_SHIFT %d\n", _PAGE_MODIFIED_SHIFT);
228#ifdef _PAGE_HUGE_SHIFT 228#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
229 pr_define("_PAGE_HUGE_SHIFT %d\n", _PAGE_HUGE_SHIFT); 229 pr_define("_PAGE_HUGE_SHIFT %d\n", _PAGE_HUGE_SHIFT);
230 pr_define("_PAGE_SPLITTING_SHIFT %d\n", _PAGE_SPLITTING_SHIFT);
230#endif 231#endif
231 if (cpu_has_rixi) { 232 if (cpu_has_rixi) {
232#ifdef _PAGE_NO_EXEC_SHIFT 233#ifdef _PAGE_NO_EXEC_SHIFT