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-unstable] [HVM][VMX][PAE] Enable PAE VMX guest on P

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [HVM][VMX][PAE] Enable PAE VMX guest on PAE host.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 20 Jun 2006 15:01:25 +0000
Delivery-date: Tue, 20 Jun 2006 08:03:28 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
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/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/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 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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] [HVM][VMX][PAE] Enable PAE VMX guest on PAE host., Xen patchbot-unstable <=