[Crash-utility] [PATCH] [PPC32] Fix vmalloc address translation for BookE

Toshikazu Nakayama nakayama.ts at ncos.nec.co.jp
Mon Jan 16 07:23:37 UTC 2012


(2012/01/16 14:15), Suzuki K. Poulose wrote:
> This patch fixes the vmalloc address translation for BookE.This
> patch is based on the PPC44x definitions and may not work fine for
> other systems.
> 
> crash>  mod
> mod: cannot access vmalloc'd module memory
> crash>
> 
> 
> After the patch :
> 
> crash>  mod
>   MODULE   NAME        SIZE  OBJECT FILE
> d1018fd8  mbcache     6023  (not loaded)  [CONFIG_KALLSYMS]
> d1077190  jbd        58360  (not loaded)  [CONFIG_KALLSYMS]
> d107ca98  llc         4525  (not loaded)  [CONFIG_KALLSYMS]
> d1130de4  ext3      203186  (not loaded)  [CONFIG_KALLSYMS]
> d114bbac  squashfs   26129  (not loaded)  [CONFIG_KALLSYMS]
> 
> 
> On ppc44x, the virtual-address is split as below :
> 
> Bits   |0      10|11      19|20         31|
> 	-----------------------------------
>         |   PGD   |    PMD   | PAGE_OFFSET  |
>          -----------------------------------
> 
> The PAGE_BASE_ADDR is a 64bit value(of type phys_addr_t).
> 
> Note : I am not sure how do we distinguish the different values (PGDIR_SHIFT etc)
> for different PPC32 systems. Since there are a lot of different platforms
> under PPC32, we need some mechanism to dynamically determine the PGDIR, PTE
> shift values. One option is to put the information in the VMCOREINFO.

Hi Suzuki,

How about using powerpc_base_platform symbol?

 *PTRRELOC(&powerpc_base_platform) = t->platform;

$ grep -rIw platform arch/powerpc/kernel/cputable.c
/* The platform string corresponding to the real PVR */
                .platform               = "power3",
                .platform               = "power3",
                .platform               = "rs64",
                .platform               = "rs64",
                .platform               = "rs64",
                .platform               = "rs64",
                .platform               = "power4",
                .platform               = "power4",
       :
       :

This kconfig based platform string data can be read
  base_platform = symbol_value("powerpc_base_platform symbols");
  read_string(base_platform, buf, buffer-size);
at ppc_init(POST_GDB).

I think platform can be distinguished with following naming rules.
 - CONFIG_40x=y: platform is "ppc403"
 - CONFIG_44x=y: platform is "ppc440"

Thanks,
Toshi
 
> Or we should hard code these values for each platform and
> compile a crash for a particular platform.
> 
> Thoughts ?
> 
> Signed-off-by: Suzuki K. Poulose<suzuki at in.ibm.com>
> ---
> 
>   defs.h |    4 ++--
>   ppc.c  |   20 ++++++++++++--------
>   2 files changed, 14 insertions(+), 10 deletions(-)
> 
> diff --git a/defs.h b/defs.h
> index 82d51e5..844f369 100755
> --- a/defs.h
> +++ b/defs.h
> @@ -2603,8 +2603,8 @@ struct load_module {
>   #define VTOP(X)            ((unsigned long)(X)-(machdep->kvbase))
>   #define IS_VMALLOC_ADDR(X) (vt->vmalloc_start&&  (ulong)(X)>= vt->vmalloc_start)
> 
> -#define PGDIR_SHIFT   (22)
> -#define PTRS_PER_PTE  (1024)
> +#define PGDIR_SHIFT   (21)
> +#define PTRS_PER_PTE  (512)
>   #define PTRS_PER_PGD  (1024)
> 
>   #define _PAGE_PRESENT   0x001   /* software: pte contains a translation */
> diff --git a/ppc.c b/ppc.c
> index 2a10fac..6a1db2a 100755
> --- a/ppc.c
> +++ b/ppc.c
> @@ -381,8 +381,8 @@ ppc_kvtop(struct task_context *tc, ulong kvaddr, physaddr_t *paddr, int verbose)
>   	ulong *page_dir;
>   	ulong *page_middle;
>   	ulong *page_table;
> -        ulong pgd_pte;
> -        ulong pte;
> +	ulong pgd_pte;
> +	unsigned long long pte;	/* PTE is 64 bit */
> 
>   	if (!IS_KVADDR(kvaddr))
>   		return FALSE;
> @@ -404,9 +404,13 @@ ppc_kvtop(struct task_context *tc, ulong kvaddr, physaddr_t *paddr, int verbose)
>   		fprintf(fp, "PAGE DIRECTORY: %lx\n", (ulong)pgd);
> 
>   	page_dir = pgd + (kvaddr>>  PGDIR_SHIFT);
> -
> -        FILL_PGD(PAGEBASE(pgd), KVADDR, PAGESIZE());
> -        pgd_pte = ULONG(machdep->pgd + PAGEOFFSET(page_dir));
> +	/*
> +	 * The (kvaddr>>  PGDIR_SHIFT) may exceed PAGESIZE().
> +	 * Use PAGEBASE(page_dir) to read the page containing the
> +	 * translation.
> +	 */
> +        FILL_PGD(PAGEBASE(page_dir), KVADDR, PAGESIZE());
> +        pgd_pte = ULONG((unsigned long)machdep->pgd + PAGEOFFSET(page_dir));
> 
>   	if (verbose)
>   		fprintf(fp, "  PGD: %lx =>  %lx\n", (ulong)page_dir, pgd_pte);
> @@ -417,7 +421,7 @@ ppc_kvtop(struct task_context *tc, ulong kvaddr, physaddr_t *paddr, int verbose)
>   	page_middle = (ulong *)pgd_pte;
> 
>   	if (machdep->flags&  CPU_BOOKE)
> -		page_table = page_middle + (BTOP(kvaddr)&  (PTRS_PER_PTE - 1));
> +		page_table = (unsigned long long *)page_middle + (BTOP(kvaddr)&  (PTRS_PER_PTE - 1));
>   	else {
>   		page_table = (ulong *)((pgd_pte&  (ulong)machdep->pagemask) + machdep->kvbase);
>   		page_table += ((ulong)BTOP(kvaddr)&  (PTRS_PER_PTE-1));
> @@ -428,10 +432,10 @@ ppc_kvtop(struct task_context *tc, ulong kvaddr, physaddr_t *paddr, int verbose)
>   			(ulong)page_table);
> 
>           FILL_PTBL(PAGEBASE(page_table), KVADDR, PAGESIZE());
> -        pte = ULONG(machdep->ptbl + PAGEOFFSET(page_table));
> +        pte = ULONGLONG((unsigned long)machdep->ptbl + PAGEOFFSET(page_table));
> 
>   	if (verbose)
> -		fprintf(fp, "  PTE: %lx =>  %lx\n", (ulong)page_table, pte);
> +		fprintf(fp, "  PTE: %lx =>  %llx\n", (ulong)page_table, pte);
> 
>   	if (!(pte&  _PAGE_PRESENT)) {
>   		if (pte&&  verbose) {
> 
> 




More information about the Crash-utility mailing list