diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2012-10-18 07:54:15 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2012-12-12 10:48:52 -0500 |
commit | 970d032fec3f9687446595ee2569fb70b858a69f (patch) | |
tree | 18fdf6999d82569a14a41021328f459a7f4bbd97 /arch/mips | |
parent | f65aad41772f6a0022e9763fe06f47604449964c (diff) |
MIPS: Transparent Huge Pages support
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips')
-rw-r--r-- | arch/mips/Kconfig | 13 | ||||
-rw-r--r-- | arch/mips/include/asm/pgtable-64.h | 2 | ||||
-rw-r--r-- | arch/mips/include/asm/pgtable-bits.h | 11 | ||||
-rw-r--r-- | arch/mips/include/asm/pgtable.h | 167 | ||||
-rw-r--r-- | arch/mips/kernel/mips_ksyms.c | 2 | ||||
-rw-r--r-- | arch/mips/mm/pgtable-64.c | 31 | ||||
-rw-r--r-- | arch/mips/mm/tlb-r4k.c | 20 | ||||
-rw-r--r-- | arch/mips/mm/tlbex.c | 3 |
8 files changed, 243 insertions, 6 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index b47d591c03dd..9934a4687ac4 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -19,6 +19,7 @@ config MIPS | |||
19 | select HAVE_KRETPROBES | 19 | select HAVE_KRETPROBES |
20 | select HAVE_DEBUG_KMEMLEAK | 20 | select HAVE_DEBUG_KMEMLEAK |
21 | select ARCH_BINFMT_ELF_RANDOMIZE_PIE | 21 | select ARCH_BINFMT_ELF_RANDOMIZE_PIE |
22 | select HAVE_ARCH_TRANSPARENT_HUGEPAGE | ||
22 | select RTC_LIB if !MACH_LOONGSON | 23 | select RTC_LIB if !MACH_LOONGSON |
23 | select GENERIC_ATOMIC64 if !64BIT | 24 | select GENERIC_ATOMIC64 if !64BIT |
24 | select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE | 25 | select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE |
@@ -1372,6 +1373,7 @@ config CPU_R4X00 | |||
1372 | depends on SYS_HAS_CPU_R4X00 | 1373 | depends on SYS_HAS_CPU_R4X00 |
1373 | select CPU_SUPPORTS_32BIT_KERNEL | 1374 | select CPU_SUPPORTS_32BIT_KERNEL |
1374 | select CPU_SUPPORTS_64BIT_KERNEL | 1375 | select CPU_SUPPORTS_64BIT_KERNEL |
1376 | select CPU_SUPPORTS_HUGEPAGES | ||
1375 | help | 1377 | help |
1376 | MIPS Technologies R4000-series processors other than 4300, including | 1378 | MIPS Technologies R4000-series processors other than 4300, including |
1377 | the R4000, R4400, R4600, and 4700. | 1379 | the R4000, R4400, R4600, and 4700. |
@@ -1382,12 +1384,14 @@ config CPU_TX49XX | |||
1382 | select CPU_HAS_PREFETCH | 1384 | select CPU_HAS_PREFETCH |
1383 | select CPU_SUPPORTS_32BIT_KERNEL | 1385 | select CPU_SUPPORTS_32BIT_KERNEL |
1384 | select CPU_SUPPORTS_64BIT_KERNEL | 1386 | select CPU_SUPPORTS_64BIT_KERNEL |
1387 | select CPU_SUPPORTS_HUGEPAGES | ||
1385 | 1388 | ||
1386 | config CPU_R5000 | 1389 | config CPU_R5000 |
1387 | bool "R5000" | 1390 | bool "R5000" |
1388 | depends on SYS_HAS_CPU_R5000 | 1391 | depends on SYS_HAS_CPU_R5000 |
1389 | select CPU_SUPPORTS_32BIT_KERNEL | 1392 | select CPU_SUPPORTS_32BIT_KERNEL |
1390 | select CPU_SUPPORTS_64BIT_KERNEL | 1393 | select CPU_SUPPORTS_64BIT_KERNEL |
1394 | select CPU_SUPPORTS_HUGEPAGES | ||
1391 | help | 1395 | help |
1392 | MIPS Technologies R5000-series processors other than the Nevada. | 1396 | MIPS Technologies R5000-series processors other than the Nevada. |
1393 | 1397 | ||
@@ -1396,6 +1400,7 @@ config CPU_R5432 | |||
1396 | depends on SYS_HAS_CPU_R5432 | 1400 | depends on SYS_HAS_CPU_R5432 |
1397 | select CPU_SUPPORTS_32BIT_KERNEL | 1401 | select CPU_SUPPORTS_32BIT_KERNEL |
1398 | select CPU_SUPPORTS_64BIT_KERNEL | 1402 | select CPU_SUPPORTS_64BIT_KERNEL |
1403 | select CPU_SUPPORTS_HUGEPAGES | ||
1399 | 1404 | ||
1400 | config CPU_R5500 | 1405 | config CPU_R5500 |
1401 | bool "R5500" | 1406 | bool "R5500" |
@@ -1421,6 +1426,7 @@ config CPU_NEVADA | |||
1421 | depends on SYS_HAS_CPU_NEVADA | 1426 | depends on SYS_HAS_CPU_NEVADA |
1422 | select CPU_SUPPORTS_32BIT_KERNEL | 1427 | select CPU_SUPPORTS_32BIT_KERNEL |
1423 | select CPU_SUPPORTS_64BIT_KERNEL | 1428 | select CPU_SUPPORTS_64BIT_KERNEL |
1429 | select CPU_SUPPORTS_HUGEPAGES | ||
1424 | help | 1430 | help |
1425 | QED / PMC-Sierra RM52xx-series ("Nevada") processors. | 1431 | QED / PMC-Sierra RM52xx-series ("Nevada") processors. |
1426 | 1432 | ||
@@ -1441,6 +1447,7 @@ config CPU_R10000 | |||
1441 | select CPU_SUPPORTS_32BIT_KERNEL | 1447 | select CPU_SUPPORTS_32BIT_KERNEL |
1442 | select CPU_SUPPORTS_64BIT_KERNEL | 1448 | select CPU_SUPPORTS_64BIT_KERNEL |
1443 | select CPU_SUPPORTS_HIGHMEM | 1449 | select CPU_SUPPORTS_HIGHMEM |
1450 | select CPU_SUPPORTS_HUGEPAGES | ||
1444 | help | 1451 | help |
1445 | MIPS Technologies R10000-series processors. | 1452 | MIPS Technologies R10000-series processors. |
1446 | 1453 | ||
@@ -1451,6 +1458,7 @@ config CPU_RM7000 | |||
1451 | select CPU_SUPPORTS_32BIT_KERNEL | 1458 | select CPU_SUPPORTS_32BIT_KERNEL |
1452 | select CPU_SUPPORTS_64BIT_KERNEL | 1459 | select CPU_SUPPORTS_64BIT_KERNEL |
1453 | select CPU_SUPPORTS_HIGHMEM | 1460 | select CPU_SUPPORTS_HIGHMEM |
1461 | select CPU_SUPPORTS_HUGEPAGES | ||
1454 | 1462 | ||
1455 | config CPU_RM9000 | 1463 | config CPU_RM9000 |
1456 | bool "RM9000" | 1464 | bool "RM9000" |
@@ -1459,6 +1467,7 @@ config CPU_RM9000 | |||
1459 | select CPU_SUPPORTS_32BIT_KERNEL | 1467 | select CPU_SUPPORTS_32BIT_KERNEL |
1460 | select CPU_SUPPORTS_64BIT_KERNEL | 1468 | select CPU_SUPPORTS_64BIT_KERNEL |
1461 | select CPU_SUPPORTS_HIGHMEM | 1469 | select CPU_SUPPORTS_HIGHMEM |
1470 | select CPU_SUPPORTS_HUGEPAGES | ||
1462 | select WEAK_ORDERING | 1471 | select WEAK_ORDERING |
1463 | 1472 | ||
1464 | config CPU_SB1 | 1473 | config CPU_SB1 |
@@ -1467,6 +1476,7 @@ config CPU_SB1 | |||
1467 | select CPU_SUPPORTS_32BIT_KERNEL | 1476 | select CPU_SUPPORTS_32BIT_KERNEL |
1468 | select CPU_SUPPORTS_64BIT_KERNEL | 1477 | select CPU_SUPPORTS_64BIT_KERNEL |
1469 | select CPU_SUPPORTS_HIGHMEM | 1478 | select CPU_SUPPORTS_HIGHMEM |
1479 | select CPU_SUPPORTS_HUGEPAGES | ||
1470 | select WEAK_ORDERING | 1480 | select WEAK_ORDERING |
1471 | 1481 | ||
1472 | config CPU_CAVIUM_OCTEON | 1482 | config CPU_CAVIUM_OCTEON |
@@ -1530,9 +1540,9 @@ config CPU_XLR | |||
1530 | select CPU_SUPPORTS_32BIT_KERNEL | 1540 | select CPU_SUPPORTS_32BIT_KERNEL |
1531 | select CPU_SUPPORTS_64BIT_KERNEL | 1541 | select CPU_SUPPORTS_64BIT_KERNEL |
1532 | select CPU_SUPPORTS_HIGHMEM | 1542 | select CPU_SUPPORTS_HIGHMEM |
1543 | select CPU_SUPPORTS_HUGEPAGES | ||
1533 | select WEAK_ORDERING | 1544 | select WEAK_ORDERING |
1534 | select WEAK_REORDERING_BEYOND_LLSC | 1545 | select WEAK_REORDERING_BEYOND_LLSC |
1535 | select CPU_SUPPORTS_HUGEPAGES | ||
1536 | help | 1546 | help |
1537 | Netlogic Microsystems XLR/XLS processors. | 1547 | Netlogic Microsystems XLR/XLS processors. |
1538 | 1548 | ||
@@ -1593,6 +1603,7 @@ config CPU_LOONGSON2 | |||
1593 | select CPU_SUPPORTS_32BIT_KERNEL | 1603 | select CPU_SUPPORTS_32BIT_KERNEL |
1594 | select CPU_SUPPORTS_64BIT_KERNEL | 1604 | select CPU_SUPPORTS_64BIT_KERNEL |
1595 | select CPU_SUPPORTS_HIGHMEM | 1605 | select CPU_SUPPORTS_HIGHMEM |
1606 | select CPU_SUPPORTS_HUGEPAGES | ||
1596 | 1607 | ||
1597 | config CPU_LOONGSON1 | 1608 | config CPU_LOONGSON1 |
1598 | bool | 1609 | bool |
diff --git a/arch/mips/include/asm/pgtable-64.h b/arch/mips/include/asm/pgtable-64.h index f5b521d5a67d..c63191055e69 100644 --- a/arch/mips/include/asm/pgtable-64.h +++ b/arch/mips/include/asm/pgtable-64.h | |||
@@ -175,7 +175,7 @@ static inline int pmd_none(pmd_t pmd) | |||
175 | 175 | ||
176 | static inline int pmd_bad(pmd_t pmd) | 176 | static inline int pmd_bad(pmd_t pmd) |
177 | { | 177 | { |
178 | #ifdef CONFIG_HUGETLB_PAGE | 178 | #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT |
179 | /* pmd_huge(pmd) but inline */ | 179 | /* pmd_huge(pmd) but inline */ |
180 | if (unlikely(pmd_val(pmd) & _PAGE_HUGE)) | 180 | if (unlikely(pmd_val(pmd) & _PAGE_HUGE)) |
181 | return 0; | 181 | return 0; |
diff --git a/arch/mips/include/asm/pgtable-bits.h b/arch/mips/include/asm/pgtable-bits.h index 1e2642c360a8..9ce1ac782448 100644 --- a/arch/mips/include/asm/pgtable-bits.h +++ b/arch/mips/include/asm/pgtable-bits.h | |||
@@ -137,8 +137,17 @@ | |||
137 | #define _PAGE_HUGE ({BUG(); 1; }) /* Dummy value */ | 137 | #define _PAGE_HUGE ({BUG(); 1; }) /* Dummy value */ |
138 | #endif | 138 | #endif |
139 | 139 | ||
140 | #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT | ||
141 | /* huge tlb page */ | ||
142 | #define _PAGE_SPLITTING_SHIFT (_PAGE_HUGE_SHIFT + 1) | ||
143 | #define _PAGE_SPLITTING (1 << _PAGE_SPLITTING_SHIFT) | ||
144 | #else | ||
145 | #define _PAGE_SPLITTING_SHIFT (_PAGE_HUGE_SHIFT) | ||
146 | #define _PAGE_SPLITTING ({BUG(); 1; }) /* Dummy value */ | ||
147 | #endif | ||
148 | |||
140 | /* Page cannot be executed */ | 149 | /* Page cannot be executed */ |
141 | #define _PAGE_NO_EXEC_SHIFT (cpu_has_rixi ? _PAGE_HUGE_SHIFT + 1 : _PAGE_HUGE_SHIFT) | 150 | #define _PAGE_NO_EXEC_SHIFT (cpu_has_rixi ? _PAGE_SPLITTING_SHIFT + 1 : _PAGE_SPLITTING_SHIFT) |
142 | #define _PAGE_NO_EXEC ({BUG_ON(!cpu_has_rixi); 1 << _PAGE_NO_EXEC_SHIFT; }) | 151 | #define _PAGE_NO_EXEC ({BUG_ON(!cpu_has_rixi); 1 << _PAGE_NO_EXEC_SHIFT; }) |
143 | 152 | ||
144 | /* Page cannot be read */ | 153 | /* Page cannot be read */ |
diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h index bc1c0fbf8d99..252202d24a84 100644 --- a/arch/mips/include/asm/pgtable.h +++ b/arch/mips/include/asm/pgtable.h | |||
@@ -8,6 +8,7 @@ | |||
8 | #ifndef _ASM_PGTABLE_H | 8 | #ifndef _ASM_PGTABLE_H |
9 | #define _ASM_PGTABLE_H | 9 | #define _ASM_PGTABLE_H |
10 | 10 | ||
11 | #include <linux/mmzone.h> | ||
11 | #ifdef CONFIG_32BIT | 12 | #ifdef CONFIG_32BIT |
12 | #include <asm/pgtable-32.h> | 13 | #include <asm/pgtable-32.h> |
13 | #endif | 14 | #endif |
@@ -94,7 +95,12 @@ extern void paging_init(void); | |||
94 | * and a page entry and page directory to the page they refer to. | 95 | * and a page entry and page directory to the page they refer to. |
95 | */ | 96 | */ |
96 | #define pmd_phys(pmd) virt_to_phys((void *)pmd_val(pmd)) | 97 | #define pmd_phys(pmd) virt_to_phys((void *)pmd_val(pmd)) |
97 | #define pmd_page(pmd) (pfn_to_page(pmd_phys(pmd) >> PAGE_SHIFT)) | 98 | |
99 | #define __pmd_page(pmd) (pfn_to_page(pmd_phys(pmd) >> PAGE_SHIFT)) | ||
100 | #ifndef CONFIG_TRANSPARENT_HUGEPAGE | ||
101 | #define pmd_page(pmd) __pmd_page(pmd) | ||
102 | #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ | ||
103 | |||
98 | #define pmd_page_vaddr(pmd) pmd_val(pmd) | 104 | #define pmd_page_vaddr(pmd) pmd_val(pmd) |
99 | 105 | ||
100 | #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) | 106 | #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) |
@@ -374,6 +380,14 @@ static inline void update_mmu_cache(struct vm_area_struct *vma, | |||
374 | __update_cache(vma, address, pte); | 380 | __update_cache(vma, address, pte); |
375 | } | 381 | } |
376 | 382 | ||
383 | static inline void update_mmu_cache_pmd(struct vm_area_struct *vma, | ||
384 | unsigned long address, pmd_t *pmdp) | ||
385 | { | ||
386 | pte_t pte = *(pte_t *)pmdp; | ||
387 | |||
388 | __update_tlb(vma, address, pte); | ||
389 | } | ||
390 | |||
377 | #define kern_addr_valid(addr) (1) | 391 | #define kern_addr_valid(addr) (1) |
378 | 392 | ||
379 | #ifdef CONFIG_64BIT_PHYS_ADDR | 393 | #ifdef CONFIG_64BIT_PHYS_ADDR |
@@ -393,6 +407,157 @@ static inline int io_remap_pfn_range(struct vm_area_struct *vma, | |||
393 | remap_pfn_range(vma, vaddr, pfn, size, prot) | 407 | remap_pfn_range(vma, vaddr, pfn, size, prot) |
394 | #endif | 408 | #endif |
395 | 409 | ||
410 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | ||
411 | |||
412 | extern int has_transparent_hugepage(void); | ||
413 | |||
414 | static inline int pmd_trans_huge(pmd_t pmd) | ||
415 | { | ||
416 | return !!(pmd_val(pmd) & _PAGE_HUGE); | ||
417 | } | ||
418 | |||
419 | static inline pmd_t pmd_mkhuge(pmd_t pmd) | ||
420 | { | ||
421 | pmd_val(pmd) |= _PAGE_HUGE; | ||
422 | |||
423 | return pmd; | ||
424 | } | ||
425 | |||
426 | static inline int pmd_trans_splitting(pmd_t pmd) | ||
427 | { | ||
428 | return !!(pmd_val(pmd) & _PAGE_SPLITTING); | ||
429 | } | ||
430 | |||
431 | static inline pmd_t pmd_mksplitting(pmd_t pmd) | ||
432 | { | ||
433 | pmd_val(pmd) |= _PAGE_SPLITTING; | ||
434 | |||
435 | return pmd; | ||
436 | } | ||
437 | |||
438 | extern void set_pmd_at(struct mm_struct *mm, unsigned long addr, | ||
439 | pmd_t *pmdp, pmd_t pmd); | ||
440 | |||
441 | #define __HAVE_ARCH_PMDP_SPLITTING_FLUSH | ||
442 | /* Extern to avoid header file madness */ | ||
443 | extern void pmdp_splitting_flush(struct vm_area_struct *vma, | ||
444 | unsigned long address, | ||
445 | pmd_t *pmdp); | ||
446 | |||
447 | #define __HAVE_ARCH_PMD_WRITE | ||
448 | static inline int pmd_write(pmd_t pmd) | ||
449 | { | ||
450 | return !!(pmd_val(pmd) & _PAGE_WRITE); | ||
451 | } | ||
452 | |||
453 | static inline pmd_t pmd_wrprotect(pmd_t pmd) | ||
454 | { | ||
455 | pmd_val(pmd) &= ~(_PAGE_WRITE | _PAGE_SILENT_WRITE); | ||
456 | return pmd; | ||
457 | } | ||
458 | |||
459 | static inline pmd_t pmd_mkwrite(pmd_t pmd) | ||
460 | { | ||
461 | pmd_val(pmd) |= _PAGE_WRITE; | ||
462 | if (pmd_val(pmd) & _PAGE_MODIFIED) | ||
463 | pmd_val(pmd) |= _PAGE_SILENT_WRITE; | ||
464 | |||
465 | return pmd; | ||
466 | } | ||
467 | |||
468 | static inline int pmd_dirty(pmd_t pmd) | ||
469 | { | ||
470 | return !!(pmd_val(pmd) & _PAGE_MODIFIED); | ||
471 | } | ||
472 | |||
473 | static inline pmd_t pmd_mkclean(pmd_t pmd) | ||
474 | { | ||
475 | pmd_val(pmd) &= ~(_PAGE_MODIFIED | _PAGE_SILENT_WRITE); | ||
476 | return pmd; | ||
477 | } | ||
478 | |||
479 | static inline pmd_t pmd_mkdirty(pmd_t pmd) | ||
480 | { | ||
481 | pmd_val(pmd) |= _PAGE_MODIFIED; | ||
482 | if (pmd_val(pmd) & _PAGE_WRITE) | ||
483 | pmd_val(pmd) |= _PAGE_SILENT_WRITE; | ||
484 | |||
485 | return pmd; | ||
486 | } | ||
487 | |||
488 | static inline int pmd_young(pmd_t pmd) | ||
489 | { | ||
490 | return !!(pmd_val(pmd) & _PAGE_ACCESSED); | ||
491 | } | ||
492 | |||
493 | static inline pmd_t pmd_mkold(pmd_t pmd) | ||
494 | { | ||
495 | pmd_val(pmd) &= ~(_PAGE_ACCESSED|_PAGE_SILENT_READ); | ||
496 | |||
497 | return pmd; | ||
498 | } | ||
499 | |||
500 | static inline pmd_t pmd_mkyoung(pmd_t pmd) | ||
501 | { | ||
502 | pmd_val(pmd) |= _PAGE_ACCESSED; | ||
503 | |||
504 | if (cpu_has_rixi) { | ||
505 | if (!(pmd_val(pmd) & _PAGE_NO_READ)) | ||
506 | pmd_val(pmd) |= _PAGE_SILENT_READ; | ||
507 | } else { | ||
508 | if (pmd_val(pmd) & _PAGE_READ) | ||
509 | pmd_val(pmd) |= _PAGE_SILENT_READ; | ||
510 | } | ||
511 | |||
512 | return pmd; | ||
513 | } | ||
514 | |||
515 | /* Extern to avoid header file madness */ | ||
516 | extern pmd_t mk_pmd(struct page *page, pgprot_t prot); | ||
517 | |||
518 | static inline unsigned long pmd_pfn(pmd_t pmd) | ||
519 | { | ||
520 | return pmd_val(pmd) >> _PFN_SHIFT; | ||
521 | } | ||
522 | |||
523 | static inline struct page *pmd_page(pmd_t pmd) | ||
524 | { | ||
525 | if (pmd_trans_huge(pmd)) | ||
526 | return pfn_to_page(pmd_pfn(pmd)); | ||
527 | |||
528 | return pfn_to_page(pmd_phys(pmd) >> PAGE_SHIFT); | ||
529 | } | ||
530 | |||
531 | static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot) | ||
532 | { | ||
533 | pmd_val(pmd) = (pmd_val(pmd) & _PAGE_CHG_MASK) | pgprot_val(newprot); | ||
534 | return pmd; | ||
535 | } | ||
536 | |||
537 | static inline pmd_t pmd_mknotpresent(pmd_t pmd) | ||
538 | { | ||
539 | pmd_val(pmd) &= ~(_PAGE_PRESENT | _PAGE_VALID | _PAGE_DIRTY); | ||
540 | |||
541 | return pmd; | ||
542 | } | ||
543 | |||
544 | /* | ||
545 | * The generic version pmdp_get_and_clear uses a version of pmd_clear() with a | ||
546 | * different prototype. | ||
547 | */ | ||
548 | #define __HAVE_ARCH_PMDP_GET_AND_CLEAR | ||
549 | static inline pmd_t pmdp_get_and_clear(struct mm_struct *mm, | ||
550 | unsigned long address, pmd_t *pmdp) | ||
551 | { | ||
552 | pmd_t old = *pmdp; | ||
553 | |||
554 | pmd_clear(pmdp); | ||
555 | |||
556 | return old; | ||
557 | } | ||
558 | |||
559 | #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ | ||
560 | |||
396 | #include <asm-generic/pgtable.h> | 561 | #include <asm-generic/pgtable.h> |
397 | 562 | ||
398 | /* | 563 | /* |
diff --git a/arch/mips/kernel/mips_ksyms.c b/arch/mips/kernel/mips_ksyms.c index 3fc1691110dc..1ba8933683aa 100644 --- a/arch/mips/kernel/mips_ksyms.c +++ b/arch/mips/kernel/mips_ksyms.c | |||
@@ -11,7 +11,7 @@ | |||
11 | #include <linux/interrupt.h> | 11 | #include <linux/interrupt.h> |
12 | #include <linux/export.h> | 12 | #include <linux/export.h> |
13 | #include <asm/checksum.h> | 13 | #include <asm/checksum.h> |
14 | #include <asm/pgtable.h> | 14 | #include <linux/mm.h> |
15 | #include <asm/uaccess.h> | 15 | #include <asm/uaccess.h> |
16 | #include <asm/ftrace.h> | 16 | #include <asm/ftrace.h> |
17 | 17 | ||
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 | ||
15 | void pgd_init(unsigned long page) | 16 | void 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 | |||
67 | void 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 | |||
79 | pmd_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 | |||
88 | void 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 | |||
64 | void __init pagetable_init(void) | 95 | void __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 | |||
382 | int __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 | |||
380 | static int __cpuinitdata ntlb; | 400 | static int __cpuinitdata ntlb; |
381 | static int __init set_ntlb(char *str) | 401 | static 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 |