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