Blame view

arch/mips/mm/hugetlbpage.c 2.02 KB
50a41ff29   David Daney   MIPS: Add support...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  /*
   * MIPS Huge TLB Page Support for Kernel.
   *
   * This file is subject to the terms and conditions of the GNU General Public
   * License.  See the file "COPYING" in the main directory of this archive
   * for more details.
   *
   * Copyright (C) 2002, Rohit Seth <rohit.seth@intel.com>
   * Copyright 2005, Embedded Alley Solutions, Inc.
   * Matt Porter <mporter@embeddedalley.com>
   * Copyright (C) 2008, 2009 Cavium Networks, Inc.
   */
  
  #include <linux/init.h>
  #include <linux/fs.h>
  #include <linux/mm.h>
  #include <linux/hugetlb.h>
  #include <linux/pagemap.h>
50a41ff29   David Daney   MIPS: Add support...
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
  #include <linux/err.h>
  #include <linux/sysctl.h>
  #include <asm/mman.h>
  #include <asm/tlb.h>
  #include <asm/tlbflush.h>
  
  pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr,
  		      unsigned long sz)
  {
  	pgd_t *pgd;
  	pud_t *pud;
  	pte_t *pte = NULL;
  
  	pgd = pgd_offset(mm, addr);
  	pud = pud_alloc(mm, pgd, addr);
  	if (pud)
  		pte = (pte_t *)pmd_alloc(mm, pud, addr);
  
  	return pte;
  }
  
  pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
  {
  	pgd_t *pgd;
  	pud_t *pud;
  	pmd_t *pmd = NULL;
  
  	pgd = pgd_offset(mm, addr);
  	if (pgd_present(*pgd)) {
  		pud = pud_offset(pgd, addr);
  		if (pud_present(*pud))
  			pmd = pmd_offset(pud, addr);
  	}
  	return (pte_t *) pmd;
  }
  
  int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr, pte_t *ptep)
  {
  	return 0;
  }
  
  /*
   * This function checks for proper alignment of input addr and len parameters.
   */
  int is_aligned_hugepage_range(unsigned long addr, unsigned long len)
  {
  	if (len & ~HPAGE_MASK)
  		return -EINVAL;
  	if (addr & ~HPAGE_MASK)
  		return -EINVAL;
  	return 0;
  }
  
  struct page *
  follow_huge_addr(struct mm_struct *mm, unsigned long address, int write)
  {
  	return ERR_PTR(-EINVAL);
  }
  
  int pmd_huge(pmd_t pmd)
  {
  	return (pmd_val(pmd) & _PAGE_HUGE) != 0;
  }
  
  int pud_huge(pud_t pud)
  {
  	return (pud_val(pud) & _PAGE_HUGE) != 0;
  }
  
  struct page *
  follow_huge_pmd(struct mm_struct *mm, unsigned long address,
  		pmd_t *pmd, int write)
  {
  	struct page *page;
  
  	page = pte_page(*(pte_t *)pmd);
  	if (page)
  		page += ((address & ~HPAGE_MASK) >> PAGE_SHIFT);
  	return page;
  }