summaryrefslogtreecommitdiff
path: root/arch/tile/mm/pgtable.c
diff options
context:
space:
mode:
authorChris Metcalf <cmetcalf@tilera.com>2013-08-12 23:08:09 +0400
committerChris Metcalf <cmetcalf@tilera.com>2013-09-03 22:52:13 +0400
commit640710a33b54de8d90ae140ef633ed0feba76a75 (patch)
treec58e0f7b36fef258674ddf9d5425608d3b5a430e /arch/tile/mm/pgtable.c
parent49cf78ef7bb34833496d59b6dfe84ae51b1ab097 (diff)
downloadlinux-640710a33b54de8d90ae140ef633ed0feba76a75.tar.xz
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.c22
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,
#endif
+/*
+ * Return a pointer to the PTE that corresponds to the given
+ * address in the given page table. A NULL page table just uses
+ * the standard kernel page table; the preferred API in this case
+ * is virt_to_kpte().
+ *
+ * The returned pointer can point to a huge page in other levels
+ * of the page table than the bottom, if the huge page is present
+ * in the page table. For bottom-level PTEs, the returned pointer
+ * can point to a PTE that is either present or not.
+ */
pte_t *virt_to_pte(struct mm_struct* mm, unsigned long addr)
{
pgd_t *pgd;
@@ -341,14 +352,21 @@ pte_t *virt_to_pte(struct mm_struct* mm, unsigned long addr)
if (pud_huge_page(*pud))
return (pte_t *)pud;
pmd = pmd_offset(pud, addr);
- if (pmd_huge_page(*pmd))
- return (pte_t *)pmd;
if (!pmd_present(*pmd))
return NULL;
+ if (pmd_huge_page(*pmd))
+ return (pte_t *)pmd;
return pte_offset_kernel(pmd, addr);
}
EXPORT_SYMBOL(virt_to_pte);
+pte_t *virt_to_kpte(unsigned long kaddr)
+{
+ BUG_ON(kaddr < PAGE_OFFSET);
+ return virt_to_pte(NULL, kaddr);
+}
+EXPORT_SYMBOL(virt_to_kpte);
+
pgprot_t set_remote_cache_cpu(pgprot_t prot, int cpu)
{
unsigned int width = smp_width;