> -----Original Message----- > From: Hatayama, Daisuke > Sent: Friday, January 26, 2018 3:56 PM > To: Indoh, Takao/印藤 隆夫 <indou.takao@xxxxxxxxxxxxxx>; > crash-utility@xxxxxxxxxx > Subject: RE: [PATCH] sadump: Fix a problem of PTI enabled kernel > > > > > -----Original Message----- > > From: Takao Indoh [mailto:indou.takao@xxxxxxxxxxxxxx] > > Sent: Friday, January 26, 2018 9:26 AM > > To: crash-utility@xxxxxxxxxx; Hatayama, Daisuke > > <d.hatayama@xxxxxxxxxxxxxx> > > Subject: [PATCH] sadump: Fix a problem of PTI enabled kernel > > > > This patch fixes a problem that a dumpfile of sadump cannot be opened > > by crash when Page Table Isolation(PTI) is enabled. > > > > When PTI is enabled, bit 12 of CR3 register is used to split user > > space and kernel space. Also bit 11:0 is used for Process Context > > IDentifiers(PCID). To open a dump file of sadump, a value of CR3 is > > used to calculate KASLR offset and phys_base, therefore this patch > > fixes to mask CR3 register value collectly for PTI enabled kernel. > > > > This patch also includes code cleanup. > > > > Signed-off-by: Takao Indoh <indou.takao@xxxxxxxxxxxxxx> > > --- > > defs.h | 2 ++ > > sadump.c | 33 +++++++++++++++++++++------------ > > symbols.c | 9 +++++++++ > > 3 files changed, 32 insertions(+), 12 deletions(-) > > > > diff --git a/defs.h b/defs.h > > index dcd6c26..a19f280 100644 > > --- a/defs.h > > +++ b/defs.h > > @@ -2605,6 +2605,8 @@ struct symbol_table_data { > > ulong divide_error_vmlinux; > > ulong idt_table_vmlinux; > > ulong saved_command_line_vmlinux; > > + ulong pti_init_vmlinux; > > + ulong kaiser_init_vmlinux; > > }; > > > > /* flags for st */ > > diff --git a/sadump.c b/sadump.c > > index 6b912d4..25cefe9 100644 > > --- a/sadump.c > > +++ b/sadump.c > > @@ -1749,7 +1749,7 @@ static ulong memparse(char *ptr, char **retptr) > > * of elfcorehdr. > > */ > > static ulong > > -get_elfcorehdr(ulong cr3, ulong kaslr_offset) > > +get_elfcorehdr(ulong kaslr_offset) > > { > > char cmdline[BUFSIZE], *ptr; > > ulong cmdline_vaddr; > > @@ -1906,7 +1906,7 @@ get_vmcoreinfo(ulong elfcorehdr, ulong *addr, int *len) > > * using "elfcorehdr=" and retrieve kaslr_offset/phys_base from > > vmcoreinfo. > > */ > > static int > > -get_kaslr_offset_from_vmcoreinfo(ulong cr3, ulong orig_kaslr_offset, > > +get_kaslr_offset_from_vmcoreinfo(ulong orig_kaslr_offset, > > ulong *kaslr_offset, ulong *phys_base) > > { > > ulong elfcorehdr_addr = 0; > > @@ -1916,7 +1916,7 @@ get_kaslr_offset_from_vmcoreinfo(ulong cr3, ulong > > orig_kaslr_offset, > > int ret = FALSE; > > > > /* Find "elfcorehdr=" in the kernel boot parameter */ > > - elfcorehdr_addr = get_elfcorehdr(cr3, orig_kaslr_offset); > > + elfcorehdr_addr = get_elfcorehdr(orig_kaslr_offset); > > if (!elfcorehdr_addr) > > return FALSE; > > > > @@ -1973,8 +1973,8 @@ quit: > > * 1) Get IDTR and CR3 value from the dump header. > > * 2) Get a virtual address of IDT from IDTR value > > * --- (A) > > - * 3) Translate (A) to physical address using CR3, which points a top of > > - * page table. > > + * 3) Translate (A) to physical address using CR3, the upper 52 bits > > + * of which points a top of page table. > > * --- (B) > > * 4) Get an address of vector0 (Devide Error) interrupt handler from > > * IDT, which are pointed by (B). > > @@ -2023,12 +2023,15 @@ quit: > > * kernel. Retrieve vmcoreinfo from address of "elfcorehdr=" and > > * get kaslr_offset and phys_base from vmcoreinfo. > > */ > > +#define PTI_USER_PGTABLE_BIT PAGE_SHIFT > > +#define PTI_USER_PGTABLE_MASK (1 << PTI_USER_PGTABLE_BIT) > > +#define CR3_PCID_MASK 0xFFFull > > int > > sadump_calc_kaslr_offset(ulong *kaslr_offset) > > { > > ulong phys_base = 0; > > struct sadump_smram_cpu_state scs; > > - uint64_t idtr = 0, cr3 = 0, idtr_paddr; > > + uint64_t idtr = 0, pgd = 0, idtr_paddr; > > ulong divide_error_vmcore; > > ulong kaslr_offset_kdump, phys_base_kdump; > > int ret = FALSE; > > @@ -2039,7 +2042,10 @@ sadump_calc_kaslr_offset(ulong *kaslr_offset) > > > > memset(&scs, 0, sizeof(scs)); > > get_sadump_smram_cpu_state_any(&scs); > > - cr3 = scs.Cr3; > > + if (st->pti_init_vmlinux || st->kaiser_init_vmlinux) > > + pgd = scs.Cr3 & ~(CR3_PCID_MASK|PTI_USER_PGTABLE_MASK); > > + else > > + pgd = scs.Cr3 & ~CR3_PCID_MASK; > > idtr = ((uint64_t)scs.IdtUpper)<<32 | (uint64_t)scs.IdtLower; > > > > /* > > @@ -2050,12 +2056,12 @@ sadump_calc_kaslr_offset(ulong *kaslr_offset) > > * > > * TODO: XEN and 5-level is not supported > > */ > > - vt->kernel_pgd[0] = cr3; > > + vt->kernel_pgd[0] = pgd; > > machdep->machspec->last_pml4_read = vt->kernel_pgd[0]; > > machdep->machspec->physical_mask_shift = > > __PHYSICAL_MASK_SHIFT_2_6; > > machdep->machspec->pgdir_shift = PGDIR_SHIFT; > > - if (!readmem(cr3, PHYSADDR, machdep->machspec->pml4, PAGESIZE(), > > - "cr3", RETURN_ON_ERROR)) > > + if (!readmem(pgd, PHYSADDR, machdep->machspec->pml4, PAGESIZE(), > > + "pgd", RETURN_ON_ERROR)) > > goto quit; > > > > /* Convert virtual address of IDT table to physical address */ > > @@ -2070,7 +2076,7 @@ sadump_calc_kaslr_offset(ulong *kaslr_offset) > > > > if (CRASHDEBUG(1)) { > > fprintf(fp, "calc_kaslr_offset: idtr=%lx\n", idtr); > > - fprintf(fp, "calc_kaslr_offset: cr3=%lx\n", cr3); > > + fprintf(fp, "calc_kaslr_offset: pgd=%lx\n", pgd); > > fprintf(fp, "calc_kaslr_offset: idtr(phys)=%lx\n", > > idtr_paddr); > > fprintf(fp, "calc_kaslr_offset: > > divide_error(vmlinux): %lx\n", > > st->divide_error_vmlinux); > > @@ -2084,9 +2090,12 @@ sadump_calc_kaslr_offset(ulong *kaslr_offset) > > * from vmcoreinfo > > */ > > if (get_kaslr_offset_from_vmcoreinfo( > > - cr3, *kaslr_offset, &kaslr_offset_kdump, > > &phys_base_kdump)) { > > + *kaslr_offset, &kaslr_offset_kdump, &phys_base_kdump)) { > > *kaslr_offset = kaslr_offset_kdump; > > phys_base = phys_base_kdump; > > + } else if (CRASHDEBUG(1)) { > > + fprintf(fp, "sadump: failed to determine which kernel was > > running at crash,\n"); > > + fprintf(fp, "sadump: asssuming the kdump 1st kernel.\n"); > > } > > > > if (CRASHDEBUG(1)) { > > diff --git a/symbols.c b/symbols.c > > index 2372887..26b319a 100644 > > --- a/symbols.c > > +++ b/symbols.c > > @@ -3072,10 +3072,14 @@ dump_symbol_table(void) > > fprintf(fp, "divide_error_vmlinux: %lx\n", > > st->divide_error_vmlinux); > > fprintf(fp, " idt_table_vmlinux: %lx\n", > > st->idt_table_vmlinux); > > fprintf(fp, "saved_command_line_vmlinux: %lx\n", > > st->saved_command_line_vmlinux); > > + fprintf(fp, " pti_init_vmlinux: %lx\n", > > st->pti_init_vmlinux); > > + fprintf(fp, " kaiser_init_vmlinux: %lx\n", > > st->kaiser_init_vmlinux); > > } else { > > fprintf(fp, "divide_error_vmlinux: (unused)\n"); > > fprintf(fp, " idt_table_vmlinux: (unused)\n"); > > fprintf(fp, "saved_command_line_vmlinux: (unused)\n"); > > + fprintf(fp, " pti_init_vmlinux: (unused)\n"); > > + fprintf(fp, " kaiser_init_vmlinux: (unused)\n"); > > } > > > > fprintf(fp, " symval_hash[%d]: %lx\n", SYMVAL_HASH, > > @@ -12306,6 +12310,11 @@ numeric_forward(const void *P_x, const void *P_y) > > st->saved_command_line_vmlinux = valueof(x); > > else if (STREQ(y->name, "saved_command_line")) > > st->saved_command_line_vmlinux = valueof(y); > > + > > + if (STREQ(x->name, "pti_init")) > > + st->pti_init_vmlinux = valueof(x); > > + else if (STREQ(y->name, "kaiser_init")) > > + st->kaiser_init_vmlinux = valueof(y); > > } > > > > xs = bfd_get_section(x); > > -- > > 1.8.3.1 > > It looks good to me. Thanks. > > Dave, could you merge this patch? > > Thanks. > HATAYAMA, Daisuke Dave, I'm resending this mail directly to you because I don't know why but it looks that reply to the Indoh-san's mail didn't reach the crash mailing list, while the other mail I sent at 12:23 reached... As being written above, I think the patch good. Could you merge it? Thanks. HATAYAMA, Daisuke -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility