diff options
author | Chris Metcalf <cmetcalf@tilera.com> | 2013-08-12 15:08:09 -0400 |
---|---|---|
committer | Chris Metcalf <cmetcalf@tilera.com> | 2013-09-03 14:52:13 -0400 |
commit | 640710a33b54de8d90ae140ef633ed0feba76a75 (patch) | |
tree | c58e0f7b36fef258674ddf9d5425608d3b5a430e /arch/tile/mm/pgtable.c | |
parent | 49cf78ef7bb34833496d59b6dfe84ae51b1ab097 (diff) |
tile: add virt_to_kpte() API and clean up and document behavior
We use virt_to_pte(NULL, va) a lot, which isn't very obvious.
I added virt_to_kpte(va) as a more obvious wrapper function,
that also validates the va as being a kernel adddress.
And, I fixed the semantics of virt_to_pte() so that we handle
the pud and pmd the same way, and we now document the fact that
we handle the final pte level differently.
Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
Diffstat (limited to 'arch/tile/mm/pgtable.c')
-rw-r--r-- | arch/tile/mm/pgtable.c | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/arch/tile/mm/pgtable.c b/arch/tile/mm/pgtable.c index 300443389671..2deaddf3e01f 100644 --- a/arch/tile/mm/pgtable.c +++ b/arch/tile/mm/pgtable.c | |||
@@ -325,6 +325,17 @@ void ptep_set_wrprotect(struct mm_struct *mm, | |||
325 | 325 | ||
326 | #endif | 326 | #endif |
327 | 327 | ||
328 | /* | ||
329 | * Return a pointer to the PTE that corresponds to the given | ||
330 | * address in the given page table. A NULL page table just uses | ||
331 | * the standard kernel page table; the preferred API in this case | ||
332 | * is virt_to_kpte(). | ||
333 | * | ||
334 | * The returned pointer can point to a huge page in other levels | ||
335 | * of the page table than the bottom, if the huge page is present | ||
336 | * in the page table. For bottom-level PTEs, the returned pointer | ||
337 | * can point to a PTE that is either present or not. | ||
338 | */ | ||
328 | pte_t *virt_to_pte(struct mm_struct* mm, unsigned long addr) | 339 | pte_t *virt_to_pte(struct mm_struct* mm, unsigned long addr) |
329 | { | 340 | { |
330 | pgd_t *pgd; | 341 | pgd_t *pgd; |
@@ -341,14 +352,21 @@ pte_t *virt_to_pte(struct mm_struct* mm, unsigned long addr) | |||
341 | if (pud_huge_page(*pud)) | 352 | if (pud_huge_page(*pud)) |
342 | return (pte_t *)pud; | 353 | return (pte_t *)pud; |
343 | pmd = pmd_offset(pud, addr); | 354 | pmd = pmd_offset(pud, addr); |
344 | if (pmd_huge_page(*pmd)) | ||
345 | return (pte_t *)pmd; | ||
346 | if (!pmd_present(*pmd)) | 355 | if (!pmd_present(*pmd)) |
347 | return NULL; | 356 | return NULL; |
357 | if (pmd_huge_page(*pmd)) | ||
358 | return (pte_t *)pmd; | ||
348 | return pte_offset_kernel(pmd, addr); | 359 | return pte_offset_kernel(pmd, addr); |
349 | } | 360 | } |
350 | EXPORT_SYMBOL(virt_to_pte); | 361 | EXPORT_SYMBOL(virt_to_pte); |
351 | 362 | ||
363 | pte_t *virt_to_kpte(unsigned long kaddr) | ||
364 | { | ||
365 | BUG_ON(kaddr < PAGE_OFFSET); | ||
366 | return virt_to_pte(NULL, kaddr); | ||
367 | } | ||
368 | EXPORT_SYMBOL(virt_to_kpte); | ||
369 | |||
352 | pgprot_t set_remote_cache_cpu(pgprot_t prot, int cpu) | 370 | pgprot_t set_remote_cache_cpu(pgprot_t prot, int cpu) |
353 | { | 371 | { |
354 | unsigned int width = smp_width; | 372 | unsigned int width = smp_width; |