[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