[Crash-utility] [PATCH] s390x : Display-hardware-flags-for-RTE-STE-PTE

Dave Anderson anderson at redhat.com
Tue Aug 15 20:00:05 UTC 2017



----- 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 at linux.vnet.ibm.com>
> Signed-off-by: Mikhail Zaslonko <zaslonko at linux.vnet.ibm.com>

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
> 
> 
> 




More information about the Crash-utility mailing list