From 3cf1db68431f187e6aaf47c338f26b0fe137f4b5 Mon Sep 17 00:00:00 2001 From: Mitchel Humpherys <mitchelh@codeaurora.org> Date: Fri, 6 Nov 2015 17:05:23 -0800 Subject: [PATCH] lrdp-v2: mm: Calculate the vmemmap dynamically We're currently using a hard-coded value for vmemmap. This doesn't work anymore. Calculate its value dynamically the same way the kernel does it. Change-Id: If3e06007ab69c2ee91fefede770c2fb5ccb59fe3 --- linux-ramdump-parser-v2/mm.py | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/linux-ramdump-parser-v2/mm.py b/linux-ramdump-parser-v2/mm.py index df85030..09e6484 100755 --- a/linux-ramdump-parser-v2/mm.py +++ b/linux-ramdump-parser-v2/mm.py @@ -9,6 +9,8 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. +import bitops + def page_buddy(ramdump, page): mapcount_offset = ramdump.field_offset('struct page', '_mapcount') @@ -127,20 +129,37 @@ def page_to_pfn_sparse(ramdump, page): # divide by struct page size for division fun return (page - addr) / sizeof_page -# Yes, we are hard coding the vmemmap. This isn't very likely to change unless -# the rest of the addresses start changing as well. When that happens, the -# entire parser will probably be broken in many other ways so a better solution -# can be derived then. + +def get_vmemmap(ramdump): + # See: include/asm-generic/pgtable-nopud.h, + # arch/arm64/include/asm/pgtable-hwdef.h, + # arch/arm64/include/asm/pgtable.h + nlevels = int(ramdump.get_config_val("CONFIG_ARM64_PGTABLE_LEVELS")) + if ramdump.is_config_defined("CONFIG_ARM64_64K_PAGES"): + page_shift = 16 + else: + page_shift = 12 + pgdir_shift = ((page_shift - 3) * nlevels) + 3 + pud_shift = pgdir_shift + pud_size = 1 << pud_shift + va_bits = int(ramdump.get_config_val("CONFIG_ARM64_VA_BITS")) + spsize = ramdump.sizeof('struct page') + vmemmap_size = bitops.align((1 << (va_bits - page_shift)) * spsize, + pud_size) + vmalloc_end = ramdump.page_offset - pud_size - vmemmap_size + return vmalloc_end + + def page_to_pfn_vmemmap(ramdump, page): - mem_map = 0xffffffbc00000000 + vmemmap = get_vmemmap(ramdump) page_size = ramdump.sizeof('struct page') - return ((page - mem_map) / page_size) + return ((page - vmemmap) / page_size) def pfn_to_page_vmemmap(ramdump, pfn): - mem_map = 0xffffffbc00000000 + vmemmap = get_vmemmap(ramdump) page_size = ramdump.sizeof('struct page') - return mem_map + (pfn * page_size) + return vmemmap + (pfn * page_size) def page_to_pfn_flat(ramdump, page): -- GitLab