WARNING - OLD ARCHIVES

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/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-3.4-testing] x86: Fix mfn/page handling in do_mmuex

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-3.4-testing] x86: Fix mfn/page handling in do_mmuext_op().
From: "Xen patchbot-3.4-testing" <patchbot-3.4-testing@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 30 Dec 2009 05:40:35 -0800
Delivery-date: Wed, 30 Dec 2009 05:41:08 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1262179235 0
# Node ID 20158bbae22c36a339d04d2fd70a1074044d31d4
# Parent  fff896fccb4ee418986933643d8025cdeb454a4b
x86: Fix mfn/page handling in do_mmuext_op().

Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
xen-unstable changeset:   20723:98c4b2498415
xen-unstable date:        Thu Dec 24 15:59:44 2009 +0000

x86: In mmuext_op(), MMUEXT_[UN]PIN_* must respect 'foreigndom'...

... and *only* those subcommands respect 'foreigndom', according to
documentation in public header xen.h.

Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
xen-unstable changeset:   20744:bb34d8e578d2
xen-unstable date:        Wed Dec 30 13:10:03 2009 +0000
---
 xen/arch/x86/mm.c |  100 ++++++++++++++++++++++++++++++------------------------
 1 files changed, 57 insertions(+), 43 deletions(-)

diff -r fff896fccb4e -r 20158bbae22c xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Wed Dec 30 12:53:26 2009 +0000
+++ b/xen/arch/x86/mm.c Wed Dec 30 13:20:35 2009 +0000
@@ -2615,9 +2615,8 @@ int do_mmuext_op(
 {
     struct mmuext_op op;
     int rc = 0, i = 0, okay;
-    unsigned long mfn = 0, gmfn = 0, type;
+    unsigned long type;
     unsigned int done = 0;
-    struct page_info *page;
     struct vcpu *curr = current;
     struct domain *d = curr->domain;
 
@@ -2658,9 +2657,6 @@ int do_mmuext_op(
         }
 
         okay = 1;
-        gmfn  = op.arg1.mfn;
-        mfn = gmfn_to_mfn(FOREIGNDOM, gmfn);
-        page = mfn_to_page(mfn);
 
         switch ( op.cmd )
         {
@@ -2681,10 +2677,9 @@ int do_mmuext_op(
                 break;
             type = PGT_l4_page_table;
 
-        pin_page:
-            rc = xsm_memory_pin_page(d, page);
-            if ( rc )
-                break;
+        pin_page: {
+            unsigned long mfn;
+            struct page_info *page;
 
             /* Ignore pinning of invalid paging levels. */
             if ( (op.cmd - MMUEXT_PIN_L1_TABLE) > (CONFIG_PAGING_LEVELS - 1) )
@@ -2693,6 +2688,7 @@ int do_mmuext_op(
             if ( paging_mode_refcounts(FOREIGNDOM) )
                 break;
 
+            mfn = gmfn_to_mfn(FOREIGNDOM, op.arg1.mfn);
             rc = get_page_and_type_from_pagenr(mfn, type, FOREIGNDOM, 0, 1);
             okay = !rc;
             if ( unlikely(!okay) )
@@ -2704,6 +2700,15 @@ int do_mmuext_op(
                 break;
             }
 
+            page = mfn_to_page(mfn);
+
+            if ( (rc = xsm_memory_pin_page(d, page)) != 0 )
+            {
+                put_page_and_type(page);
+                okay = 0;
+                break;
+            }
+
             if ( unlikely(test_and_set_bit(_PGT_pinned,
                                            &page->u.inuse.type_info)) )
             {
@@ -2714,7 +2719,7 @@ int do_mmuext_op(
             }
 
             /* A page is dirtied when its pin status is set. */
-            paging_mark_dirty(d, mfn);
+            paging_mark_dirty(FOREIGNDOM, mfn);
            
             /* We can race domain destruction (domain_relinquish_resources). */
             if ( unlikely(this_cpu(percpu_mm_info).foreign != NULL) )
@@ -2730,44 +2735,51 @@ int do_mmuext_op(
             }
 
             break;
-
-        case MMUEXT_UNPIN_TABLE:
-            if ( paging_mode_refcounts(d) )
+        }
+
+        case MMUEXT_UNPIN_TABLE: {
+            unsigned long mfn;
+            struct page_info *page;
+
+            if ( paging_mode_refcounts(FOREIGNDOM) )
                 break;
 
-            if ( unlikely(!(okay = get_page_from_pagenr(mfn, d))) )
+            mfn = gmfn_to_mfn(FOREIGNDOM, op.arg1.mfn);
+            if ( unlikely(!(okay = get_page_from_pagenr(mfn, FOREIGNDOM))) )
             {
-                MEM_LOG("Mfn %lx bad domain (dom=%p)",
-                        mfn, page_get_owner(page));
+                MEM_LOG("Mfn %lx bad domain", mfn);
+                break;
             }
-            else if ( likely(test_and_clear_bit(_PGT_pinned, 
-                                                &page->u.inuse.type_info)) )
-            {
-                put_page_and_type(page);
-                put_page(page);
-                if ( !rc )
-                {
-                    /* A page is dirtied when its pin status is cleared. */
-                    paging_mark_dirty(d, mfn);
-                }
-            }
-            else
+
+            page = mfn_to_page(mfn);
+
+            if ( !test_and_clear_bit(_PGT_pinned, &page->u.inuse.type_info) )
             {
                 okay = 0;
                 put_page(page);
                 MEM_LOG("Mfn %lx not pinned", mfn);
+                break;
             }
+
+            put_page_and_type(page);
+            put_page(page);
+
+            /* A page is dirtied when its pin status is cleared. */
+            paging_mark_dirty(FOREIGNDOM, mfn);
+
             break;
+        }
 
         case MMUEXT_NEW_BASEPTR:
-            okay = new_guest_cr3(mfn);
+            okay = new_guest_cr3(gmfn_to_mfn(d, op.arg1.mfn));
             this_cpu(percpu_mm_info).deferred_ops &= ~DOP_FLUSH_TLB;
             break;
         
 #ifdef __x86_64__
         case MMUEXT_NEW_USER_BASEPTR: {
-            unsigned long old_mfn;
-
+            unsigned long old_mfn, mfn;
+
+            mfn = gmfn_to_mfn(d, op.arg1.mfn);
             if ( mfn != 0 )
             {
                 if ( paging_mode_refcounts(d) )
@@ -2877,12 +2889,13 @@ int do_mmuext_op(
             break;
         }
 
-        case MMUEXT_CLEAR_PAGE:
-        {
+        case MMUEXT_CLEAR_PAGE: {
+            unsigned long mfn;
             unsigned char *ptr;
 
-            okay = !get_page_and_type_from_pagenr(mfn, PGT_writable_page,
-                                                  FOREIGNDOM, 0, 0);
+            mfn = gmfn_to_mfn(d, op.arg1.mfn);
+            okay = !get_page_and_type_from_pagenr(
+                mfn, PGT_writable_page, d, 0, 0);
             if ( unlikely(!okay) )
             {
                 MEM_LOG("Error while clearing mfn %lx", mfn);
@@ -2896,7 +2909,7 @@ int do_mmuext_op(
             clear_page(ptr);
             fixunmap_domain_page(ptr);
 
-            put_page_and_type(page);
+            put_page_and_type(mfn_to_page(mfn));
             break;
         }
 
@@ -2904,18 +2917,19 @@ int do_mmuext_op(
         {
             const unsigned char *src;
             unsigned char *dst;
-            unsigned long src_mfn;
-
-            src_mfn = gmfn_to_mfn(FOREIGNDOM, op.arg2.src_mfn);
-            okay = get_page_from_pagenr(src_mfn, FOREIGNDOM);
+            unsigned long src_mfn, mfn;
+
+            src_mfn = gmfn_to_mfn(d, op.arg2.src_mfn);
+            okay = get_page_from_pagenr(src_mfn, d);
             if ( unlikely(!okay) )
             {
                 MEM_LOG("Error while copying from mfn %lx", src_mfn);
                 break;
             }
 
-            okay = !get_page_and_type_from_pagenr(mfn, PGT_writable_page,
-                                                  FOREIGNDOM, 0, 0);
+            mfn = gmfn_to_mfn(d, op.arg1.mfn);
+            okay = !get_page_and_type_from_pagenr(
+                mfn, PGT_writable_page, d, 0, 0);
             if ( unlikely(!okay) )
             {
                 put_page(mfn_to_page(src_mfn));
@@ -2932,7 +2946,7 @@ int do_mmuext_op(
             fixunmap_domain_page(dst);
             unmap_domain_page(src);
 
-            put_page_and_type(page);
+            put_page_and_type(mfn_to_page(mfn));
             put_page(mfn_to_page(src_mfn));
             break;
         }

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-3.4-testing] x86: Fix mfn/page handling in do_mmuext_op()., Xen patchbot-3.4-testing <=