Hari,
Thanks for looking into this.  I'm currently on vacation and
and so I'll check out this patch next week.
Thanks,
  Dave Anderson
 Crash utility currently does not supporting virtual to physical address
 translation for huge pages on PPC64.
 This patch tries to address this issue by providing address translation
 support for huge pages in 'vtop' command on PPC64.
 Below are couple of outputs for address translation of huge pages on
 crash-7.0.1 (with Dave's patch for vtop issue on >=3.10 kernel)
 #On kernel release 3.6.0-rc1
   crash> set 8149
     PID: 8149
 COMMAND: "hugepage-mmap"
    TASK: c000000079ce49f0  [THREAD_INFO: c00000007795c000]
     CPU: 0
   STATE: TASK_INTERRUPTIBLE
 crash> vtop 0xefff0000000
 VIRTUAL           PHYSICAL
 vtop: invalid kernel virtual address: 4000000079060000  type: "page table"
   crash>
 #On kernel release 3.11.0-rc2
   crash> set 13011
     PID: 13011
 COMMAND: "hugepage-mmap"
    TASK: c000000071600000  [THREAD_INFO: c000000078240000]
     CPU: 0
   STATE: TASK_INTERRUPTIBLE
 crash> vtop 0x1efff0000000
 VIRTUAL           PHYSICAL
 1efff0000000      (not mapped)
 PAGE DIRECTORY: c000000002770000
   L4: c000000002770df8 => 0
       VMA              START             END        FLAGS FILE
 c000000024f13af0     1efff0000000     1f0000000000 4400fb
 /mnt/huge/hugepagefile
 FILE: /mnt/huge/hugepagefile  OFFSET: 0
   crash>
 In the two cases mentioned above, crash fails to convert huge pages to
 corresponding physical addresses.
 Below are the outputs with this patch "applied"
 #On kernel release 3.6.0-rc1
   crash> vtop 0xefff0000000
 VIRTUAL           PHYSICAL
 efff0000000       37000000
 PAGE DIRECTORY: c00000007906f800
   L4: c00000007906f870 => c00000007c588000
   PMD: c00000007c58fff8 => 4000000079063798
  HUGE PAGE: 37000000
     PTE      PHYSICAL  FLAGS
 dc008000393  37000000  (PRESENT|USER|COHERENT|DIRTY|ACCESSED)
       VMA              START             END        FLAGS FILE
 c00000007bf3a140      efff0000000      f0000000000 4800fb
 /mnt/huge/hugepagefile
       PAGE       PHYSICAL      MAPPING       INDEX CNT FLAGS
 c00000007f380000 37000000 c00000007af00e88        0  2 3701000004018
   crash>
 #On kernel release 3.11.0-rc2
   crash> vtop 0x1efff0000000
 VIRTUAL           PHYSICAL
 1efff0000000      45000000
 PAGE DIRECTORY: c000000002770000
   L4: c000000002773df8 => c00000007ab80000
   PMD: c00000007ab81f80 => 114008000393
  HUGE PAGE: 45000000
     PTE       PHYSICAL  FLAGS
 114008000393  45000000  (PRESENT|USER|COHERENT|DIRTY|ACCESSED)
       VMA              START             END        FLAGS FILE
 c000000024f13af0     1efff0000000     1f0000000000 4400fb
 /mnt/huge/hugepagefile
       PAGE       PHYSICAL      MAPPING       INDEX CNT FLAGS
 c00000007f460000 45000000 c000000072ea0c70        0  2 1140400004018
   crash>
 With the patch applied huge pages could be converted to corresponding
 physical pages
 from huge pte in 3.11 kernel and from huge page directory on 3.6 kernel
 respectively.
 Though, there are couple of things still to be taken up (see TODOs).
 	1) Only base physical address is returned for a huge page as of now.
 	2) Appropraite offset in huge page directory to get the actual physical
 page for a given huge page.
 Signed-off-by: Hari Bathini <hbathini(a)linux.vnet.ibm.com>
 ---
  defs.h  |    6 +++-
  ppc64.c |   91
 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
  2 files changed, 92 insertions(+), 5 deletions(-)
 diff --git a/defs.h b/defs.h
 index 275697b..7196bc9 100755
 --- a/defs.h
 +++ b/defs.h
 @@ -3494,7 +3494,11 @@ struct efi_memory_desc_t {
  #define PTE_SHIFT_L4_BOOK3E_4K 24
  #define PMD_MASKED_BITS_64K  0x1ff
 -#define L4_OFFSET(vaddr)  ((vaddr >> (machdep->machspec->l4_shift)) &
 0x1ff)
 +#define PD_HUGE           0x8000000000000000
 +#define HUGE_PTE_MASK     0x03
 +#define HUGEPD_SHIFT_MASK 0x3f
 +#define L4_MASK           (THIS_KERNEL_VERSION >= LINUX(3,10,0) ? 0xfff :
 0x1ff)
 +#define L4_OFFSET(vaddr)  ((vaddr >> (machdep->machspec->l4_shift)) &
 L4_MASK)
  #define PGD_OFFSET_L4(vaddr)	\
  	((vaddr >> (machdep->machspec->l3_shift)) &
 (machdep->machspec->ptrs_per_l3 - 1))
 diff --git a/ppc64.c b/ppc64.c
 index 6f4f623..bf7def3 100755
 --- a/ppc64.c
 +++ b/ppc64.c
 @@ -55,7 +55,51 @@ static int ppc64_get_cpu_map(void);
  static void ppc64_clear_machdep_cache(void);
  static void ppc64_vmemmap_init(void);
  static int ppc64_get_kvaddr_ranges(struct vaddr_range *);
 +static uint get_ptetype(ulong pte);
 +static int is_hugepage(ulong pte);
 +static int is_hugepd(ulong pte);
 +static ulong hugepage_dir(ulong pte);
 +static inline uint get_ptetype(ulong pte)
 +{
 +	uint pte_type = 0; /* 0: regular entry; 1: huge pte; 2: huge pd */
 +
 +	if (is_hugepage(pte))
 +		pte_type = 1;
 +	else if (is_hugepd(pte))
 +		pte_type = 2;
 +
 +	return pte_type;
 +}
 +
 +static int is_hugepage(ulong pte)
 +{
 +	/*
 +	 * leaf pte for huge page, bottom two bits != 00
 +	 */
 +	return ((pte & HUGE_PTE_MASK) != 0x0);
 +}
 +
 +static inline int is_hugepd(ulong pte)
 +{
 +	if (THIS_KERNEL_VERSION >= LINUX(3,10,0)) {
 +		/*
 +		 * hugepd pointer, bottom two bits == 00 and next 4 bits
 +		 * indicate size of table
 +		*/
 +		return (((pte & HUGE_PTE_MASK) == 0x0) &&
 +			((pte & HUGEPD_SHIFT_MASK) != 0));
 +	} else
 +		return ((pte & PD_HUGE) == 0x0);
 +}
 +
 +static inline ulong hugepage_dir(ulong pte)
 +{
 +	if (THIS_KERNEL_VERSION >= LINUX(3,10,0))
 +		return (ulong)(pte & ~HUGEPD_SHIFT_MASK);
 +	else
 +		return (ulong)((pte & ~HUGEPD_SHIFT_MASK) | PD_HUGE);
 +}
  static int book3e_is_kvaddr(ulong addr)
  {
 @@ -637,6 +681,7 @@ ppc64_vtop_level4(ulong vaddr, ulong *level4,
 physaddr_t *paddr, int verbose)
  	ulong *page_table;
  	ulong level4_pte, pgd_pte, pmd_pte;
  	ulong pte;
 +	uint  hugepage_type = 0; /* 0: regular entry; 1: huge pte; 2: huge pd */
  	if (verbose)
  		fprintf(fp, "PAGE DIRECTORY: %lx\n", (ulong)level4);
 @@ -649,6 +694,12 @@ ppc64_vtop_level4(ulong vaddr, ulong *level4,
 physaddr_t *paddr, int verbose)
  	if (!level4_pte)
  		return FALSE;
 +	hugepage_type = get_ptetype(level4_pte);
 +	if (hugepage_type) {
 +		pte = level4_pte;
 +		goto out;
 +	}
 +
  	/* Sometimes we don't have level3 pagetable entries */
  	if (machdep->machspec->l3_index_size != 0) {
  		page_dir = (ulong *)((ulong *)level4_pte + PGD_OFFSET_L4(vaddr));
 @@ -659,6 +710,12 @@ ppc64_vtop_level4(ulong vaddr, ulong *level4,
 physaddr_t *paddr, int verbose)
  			fprintf(fp, "  PGD: %lx => %lx\n", (ulong)page_dir, pgd_pte);
  		if (!pgd_pte)
  			return FALSE;
 +
 +		hugepage_type = get_ptetype(pgd_pte);
 +		if (hugepage_type) {
 +			pte = pgd_pte;
 +			goto out;
 +		}
  	} else {
  		pgd_pte = level4_pte;
  	}
 @@ -673,6 +730,12 @@ ppc64_vtop_level4(ulong vaddr, ulong *level4,
 physaddr_t *paddr, int verbose)
  	if (!(pmd_pte))
  		return FALSE;
 +	hugepage_type = get_ptetype(pmd_pte);
 +	if (hugepage_type) {
 +		pte = pmd_pte;
 +		goto out;
 +	}
 +
  	page_table = (ulong *)(pmd_pte & ~(machdep->machspec->l2_masked_bits))
  			 + (BTOP(vaddr) & (machdep->machspec->ptrs_per_l1 - 1));
  	if (verbose)
 @@ -696,17 +759,37 @@ ppc64_vtop_level4(ulong vaddr, ulong *level4,
 physaddr_t *paddr, int verbose)
  	if (!pte)
  		return FALSE;
 -	*paddr = PAGEBASE(PTOB(pte >> machdep->machspec->pte_shift))
 -			+ PAGEOFFSET(vaddr);
 +out:
 +	if (hugepage_type) {
 +		if (hugepage_type == 2) {
 +			/* TODO: Calculate the offset within the huge page
 +			 * directory for this huge page to get corresponding
 +			 * physical address. In the current form, it may
 +			 * return the physical address of the first huge page
 +			 * in this directory for all the huge pages
 +			 * in this huge page directory.
 +			 */
 +			readmem(hugepage_dir(pte), KVADDR, &pte, sizeof(pte),
 +				"hugepd_entry", RETURN_ON_ERROR);
 +		}
 +		/* TODO: get page offset for huge pages based on page size */
 +		*paddr = PAGEBASE(PTOB(pte >> machdep->machspec->pte_shift));
 +	} else {
 +		*paddr = PAGEBASE(PTOB(pte >> machdep->machspec->pte_shift))
 +				+ PAGEOFFSET(vaddr);
 +	}
  	if (verbose) {
 -		fprintf(fp, " PAGE: %lx\n\n", PAGEBASE(*paddr));
 +		if (hugepage_type)
 +			fprintf(fp, " HUGE PAGE: %lx\n\n", PAGEBASE(*paddr));
 +		else
 +			fprintf(fp, " PAGE: %lx\n\n", PAGEBASE(*paddr));
  		ppc64_translate_pte(pte, 0, machdep->machspec->pte_shift);
  	}
  	return TRUE;
  }
 -
 +
  /*
   *  Translates a user virtual address to its physical address.
 cmd_vtop()
   *  sets the verbose flag so that the pte translation gets displayed; all
 ------------------------------
 --
 Crash-utility mailing list
 Crash-utility(a)redhat.com
 
https://www.redhat.com/mailman/listinfo/crash-utility
 End of Crash-utility Digest, Vol 95, Issue 3
 ********************************************