Xen 
 
Home About Xen.org Xen Xen Summit Wiki Mailing List Bug Tracker Xen Downloads
 
   
 

xen-devel

[Xen-devel] xc_get_pfn_list() creates broken core files

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] xc_get_pfn_list() creates broken core files
From: John Levon <levon@xxxxxxxxxxxxxxxxx>
Date: Thu, 23 Nov 2006 02:45:21 +0000
Delivery-date: Wed, 22 Nov 2006 18:45:29 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mutt/1.5.9i
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