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