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

[Xen-changelog] Fix MMU_NORMAL_PT_UPDATE when passed a page that is no longer of type page-table.



# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxxxx
# Node ID 09d9d6e7b9851cfb2206395ced55b4769e164b4a
# Parent  25483d9b55d4307d125f4135b609a6387f247ba8
Fix MMU_NORMAL_PT_UPDATE when passed a page that is no longer of type 
page-table.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 xen/arch/x86/mm.c |  101 ++++++++++++++++++++++++------------------------------
 1 files changed, 45 insertions(+), 56 deletions(-)

diff -r 25483d9b55d4 -r 09d9d6e7b985 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Wed May 31 16:07:47 2006 -0600
+++ b/xen/arch/x86/mm.c Thu Jun 01 10:34:21 2006 +0100
@@ -2213,99 +2213,88 @@ int do_mmu_update(
 
             switch ( (type_info = page->u.inuse.type_info) & PGT_type_mask )
             {
-            case PGT_l1_page_table: 
-                ASSERT( !shadow_mode_refcounts(d) );
-                if ( likely(get_page_type(
+            case PGT_l1_page_table:
+            case PGT_l2_page_table:
+            case PGT_l3_page_table:
+            case PGT_l4_page_table:
+            {
+                ASSERT(!shadow_mode_refcounts(d));
+                if ( unlikely(!get_page_type(
                     page, type_info & (PGT_type_mask|PGT_va_mask))) )
+                    goto not_a_pt;
+
+                switch ( type_info & PGT_type_mask )
                 {
-                    l1_pgentry_t l1e;
-
-                    /* FIXME: doesn't work with PAE */
-                    l1e = l1e_from_intpte(req.val);
+                case PGT_l1_page_table:
+                {
+                    l1_pgentry_t l1e = l1e_from_intpte(req.val);
                     okay = mod_l1_entry(va, l1e);
                     if ( okay && unlikely(shadow_mode_enabled(d)) )
                         shadow_l1_normal_pt_update(
                             d, req.ptr, l1e, &sh_mapcache);
-                    put_page_type(page);
                 }
                 break;
-            case PGT_l2_page_table:
-                ASSERT( !shadow_mode_refcounts(d) );
-                if ( likely(get_page_type(
-                    page, type_info & (PGT_type_mask|PGT_va_mask))) )
+                case PGT_l2_page_table:
                 {
-                    l2_pgentry_t l2e;
-
-                    /* FIXME: doesn't work with PAE */
-                    l2e = l2e_from_intpte(req.val);
+                    l2_pgentry_t l2e = l2e_from_intpte(req.val);
                     okay = mod_l2_entry(
                         (l2_pgentry_t *)va, l2e, mfn, type_info);
                     if ( okay && unlikely(shadow_mode_enabled(d)) )
                         shadow_l2_normal_pt_update(
                             d, req.ptr, l2e, &sh_mapcache);
-                    put_page_type(page);
                 }
                 break;
 #if CONFIG_PAGING_LEVELS >= 3
-            case PGT_l3_page_table:
-                ASSERT( !shadow_mode_refcounts(d) );
-                if ( likely(get_page_type(
-                    page, type_info & (PGT_type_mask|PGT_va_mask))) )
+                case PGT_l3_page_table:
                 {
-                    l3_pgentry_t l3e;
-
-                    /* FIXME: doesn't work with PAE */
-                    l3e = l3e_from_intpte(req.val);
+                    l3_pgentry_t l3e = l3e_from_intpte(req.val);
                     okay = mod_l3_entry(va, l3e, mfn, type_info);
                     if ( okay && unlikely(shadow_mode_enabled(d)) )
                         shadow_l3_normal_pt_update(
                             d, req.ptr, l3e, &sh_mapcache);
-                    put_page_type(page);
                 }
                 break;
 #endif
 #if CONFIG_PAGING_LEVELS >= 4
-            case PGT_l4_page_table:
-                ASSERT( !shadow_mode_refcounts(d) );
-                if ( likely(get_page_type(
-                    page, type_info & (PGT_type_mask|PGT_va_mask))) )
+                case PGT_l4_page_table:
                 {
-                    l4_pgentry_t l4e;
-
-                    l4e = l4e_from_intpte(req.val);
+                    l4_pgentry_t l4e = l4e_from_intpte(req.val);
                     okay = mod_l4_entry(va, l4e, mfn, type_info);
                     if ( okay && unlikely(shadow_mode_enabled(d)) )
                         shadow_l4_normal_pt_update(
                             d, req.ptr, l4e, &sh_mapcache);
-                    put_page_type(page);
                 }
                 break;
 #endif
+                }
+
+                put_page_type(page);
+            }
+            break;
+
             default:
-                if ( likely(get_page_type(page, PGT_writable_page)) )
+            not_a_pt:
+            {
+                if ( unlikely(!get_page_type(page, PGT_writable_page)) )
+                    break;
+
+                if ( shadow_mode_enabled(d) )
                 {
-                    if ( shadow_mode_enabled(d) )
-                    {
-                        shadow_lock(d);
-
-                        __mark_dirty(d, mfn);
-
-                        if ( page_is_page_table(page) &&
-                             !page_out_of_sync(page) )
-                        {
-                            shadow_mark_mfn_out_of_sync(v, gmfn, mfn);
-                        }
-                    }
-
-                    *(intpte_t *)va = req.val;
-                    okay = 1;
-
-                    if ( shadow_mode_enabled(d) )
-                        shadow_unlock(d);
-
-                    put_page_type(page);
+                    shadow_lock(d);
+                    __mark_dirty(d, mfn);
+                    if ( page_is_page_table(page) && !page_out_of_sync(page) )
+                        shadow_mark_mfn_out_of_sync(v, gmfn, mfn);
                 }
-                break;
+
+                *(intpte_t *)va = req.val;
+                okay = 1;
+
+                if ( shadow_mode_enabled(d) )
+                    shadow_unlock(d);
+
+                put_page_type(page);
+            }
+            break;
             }
 
             unmap_domain_page_with_cache(va, &mapcache);

_______________________________________________
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®.