diff options
Diffstat (limited to 'arch/sparc64/mm/hugetlbpage.c')
| -rw-r--r-- | arch/sparc64/mm/hugetlbpage.c | 40 |
1 files changed, 19 insertions, 21 deletions
diff --git a/arch/sparc64/mm/hugetlbpage.c b/arch/sparc64/mm/hugetlbpage.c index a7a24869d045..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); |
| @@ -263,18 +264,6 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, | |||
| 263 | return entry; | 264 | return entry; |
| 264 | } | 265 | } |
| 265 | 266 | ||
| 266 | /* | ||
| 267 | * This function checks for proper alignment of input addr and len parameters. | ||
| 268 | */ | ||
| 269 | int is_aligned_hugepage_range(unsigned long addr, unsigned long len) | ||
| 270 | { | ||
| 271 | if (len & ~HPAGE_MASK) | ||
| 272 | return -EINVAL; | ||
| 273 | if (addr & ~HPAGE_MASK) | ||
| 274 | return -EINVAL; | ||
| 275 | return 0; | ||
| 276 | } | ||
| 277 | |||
| 278 | struct page *follow_huge_addr(struct mm_struct *mm, | 267 | struct page *follow_huge_addr(struct mm_struct *mm, |
| 279 | unsigned long address, int write) | 268 | unsigned long address, int write) |
| 280 | { | 269 | { |
| @@ -302,6 +291,15 @@ static void context_reload(void *__data) | |||
| 302 | 291 | ||
| 303 | void hugetlb_prefault_arch_hook(struct mm_struct *mm) | 292 | void hugetlb_prefault_arch_hook(struct mm_struct *mm) |
| 304 | { | 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 | |||
| 305 | /* On UltraSPARC-III+ and later, configure the second half of | 303 | /* On UltraSPARC-III+ and later, configure the second half of |
| 306 | * the Data-TLB for huge pages. | 304 | * the Data-TLB for huge pages. |
| 307 | */ | 305 | */ |
