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

[Xen-changelog] [xen-unstable] [HVM][VMX][PAE] Enable PAE VMX guest on PAE host.



# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 1507021dccdfb2fb0af8c129298348050be4654b
# Parent  0991ed8e4ae577d72b841d85d1cf414a224af172
[HVM][VMX][PAE] Enable PAE VMX guest on PAE host.
The PAE VMX guest supports NX bit and can do kernel build successfully.

Signed-off-by: Jun Nakajima <jun.nakajima@xxxxxxxxx>
Signed-off-by: Xiaohui Xin <xiaohui.xin@xxxxxxxxx>
---
 xen/arch/x86/Makefile            |    2 
 xen/arch/x86/audit.c             |    4 -
 xen/arch/x86/hvm/vmx/vmx.c       |   13 ----
 xen/arch/x86/shadow.c            |  125 +++++++++++++++++++++++++--------------
 xen/arch/x86/shadow32.c          |   12 +--
 xen/arch/x86/shadow_guest32pae.c |    2 
 xen/arch/x86/shadow_public.c     |   40 ++++++++----
 xen/include/asm-x86/mm.h         |    2 
 xen/include/asm-x86/shadow.h     |   44 +++++++++++--
 xen/include/asm-x86/shadow_64.h  |   36 +++--------
 xen/include/asm-x86/shadow_ops.h |    8 ++
 11 files changed, 178 insertions(+), 110 deletions(-)

diff -r 0991ed8e4ae5 -r 1507021dccdf xen/arch/x86/Makefile
--- a/xen/arch/x86/Makefile     Mon Jun 19 16:39:27 2006 +0100
+++ b/xen/arch/x86/Makefile     Mon Jun 19 16:47:21 2006 +0100
@@ -41,7 +41,7 @@ obj-y += x86_emulate.o
 obj-y += x86_emulate.o
 
 ifneq ($(pae),n)
-obj-$(x86_32) += shadow.o shadow_public.o shadow_guest32.o
+obj-$(x86_32) += shadow.o shadow_public.o shadow_guest32.o shadow_guest32pae.o
 else
 obj-$(x86_32) += shadow32.o
 endif
diff -r 0991ed8e4ae5 -r 1507021dccdf xen/arch/x86/audit.c
--- a/xen/arch/x86/audit.c      Mon Jun 19 16:39:27 2006 +0100
+++ b/xen/arch/x86/audit.c      Mon Jun 19 16:47:21 2006 +0100
@@ -923,8 +923,8 @@ void _audit_domain(struct domain *d, int
                                d->domain_id, page_to_mfn(page),
                                page->u.inuse.type_info,
                                page->count_info);
-                        printk("a->gpfn_and_flags=%p\n",
-                               (void *)a->gpfn_and_flags);
+                        printk("a->gpfn_and_flags=%"PRIx64"\n",
+                               (u64)a->gpfn_and_flags);
                         errors++;
                     }
                     break;
diff -r 0991ed8e4ae5 -r 1507021dccdf xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Mon Jun 19 16:39:27 2006 +0100
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Mon Jun 19 16:47:21 2006 +0100
@@ -1623,7 +1623,7 @@ static int mov_to_cr(int gp, int cr, str
             if ( vmx_pgbit_test(v) )
             {
                 /* The guest is a 32-bit PAE guest. */
-#if CONFIG_PAGING_LEVELS >= 4
+#if CONFIG_PAGING_LEVELS >= 3
                 unsigned long mfn, old_base_mfn;
 
                 if( !shadow_set_guest_paging_levels(v->domain, PAGING_L3) )
@@ -1667,7 +1667,7 @@ static int mov_to_cr(int gp, int cr, str
             else
             {
                 /*  The guest is a 64 bit or 32-bit PAE guest. */
-#if CONFIG_PAGING_LEVELS >= 4
+#if CONFIG_PAGING_LEVELS >= 3
                 if ( (v->domain->arch.ops != NULL) &&
                         v->domain->arch.ops->guest_paging_levels == PAGING_L2)
                 {
@@ -1680,15 +1680,6 @@ static int mov_to_cr(int gp, int cr, str
                     {
                         printk("Unsupported guest paging levels\n");
                         /* need to take a clean path */
-                        domain_crash_synchronous();
-                    }
-                }
-                else
-                {
-                    if ( !shadow_set_guest_paging_levels(v->domain,
-                                                            PAGING_L4) )
-                    {
-                        printk("Unsupported guest paging levels\n");
                         domain_crash_synchronous();
                     }
                 }
diff -r 0991ed8e4ae5 -r 1507021dccdf xen/arch/x86/shadow.c
--- a/xen/arch/x86/shadow.c     Mon Jun 19 16:39:27 2006 +0100
+++ b/xen/arch/x86/shadow.c     Mon Jun 19 16:47:21 2006 +0100
@@ -222,6 +222,7 @@ alloc_shadow_page(struct domain *d,
     unsigned long smfn, real_gpfn;
     int pin = 0;
     void *l1, *lp;
+    u64 index = 0;
 
     // Currently, we only keep pre-zero'ed pages around for use as L1's...
     // This will change.  Soon.
@@ -354,9 +355,19 @@ alloc_shadow_page(struct domain *d,
         if ( d->arch.ops->guest_paging_levels == PAGING_L2 )
             pin = 1;
 #endif
+
+#if CONFIG_PAGING_LEVELS == 3 & defined ( GUEST_32PAE )
+        /*
+         * We use PGT_l4_shadow for 2-level paging guests on PAE
+         */
+        if ( d->arch.ops->guest_paging_levels == PAGING_L3 )
+            pin = 1;
+#endif
+        if ( d->arch.ops->guest_paging_levels == PAGING_L3 )
+            index = get_cr3_idxval(current);
         break;
 
-#if CONFIG_PAGING_LEVELS >= 4
+#if CONFIG_PAGING_LEVELS >= 3
     case PGT_fl1_shadow:
         perfc_incr(shadow_l1_pages);
         d->arch.shadow_page_count++;
@@ -393,7 +404,7 @@ alloc_shadow_page(struct domain *d,
     //
     ASSERT( (psh_type == PGT_snapshot) || !mfn_out_of_sync(gmfn) );
 
-    set_shadow_status(d, gpfn, gmfn, smfn, psh_type);
+    set_shadow_status(d, gpfn, gmfn, smfn, psh_type, index);
 
     if ( pin )
         shadow_pin(smfn);
@@ -1324,7 +1335,7 @@ increase_writable_pte_prediction(struct 
     prediction = (prediction & PGT_mfn_mask) | score;
 
     //printk("increase gpfn=%lx pred=%lx create=%d\n", gpfn, prediction, 
create);
-    set_shadow_status(d, GPFN_TO_GPTEPAGE(gpfn), 0, prediction, 
PGT_writable_pred);
+    set_shadow_status(d, GPFN_TO_GPTEPAGE(gpfn), 0, prediction, 
PGT_writable_pred, 0);
 
     if ( create )
         perfc_incr(writable_pte_predictions);
@@ -1345,10 +1356,10 @@ decrease_writable_pte_prediction(struct 
     //printk("decrease gpfn=%lx pred=%lx score=%lx\n", gpfn, prediction, 
score);
 
     if ( score )
-        set_shadow_status(d, GPFN_TO_GPTEPAGE(gpfn), 0, prediction, 
PGT_writable_pred);
+        set_shadow_status(d, GPFN_TO_GPTEPAGE(gpfn), 0, prediction, 
PGT_writable_pred, 0);
     else
     {
-        delete_shadow_status(d, GPFN_TO_GPTEPAGE(gpfn), 0, PGT_writable_pred);
+        delete_shadow_status(d, GPFN_TO_GPTEPAGE(gpfn), 0, PGT_writable_pred, 
0);
         perfc_decr(writable_pte_predictions);
     }
 }
@@ -1385,7 +1396,7 @@ static u32 remove_all_write_access_in_pt
     int is_l1_shadow =
         ((mfn_to_page(pt_mfn)->u.inuse.type_info & PGT_type_mask) ==
          PGT_l1_shadow);
-#if CONFIG_PAGING_LEVELS == 4
+#if CONFIG_PAGING_LEVELS >= 3
     is_l1_shadow |=
       ((mfn_to_page(pt_mfn)->u.inuse.type_info & PGT_type_mask) ==
                 PGT_fl1_shadow);
@@ -1494,7 +1505,7 @@ static int remove_all_write_access(
         while ( a && a->gpfn_and_flags )
         {
             if ( (a->gpfn_and_flags & PGT_type_mask) == PGT_l1_shadow
-#if CONFIG_PAGING_LEVELS >= 4
+#if CONFIG_PAGING_LEVELS >= 3
               || (a->gpfn_and_flags & PGT_type_mask) == PGT_fl1_shadow
 #endif
               )
@@ -1538,8 +1549,8 @@ static void resync_pae_guest_l3(struct d
             continue;
 
         idx = get_cr3_idxval(v);
-        smfn = __shadow_status(
-            d, ((unsigned long)(idx << PGT_pae_idx_shift) | entry->gpfn), 
PGT_l4_shadow);
+
+        smfn = __shadow_status(d, entry->gpfn, PGT_l4_shadow);
 
         if ( !smfn ) 
             continue;
@@ -1706,7 +1717,7 @@ static int resync_all(struct domain *d, 
                 {
                     int error;
 
-#if CONFIG_PAGING_LEVELS == 4
+#if CONFIG_PAGING_LEVELS >= 3
                     unsigned long gpfn;
 
                     gpfn = guest_l1e_get_paddr(guest1[i]) >> PAGE_SHIFT;
@@ -2420,17 +2431,6 @@ static void shadow_update_pagetables(str
         v->arch.guest_vtable = map_domain_page_global(gmfn);
     }
 
-#if CONFIG_PAGING_LEVELS >= 3
-    /*
-     * Handle 32-bit PAE enabled guest
-     */
-    if ( SH_GUEST_32PAE && d->arch.ops->guest_paging_levels == PAGING_L3 ) 
-    {
-        u32 index = get_cr3_idxval(v);
-        gpfn = ((unsigned long)index << PGT_pae_idx_shift) | gpfn;
-    }
-#endif
-
     /*
      *  arch.shadow_table
      */
@@ -2443,6 +2443,23 @@ static void shadow_update_pagetables(str
         if ( unlikely(!(smfn = __shadow_status(d, gpfn, PGT_l4_shadow))) )
             smfn = shadow_l3_table(v, gpfn, gmfn);
     } 
+    else
+#endif
+
+#if CONFIG_PAGING_LEVELS == 3 & defined ( GUEST_32PAE )
+    /*
+     * We use PGT_l4_shadow for 2-level paging guests on PAE
+     */
+    if ( d->arch.ops->guest_paging_levels == PAGING_L3 )
+    {
+        if ( unlikely(!(smfn = __shadow_status(d, gpfn, PGT_l4_shadow))) )
+            smfn = shadow_l3_table(v, gpfn, gmfn);
+        else
+        {
+            update_top_level_shadow(v, smfn);
+            need_sync = 1;
+        }
+    }
     else
 #endif
     if ( unlikely(!(smfn = __shadow_status(d, gpfn, PGT_base_page_table))) ) 
@@ -3093,6 +3110,36 @@ static inline unsigned long init_bl2(
 
     return smfn;
 }
+
+static inline unsigned long init_l3(
+    struct vcpu *v, unsigned long gpfn, unsigned long gmfn)
+{
+    unsigned long smfn;
+    l4_pgentry_t *spl4e;
+    unsigned long index;
+
+    if ( unlikely(!(smfn = alloc_shadow_page(v->domain, gpfn, gmfn, 
PGT_l4_shadow))) )
+    {
+        printk("Couldn't alloc an L4 shadow for pfn= %lx mfn= %lx\n", gpfn, 
gmfn);
+        BUG(); /* XXX Deal gracefully wiht failure. */
+    }
+
+    /* Map the self entry, L4&L3 share the same page */
+    spl4e = (l4_pgentry_t *)map_domain_page(smfn);
+
+    /*
+     * Shadow L4's pfn_info->tlbflush_timestamp
+     * should also save it's own index.
+     */
+
+    index = get_cr3_idxval(v);
+    frame_table[smfn].tlbflush_timestamp = index;
+
+    memset(spl4e, 0, L4_PAGETABLE_ENTRIES*sizeof(l4_pgentry_t));
+    spl4e[PAE_SHADOW_SELF_ENTRY] = l4e_from_pfn(smfn, __PAGE_HYPERVISOR);
+    unmap_domain_page(spl4e);
+    return smfn;
+}
 #endif
 
 #if CONFIG_PAGING_LEVELS == 3
@@ -3111,6 +3158,12 @@ static unsigned long shadow_l3_table(
          d->arch.ops->guest_paging_levels == PAGING_L2 )
     {
         return init_bl2(d, gpfn, gmfn);
+    }
+
+    if ( SH_GUEST_32PAE &&
+         d->arch.ops->guest_paging_levels == PAGING_L3 )
+    {
+        return init_l3(v, gpfn, gmfn);
     }
 
     if ( unlikely(!(smfn = alloc_shadow_page(d, gpfn, gmfn, PGT_l3_shadow))) )
@@ -3223,6 +3276,11 @@ static unsigned long shadow_l4_table(
         return init_bl2(d, gpfn, gmfn);
     }
 
+    if ( SH_GUEST_32PAE && d->arch.ops->guest_paging_levels == PAGING_L3 )
+    {
+        return init_l3(v, gpfn, gmfn);
+    }
+
     if ( unlikely(!(smfn = alloc_shadow_page(d, gpfn, gmfn, PGT_l4_shadow))) )
     {
         printk("Couldn't alloc an L4 shadow for pfn=%lx mfn=%lx\n", gpfn, 
gmfn);
@@ -3230,24 +3288,6 @@ static unsigned long shadow_l4_table(
     }
 
     spl4e = (l4_pgentry_t *)map_domain_page(smfn);
-
-    /* For 32-bit PAE guest on 64-bit host */
-    if ( SH_GUEST_32PAE && d->arch.ops->guest_paging_levels == PAGING_L3 ) 
-    {
-        unsigned long index;
-        /*
-         * Shadow L4's pfn_info->tlbflush_timestamp
-         * should also save it's own index.
-         */
-        index = get_cr3_idxval(v);
-        frame_table[smfn].tlbflush_timestamp = index;
-
-        memset(spl4e, 0, L4_PAGETABLE_ENTRIES*sizeof(l4_pgentry_t));
-        /* Map the self entry */
-        spl4e[PAE_SHADOW_SELF_ENTRY] = l4e_from_pfn(smfn, __PAGE_HYPERVISOR);
-        unmap_domain_page(spl4e);
-        return smfn;
-    }
 
     /* Install hypervisor and 4x linear p.t. mapings. */
     if ( (PGT_base_page_table == PGT_l4_page_table) &&
@@ -3378,7 +3418,7 @@ validate_bl2e_change(
  * This shadow_mark_va_out_of_sync() is for 2M page shadow
  */
 static void shadow_mark_va_out_of_sync_2mp(
-  struct vcpu *v, unsigned long gpfn, unsigned long mfn, unsigned long 
writable_pl1e)
+  struct vcpu *v, unsigned long gpfn, unsigned long mfn, paddr_t writable_pl1e)
 {
     struct out_of_sync_entry *entry =
       shadow_mark_mfn_out_of_sync(v, gpfn, mfn);
@@ -3647,6 +3687,7 @@ static inline int l2e_rw_fault(
     }
 
     unmap_domain_page(l1_p);
+    *gl2e_p = gl2e;
     return 1;
 
 }
@@ -3720,7 +3761,7 @@ static inline int guest_page_fault(
 
     ASSERT( d->arch.ops->guest_paging_levels >= PAGING_L3 );
 
-#if CONFIG_PAGING_LEVELS >= 4
+#if CONFIG_PAGING_LEVELS >= 3
     if ( (error_code & (ERROR_I | ERROR_P)) == (ERROR_I | ERROR_P) )
         return 1;
 #endif
@@ -4056,7 +4097,7 @@ struct shadow_ops MODE_32_2_HANDLER = {
 };
 #endif
 
-#if ( CONFIG_PAGING_LEVELS == 3 && !defined (GUEST_PGENTRY_32) ) ||  \
+#if ( CONFIG_PAGING_LEVELS == 3 && !defined (GUEST_PGENTRY_32) && !defined 
(GUEST_32PAE) ) ||  \
     ( CONFIG_PAGING_LEVELS == 4 && defined (GUEST_PGENTRY_32) ) 
 
 
diff -r 0991ed8e4ae5 -r 1507021dccdf xen/arch/x86/shadow32.c
--- a/xen/arch/x86/shadow32.c   Mon Jun 19 16:39:27 2006 +0100
+++ b/xen/arch/x86/shadow32.c   Mon Jun 19 16:47:21 2006 +0100
@@ -306,7 +306,7 @@ alloc_shadow_page(struct domain *d,
     //
     ASSERT( (psh_type == PGT_snapshot) || !mfn_out_of_sync(gmfn) );
 
-    set_shadow_status(d, gpfn, gmfn, smfn, psh_type);
+    set_shadow_status(d, gpfn, gmfn, smfn, psh_type, 0);
 
     if ( pin )
         shadow_pin(smfn);
@@ -395,7 +395,7 @@ void free_shadow_page(unsigned long smfn
 
     ASSERT( ! IS_INVALID_M2P_ENTRY(gpfn) );
 
-    delete_shadow_status(d, gpfn, gmfn, type);
+    delete_shadow_status(d, gpfn, gmfn, type, 0);
 
     switch ( type )
     {
@@ -2319,7 +2319,7 @@ increase_writable_pte_prediction(struct 
     prediction = (prediction & PGT_mfn_mask) | score;
 
     //printk("increase gpfn=%lx pred=%lx create=%d\n", gpfn, prediction, 
create);
-    set_shadow_status(d, GPFN_TO_GPTEPAGE(gpfn), 0, prediction, 
PGT_writable_pred);
+    set_shadow_status(d, GPFN_TO_GPTEPAGE(gpfn), 0, prediction, 
PGT_writable_pred, 0);
 
     if ( create )
         perfc_incr(writable_pte_predictions);
@@ -2340,10 +2340,10 @@ decrease_writable_pte_prediction(struct 
     //printk("decrease gpfn=%lx pred=%lx score=%lx\n", gpfn, prediction, 
score);
 
     if ( score )
-        set_shadow_status(d, GPFN_TO_GPTEPAGE(gpfn), 0, prediction, 
PGT_writable_pred);
+        set_shadow_status(d, GPFN_TO_GPTEPAGE(gpfn), 0, prediction, 
PGT_writable_pred, 0);
     else
     {
-        delete_shadow_status(d, GPFN_TO_GPTEPAGE(gpfn), 0, PGT_writable_pred);
+        delete_shadow_status(d, GPFN_TO_GPTEPAGE(gpfn), 0, PGT_writable_pred, 
0);
         perfc_decr(writable_pte_predictions);
     }
 }
@@ -2381,7 +2381,7 @@ free_writable_pte_predictions(struct dom
              * keep an accurate count of writable_pte_predictions to keep it
              * happy.
              */
-            delete_shadow_status(d, gpfn_list[count], 0, PGT_writable_pred);
+            delete_shadow_status(d, gpfn_list[count], 0, PGT_writable_pred, 0);
             perfc_decr(writable_pte_predictions);
         }
 
diff -r 0991ed8e4ae5 -r 1507021dccdf xen/arch/x86/shadow_guest32pae.c
--- a/xen/arch/x86/shadow_guest32pae.c  Mon Jun 19 16:39:27 2006 +0100
+++ b/xen/arch/x86/shadow_guest32pae.c  Mon Jun 19 16:47:21 2006 +0100
@@ -1,5 +1,4 @@
 #define GUEST_32PAE
-#if defined (__x86_64__)
 
 #include "shadow.c"
 struct shadow_ops MODE_64_PAE_HANDLER = {
@@ -15,4 +14,3 @@ struct shadow_ops MODE_64_PAE_HANDLER = 
     .gva_to_gpa                 = gva_to_gpa_64,
 };
 
-#endif
diff -r 0991ed8e4ae5 -r 1507021dccdf xen/arch/x86/shadow_public.c
--- a/xen/arch/x86/shadow_public.c      Mon Jun 19 16:39:27 2006 +0100
+++ b/xen/arch/x86/shadow_public.c      Mon Jun 19 16:47:21 2006 +0100
@@ -123,8 +123,19 @@ int shadow_set_guest_paging_levels(struc
 #endif
 #if CONFIG_PAGING_LEVELS == 3
     case 3:
-        if ( d->arch.ops != &MODE_64_3_HANDLER )
-            d->arch.ops = &MODE_64_3_HANDLER;
+        if ( d->arch.ops == NULL ||
+                    shadow_mode_log_dirty(d) )
+        {
+            if ( d->arch.ops != &MODE_64_3_HANDLER )
+                d->arch.ops = &MODE_64_3_HANDLER;
+        }
+        else
+        {
+            if ( d->arch.ops == &MODE_64_2_HANDLER )
+                free_shadow_pages(d);
+            if ( d->arch.ops != &MODE_64_PAE_HANDLER )
+                d->arch.ops = &MODE_64_PAE_HANDLER;
+        }
         shadow_unlock(d);
         return 1;
 #endif
@@ -268,10 +279,8 @@ free_shadow_tables(struct domain *d, uns
                     put_shadow_ref(entry_get_pfn(ple[i]));
                 if (d->arch.ops->guest_paging_levels == PAGING_L3)
                 {
-#if CONFIG_PAGING_LEVELS == 4
+#if CONFIG_PAGING_LEVELS >= 3
                     if ( i == PAE_L3_PAGETABLE_ENTRIES && level == PAGING_L4 )
-#elif CONFIG_PAGING_LEVELS == 3
-                    if ( i == PAE_L3_PAGETABLE_ENTRIES && level == PAGING_L3 )
 #endif
                         break;
                 }
@@ -710,6 +719,7 @@ void free_shadow_page(unsigned long smfn
     struct domain *d = page_get_owner(mfn_to_page(gmfn));
     unsigned long gpfn = mfn_to_gmfn(d, gmfn);
     unsigned long type = page->u.inuse.type_info & PGT_type_mask;
+    u64 index = 0;
 
     SH_VVLOG("%s: free'ing smfn=%lx", __func__, smfn);
 
@@ -722,12 +732,16 @@ void free_shadow_page(unsigned long smfn
         if ( !mfn )
             gpfn |= (1UL << 63);
     }
+#endif
+#if CONFIG_PAGING_LEVELS >= 3
     if ( d->arch.ops->guest_paging_levels == PAGING_L3 )
-        if ( type == PGT_l4_shadow ) 
-            gpfn = ((unsigned long)page->tlbflush_timestamp << 
PGT_pae_idx_shift) | gpfn;
-#endif
-
-    delete_shadow_status(d, gpfn, gmfn, type);
+    {
+        if ( type == PGT_l4_shadow )
+            index = page->tlbflush_timestamp;
+    }
+#endif
+
+    delete_shadow_status(d, gpfn, gmfn, type, index);
 
     switch ( type )
     {
@@ -835,7 +849,7 @@ free_writable_pte_predictions(struct dom
         while ( count )
         {
             count--;
-            delete_shadow_status(d, gpfn_list[count], 0, PGT_writable_pred);
+            delete_shadow_status(d, gpfn_list[count], 0, PGT_writable_pred, 0);
         }
 
         xfree(gpfn_list);
@@ -1050,8 +1064,8 @@ void __shadow_mode_disable(struct domain
     {
         if ( d->arch.shadow_ht[i].gpfn_and_flags != 0 )
         {
-            printk("%s: d->arch.shadow_ht[%x].gpfn_and_flags=%lx\n",
-                   __FILE__, i, d->arch.shadow_ht[i].gpfn_and_flags);
+            printk("%s: d->arch.shadow_ht[%x].gpfn_and_flags=%"PRIx64"\n",
+                   __FILE__, i, (u64)d->arch.shadow_ht[i].gpfn_and_flags);
             BUG();
         }
     }
diff -r 0991ed8e4ae5 -r 1507021dccdf xen/include/asm-x86/mm.h
--- a/xen/include/asm-x86/mm.h  Mon Jun 19 16:39:27 2006 +0100
+++ b/xen/include/asm-x86/mm.h  Mon Jun 19 16:47:21 2006 +0100
@@ -103,13 +103,11 @@ struct page_info
 #define PGT_high_mfn_mask   (0xfffUL << PGT_high_mfn_shift)
 #define PGT_mfn_mask        (((1U<<23)-1) | PGT_high_mfn_mask)
 #define PGT_high_mfn_nx     (0x800UL << PGT_high_mfn_shift)
-#define PGT_pae_idx_shift   PGT_high_mfn_shift
 #else
  /* 23-bit mfn mask for shadow types: good for up to 32GB RAM. */
 #define PGT_mfn_mask        ((1U<<23)-1)
  /* NX for PAE xen is not supported yet */
 #define PGT_high_mfn_nx     (1ULL << 63)
-#define PGT_pae_idx_shift   23
 #endif
 
 #define PGT_score_shift     23
diff -r 0991ed8e4ae5 -r 1507021dccdf xen/include/asm-x86/shadow.h
--- a/xen/include/asm-x86/shadow.h      Mon Jun 19 16:39:27 2006 +0100
+++ b/xen/include/asm-x86/shadow.h      Mon Jun 19 16:47:21 2006 +0100
@@ -112,6 +112,30 @@ do {                                    
 } while (0)
 #endif
 
+#if CONFIG_PAGING_LEVELS >= 3
+static inline u64 get_cr3_idxval(struct vcpu *v)
+{
+    u64 pae_cr3;
+
+    if ( v->domain->arch.ops->guest_paging_levels == PAGING_L3 &&
+            !shadow_mode_log_dirty(v->domain) )
+    {
+        pae_cr3 = hvm_get_guest_ctrl_reg(v, 3); /* get CR3 */
+        return (pae_cr3 >> PAE_CR3_ALIGN) & PAE_CR3_IDX_MASK;
+    }
+    else
+        return 0;
+}
+
+#define shadow_key_t u64
+#define index_to_key(x) ((x) << 32)
+#else
+#define get_cr3_idxval(v) (0)
+#define shadow_key_t unsigned long
+#define index_to_key(x)  (0)
+#endif
+
+
 #define SHADOW_ENCODE_MIN_MAX(_min, _max) ((((GUEST_L1_PAGETABLE_ENTRIES - 1) 
- (_max)) << 16) | (_min))
 #define SHADOW_MIN(_encoded) ((_encoded) & ((1u<<16) - 1))
 #define SHADOW_MAX(_encoded) ((GUEST_L1_PAGETABLE_ENTRIES - 1) - ((_encoded) 
>> 16))
@@ -309,7 +333,7 @@ extern unsigned long get_mfn_from_gpfn_f
 
 struct shadow_status {
     struct shadow_status *next;   /* Pull-to-front list per hash bucket. */
-    unsigned long gpfn_and_flags; /* Guest pfn plus flags. */
+    shadow_key_t  gpfn_and_flags; /* Guest pfn plus flags. */
     unsigned long smfn;           /* Shadow mfn.           */
 };
 
@@ -1180,7 +1204,13 @@ static inline unsigned long __shadow_sta
     struct domain *d, unsigned long gpfn, unsigned long stype)
 {
     struct shadow_status *p, *x, *head;
-    unsigned long key = gpfn | stype;
+    shadow_key_t key;
+#if CONFIG_PAGING_LEVELS >= 3
+    if ( d->arch.ops->guest_paging_levels == PAGING_L3 && stype == 
PGT_l4_shadow )
+        key = gpfn | stype | index_to_key(get_cr3_idxval(current));
+    else
+#endif
+        key = gpfn | stype;
 
     ASSERT(shadow_lock_is_acquired(d));
     ASSERT(gpfn == (gpfn & PGT_mfn_mask));
@@ -1295,10 +1325,11 @@ shadow_max_pgtable_type(struct domain *d
 }
 
 static inline void delete_shadow_status(
-    struct domain *d, unsigned long gpfn, unsigned long gmfn, unsigned int 
stype)
+    struct domain *d, unsigned long gpfn, unsigned long gmfn, unsigned int 
stype, u64 index)
 {
     struct shadow_status *p, *x, *n, *head;
-    unsigned long key = gpfn | stype;
+
+    shadow_key_t key = gpfn | stype | index_to_key(index);
 
     ASSERT(shadow_lock_is_acquired(d));
     ASSERT(!(gpfn & ~PGT_mfn_mask));
@@ -1374,11 +1405,12 @@ static inline void delete_shadow_status(
 
 static inline void set_shadow_status(
     struct domain *d, unsigned long gpfn, unsigned long gmfn,
-    unsigned long smfn, unsigned long stype)
+    unsigned long smfn, unsigned long stype, u64 index)
 {
     struct shadow_status *x, *head, *extra;
     int i;
-    unsigned long key = gpfn | stype;
+
+    shadow_key_t key = gpfn | stype | index_to_key(index);
 
     SH_VVLOG("set gpfn=%lx gmfn=%lx smfn=%lx t=%lx", gpfn, gmfn, smfn, stype);
 
diff -r 0991ed8e4ae5 -r 1507021dccdf xen/include/asm-x86/shadow_64.h
--- a/xen/include/asm-x86/shadow_64.h   Mon Jun 19 16:39:27 2006 +0100
+++ b/xen/include/asm-x86/shadow_64.h   Mon Jun 19 16:47:21 2006 +0100
@@ -36,9 +36,9 @@
  */
 extern struct shadow_ops MODE_64_2_HANDLER;
 extern struct shadow_ops MODE_64_3_HANDLER;
+extern struct shadow_ops MODE_64_PAE_HANDLER;
 #if CONFIG_PAGING_LEVELS == 4
 extern struct shadow_ops MODE_64_4_HANDLER;
-extern struct shadow_ops MODE_64_PAE_HANDLER;
 #endif
 
 #if CONFIG_PAGING_LEVELS == 3
@@ -65,10 +65,6 @@ typedef struct { intpte_t l4; } l4_pgent
 #define ESH_LOG(_f, _a...) ((void)0)
 #endif
 
-#define PAGING_L4      4UL
-#define PAGING_L3      3UL
-#define PAGING_L2      2UL
-#define PAGING_L1      1UL
 #define L_MASK  0xff
 
 #define PAE_PAGING_LEVELS   3
@@ -108,18 +104,14 @@ typedef struct { intpte_t lo; } pgentry_
 #define entry_has_changed(x,y,flags) \
         ( !!(((x).lo ^ (y).lo) & 
((PADDR_MASK&PAGE_MASK)|put_pte_flags(flags))) )
 
+/******************************************************************************/
+/*
+ * The macro and inlines are for 32-bit PAE guest 
+ */
+#define PAE_PDPT_RESERVED   0x1e6 /* [8:5], [2,1] */
+
 #define PAE_SHADOW_SELF_ENTRY   259
 #define PAE_L3_PAGETABLE_ENTRIES   4
-
-/******************************************************************************/
-/*
- * The macro and inlines are for 32-bit PAE guest on 64-bit host
- */
-#define PAE_CR3_ALIGN       5
-#define PAE_CR3_IDX_MASK    0x7f
-#define PAE_CR3_IDX_NO      128
-
-#define PAE_PDPT_RESERVED   0x1e6 /* [8:5], [2,1] */
 
 
/******************************************************************************/
 static inline int  table_offset_64(unsigned long va, int level)
@@ -186,19 +178,10 @@ static inline int guest_table_offset_64(
     }
 }
 
-static inline unsigned long get_cr3_idxval(struct vcpu *v)
-{
-    unsigned long pae_cr3 = hvm_get_guest_ctrl_reg(v, 3); /* get CR3 */
-
-    return (pae_cr3 >> PAE_CR3_ALIGN) & PAE_CR3_IDX_MASK;
-}
-
-
 #define SH_GUEST_32PAE 1
 #else 
 #define guest_table_offset_64(va, level, index) \
             table_offset_64((va),(level))
-#define get_cr3_idxval(v) 0
 #define SH_GUEST_32PAE 0
 #endif
 
@@ -514,7 +497,10 @@ static inline void entry_general(
 
                 l1_p =(pgentry_64_t *)map_domain_page(smfn);
                 for (i = 0; i < L1_PAGETABLE_ENTRIES; i++)
-                    entry_remove_flags(l1_p[i], _PAGE_RW);
+                {
+                    if ( mfn_is_page_table(entry_get_pfn(l1_p[i])) )
+                        entry_remove_flags(l1_p[i], _PAGE_RW);
+                }
 
                 unmap_domain_page(l1_p);
             }
diff -r 0991ed8e4ae5 -r 1507021dccdf xen/include/asm-x86/shadow_ops.h
--- a/xen/include/asm-x86/shadow_ops.h  Mon Jun 19 16:39:27 2006 +0100
+++ b/xen/include/asm-x86/shadow_ops.h  Mon Jun 19 16:47:21 2006 +0100
@@ -21,6 +21,14 @@
 
 #ifndef _XEN_SHADOW_OPS_H
 #define _XEN_SHADOW_OPS_H
+
+#define PAGING_L4      4UL
+#define PAGING_L3      3UL
+#define PAGING_L2      2UL
+#define PAGING_L1      1UL
+
+#define PAE_CR3_ALIGN       5
+#define PAE_CR3_IDX_MASK    0x7f
 
 #if defined( GUEST_PGENTRY_32 )
 

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