aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/include/asm/pgtable.h
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/include/asm/pgtable.h
parentf65aad41772f6a0022e9763fe06f47604449964c (diff)
MIPS: Transparent Huge Pages support
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/include/asm/pgtable.h')
-rw-r--r--arch/mips/include/asm/pgtable.h167
1 files changed, 166 insertions, 1 deletions
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
383static 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
412extern int has_transparent_hugepage(void);
413
414static inline int pmd_trans_huge(pmd_t pmd)
415{
416 return !!(pmd_val(pmd) & _PAGE_HUGE);
417}
418
419static inline pmd_t pmd_mkhuge(pmd_t pmd)
420{
421 pmd_val(pmd) |= _PAGE_HUGE;
422
423 return pmd;
424}
425
426static inline int pmd_trans_splitting(pmd_t pmd)
427{
428 return !!(pmd_val(pmd) & _PAGE_SPLITTING);
429}
430
431static inline pmd_t pmd_mksplitting(pmd_t pmd)
432{
433 pmd_val(pmd) |= _PAGE_SPLITTING;
434
435 return pmd;
436}
437
438extern 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 */
443extern void pmdp_splitting_flush(struct vm_area_struct *vma,
444 unsigned long address,
445 pmd_t *pmdp);
446
447#define __HAVE_ARCH_PMD_WRITE
448static inline int pmd_write(pmd_t pmd)
449{
450 return !!(pmd_val(pmd) & _PAGE_WRITE);
451}
452
453static inline pmd_t pmd_wrprotect(pmd_t pmd)
454{
455 pmd_val(pmd) &= ~(_PAGE_WRITE | _PAGE_SILENT_WRITE);
456 return pmd;
457}
458
459static 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
468static inline int pmd_dirty(pmd_t pmd)
469{
470 return !!(pmd_val(pmd) & _PAGE_MODIFIED);
471}
472
473static inline pmd_t pmd_mkclean(pmd_t pmd)
474{
475 pmd_val(pmd) &= ~(_PAGE_MODIFIED | _PAGE_SILENT_WRITE);
476 return pmd;
477}
478
479static 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
488static inline int pmd_young(pmd_t pmd)
489{
490 return !!(pmd_val(pmd) & _PAGE_ACCESSED);
491}
492
493static inline pmd_t pmd_mkold(pmd_t pmd)
494{
495 pmd_val(pmd) &= ~(_PAGE_ACCESSED|_PAGE_SILENT_READ);
496
497 return pmd;
498}
499
500static 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 */
516extern pmd_t mk_pmd(struct page *page, pgprot_t prot);
517
518static inline unsigned long pmd_pfn(pmd_t pmd)
519{
520 return pmd_val(pmd) >> _PFN_SHIFT;
521}
522
523static 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
531static 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
537static 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
549static 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/*