<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<tt>Dave Anderson wrote:</tt>
<blockquote TYPE=CITE><tt>Itsuro ODA wrote:</tt><tt></tt>
<p><tt>> Hi Dave,</tt>
<br><tt>></tt>
<br><tt>> > - Introduced support for xendumps of para-virtualized ia64
kernels.</tt>
<br><tt>> > It should be noted that currently the ia64 Xen
kernel does not</tt>
<br><tt>> > lay down a switch_stack for the panic task, so
only raw "bt -t"</tt>
<br><tt>> > backtraces can be done on the panic task.
(anderson@redhat.com)</tt>
<br><tt>></tt>
<br><tt>> page_index may contain INVALID_MFN (0xffffffffffffffffUL).</tt>
<br><tt>> I think it is better to check it.</tt>
<br><tt>> Here is a patch for this.</tt>
<br><tt>></tt>
<br><tt>> ---</tt>
<br><tt>> --- crash-4.0-3.15-org/xendump.h
2006-12-21 09:57:29.000000000 +0900</tt>
<br><tt>> +++ crash-4.0-3.15/xendump.h 2006-12-21 14:37:35.000000000
+0900</tt>
<br><tt>> @@ -113,3 +113,8 @@</tt>
<br><tt>> uint32_t hypercall_imm; /* Break
imm for Xen hypercalls. */</tt>
<br><tt>> /* #endif */</tt>
<br><tt>> } xen_domctl_arch_setup_t;</tt>
<br><tt>> +</tt>
<br><tt>> +#ifdef IA64</tt>
<br><tt>> +#define INVALID_MFN (0xffffffffffffffffUL)</tt>
<br><tt>> +#endif</tt>
<br><tt>> +</tt>
<br><tt>> --- crash-4.0-3.15-org/xendump.c
2006-12-21 09:57:29.000000000 +0900</tt>
<br><tt>> +++ crash-4.0-3.15/xendump.c 2006-12-21 14:42:48.000000000
+0900</tt>
<br><tt>> @@ -31,6 +31,7 @@</tt>
<br><tt>></tt>
<br><tt>> static void xc_core_p2m_create(void);</tt>
<br><tt>> static ulong xc_core_pfn_to_page_index(ulong);</tt>
<br><tt>> +static int check_mfn_is_valid(ulong);</tt>
<br><tt>></tt>
<br><tt>> /*</tt>
<br><tt>> * Determine whether a file is a xendump creation,
and if TRUE,</tt>
<br><tt>> @@ -1362,7 +1363,7 @@</tt>
<br><tt>> off_t offset;</tt>
<br><tt>></tt>
<br><tt>> if (xd->flags
& XC_CORE_NO_P2MM)</tt>
<br><tt>> -
return pfn;</tt>
<br><tt>> +
return check_mfn_is_valid(pfn) ? pfn : PFN_NOT_FOUND;</tt>
<br><tt>></tt>
<br><tt>> idx = pfn/PFNS_PER_PAGE;</tt>
<br><tt>></tt>
<br><tt>> @@ -1405,6 +1406,34 @@</tt>
<br><tt>> return mfn_idx;</tt>
<br><tt>> }</tt>
<br><tt>></tt>
<br><tt>> +static int</tt>
<br><tt>> +check_mfn_is_valid(ulong idx)</tt>
<br><tt>> +{</tt>
<br><tt>> + ulong mfn;</tt>
<br><tt>> +</tt>
<br><tt>> + if (idx >= xd->xc_core.header.xch_nr_pages)</tt>
<br><tt>> +
return FALSE;</tt>
<br><tt>> +</tt>
<br><tt>> + if (lseek(xd->xfd,</tt>
<br><tt>> +
(off_t)xd->xc_core.header.xch_index_offset + idx * sizeof(ulong),</tt>
<br><tt>> +
SEEK_SET) == -1) {</tt>
<br><tt>> +
error(INFO, "cannot lseek to page index\n");</tt>
<br><tt>> +
return FALSE;</tt>
<br><tt>> + }</tt>
<br><tt>> +</tt>
<br><tt>> + if (read(xd->xfd, &mfn,
sizeof(ulong)) != sizeof(ulong)) {</tt>
<br><tt>> +
error(INFO, "cannot read index page %d\n", idx);</tt>
<br><tt>> +
return FALSE;</tt>
<br><tt>> + }</tt>
<br><tt>> +</tt>
<br><tt>> + if (mfn == INVALID_MFN)
{</tt>
<br><tt>> +
error(INFO, "idx: %lx indicates INVALID_MFN\n", idx);</tt>
<br><tt>> +
return FALSE;</tt>
<br><tt>> + } else {</tt>
<br><tt>> +
return TRUE;</tt>
<br><tt>> + }</tt>
<br><tt>> +}</tt>
<br><tt>> +</tt>
<br><tt>> /*</tt>
<br><tt>> * Store the panic task's stack hooks from where
it was found</tt>
<br><tt>> * in get_active_set_panic_task().</tt>
<br><tt>> ---</tt>
<br><tt>></tt>
<br><tt>> Thanks.</tt>
<br><tt>> --</tt>
<br><tt>> Itsuro ODA <oda@valinux.co.jp></tt><tt></tt>
<p><tt>Oda-san,</tt><tt></tt>
<p><tt>Good catch. I was never reading "bad addresses", so I didn't</tt>
<br><tt>see any issue there. Now, after going back and checking it
out,</tt>
<br><tt>I see that if you attempt to read an uninstantiated pfn, it returns</tt>
<br><tt>the page index, and so it seeks to and reads whatever's in the</tt>
<br><tt>xendump from that location. Given the way the FV xendump
is</tt>
<br><tt>laid out, there has to be *something* there in the dumpfile, which</tt>
<br><tt>I would have thought would have been sparse file space and</tt>
<br><tt>read as all zeroes? But in some dumps, it looks like there's
"junk"</tt>
<br><tt>data there? Whatever -- it's harmless.</tt><tt></tt>
<p><tt>In any case, I agree with you -- it's much better to return a read</tt>
<br><tt>error as xc_core_read() expects. I'll just adjust your patch
slightly</tt>
<br><tt>to handle all architectures.</tt><tt></tt>
<p><tt>Thanks,</tt>
<br><tt> Dave</tt></blockquote>
<tt></tt>
<p><br><tt>Oda-san,</tt><tt></tt>
<p><tt>Thanks again for the "overnight-QA" and for introducing support</tt>
<br><tt>for xendumps of fully-virtualized ia64 kernels! I've posted
a new</tt>
<br><tt>crash version with both fixes.</tt><tt></tt>
<p><tt>I modified your check_mfn_is_valid() function so that
it could</tt>
<br><tt>be used by all 3 architectures as well as for xendumps of</tt>
<br><tt>32-bit kernels running on a 64-bit host:</tt>
<br><tt></tt> <tt></tt>
<p><tt>/*</tt>
<br><tt> * In xendumps containing INVALID_MFN markers in the
page index,</tt>
<br><tt> * return the validity of the pfn.</tt>
<br><tt> */</tt>
<br><tt>static int</tt>
<br><tt>xc_core_pfn_valid(ulong pfn)</tt>
<br><tt>{</tt>
<br><tt> ulong mfn;</tt>
<br><tt> off_t offset;</tt><tt></tt>
<p><tt> if (pfn >= (ulong)xd->xc_core.header.xch_nr_pages)</tt>
<br><tt>
return FALSE;</tt><tt></tt>
<p><tt> offset = (off_t)xd->xc_core.header.xch_index_offset;</tt><tt></tt>
<p><tt> if (xd->flags & XC_CORE_64BIT_HOST)</tt>
<br><tt>
offset += (off_t)(pfn * sizeof(ulonglong));</tt>
<br><tt> else</tt>
<br><tt>
offset += (off_t)(pfn * sizeof(ulong));</tt><tt></tt>
<p><tt> /*</tt>
<br><tt> * The lseek
and read should never fail, so report</tt>
<br><tt> * any errors
unconditionally.</tt>
<br><tt> */</tt>
<br><tt> if (lseek(xd->xfd, offset,
SEEK_SET) == -1) {</tt>
<br><tt>
error(INFO,</tt>
<br><tt>
"xendump: cannot lseek to page index for pfn %lx\n",</tt>
<br><tt>
pfn);</tt>
<br><tt>
return FALSE;</tt>
<br><tt> }</tt><tt></tt>
<p><tt> if (read(xd->xfd, &mfn,
sizeof(ulong)) != sizeof(ulong)) {</tt>
<br><tt>
error(INFO,</tt>
<br><tt>
"xendump: cannot read index page for pfn %lx\n",</tt>
<br><tt>
pfn);</tt>
<br><tt>
return FALSE;</tt>
<br><tt> }</tt><tt></tt>
<p><tt> /*</tt>
<br><tt> * If it's
an invalid mfn, let the caller decide whether</tt>
<br><tt> * to display
an error message (unless debugging).</tt>
<br><tt> */</tt>
<br><tt> if (mfn == INVALID_MFN)
{</tt>
<br><tt>
if (CRASHDEBUG(1))</tt>
<br><tt>
error(INFO,</tt>
<br><tt>
"xendump: pfn %lx contains INVALID_MFN\n",</tt>
<br><tt>
pfn);</tt>
<br><tt>
return FALSE;</tt>
<br><tt> }</tt><tt></tt>
<p><tt> return TRUE;</tt>
<br><tt>}</tt><tt></tt>
<p><tt>Thanks again,</tt>
<br><tt> Dave</tt>
<br><tt></tt> </html>