[Crash-utility] [PATCH v3 0/3] vmalloc translation support for PPC

Suzuki K. Poulose suzuki at in.ibm.com
Thu Feb 16 11:33:56 UTC 2012


On 02/15/2012 08:49 PM, Dave Anderson wrote:
>
>
> ----- Original Message -----
>> On 02/15/2012 10:56 AM, Suzuki K. Poulose wrote:
>>> On 02/13/2012 10:17 PM, Dave Anderson wrote:
>>>>
>>>> ----- Original Message -----
>>>>> The following series implements :
>>>>>
>>>>> * An infrastructure for platform based vmalloc translation for
>>>>> PPC32
>>>>> * vmalloc translation support for PPC44x
>>>>>
>>>>> Changes since V2:
>>>>>
>>>>> * Rebased to crash-6.0.3
>>>>> * Maintains a list of probe functions, rather than platform
>>>>> definitions.
>>>>>
>>>>>
>>>>> Each platform can define their own probe_function which would get
>>>>> the name of the
>>>>> ppc platform (read from kernel) and the probe can check if the
>>>>> platform is one of its
>>>>> variant. The probe function can then update the 'platform'
>>>>> defintions for the virtual
>>>>> address translation.
>>>>>
>>>>> If none of the defined platforms match, falls back to using the
>>>>> default PPC32
>>>>> definitions.
>>>>>
>>>>> ---
>>>>>
>>>>> Suzuki K. Poulose (3):
>>>>> [ppc] virtual address translation bits for PPC44x
>>>>> [ppc] Support for platform based Virtual address translation
>>>>> [ppc] Non-linear address translation routine
>>>>
>>>> Hi Suzuki,
>>>>
>>>> I'll defer the technical ACK to Toshi, but I do have a couple of
>>>> other suggestions.
>>>>
>>>> Here's a sample vmalloc translation:
>>>>
>>>> crash>  vtop d1180000
>>>> VIRTUAL PHYSICAL
>>>> d1180000 ff800000
>>>>
>>>> Using ppc440gp board definitions:
>>>> PAGE DIRECTORY: c056f000
>>>> PGD: c0570a20 =>  c784b000
>>>> PMD: c784b000 =>  c784bc00
>>>> PTE: c784bc00 =>  1ff80051b
>>>> PAGE: ff800000
>>>>
>>>> PTE PHYSICAL FLAGS
>>>> ff80051b ff800000 (PRESENT|USER|GUARDED|COHERENT|ACCESSED)
>>>>
>>>> PAGE PHYSICAL MAPPING INDEX CNT FLAGS
>>>> crash>
>>>>
>>>> This may have been a pre-existing issue, but for vmalloc
>>>> addresses, the
>>>> page struct translation at the end of the display (under PAGE
>>>> PHYSICAL MAPPING...)
>>>> is missing for vmalloc addresses. For user-space and unity-mapped
>>>> addresses the translation is done as intended:
>>>>
>>>> User-space:
>>>>
>>>> crash>  vtop ff8f000
>>>> VIRTUAL PHYSICAL
>>>> ff8f000 6b90000
>>>>
>>>> Using ppc440gp board definitions:
>>>> PAGE DIRECTORY: c7a3a000
>>>> PGD: c7a3a1fc =>  c7bfc000
>>>> PMD: c7bfc000 =>  c7bfcc78
>>>> PTE: c7bfcc78 =>  6b9005b
>>>> PAGE: 6b90000
>>>>
>>>> PTE PHYSICAL FLAGS
>>>> 6b9005b 6b90000 (PRESENT|USER|GUARDED|COHERENT|WRITETHRU)
>>>>
>>>> VMA START END FLAGS FILE
>>>> c7b09898 ff8f000 ff92000 100073
>>>>
>>>> PAGE PHYSICAL MAPPING INDEX CNT FLAGS
>>>> c06b5200 6b90000 c7a9fc61 ff8f 1 80068
>>>> crash>
>>>>
>>>> Kernel unity-mapped:
>>>>
>>>> crash>  vtop c7b14000
>>>> VIRTUAL PHYSICAL
>>>> c7b14000 7b14000
>>>>
>>>> Using ppc440gp board definitions:
>>>> PAGE DIRECTORY: c056f000
>>>> PGD: c05708f4 =>  0
>>>>
>>>> PAGE PHYSICAL MAPPING INDEX CNT FLAGS
>>>> c06d4280 7b14000 0 0 1 0
>>>> crash>
>>>>
>>>> That should be a trivial fix.
>>>
>>> I took a look at the above issue of vtop report and here is what
>>> I find :
>>>
>>> crash>  p *vmlist
>>> $17 = {
>>> next = 0xc784e880,
>>> addr = 0xd1002000,
>>> size = 8192,
>>> flags = 1,
>>> pages = 0x0,
>>> nr_pages = 0,
>>> phys_addr = 8837398528,
>>> caller = 0xc042bf40
>>> }
>>> crash>  vtop 0xd1002000
>>> VIRTUAL PHYSICAL
>>> d1002000 ec00000
>>>
>>> PAGE DIRECTORY: c0578000
>>> PGD: c0579a20 =>  c784b000
>>> PMD: c784b000 =>  c784b010
>>> PTE: c784b010 =>  20ec0051b
>>> PAGE: ec00000
>>>
>>> PTE PHYSICAL FLAGS
>>> ec0051b ec00000 (PRESENT|USER|GUARDED|COHERENT|ACCESSED)
>>>
>>> PAGE PHYSICAL MAPPING INDEX CNT FLAGS
>>>
>>> crash>  x /i vmlist->caller
>>> 0xc042bf40<setup_indirect_pci+84>: blr
>>>
>>> Here, the total amount for RAM on the machine is 128M and looks like
>>> the above address is memory mapped PCI bus, which lies above the 128M.
>>> Also note that the number of pages is '0'. Since the page lies above the
>>> 128M and the number of pages is 0, the dump_mem_map fails to find the page struct
>>> for the corresponding phsyical address.
>>>
>>> If we go further in the vmlist to find the vmalloc address pages that have pages,
>>> we get :
>>>
>>> crash>  p *(vmlist->next->next->next)
>>> $16 = {
>>> next = 0xc78e51c0,
>>> addr = 0xd1008000,
>>> size = 8192,
>>> flags = 2,
>>> pages = 0xc7891680,
>>> nr_pages = 1,
>>> phys_addr = 0,
>>> caller = 0xc006a1d0
>>> }
>>> crash>  vtop 0xd1008000
>>> VIRTUAL PHYSICAL
>>> d1008000 7896000
>>>
>>> PAGE DIRECTORY: c0578000
>>> PGD: c0579a20 =>  c784b000
>>> PMD: c784b000 =>  c784b040
>>> PTE: c784b040 =>  789601f
>>> PAGE: 7896000
>>>
>>> PTE PHYSICAL FLAGS
>>> 789601f 7896000 (PRESENT|USER|RW|GUARDED|COHERENT)
>>>
>>> PAGE PHYSICAL MAPPING INDEX CNT FLAGS
>>> c06d72c0 7896000 0 0 1 0
>>>
>>> So, may be we could add a check in the vmalloc translation to see if there is really
>>> a page allocated for the block and then do the translation of the pages.
>>
>> I have a patch which could do something like:
>>
>> crash>  vtop d1002000
>> VIRTUAL   PHYSICAL
>> d1002000  20ec00000
>>
>> PAGE DIRECTORY: c0578000
>>     PGD: c0579a20 =>  c784b000
>>     PMD: c784b000 =>  c784b010
>>     PTE: c784b010 =>  20ec0051b
>>    PAGE: 20ec00000
>>
>>      PTE     PHYSICAL   FLAGS
>> 20ec0051b  20ec00000  (PRESENT|USER|GUARDED|COHERENT|ACCESSED)
>>
>> The memory 0x20ec00000 doesn't have a PFN associated with it.
>> It could be an MMIO region above the RAM(128 MB).
>> crash>
>
> Ah yes, I'm sorry Suzuike -- I forgot that can be seen on any
> architecture.
>
> Taking x86_64 as an example, it's seen by just looking at the
> first two entries on the vmlist:
>
>    crash>  kmem -v
>       VM_STRUCT                 ADDRESS RANGE               SIZE
>    ffff88003f824f00  ffffc90000000000 - ffffc90000002000    8192
>    ffff88003f824a00  ffffc90000003000 - ffffc90000104000  1052672
>    ... [ cut ] ...
>
> The second vm_struct in the vmlist at ffff88003f824a00 shows
> that there are 256 pages associated with it:
>
>    crash>  vm_struct ffff88003f824a00
>    struct vm_struct {
>      next = 0xffff88003f824980,
>      addr = 0xffffc90000003000,
>      size = 1052672,
>      flags = 2,
>      pages = 0xffff88003fae7000,
>      nr_pages = 256,
>      phys_addr = 0,
>      caller = 0xffffffff818e426c
>    }
>    crash>
>
> and so for any vmalloc address within it, the page translation is
> displayed by vtop:
>
>    crash>  vtop ffffc90000003000
>    VIRTUAL           PHYSICAL
>    ffffc90000003000  3faed000
>
>    PML4 DIRECTORY: ffffffff81001000
>    PAGE DIRECTORY: 3faa5067
>       PUD: 3faa5000 =>  3faa6067
>       PMD: 3faa6000 =>  3faa7067
>       PTE: 3faa7018 =>  800000003faed163
>      PAGE: 3faed000
>
>          PTE         PHYSICAL  FLAGS
>    800000003faed163  3faed000  (PRESENT|RW|ACCESSED|DIRTY|GLOBAL|NX)
>
>          PAGE       PHYSICAL      MAPPING       INDEX CNT FLAGS
>    ffffea0000dee3d8 3faed000                0        0  1 20000000000000
>    crash>
>
> But the first entry in the vmlist at ffff88003f824f00 does not have
> any pages:
>
>    crash>  kmem -v
>       VM_STRUCT                 ADDRESS RANGE               SIZE
>    ffff88003f824f00  ffffc90000000000 - ffffc90000002000    8192
>    ffff88003f824a00  ffffc90000003000 - ffffc90000104000  1052672
>    ... [ cut ] ...
>
>    crash>  vm_struct ffff88003f824f00
>    struct vm_struct {
>      next = 0xffff88003f824a00,
>      addr = 0xffffc90000000000,
>      size = 8192,
>      flags = 1,
>      pages = 0x0,
>      nr_pages = 0,
>      phys_addr = 4275044352,
>      caller = 0xffffffff818d5a66
>    }
>
> and so no page translation is shown:
>
>    crash>  vtop ffffc90000000000
>    VIRTUAL           PHYSICAL
>    ffffc90000000000  fed00000
>
>    PML4 DIRECTORY: ffffffff81001000
>    PAGE DIRECTORY: 3faa5067
>       PUD: 3faa5000 =>  3faa6067
>       PMD: 3faa6000 =>  3faa7067
>       PTE: 3faa7000 =>  80000000fed00173
>      PAGE: fed00000
>
>          PTE         PHYSICAL  FLAGS
>    80000000fed00173  fed00000  (PRESENT|RW|PCD|ACCESSED|DIRTY|GLOBAL|NX)
>
>    crash>
>
> So just do the same thing -- no verbose expanation is required.

There are two ways to fix this :

1) Fix dump_mem_map*() to print the header only when there is information to dump.

--- a/memory.c
+++ b/memory.c
@@ -4637,13 +4637,6 @@ dump_mem_map_SPARSEMEM(struct meminfo *mi)
                         continue;
                 }
  
-               if (print_hdr) {
-                       if (!(pc->curcmd_flags & HEADER_PRINTED))
-                               fprintf(fp, "%s", hdr);
-                       print_hdr = FALSE;
-                       pc->curcmd_flags |= HEADER_PRINTED;
-               }
-
                 pp = section_mem_map_addr(section);
                 pp = sparse_decode_mem_map(pp, section_nr);
                 phys = (physaddr_t) section_nr * PAGES_PER_SECTION() * PAGESIZE();
@@ -4854,6 +4847,13 @@ dump_mem_map_SPARSEMEM(struct meminfo *mi)
                         }
  
                         if (bufferindex > buffersize) {
+                               if (print_hdr) {
+                                       if (!(pc->curcmd_flags & HEADER_PRINTED))
+                                               fprintf(fp, "%s", hdr);
+                                       print_hdr = FALSE;
+                                       pc->curcmd_flags |= HEADER_PRINTED;
+                               }
+
                                 fprintf(fp, "%s", outputbuffer);
                                 bufferindex = 0;
                         }
@@ -4867,6 +4867,13 @@ dump_mem_map_SPARSEMEM(struct meminfo *mi)
         }
  
         if (bufferindex > 0) {
+               if (print_hdr) {
+                       if (!(pc->curcmd_flags & HEADER_PRINTED))
+                               fprintf(fp, "%s", hdr);
+                       print_hdr = FALSE;
+                       pc->curcmd_flags |= HEADER_PRINTED;
+               }
+
                 fprintf(fp, "%s", outputbuffer);
         }

Similarly for the dump_mem_map().

2) Fix ppc_pgd_vtop() to return FALSE if the paddr > machdep->memsize

--- a/ppc.c
+++ b/ppc.c
@@ -438,6 +438,10 @@ ppc_pgd_vtop(ulong *pgd, ulong vaddr, physaddr_t *paddr, int verbose)
  
         *paddr = PAGEBASE(pte) + PAGEOFFSET(vaddr);
  
+       if (*paddr > machdep->memsize)
+       /* We don't have pages above System RAM */
+               return FALSE;
+
         return TRUE;
  
  no_page:

I prefer the (1). What do you think ?

Thanks
Suzuki




More information about the Crash-utility mailing list