diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-22 13:56:57 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-22 13:56:57 -0500 |
commit | d04ef3a795b3b7b376a02713ed5e211e9ae1f917 (patch) | |
tree | 837da034751a2fc1be0fc5a105c218d41a498eb6 /arch/sparc64/mm/hugetlbpage.c | |
parent | 36177ba655c238e33400cc2837a28720b62784bd (diff) | |
parent | dcc1e8dd88d4bc55e32a26dad7633d20ffe606d2 (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6:
[SPARC64]: Add a secondary TSB for hugepage mappings.
[SPARC]: Respect vm_page_prot in io_remap_page_range().
Diffstat (limited to 'arch/sparc64/mm/hugetlbpage.c')
-rw-r--r-- | arch/sparc64/mm/hugetlbpage.c | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/arch/sparc64/mm/hugetlbpage.c b/arch/sparc64/mm/hugetlbpage.c index 280dc7958a13..074620d413d4 100644 --- a/arch/sparc64/mm/hugetlbpage.c +++ b/arch/sparc64/mm/hugetlbpage.c | |||
@@ -199,13 +199,11 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr) | |||
199 | pte_t *pte = NULL; | 199 | pte_t *pte = NULL; |
200 | 200 | ||
201 | pgd = pgd_offset(mm, addr); | 201 | pgd = pgd_offset(mm, addr); |
202 | if (pgd) { | 202 | pud = pud_alloc(mm, pgd, addr); |
203 | pud = pud_offset(pgd, addr); | 203 | if (pud) { |
204 | if (pud) { | 204 | pmd = pmd_alloc(mm, pud, addr); |
205 | pmd = pmd_alloc(mm, pud, addr); | 205 | if (pmd) |
206 | if (pmd) | 206 | pte = pte_alloc_map(mm, pmd, addr); |
207 | pte = pte_alloc_map(mm, pmd, addr); | ||
208 | } | ||
209 | } | 207 | } |
210 | return pte; | 208 | return pte; |
211 | } | 209 | } |
@@ -231,13 +229,14 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) | |||
231 | return pte; | 229 | return pte; |
232 | } | 230 | } |
233 | 231 | ||
234 | #define mk_pte_huge(entry) do { pte_val(entry) |= _PAGE_SZHUGE; } while (0) | ||
235 | |||
236 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, | 232 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, |
237 | pte_t *ptep, pte_t entry) | 233 | pte_t *ptep, pte_t entry) |
238 | { | 234 | { |
239 | int i; | 235 | int i; |
240 | 236 | ||
237 | if (!pte_present(*ptep) && pte_present(entry)) | ||
238 | mm->context.huge_pte_count++; | ||
239 | |||
241 | for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) { | 240 | for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) { |
242 | set_pte_at(mm, addr, ptep, entry); | 241 | set_pte_at(mm, addr, ptep, entry); |
243 | ptep++; | 242 | ptep++; |
@@ -253,6 +252,8 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, | |||
253 | int i; | 252 | int i; |
254 | 253 | ||
255 | entry = *ptep; | 254 | entry = *ptep; |
255 | if (pte_present(entry)) | ||
256 | mm->context.huge_pte_count--; | ||
256 | 257 | ||
257 | for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) { | 258 | for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) { |
258 | pte_clear(mm, addr, ptep); | 259 | pte_clear(mm, addr, ptep); |
@@ -290,6 +291,15 @@ static void context_reload(void *__data) | |||
290 | 291 | ||
291 | void hugetlb_prefault_arch_hook(struct mm_struct *mm) | 292 | void hugetlb_prefault_arch_hook(struct mm_struct *mm) |
292 | { | 293 | { |
294 | struct tsb_config *tp = &mm->context.tsb_block[MM_TSB_HUGE]; | ||
295 | |||
296 | if (likely(tp->tsb != NULL)) | ||
297 | return; | ||
298 | |||
299 | tsb_grow(mm, MM_TSB_HUGE, 0); | ||
300 | tsb_context_switch(mm); | ||
301 | smp_tsb_sync(mm); | ||
302 | |||
293 | /* On UltraSPARC-III+ and later, configure the second half of | 303 | /* On UltraSPARC-III+ and later, configure the second half of |
294 | * the Data-TLB for huge pages. | 304 | * the Data-TLB for huge pages. |
295 | */ | 305 | */ |