Hello Dave, This patch adds some output to the vtop command on s390x. Like on x86 we now print information for the page table walk: * "Region-First-Table Entry" (RFTE) * "Region-Second-Table Entry" (RSTE) * "Region-Third-Table Entry" (RTTE) * "Segment Table Entry" (STE) * "Page Table Entry" (PTE) * "Read address of page" (PAGE) Depending on the size of the address space the page tables can start at different levels. Example for three level page tables: crash> vtop 3ff8000c000 VIRTUAL PHYSICAL 3ff8000c000 2e3832000 PAGE DIRECTORY: 0000000000aaa000 RTTE: 0000000000aadff8 => 00000002e3c00007 STE: 00000002e3c00000 => 00000002e3df7000 PTE: 00000002e3df7060 => 00000002e383203d PAGE: 00000002e3832000 PAGE PHYSICAL MAPPING INDEX CNT FLAGS 3d10b8e0c80 2e3832000 0 0 1 7fffc0000000000 The first entry e.g. "PTE: 00000002e3df7060" is the physical address of the entry in the table. The second, e.g. "=> 00000002e383203d" is the content of the entry itself (address and flags). Reviewed-by: Heiko Carstens <heiko.carstens@xxxxxxxxxx> Tested-by: Mikhail Zaslonko <zaslonko@xxxxxxxxxxxxxxxxxx> Signed-off-by: Michael Holzheu <holzheu@xxxxxxxxxxxxxxxxxx> --- s390x.c | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/s390x.c b/s390x.c index 96ce3dc..9246f75 100644 --- a/s390x.c +++ b/s390x.c @@ -613,16 +613,19 @@ static inline int s390x_pte_present(unsigned long x){ /* Region or segment table traversal function */ static ulong _kl_rsg_table_deref_s390x(ulong vaddr, ulong table, - int len, int level) + int len, int level, int verbose) { - ulong offset, entry; + const char *name_vec[] = {"STE", "RTTE", "RSTE", "RFTE"}; + ulong offset, entry, addr; offset = ((vaddr >> (11*level + 20)) & 0x7ffULL) * 8; if (offset >= (len + 1)*4096) /* Offset is over the table limit. */ return 0; - readmem(table + offset, KVADDR, &entry, sizeof(entry), "entry", - FAULT_ON_ERROR); + 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); /* * Check if the segment table entry could be read and doesn't have * any of the reserved bits set. @@ -653,13 +656,17 @@ static int swap_entry(ulong entry) } /* Page table traversal function */ -static ulong _kl_pg_table_deref_s390x(ulong vaddr, ulong table) +static ulong _kl_pg_table_deref_s390x(ulong vaddr, ulong table, int verbose) { - ulong offset, entry; + ulong offset, entry, addr; offset = ((vaddr >> 12) & 0xffULL) * 8; - readmem(table + offset, KVADDR, &entry, sizeof(entry), "entry", - FAULT_ON_ERROR); + 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); + } /* * Return zero if the page table entry has the reserved (0x800) or * the invalid (0x400) bit set and it is not a swap entry. @@ -676,6 +683,9 @@ int s390x_vtop(ulong table, ulong vaddr, physaddr_t *phys_addr, int verbose) ulong entry, paddr; int level, len; + if (verbose) + fprintf(fp, "PAGE DIRECTORY: %016lx\n", table); + *phys_addr = 0; /* * Walk the region and segment tables. @@ -693,7 +703,8 @@ int s390x_vtop(ulong table, ulong vaddr, physaddr_t *phys_addr, int verbose) return FALSE; } while (level >= 0) { - entry = _kl_rsg_table_deref_s390x(vaddr, table, len, level); + entry = _kl_rsg_table_deref_s390x(vaddr, table, len, level, + verbose); if (!entry) return FALSE; table = entry & ~0xfffULL; @@ -717,7 +728,7 @@ int s390x_vtop(ulong table, ulong vaddr, physaddr_t *phys_addr, int verbose) } /* Get the page table entry */ - entry = _kl_pg_table_deref_s390x(vaddr, entry & ~0x7ffULL); + entry = _kl_pg_table_deref_s390x(vaddr, entry & ~0x7ffULL, verbose); if (!entry) return FALSE; -- 2.11.2
>From f6904d299589b9639963fcb1fafe58c3577d27a6 Mon Sep 17 00:00:00 2001 From: Michael Holzheu <holzheu@xxxxxxxxxxxxxxxxxx> Date: Fri, 21 Jul 2017 16:02:00 +0200 Subject: [PATCH] [PATCH] s390x: Add page table walk information to vtop command Hello Dave, This patch adds some output to the vtop command on s390x. Like on x86 we now print information on the page table walk: * "Region-First-Table Entry" (RFTE) * "Region-Second-Table Entry" (RSTE) * "Region-Third-Table Entry" (RTTE) * "Segment Table Entry" (STE) * "Page Table Entry" (PTE) * "Read address of page" (PAGE) Depending on the size of the address space, the page tables can start at different levels. Example: crash> vtop 3ff8000c000 VIRTUAL PHYSICAL 3ff8000c000 2e3832000 PAGE DIRECTORY: 0000000000aaa000 RTTE: 0000000000aadff8 => 00000002e3c00007 STE: 00000002e3c00000 => 00000002e3df7000 PTE: 00000002e3df7060 => 00000002e383203d PAGE: 00000002e3832000 PAGE PHYSICAL MAPPING INDEX CNT FLAGS 3d10b8e0c80 2e3832000 0 0 1 7fffc0000000000 Reviewed-by: Heiko Carstens <heiko.carstens@xxxxxxxxxx> Reviewed-by: Mikhail Zaslonko <zaslonko@xxxxxxxxxxxxxxxxxx> Signed-off-by: Michael Holzheu <holzheu@xxxxxxxxxxxxxxxxxx> --- s390x.c | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/s390x.c b/s390x.c index 96ce3dc..9246f75 100644 --- a/s390x.c +++ b/s390x.c @@ -613,16 +613,19 @@ static inline int s390x_pte_present(unsigned long x){ /* Region or segment table traversal function */ static ulong _kl_rsg_table_deref_s390x(ulong vaddr, ulong table, - int len, int level) + int len, int level, int verbose) { - ulong offset, entry; + const char *name_vec[] = {"STE", "RTTE", "RSTE", "RFTE"}; + ulong offset, entry, addr; offset = ((vaddr >> (11*level + 20)) & 0x7ffULL) * 8; if (offset >= (len + 1)*4096) /* Offset is over the table limit. */ return 0; - readmem(table + offset, KVADDR, &entry, sizeof(entry), "entry", - FAULT_ON_ERROR); + 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); /* * Check if the segment table entry could be read and doesn't have * any of the reserved bits set. @@ -653,13 +656,17 @@ static int swap_entry(ulong entry) } /* Page table traversal function */ -static ulong _kl_pg_table_deref_s390x(ulong vaddr, ulong table) +static ulong _kl_pg_table_deref_s390x(ulong vaddr, ulong table, int verbose) { - ulong offset, entry; + ulong offset, entry, addr; offset = ((vaddr >> 12) & 0xffULL) * 8; - readmem(table + offset, KVADDR, &entry, sizeof(entry), "entry", - FAULT_ON_ERROR); + 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); + } /* * Return zero if the page table entry has the reserved (0x800) or * the invalid (0x400) bit set and it is not a swap entry. @@ -676,6 +683,9 @@ int s390x_vtop(ulong table, ulong vaddr, physaddr_t *phys_addr, int verbose) ulong entry, paddr; int level, len; + if (verbose) + fprintf(fp, "PAGE DIRECTORY: %016lx\n", table); + *phys_addr = 0; /* * Walk the region and segment tables. @@ -693,7 +703,8 @@ int s390x_vtop(ulong table, ulong vaddr, physaddr_t *phys_addr, int verbose) return FALSE; } while (level >= 0) { - entry = _kl_rsg_table_deref_s390x(vaddr, table, len, level); + entry = _kl_rsg_table_deref_s390x(vaddr, table, len, level, + verbose); if (!entry) return FALSE; table = entry & ~0xfffULL; @@ -717,7 +728,7 @@ int s390x_vtop(ulong table, ulong vaddr, physaddr_t *phys_addr, int verbose) } /* Get the page table entry */ - entry = _kl_pg_table_deref_s390x(vaddr, entry & ~0x7ffULL); + entry = _kl_pg_table_deref_s390x(vaddr, entry & ~0x7ffULL, verbose); if (!entry) return FALSE; -- 2.11.2
-- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility