After this patch 1GB and 2MB pages are being correctly processed during
virtual address resolving.

Signed-off-by: Viktor Prutyanov <viktor.prutya...@virtuozzo.com>
---
 contrib/elf2dmp/addrspace.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/contrib/elf2dmp/addrspace.c b/contrib/elf2dmp/addrspace.c
index 70f4271..f36e749 100644
--- a/contrib/elf2dmp/addrspace.c
+++ b/contrib/elf2dmp/addrspace.c
@@ -145,6 +145,21 @@ static bool is_present(uint64_t entry)
     return entry & 0x1;
 }
 
+static bool page_size_flag(uint64_t entry)
+{
+    return entry & (1 << 7);
+}
+
+static uint64_t get_1GB_paddr(uint64_t va, uint64_t pdpte)
+{
+    return (pdpte & 0xfffffc0000000) | (va & 0x3fffffff);
+}
+
+static uint64_t get_2MB_paddr(uint64_t va, uint64_t pgd_entry)
+{
+    return (pgd_entry & 0xfffffffe00000) | (va & 0x00000001fffff);
+}
+
 static uint64_t va_space_va2pa(struct va_space *vs, uint64_t va)
 {
     uint64_t pml4e, pdpe, pgd, pte;
@@ -159,11 +174,19 @@ static uint64_t va_space_va2pa(struct va_space *vs, 
uint64_t va)
         return INVALID_PA;
     }
 
+    if (page_size_flag(pdpe)) {
+        return get_1GB_paddr(va, pdpe);
+    }
+
     pgd = get_pgd(vs, va, pdpe);
     if (!is_present(pgd)) {
         return INVALID_PA;
     }
 
+    if (page_size_flag(pgd)) {
+        return get_2MB_paddr(va, pgd);
+    }
+
     pte = get_pte(vs, va, pgd);
     if (!is_present(pte)) {
         return INVALID_PA;
-- 
2.7.4


Reply via email to