[Crash-utility] Fwd: s390x fixes
Dave Anderson
anderson at redhat.com
Wed May 2 13:08:26 UTC 2012
----- Original Message -----
> Hi Dave,
>
> On Tue, 01 May 2012 15:24:17 -0400 (EDT)
> Dave Anderson <anderson at redhat.com> wrote:
>
> > With respect to the 3rd "vm -p" bug, I did some cursory debugging,
> > and
> > here's what I found.
> >
> > In all cases, the readmem() failure occurs in
> > _kl_pg_table_deref_s390x() as a result of transitioning from one
> > page
> > of PTEs to the next, because the pointer to the "next" page of PTES
> > contains 0x20, which looks to be _SEGMENT_ENTRY_INV or
> > _REGION_ENTRY_INV? (not sure of the s390x nomenclature...)
> >
> > So you'll see something like this in the page table that points
> > to the pages of PTEs:
> >
> > ...
> > c6386e0: 0000000000000020
> > 0000000000000020 ....... ....... c6386f0: 000000001608c800
> > 0000000000000020 ............... c638700: 0000000000000020
> > 0000000000000020 ....... ....... ...
> >
> > The vaddr's in the page of PTEs pointed to by c6386f0 (at
> > 000000001608c800) all resolve as expected, but when the virtual
> > address bumps it to c6386f8, it reads the 0x20, and passes it to
> > _kl_pg_table_deref_s390x(). The user vaddr(s) that resolve to that
> > next page of PTEs are legitimate, given that they are in the virtual
> > region defined by the vm_area_struct. But they certainly may not be
> > mapped.
> >
> > Anyway, it seems that there should be something that catches the
> > invalid entry in s390x_vtop() -- prior to calling
> > _kl_pg_table_deref_s390x()-- and return FALSE at that point.
> >
> > So if I make this kludge:
> >
> > ...
> >
> > /* Check if this is a large page. */
> > if (entry & 0x400ULL) {
> > /* Add the 1MB page offset and return the final
> > value. */ *phys_addr = table + (vaddr & 0xfffffULL);
> > return TRUE;
> > }
> >
> > ======> if (entry == 0x20) return FALSE;
> >
> > /* Get the page table entry */
> > entry = _kl_pg_table_deref_s390x(vaddr, entry & ~0x7ffULL);
> > if (!entry)
> > return FALSE;
> >
> > /* Isolate the page origin from the page table entry. */
> > paddr = entry & ~0xfffULL;
> >
> > /* Add the page offset and return the final value. */
> > *phys_addr = paddr + (vaddr & 0xfffULL);
> >
> > return TRUE;
> > }
> >
> > then everything seems to work OK.
> >
> > So unless the calculation of the next page of PTEs is incorrect,
> > which seems unlikely, it seems that the 0x20 is legitimate, and
> > should be recognized? What do you think?
>
> 0x20 means that the invalid bit of a region table entry is set (bit 58).
> The problem is a wrong check in _kl_rsg_table_deref_s390x() where we
> check for 0x40 (instead of 0x20).
>
> The following is the correct fix for the problem:
> ---
> s390x.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> --- a/s390x.c
> +++ b/s390x.c
> @@ -568,7 +568,7 @@ static ulong _kl_rsg_table_deref_s390x(u
> if ((entry & 0xcULL) != (level << 2))
> return 0;
> /* Check if the region table entry has the invalid bit set. */
> - if (entry & 0x40ULL)
> + if (entry & 0x20ULL)
> return 0;
> /* Region table entry is valid and well formed. */
> return entry;
Much better -- queued for crash-6.0.7.
Thanks,
Dave
More information about the Crash-utility
mailing list