diff options
Diffstat (limited to 'mm/pagewalk.c')
-rw-r--r-- | mm/pagewalk.c | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/mm/pagewalk.c b/mm/pagewalk.c index 03761577ae86..60f7856e508f 100644 --- a/mm/pagewalk.c +++ b/mm/pagewalk.c | |||
@@ -69,14 +69,14 @@ again: | |||
69 | return err; | 69 | return err; |
70 | } | 70 | } |
71 | 71 | ||
72 | static int walk_pud_range(pgd_t *pgd, unsigned long addr, unsigned long end, | 72 | static int walk_pud_range(p4d_t *p4d, unsigned long addr, unsigned long end, |
73 | struct mm_walk *walk) | 73 | struct mm_walk *walk) |
74 | { | 74 | { |
75 | pud_t *pud; | 75 | pud_t *pud; |
76 | unsigned long next; | 76 | unsigned long next; |
77 | int err = 0; | 77 | int err = 0; |
78 | 78 | ||
79 | pud = pud_offset(pgd, addr); | 79 | pud = pud_offset(p4d, addr); |
80 | do { | 80 | do { |
81 | again: | 81 | again: |
82 | next = pud_addr_end(addr, end); | 82 | next = pud_addr_end(addr, end); |
@@ -113,6 +113,32 @@ static int walk_pud_range(pgd_t *pgd, unsigned long addr, unsigned long end, | |||
113 | return err; | 113 | return err; |
114 | } | 114 | } |
115 | 115 | ||
116 | static int walk_p4d_range(pgd_t *pgd, unsigned long addr, unsigned long end, | ||
117 | struct mm_walk *walk) | ||
118 | { | ||
119 | p4d_t *p4d; | ||
120 | unsigned long next; | ||
121 | int err = 0; | ||
122 | |||
123 | p4d = p4d_offset(pgd, addr); | ||
124 | do { | ||
125 | next = p4d_addr_end(addr, end); | ||
126 | if (p4d_none_or_clear_bad(p4d)) { | ||
127 | if (walk->pte_hole) | ||
128 | err = walk->pte_hole(addr, next, walk); | ||
129 | if (err) | ||
130 | break; | ||
131 | continue; | ||
132 | } | ||
133 | if (walk->pmd_entry || walk->pte_entry) | ||
134 | err = walk_pud_range(p4d, addr, next, walk); | ||
135 | if (err) | ||
136 | break; | ||
137 | } while (p4d++, addr = next, addr != end); | ||
138 | |||
139 | return err; | ||
140 | } | ||
141 | |||
116 | static int walk_pgd_range(unsigned long addr, unsigned long end, | 142 | static int walk_pgd_range(unsigned long addr, unsigned long end, |
117 | struct mm_walk *walk) | 143 | struct mm_walk *walk) |
118 | { | 144 | { |
@@ -131,7 +157,7 @@ static int walk_pgd_range(unsigned long addr, unsigned long end, | |||
131 | continue; | 157 | continue; |
132 | } | 158 | } |
133 | if (walk->pmd_entry || walk->pte_entry) | 159 | if (walk->pmd_entry || walk->pte_entry) |
134 | err = walk_pud_range(pgd, addr, next, walk); | 160 | err = walk_p4d_range(pgd, addr, next, walk); |
135 | if (err) | 161 | if (err) |
136 | break; | 162 | break; |
137 | } while (pgd++, addr = next, addr != end); | 163 | } while (pgd++, addr = next, addr != end); |