[PATCH Makedumpfile 09/10] arm64: Add support for 4level 4K page translations table
Pratyush Anand
panand at redhat.com
Tue Oct 25 00:23:01 PDT 2016
From: Azriel Samson <asamson at codeaurora.org>
Add PUD translation for 4 level page tables.
Signed-off-by: Mansi Patel <mansip at codeaurora.org>
Signed-off-by: Azriel Samson <asamson at codeaurora.org>
Signed-off-by: Sameer Goel <sgoel at codeaurora.org>
Signed-off-by: Pratyush Anand <panand at redhat.com>
---
arch/arm64.c | 30 ++++++++++++++++++++++++++++--
1 file changed, 28 insertions(+), 2 deletions(-)
diff --git a/arch/arm64.c b/arch/arm64.c
index da8f43c62380..df58e92536e2 100644
--- a/arch/arm64.c
+++ b/arch/arm64.c
@@ -54,7 +54,9 @@ static int va_bits;
#define PAGE_MASK (~(PAGESIZE() - 1))
#define PGDIR_SHIFT ((PAGESHIFT() - 3) * pgtable_level + 3)
#define PTRS_PER_PGD (1 << (va_bits - PGDIR_SHIFT))
+#define PUD_SHIFT get_pud_shift_arm64()
#define PTRS_PER_PTE (1 << (PAGESHIFT() - 3))
+#define PTRS_PER_PUD PTRS_PER_PTE
#define PMD_SHIFT ((PAGESHIFT() - 3) * 2 + 3)
#define PMD_SIZE (1UL << PMD_SHIFT)
#define PMD_MASK (~(PMD_SIZE - 1))
@@ -89,6 +91,18 @@ static int va_bits;
#define pmd_offset_pgtbl_lvl_2(pud, vaddr) ((pmd_t *)pud)
#define pmd_offset_pgtbl_lvl_3(pud, vaddr) ((pmd_t *)pud_page_paddr((*pud)) + pmd_index(vaddr))
+#define pud_index(vaddr) (((vaddr) >> PUD_SHIFT) & (PTRS_PER_PUD - 1))
+#define pgd_page_paddr(pgd) (pgd_val(pgd) & PHYS_MASK & (int32_t)PAGE_MASK)
+
+static int
+get_pud_shift_arm64(void)
+{
+ if (pgtable_level == 4)
+ return ((PAGESHIFT() - 3) * 3 + 3);
+ else
+ return PGDIR_SHIFT;
+}
+
static pmd_t *
pmd_offset(pud_t *puda, pud_t *pudv, unsigned long vaddr)
{
@@ -99,6 +113,15 @@ pmd_offset(pud_t *puda, pud_t *pudv, unsigned long vaddr)
}
}
+static pud_t *
+pud_offset(pgd_t *pgda, pgd_t *pgdv, unsigned long vaddr)
+{
+ if (pgtable_level == 4)
+ return ((pud_t *)pgd_page_paddr((*pgdv)) + pud_index(vaddr));
+ else
+ return (pud_t *)(pgda);
+}
+
static int calculate_plat_config(void)
{
va_bits = NUMBER(VA_BITS);
@@ -212,8 +235,11 @@ vaddr_to_paddr_arm64(unsigned long vaddr)
return NOT_PADDR;
}
- pudv.pgd = pgdv;
- puda = (pud_t *)pgda;
+ puda = pud_offset(pgda, &pgdv, vaddr);
+ if (!readmem(PADDR, (unsigned long long)puda, &pudv, sizeof(pudv))) {
+ ERRMSG("Can't read pud\n");
+ return NOT_PADDR;
+ }
pmda = pmd_offset(puda, &pudv, vaddr);
if (!readmem(PADDR, (unsigned long long)pmda, &pmdv, sizeof(pmdv))) {
--
2.7.4
More information about the kexec
mailing list