[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] Foreign mappings need to verify if the underlying pages are sharable/shared. If



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1261031276 0
# Node ID 98bd49474dbf9a4a1d958d30bd947f1258b5246b
# Parent  46754a9f0be1bc2eddb16af5124ff5bb30b93e41
Foreign mappings need to verify if the underlying pages are sharable/shared. If
so, only RO mappings are allowed to go ahead. If an RW mapping to
sharable/shared page is requested, the GFN will be unshared (if there are free
pages for private copies) or an error returned otherwise. Note that all tools
(libxc + backends) which map foreign mappings need to check for error return
values.

Signed-off-by: Grzegorz Milos <Grzegorz.Milos@xxxxxxxxxx>
---
 xen/arch/x86/mm.c        |   33 +++++++++++++++++++++++++++++++++
 xen/common/grant_table.c |   27 +++++++++++++++++++--------
 2 files changed, 52 insertions(+), 8 deletions(-)

diff -r 46754a9f0be1 -r 98bd49474dbf xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Thu Dec 17 06:27:56 2009 +0000
+++ b/xen/arch/x86/mm.c Thu Dec 17 06:27:56 2009 +0000
@@ -3147,6 +3147,20 @@ int do_mmu_update(
                         rc = -ENOENT;
                         break;
                     }
+                    /* XXX: Ugly: pull all the checks into a separate 
function. 
+                     * Don't want to do it now, not to interfere with 
mem_paging
+                     * patches */
+                    else if ( p2m_ram_shared == l1e_p2mt )
+                    {
+                        /* Unshare the page for RW foreign mappings */
+                        if(l1e_get_flags(l1e) & _PAGE_RW)
+                        {
+                            rc = mem_sharing_unshare_page(pg_owner, 
+                                                          l1e_get_pfn(l1e), 
+                                                          0);
+                            if(rc) break; 
+                        }
+                    } 
 
                     okay = mod_l1_entry(va, l1e, mfn,
                                         cmd == MMU_PT_UPDATE_PRESERVE_AD, v,
@@ -3171,6 +3185,13 @@ int do_mmu_update(
                         rc = -ENOENT;
                         break;
                     }
+                    else if ( p2m_ram_shared == l2e_p2mt )
+                    {
+                        MEM_LOG("Unexpected attempt to map shared page.\n");
+                        rc = -EINVAL;
+                        break;
+                    }
+
 
                     okay = mod_l2_entry(va, l2e, mfn,
                                         cmd == MMU_PT_UPDATE_PRESERVE_AD, v);
@@ -3192,6 +3213,12 @@ int do_mmu_update(
                     else if ( p2m_ram_paging_in_start == l3e_p2mt )
                     {
                         rc = -ENOENT;
+                        break;
+                    }
+                    else if ( p2m_ram_shared == l3e_p2mt )
+                    {
+                        MEM_LOG("Unexpected attempt to map shared page.\n");
+                        rc = -EINVAL;
                         break;
                     }
 
@@ -3217,6 +3244,12 @@ int do_mmu_update(
                     else if ( p2m_ram_paging_in_start == l4e_p2mt )
                     {
                         rc = -ENOENT;
+                        break;
+                    }
+                    else if ( p2m_ram_shared == l4e_p2mt )
+                    {
+                        MEM_LOG("Unexpected attempt to map shared page.\n");
+                        rc = -EINVAL;
                         break;
                     }
 
diff -r 46754a9f0be1 -r 98bd49474dbf xen/common/grant_table.c
--- a/xen/common/grant_table.c  Thu Dec 17 06:27:56 2009 +0000
+++ b/xen/common/grant_table.c  Thu Dec 17 06:27:56 2009 +0000
@@ -105,6 +105,8 @@ static unsigned inline int max_nr_maptra
     return (max_nr_grant_frames * MAX_MAPTRACK_TO_GRANTS_RATIO);
 }
 
+#define gfn_to_mfn_private(_d, _gfn, _p2mt) \
+    mfn_x(gfn_to_mfn_unshare(_d, _gfn, _p2mt, 1)) 
 
 #define SHGNT_PER_PAGE_V1 (PAGE_SIZE / sizeof(grant_entry_v1_t))
 #define shared_entry_v1(t, e) \
@@ -493,12 +495,16 @@ __gnttab_map_grant_ref(
 
         if ( !act->pin )
         {
+            p2m_type_t p2mt;
+
             act->domid = ld->domain_id;
             if ( sha1 )
                 act->gfn = sha1->frame;
             else
                 act->gfn = sha2->full_page.frame;
-            act->frame = gmfn_to_mfn(rd, act->gfn);
+            act->frame = (op->flags & GNTMAP_readonly) ?  
+                            gmfn_to_mfn(rd, act->gfn) :
+                            gfn_to_mfn_private(rd, act->gfn, &p2mt); 
             act->start = 0;
             act->length = PAGE_SIZE;
             act->is_sub_page = 0;
@@ -549,7 +555,7 @@ __gnttab_map_grant_ref(
         if ( rc != GNTST_okay )
             goto undo_out;
     }
-    else if ( owner == rd )
+    else if ( owner == rd || owner == dom_cow )
     {
         if ( gnttab_host_mapping_get_page_type(op, ld, rd) &&
              !get_page_type(pg, PGT_writable_page) )
@@ -1365,6 +1371,7 @@ gnttab_transfer(
     struct gnttab_transfer gop;
     unsigned long mfn;
     unsigned int max_bitsize;
+    p2m_type_t p2mt;
 
     for ( i = 0; i < count; i++ )
     {
@@ -1379,7 +1386,7 @@ gnttab_transfer(
             return -EFAULT;
         }
 
-        mfn = gmfn_to_mfn(d, gop.mfn);
+        mfn = gfn_to_mfn_private(d, gop.mfn, &p2mt);
 
         /* Check the passed page frame for basic validity. */
         if ( unlikely(!mfn_valid(mfn)) )
@@ -1650,6 +1657,7 @@ __acquire_grant_for_copy(
     int is_sub_page;
     struct domain *ignore;
     s16 rc = GNTST_okay;
+    p2m_type_t p2mt;
 
     *owning_domain = NULL;
 
@@ -1762,7 +1770,8 @@ __acquire_grant_for_copy(
         else if ( sha1 )
         {
             act->gfn = sha1->frame;
-            grant_frame = gmfn_to_mfn(rd, act->gfn);
+            grant_frame = readonly ? gmfn_to_mfn(rd, act->gfn) :
+                                     gfn_to_mfn_private(rd, act->gfn, &p2mt);
             is_sub_page = 0;
             trans_page_off = 0;
             trans_length = PAGE_SIZE;
@@ -1771,7 +1780,8 @@ __acquire_grant_for_copy(
         else if ( !(sha2->hdr.flags & GTF_sub_page) )
         {
             act->gfn = sha2->full_page.frame;
-            grant_frame = gmfn_to_mfn(rd, act->gfn);
+            grant_frame = readonly ? gmfn_to_mfn(rd, act->gfn) :
+                                     gfn_to_mfn_private(rd, act->gfn, &p2mt);
             is_sub_page = 0;
             trans_page_off = 0;
             trans_length = PAGE_SIZE;
@@ -1780,7 +1790,8 @@ __acquire_grant_for_copy(
         else
         {
             act->gfn = sha2->sub_page.frame;
-            grant_frame = gmfn_to_mfn(rd, act->gfn);
+            grant_frame = readonly ? gmfn_to_mfn(rd, act->gfn) :
+                                     gfn_to_mfn_private(rd, act->gfn, &p2mt);
             is_sub_page = 1;
             trans_page_off = sha2->sub_page.page_off;
             trans_length = sha2->sub_page.length;
@@ -1917,7 +1928,7 @@ __gnttab_copy(
     else
     {
         p2m_type_t p2mt;
-        d_frame = mfn_x(gfn_to_mfn(dd, op->dest.u.gmfn, &p2mt));
+        d_frame = gfn_to_mfn_private(dd, op->dest.u.gmfn, &p2mt);
         if ( p2m_is_paging(p2mt) )
         {
             p2m_mem_paging_populate(dd, op->dest.u.gmfn);
@@ -2351,7 +2362,7 @@ grant_table_create(
             goto no_mem_4;
         clear_page(t->shared_raw[i]);
     }
-
+    
     for ( i = 0; i < INITIAL_NR_GRANT_FRAMES; i++ )
         gnttab_create_shared_page(d, t, i);
 

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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.