summaryrefslogtreecommitdiffstats
path: root/arch/mips/mm
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2012-10-18 13:54:15 +0200
committerRalf Baechle <ralf@linux-mips.org>2012-12-12 16:48:52 +0100
commit970d032fec3f9687446595ee2569fb70b858a69f (patch)
tree18fdf6999d82569a14a41021328f459a7f4bbd97 /arch/mips/mm
parentf65aad41772f6a0022e9763fe06f47604449964c (diff)
downloadlinux-970d032fec3f9687446595ee2569fb70b858a69f.tar.bz2
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 @@
#include <asm/fixmap.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
+#include <asm/tlbflush.h>
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