[Crash-utility] [PATCH v2] x86_64: Make the conversion between 4level and 5level paging automatically
Dave Anderson
anderson at redhat.com
Tue Jul 10 18:01:54 UTC 2018
----- Original Message -----
>
> Hello Dou,
>
> This patch was failing on most -- but not all -- of my test dumpfiles, because of
> fatal read or seek errors during session initialization.
>
> As it turns out, the "l5_enabled" local variable needs to be zeroed-out, because
> if neither the "if" or the "else" are true, it uses whatever old stack garbage
> that l5_enabled contains:
>
> > + /* 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;
> > + }
>
> I'll fix that and retest.
It still fails on 4.17 and later kernels that have this in their VMCOREINFO:
NUMBER(pgtable_l5_enabled)=0
You need to do atoi(string) to get its value. I'll fix that and retest again...
Dave
>
> Thanks,
> Dave
>
>
>
>
>
> ----- Original Message -----
> > 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 <anderson at redhat.com>
> > Signed-off-by: Dou Liyang <douly.fnst at cn.fujitsu.com>
> > ---
> > 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
> Crash-utility at redhat.com
> https://www.redhat.com/mailman/listinfo/crash-utility
>
More information about the Crash-utility
mailing list