Dear Dave, At 07/09/2018 10:20 PM, Dave Anderson wrote: [...]
Since the "__pgtable_l5_enabled" symbol is a static data symbol located in the __START_KERNEL_map region, x86_64_VTOP() only needs the kernel's "phys_base" value in order to translate the symbol value into a physical address: ulong x86_64_VTOP(ulong vaddr) { if (vaddr >= __START_KERNEL_map) return ((vaddr) - (ulong)__START_KERNEL_map + machdep->machspec->phys_base); else return ((vaddr) - PAGE_OFFSET); } So if the contents of "__pgtable_l5_enabled" is all that is needed, I think you can do something like: case POST_RELOC: + if (!(machdep->flags & VM_5LEVEL) && + kernel_symbol_exists("__pgtable_l5_enabled")) { + int l5_enabled; + readmem(symbol_value("__pgtable_l5_enabled"), KVADDR, + &l5_enabled, sizeof(int), "__pgtable_l5_enabled", + FAULT_ON_ERROR); + + if (l5_enabled) { + ... execute the relevant section from PRE_GDB ... + } which would be this section from PRE_GDB: case VM_5LEVEL: machdep->machspec->userspace_top = USERSPACE_TOP_5LEVEL; machdep->machspec->page_offset = PAGE_OFFSET_5LEVEL; machdep->machspec->vmalloc_start_addr = VMALLOC_START_ADDR_5LEVEL; machdep->machspec->vmalloc_end = VMALLOC_END_5LEVEL; machdep->machspec->modules_vaddr = MODULES_VADDR_5LEVEL; machdep->machspec->modules_end = MODULES_END_5LEVEL; machdep->machspec->vmemmap_vaddr = VMEMMAP_VADDR_5LEVEL; machdep->machspec->vmemmap_end = VMEMMAP_END_5LEVEL; if (symbol_exists("vmemmap_populate")) machdep->flags |= VMEMMAP; machdep->machspec->physical_mask_shift = __PHYSICAL_MASK_SHIFT_5LEVEL; machdep->machspec->pgdir_shift = PGDIR_SHIFT_5LEVEL; machdep->machspec->ptrs_per_pgd = PTRS_PER_PGD_5LEVEL; if ((machdep->machspec->p4d = (char *)malloc(PAGESIZE())) == NULL) error(FATAL, "cannot malloc p4d space."); machdep->machspec->last_p4d_read = 0; machdep->uvtop = x86_64_uvtop_level4; /* 5-level is optional per-task */ } machdep->kvbase = (ulong)PAGE_OFFSET; machdep->identity_map_base = (ulong)PAGE_OFFSET; The only things that I can think of that might be a problem is the readmem() of "__pgtable_l5_enabled" will need to get by this part of x86_64_kvtop() in order to use x86_64_VTOP(): if (!IS_VMALLOC_ADDR(kvaddr)) { *paddr = x86_64_VTOP(kvaddr); if (!verbose) return TRUE; } where IS_VMALLOC_ADDR() would still be using the 4-level addresses. But that could be worked around some way.
AFAIC, It doesn't matter, here, due to the vt->vmalloc_start is 0 at this time, we always use the x86_64_VTOP(). if (!vt->vmalloc_start) { *paddr = x86_64_VTOP(kvaddr); return TRUE; } if (!IS_VMALLOC_ADDR(kvaddr)) { *paddr = x86_64_VTOP(kvaddr); if (!verbose) return TRUE; }
Can you give that a test?
Yes, I have tested this both in KDump and virsh dump cases. It can work well. I will send v2 patch for you. Thanks, dou. -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility