[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] xc_get_pfn_list() creates broken core files
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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |