This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
Home Products Support Community News


[Xen-devel] [PATCH 15/21] xenpaging: update machine_to_phys_mapping duri

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH 15/21] xenpaging: update machine_to_phys_mapping during page-in and page deallocation
From: Olaf Hering <olaf@xxxxxxxxx>
Date: Fri, 26 Nov 2010 14:49:16 +0100
Delivery-date: Fri, 26 Nov 2010 06:19:16 -0800
Dkim-signature: v=1; a=rsa-sha1; c=relaxed/relaxed; t=1290779362; l=2987; s=domk; d=aepfle.de; h=References:Subject:To:From:Date:X-RZG-CLASS-ID:X-RZG-AUTH; bh=aXJOK71gtRskKL/84ubhqb9Rrhw=; b=o1XTJI2gBBStVChvSNa6DS2TuYcs2ojT9+0DKQ0uk7yrZwUvKQuieOOYTphMfangF4u +eifopmQhKDUXZedjTa4f/PdGG0fY1CMVb2O60BbKyfCaANrXPG/TkW6KOrh7wO24CInG lYqe0KleCz2iDGZEx3SRobRAmHPERRZaCAc=
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
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/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <20101126134901.384130351@xxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: quilt/0.48-4.4
The machine_to_phys_mapping array needs updating during page-in, and
during page deallocation.  If a page is gone, a call to
get_gpfn_from_mfn will still return the old gfn for an already paged-out
page.  This happens when the entire guest ram is paged-out before
xen_vga_populate_vram() runs.  Then XENMEM_populate_physmap is called
with gfn 0xff000.  A new page is allocated with alloc_domheap_pages.
This new page does not have a gfn yet.  However, in
guest_physmap_add_entry() the passed mfn maps still to an old gfn
(perhaps from another old guest).  This old gfn is in paged-out state in
this guests context and has no mfn anymore.  As a result, the ASSERT()
triggers because p2m_is_ram() is true for p2m_ram_paging* types.

If the machine_to_phys_mapping array is updated properly, both loops in
guest_physmap_add_entry() turn into no-ops for the new page and the
mfn/gfn mapping will be done at the end of the function.

The same thing needs to happen dring a page-in, the current gfn must be
written for the page.

If XENMEM_add_to_physmap is used with XENMAPSPACE_gmfn,
get_gpfn_from_mfn() will return an appearently valid gfn.  As a result,
guest_physmap_remove_page() is called.  The ASSERT in p2m_remove_page
triggers because the passed mfn does not match the old mfn for the
passed gfn.

Signed-off-by: Olaf Hering <olaf@xxxxxxxxx>

  invalidate machine_to_phys_mapping[] during page deallocation
  call set_gpfn_from_mfn only if mfn is valid
 xen/arch/x86/mm/p2m.c   |   15 +++++++++++----
 xen/common/page_alloc.c |    9 +++++++++
 2 files changed, 20 insertions(+), 4 deletions(-)

--- xen-unstable.hg-4.1.22433.orig/xen/arch/x86/mm/p2m.c
+++ xen-unstable.hg-4.1.22433/xen/arch/x86/mm/p2m.c
@@ -2825,10 +2825,17 @@ void p2m_mem_paging_resume(struct p2m_do
     /* Fix p2m entry */
     mfn = gfn_to_mfn(p2m, rsp.gfn, &p2mt);
-    p2m_lock(p2m);
-    set_p2m_entry(p2m, rsp.gfn, mfn, 0, p2m_ram_rw);
-    audit_p2m(p2m, 1);
-    p2m_unlock(p2m);
+    if ( mfn_valid(mfn) )
+    {
+        p2m_lock(p2m);
+        set_p2m_entry(p2m, rsp.gfn, mfn, 0, p2m_ram_rw);
+        set_gpfn_from_mfn(mfn_x(mfn), rsp.gfn);
+        audit_p2m(p2m, 1);
+        p2m_unlock(p2m);
+    } else {
+        gdprintk(XENLOG_ERR, "invalid mfn %lx for gfn %lx p2mt %x flags %lx\n",
+            mfn_x(mfn), rsp.gfn, p2mt, (unsigned long)rsp.flags);
+    }
     /* Unpause domain */
     if ( rsp.flags & MEM_EVENT_FLAG_VCPU_PAUSED )
--- xen-unstable.hg-4.1.22433.orig/xen/common/page_alloc.c
+++ xen-unstable.hg-4.1.22433/xen/common/page_alloc.c
@@ -1199,9 +1199,18 @@ void free_domheap_pages(struct page_info
     int            i, drop_dom_ref;
     struct domain *d = page_get_owner(pg);
+    unsigned long mfn;
+    /* this page is not a gfn anymore */
+    mfn = page_to_mfn(pg);
+    if ( mfn_valid(mfn) )
+    {
+        for ( i = 0; i < (1 << order); i++ )
+            set_gpfn_from_mfn(mfn + i, INVALID_M2P_ENTRY);
+    }
     if ( unlikely(is_xen_heap_page(pg)) )
         /* NB. May recursively lock from relinquish_memory(). */

Xen-devel mailing list