Currently, Crash only enable support for kernel-only 5-level page tables by
entering the command line option "--machdep vm=5level". Since Linux 4.17,
the Linux kernel can be both 4level and 5level page tables. This command line
can't work well for this.

Using the "pgtable_l5_enabled" to detect whether the kernel proper for 5 level
page tables automatically. Also move the 5-level paging setup from 
machdep_init(PRE_GDB)
to machdep_init(POST_RELOC).

Signed-off-by: Dave Anderson <[email protected]>
Signed-off-by: Dou Liyang <[email protected]>
---
Changelog v1 --> v2

 1. Make it support live systems suggested by Dave
 2. Using __pgtable_l5_enabled for check.
 3. Do some tests in both kdump(5level and 4level) and virsh dump(5level and 
4level) 
---
 x86_64.c | 56 +++++++++++++++++++++++++++++++++++++-------------------
 1 file changed, 37 insertions(+), 19 deletions(-)

diff --git a/x86_64.c b/x86_64.c
index 6d1ae2f..07b6aa9 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -294,25 +294,6 @@ x86_64_init(int when)
                        machdep->machspec->pgdir_shift = PGDIR_SHIFT;
                        machdep->machspec->ptrs_per_pgd = PTRS_PER_PGD;
                        break;
-
-               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;
@@ -346,6 +327,43 @@ x86_64_init(int when)
                break;
 
        case POST_RELOC:
+               /* Check for 5-level paging */
+               if (!(machdep->flags & VM_5LEVEL)) {
+                       int l5_enabled;
+                       if ((string = 
pc->read_vmcoreinfo("NUMBER(pgtable_l5_enabled)"))) {
+                               l5_enabled = 1;
+                               free(string);
+                       } else if (kernel_symbol_exists("__pgtable_l5_enabled"))
+                               readmem(symbol_value("__pgtable_l5_enabled"), 
KVADDR,
+                                       &l5_enabled, sizeof(int), 
"__pgtable_l5_enabled",
+                                       FAULT_ON_ERROR);
+
+                       if (l5_enabled)
+                               machdep->flags |= VM_5LEVEL;
+               }
+               if (machdep->flags & 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;
+
+               }
+
                /*
                 *  Check for CONFIG_RANDOMIZE_MEMORY, and set page_offset here.
                 *  The remainder of the virtual address range setups will get
-- 
2.14.3



--
Crash-utility mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/crash-utility

Reply via email to