I noticed that the p2m list in domain core files was incorrect. The problem lies
in XEN_DOMCTL_getmemlist, here:
227 list_ent = d->page_list.next;
228 for ( i = 0; (i < max_pfns) && (list_ent != &d->page_list); i++
)
229 {
230 mfn = page_to_mfn(list_entry(
231 list_ent, struct page_info, list));
...
238 list_ent = mfn_to_page(mfn)->list.next;
239 }
This does not account correctly for 'holes' where the pfn no longer maps an
mfn, and thus doesn't appear on page_list. As a result the whole array gets out
of sync. What's the right fix here? Below is what I threw together to verify
the problem.
thanks,
john
diff --git a/tools/libxc/xc_core.c b/tools/libxc/xc_core.c
--- a/tools/libxc/xc_core.c
+++ b/tools/libxc/xc_core.c
@@ -103,7 +103,12 @@ xc_domain_dumpcore_via_callback(int xc_h
for ( dump_mem = dump_mem_start, i = 0; i < nr_pages; i++ )
{
- copy_from_domain_page(xc_handle, domid, page_array[i], dump_mem);
+ fprintf(stderr, "page_array %d is %lx\n", i, page_array[i]);
+ if (page_array[i] == -1) {
+ memset(dump_mem, 0, PAGE_SIZE);
+ } else {
+ copy_from_domain_page(xc_handle, domid, page_array[i],
dump_mem);
+ }
dump_mem += PAGE_SIZE;
if ( ((i + 1) % DUMP_INCREMENT == 0) || ((i + 1) == nr_pages) )
{
diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
--- a/xen/arch/x86/domctl.c
+++ b/xen/arch/x86/domctl.c
@@ -215,6 +215,7 @@ long arch_do_domctl(
struct domain *d = find_domain_by_id(domctl->domain);
unsigned long max_pfns = domctl->u.getmemlist.max_pfns;
unsigned long mfn, gmfn;
+ unsigned long gpfn;
struct list_head *list_ent;
ret = -EINVAL;
@@ -255,6 +256,26 @@ long arch_do_domctl(
{
mfn = page_to_mfn(list_entry(
list_ent, struct page_info, list));
+ gpfn = get_gpfn_from_mfn(mfn);
+#ifdef __x86_64__
+ if (gpfn != 0x5555555555555555L)
+#else
+ if (gpfn != 0x55555555L)
+#endif
+ {
+ /* Account for unmapped gpfn's. */
+ while (i < gpfn)
+ {
+ unsigned long tmp = -1;
+ if (
copy_to_guest_offset(domctl->u.getmemlist.buffer,
+ i, &tmp, 1) )
+ {
+ ret = -EFAULT;
+ break;
+ }
+ i++;
+ }
+ }
if ( copy_to_guest_offset(domctl->u.getmemlist.buffer,
i, &mfn, 1) )
{
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|