----- Original Message ----- > Hello Dave, > > Please find enclosed patch below. > > Enhancement to the S390X "vtop" command to display binary values of > hardware flags for region, segment and page table entries along with > page table walk information. > > For example: > > crash> vtop -u 0x60000000000000 > VIRTUAL PHYSICAL > 60000000000000 5b50a000 > > PAGE DIRECTORY: 000000005cea0000 > RFTE: 000000005cea0018 => 000000006612400f (flags = 00f) > flags in binary : P=0; TF=00; I=0; TT=11; TL=11 > RSTE: 0000000066124000 => 000000005d91800b (flags = 00b) > flags in binary : P=0; TF=00; I=0; TT=10; TL=11 > RTTE: 000000005d918000 => 000000006615c007 (flags = 007) > flags in binary : FC=0; P=0; TF=00; I=0; CR=0; TT=01; TL=11 > STE: 000000006615c000 => 000000005ce48800 (flags = 800) > flags in binary : FC=0; P=0; I=0; CS=0; TT=00 > PTE: 000000005ce48800 => 000000005b50a03f (flags = 03f) > flags in binary : I=0; P=0 > PAGE: 000000005b50a000 > > or, for large pages: > > crash> vtop -k 0x3d100000000 > VIRTUAL PHYSICAL > 3d100000000 77c00000 > > PAGE DIRECTORY: 0000000001210000 > RTTE: 0000000001213d10 => 0000000077dc4007 (flags = 007) > flags in binary : FC=0; P=0; TF=00; I=0; CR=0; TT=01; TL=11 > STE: 0000000077dc4000 => 0000000077c03403 (flags = 03403) > flags in binary : AV=0, ACC=0011; F=0; FC=1; P=0; I=0; CS=0; TT=00 > > Reviewed-by: Michael Holzheu <holzheu@xxxxxxxxxxxxxxxxxx> > Signed-off-by: Mikhail Zaslonko <zaslonko@xxxxxxxxxxxxxxxxxx> Hello Mikhail, Looks good and tests OK -- queued for crash-7.2.0: https://github.com/crash-utility/crash/commit/cba615e62ae6e294af1244bf90b218829db1ea03 Thanks, Dave > --- > s390x.c | 183 > +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- > 1 file changed, 175 insertions(+), 8 deletions(-) > > diff --git a/s390x.c b/s390x.c > index 9246f75..fa202bc 100644 > --- a/s390x.c > +++ b/s390x.c > @@ -26,7 +26,8 @@ > > /* Flags used in entries of page dirs and page tables. > */ > -#define S390X_PAGE_PRESENT 0x001ULL /* set: loaded in physical memory > +#define S390X_PTE_FLAG_BITS 0xfffULL /* Page table entry flag bits */ > +#define S390X_PAGE_PRESENT 0x001ULL /* set: loaded in physical memory > * clear: not loaded in > physical mem */ > #define S390X_PAGE_RO 0x200ULL /* HW read-only */ > #define S390X_PAGE_INVALID 0x400ULL /* HW invalid */ > @@ -46,6 +47,49 @@ > #define S390X_PSW_MASK_PSTATE 0x0001000000000000UL > > /* > + * Flags for Region and Segment table entries. > + */ > +#define S390X_RTE_FLAG_BITS_FC0 0xfffULL > +#define S390X_RTE_FLAG_BITS_FC1 0x7fffffffULL > +#define S390X_RTE_TL 0x3ULL > +#define S390X_RTE_TL_10 0x2ULL > +#define S390X_RTE_TL_01 0x1ULL > +#define S390X_RTE_TT 0xcULL > +#define S390X_RTE_TT_10 0x8ULL > +#define S390X_RTE_TT_01 0x4ULL > +#define S390X_RTE_CR 0x10ULL > +#define S390X_RTE_I 0x20ULL > +#define S390X_RTE_TF 0xc0ULL > +#define S390X_RTE_TF_10 0x80ULL > +#define S390X_RTE_TF_01 0x40ULL > +#define S390X_RTE_P 0x200ULL > +#define S390X_RTE_FC 0x400ULL > +#define S390X_RTE_F 0x800ULL > +#define S390X_RTE_ACC 0xf000ULL > +#define S390X_RTE_ACC_1000 0x8000ULL > +#define S390X_RTE_ACC_0100 0x4000ULL > +#define S390X_RTE_ACC_0010 0x2000ULL > +#define S390X_RTE_ACC_0001 0x1000ULL > +#define S390X_RTE_AV 0x10000ULL > + > +#define S390X_STE_FLAG_BITS_FC0 0x7ffULL > +#define S390X_STE_FLAG_BITS_FC1 0xfffffULL > +#define S390X_STE_TT 0xcULL > +#define S390X_STE_TT_10 0x8ULL > +#define S390X_STE_TT_01 0x4ULL > +#define S390X_STE_CS 0x10ULL > +#define S390X_STE_I 0x20ULL > +#define S390X_STE_P 0x200ULL > +#define S390X_STE_FC 0x400ULL > +#define S390X_STE_F 0x800ULL > +#define S390X_STE_ACC 0xf000ULL > +#define S390X_STE_ACC_1000 0x8000ULL > +#define S390X_STE_ACC_0100 0x4000ULL > +#define S390X_STE_ACC_0010 0x2000ULL > +#define S390X_STE_ACC_0001 0x1000ULL > +#define S390X_STE_AV 0x10000ULL > + > +/* > * S390x prstatus ELF Note > */ > struct s390x_nt_prstatus { > @@ -611,12 +655,115 @@ static inline int s390x_pte_present(unsigned long x){ > * page table traversal functions > */ > > +/* Print flags of Segment-Table entry with format control = 1 */ > +static void print_segment_entry_fc1(ulong val) > +{ > + fprintf(fp, "AV=%u; ACC=%u%u%u%u; F=%u; FC=%u; P=%u; I=%u; CS=%u; > TT=%u%u\n", > + !!(val & S390X_STE_AV), > + !!(val & S390X_STE_ACC_1000), > + !!(val & S390X_STE_ACC_0100), > + !!(val & S390X_STE_ACC_0010), > + !!(val & S390X_STE_ACC_0001), > + !!(val & S390X_STE_F), > + !!(val & S390X_STE_FC), > + !!(val & S390X_STE_P), > + !!(val & S390X_STE_I), > + !!(val & S390X_STE_CS), > + !!(val & S390X_STE_TT_10), > + !!(val & S390X_STE_TT_01)); > +} > + > +/* Print flags of Segment-Table entry with format control = 0 */ > +static void print_segment_entry_fc0(ulong val) > +{ > + fprintf(fp, "FC=%u; P=%u; I=%u; CS=%u; TT=%u%u\n", > + !!(val & S390X_STE_FC), > + !!(val & S390X_STE_P), > + !!(val & S390X_STE_I), > + !!(val & S390X_STE_CS), > + !!(val & S390X_STE_TT_10), > + !!(val & S390X_STE_TT_01)); > +} > + > +/* Print flags of Region-Third-Table entry with format control = 1 */ > +static void print_region_third_entry_fc1(ulong val) > +{ > + fprintf(fp, "AV=%u; ACC=%u%u%u%u; F=%u; FC=%u; P=%u; I=%u; CR=%u; > TT=%u%u\n", > + !!(val & S390X_RTE_AV), > + !!(val & S390X_RTE_ACC_1000), > + !!(val & S390X_RTE_ACC_0100), > + !!(val & S390X_RTE_ACC_0010), > + !!(val & S390X_RTE_ACC_0001), > + !!(val & S390X_RTE_F), > + !!(val & S390X_RTE_FC), > + !!(val & S390X_RTE_P), > + !!(val & S390X_RTE_I), > + !!(val & S390X_RTE_CR), > + !!(val & S390X_RTE_TT_10), > + !!(val & S390X_RTE_TT_01)); > +} > + > +/* Print flags of Region-Third-Table entry with format control = 0 */ > +static void print_region_third_entry_fc0(ulong val) > +{ > + fprintf(fp, "FC=%u; P=%u; TF=%u%u; I=%u; CR=%u; TT=%u%u; TL=%u%u\n", > + !!(val & S390X_RTE_FC), > + !!(val & S390X_RTE_P), > + !!(val & S390X_RTE_TF_10), > + !!(val & S390X_RTE_TF_01), > + !!(val & S390X_RTE_I), > + !!(val & S390X_RTE_CR), > + !!(val & S390X_RTE_TT_10), > + !!(val & S390X_RTE_TT_01), > + !!(val & S390X_RTE_TL_10), > + !!(val & S390X_RTE_TL_01)); > +} > + > +/* Print flags of Region-First/Second-Table entry */ > +static void print_region_first_second_entry(ulong val) > +{ > + fprintf(fp, "P=%u; TF=%u%u; I=%u; TT=%u%u; TL=%u%u\n", > + !!(val & S390X_RTE_P), > + !!(val & S390X_RTE_TF_10), > + !!(val & S390X_RTE_TF_01), > + !!(val & S390X_RTE_I), > + !!(val & S390X_RTE_TT_10), > + !!(val & S390X_RTE_TT_01), > + !!(val & S390X_RTE_TL_10), > + !!(val & S390X_RTE_TL_01)); > +} > + > +/* Print the binary flags for Region or Segment table entry */ > +static void s390x_print_te_binary_flags(ulong val, int level) > +{ > + fprintf(fp, " flags in binary : "); > + switch (level) { > + case 0: > + if (val & S390X_STE_FC) > + print_segment_entry_fc1(val); > + else > + print_segment_entry_fc0(val); > + break; > + case 1: > + if (val & S390X_RTE_FC) > + print_region_third_entry_fc1(val); > + else > + print_region_third_entry_fc0(val); > + break; > + case 2: > + case 3: > + print_region_first_second_entry(val); > + break; > + } > +} > + > /* Region or segment table traversal function */ > static ulong _kl_rsg_table_deref_s390x(ulong vaddr, ulong table, > int len, int level, int verbose) > { > const char *name_vec[] = {"STE", "RTTE", "RSTE", "RFTE"}; > - ulong offset, entry, addr; > + ulong offset, entry, flags, addr; > + int flags_prt_len; > > offset = ((vaddr >> (11*level + 20)) & 0x7ffULL) * 8; > if (offset >= (len + 1)*4096) > @@ -624,16 +771,33 @@ static ulong _kl_rsg_table_deref_s390x(ulong > vaddr, ulong table, > return 0; > addr = table + offset; > readmem(addr, KVADDR, &entry, sizeof(entry), "entry", FAULT_ON_ERROR); > - if (verbose) > - fprintf(fp, "%5s: %016lx => %016lx\n", name_vec[level], addr, > entry); > + if (verbose) { > + flags_prt_len = 3; > + if (entry & S390X_RTE_FC) > + if (level) { > + flags = entry & S390X_RTE_FLAG_BITS_FC1; > + flags_prt_len = 8; > + } else { > + flags = entry & S390X_STE_FLAG_BITS_FC1; > + flags_prt_len = 5; > + } > + else > + if (level) > + flags = entry & S390X_RTE_FLAG_BITS_FC0; > + else > + flags = entry & S390X_STE_FLAG_BITS_FC0; > + fprintf(fp, "%5s: %016lx => %016lx (flags = %0*lx)\n", > + name_vec[level], addr, entry, flags_prt_len, flags); > + s390x_print_te_binary_flags(entry, level); > + } > /* > * Check if the segment table entry could be read and doesn't have > * any of the reserved bits set. > */ > - if ((entry & 0xcULL) != (level << 2)) > + if ((entry & S390X_RTE_TT) != (level << 2)) > return 0; > /* Check if the region table entry has the invalid bit set. */ > - if (entry & 0x20ULL) > + if (entry & S390X_RTE_I) > return 0; > /* Region table entry is valid and well formed. */ > return entry; > @@ -664,8 +828,11 @@ static ulong _kl_pg_table_deref_s390x(ulong vaddr, > ulong table, int verbose) > addr = table + offset; > readmem(addr, KVADDR, &entry, sizeof(entry), "entry", FAULT_ON_ERROR); > if (verbose) { > - fprintf(fp, "%5s: %016lx => %016lx\n", "PTE", addr, entry); > - fprintf(fp, "%5s: %016llx\n", "PAGE", entry & ~0xfffULL); > + fprintf(fp, "%5s: %016lx => %016lx (flags = %03llx)\n", > + "PTE", addr, entry, entry & S390X_PTE_FLAG_BITS); > + fprintf(fp, " flags in binary : I=%u; P=%u\n", > + !!(entry & S390X_PAGE_INVALID), !!(entry & S390X_PAGE_RO)); > + fprintf(fp, "%5s: %016llx\n", "PAGE", entry & > ~S390X_PTE_FLAG_BITS); > } > /* > * Return zero if the page table entry has the reserved (0x800) or > -- > 2.11.2 > > > -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility