(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<[email protected]>
> ---
> 
>   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) {
> 
> 

--
Crash-utility mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/crash-utility

Reply via email to