summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
35f0597)
This tile-specific API had a minor bug, in that if a super huge (>4GB)
page mapped a particular address range, we wouldn't handle it correctly.
As part of fixing that bug, I also cleaned up some of the pud and pmd
accessors to make them more consistent.
Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
/* We have no pmd or pud since we are strictly a two-level page table */
#include <asm-generic/pgtable-nopmd.h>
/* We have no pmd or pud since we are strictly a two-level page table */
#include <asm-generic/pgtable-nopmd.h>
+static inline int pud_huge_page(pud_t pud) { return 0; }
+
/* We don't define any pgds for these addresses. */
static inline int pgd_addr_invalid(unsigned long addr)
{
/* We don't define any pgds for these addresses. */
static inline int pgd_addr_invalid(unsigned long addr)
{
/* We have no pud since we are a three-level page table. */
#include <asm-generic/pgtable-nopud.h>
/* We have no pud since we are a three-level page table. */
#include <asm-generic/pgtable-nopud.h>
+/*
+ * pmds are the same as pgds and ptes, so converting is a no-op.
+ */
+#define pmd_pte(pmd) (pmd)
+#define pmdp_ptep(pmdp) (pmdp)
+#define pte_pmd(pte) (pte)
+
+#define pud_pte(pud) ((pud).pgd)
+
static inline int pud_none(pud_t pud)
{
return pud_val(pud) == 0;
static inline int pud_none(pud_t pud)
{
return pud_val(pud) == 0;
return pud_val(pud) & _PAGE_PRESENT;
}
return pud_val(pud) & _PAGE_PRESENT;
}
+static inline int pud_huge_page(pud_t pud)
+{
+ return pud_val(pud) & _PAGE_HUGE_PAGE;
+}
+
#define pmd_ERROR(e) \
pr_err("%s:%d: bad pmd 0x%016llx.\n", __FILE__, __LINE__, pmd_val(e))
#define pmd_ERROR(e) \
pr_err("%s:%d: bad pmd 0x%016llx.\n", __FILE__, __LINE__, pmd_val(e))
/* Return the page-table frame number (ptfn) that a pud_t points at. */
#define pud_ptfn(pud) hv_pte_get_ptfn((pud).pgd)
/* Return the page-table frame number (ptfn) that a pud_t points at. */
#define pud_ptfn(pud) hv_pte_get_ptfn((pud).pgd)
+/* Return the page frame number (pfn) that a pud_t points at. */
+#define pud_pfn(pud) pte_pfn(pud_pte(pud))
+
/*
* A given kernel pud_t maps to a kernel pmd_t table at a specific
* virtual address. Since kernel pmd_t tables can be aligned at
/*
* A given kernel pud_t maps to a kernel pmd_t table at a specific
* virtual address. Since kernel pmd_t tables can be aligned at
return hv_pte(__insn_exch(&ptep->val, 0UL));
}
return hv_pte(__insn_exch(&ptep->val, 0UL));
}
-/*
- * pmds are the same as pgds and ptes, so converting is a no-op.
- */
-#define pmd_pte(pmd) (pmd)
-#define pmdp_ptep(pmdp) (pmdp)
-#define pte_pmd(pte) (pte)
-
#endif /* __ASSEMBLY__ */
#endif /* _ASM_TILE_PGTABLE_64_H */
#endif /* __ASSEMBLY__ */
#endif /* _ASM_TILE_PGTABLE_64_H */
pud = pud_offset(pgd, addr);
if (!pud_present(*pud))
return NULL;
pud = pud_offset(pgd, addr);
if (!pud_present(*pud))
return NULL;
+ if (pud_huge_page(*pud))
+ return (pte_t *)pud;
pmd = pmd_offset(pud, addr);
if (pmd_huge_page(*pmd))
return (pte_t *)pmd;
pmd = pmd_offset(pud, addr);
if (pmd_huge_page(*pmd))
return (pte_t *)pmd;
return NULL;
return pte_offset_kernel(pmd, addr);
}
return NULL;
return pte_offset_kernel(pmd, addr);
}
+EXPORT_SYMBOL(virt_to_pte);
pgprot_t set_remote_cache_cpu(pgprot_t prot, int cpu)
{
pgprot_t set_remote_cache_cpu(pgprot_t prot, int cpu)
{