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

[Xen-changelog] [xen-unstable] hvm hap: P2M page table cleanup and bug fix.



# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1175515559 -3600
# Node ID f0f9533b2a2385fe2bd4193ecae523f0416368d9
# Parent  149943a5d2c812c211decfc29e47e85f3182bc46
hvm hap: P2M page table cleanup and bug fix.

Force P2M top-level page table to be allocated below 4GB
memory space when Xen is running under PAE mode. Also remove
hap.p2m_freelists because hap mode does not have P2M batch
allocation. The backpointer parameter of hap_alloc() function is
removed since this parameter is unused.

Signed-off-by: Wei Huang <wei.huang2@xxxxxxx>
---
 xen/arch/x86/mm/hap/hap.c    |   68 +++++++++++++++++++++----------------------
 xen/include/asm-x86/domain.h |    1 
 2 files changed, 34 insertions(+), 35 deletions(-)

diff -r 149943a5d2c8 -r f0f9533b2a23 xen/arch/x86/mm/hap/hap.c
--- a/xen/arch/x86/mm/hap/hap.c Mon Apr 02 11:50:06 2007 +0100
+++ b/xen/arch/x86/mm/hap/hap.c Mon Apr 02 13:05:59 2007 +0100
@@ -52,7 +52,7 @@
 /************************************************/
 /*             HAP SUPPORT FUNCTIONS            */
 /************************************************/
-mfn_t hap_alloc(struct domain *d, unsigned long backpointer)
+mfn_t hap_alloc(struct domain *d)
 {
     struct page_info *sp = NULL;
     void *p;
@@ -82,43 +82,43 @@ void hap_free(struct domain *d, mfn_t sm
     list_add_tail(&sp->list, &d->arch.paging.hap.freelists);
 }
 
-static int hap_alloc_p2m_pages(struct domain *d)
-{
-    struct page_info *pg;
-
-    ASSERT(hap_locked_by_me(d));
-
-    pg = mfn_to_page(hap_alloc(d, 0));
-    d->arch.paging.hap.p2m_pages += 1;
-    d->arch.paging.hap.total_pages -= 1;
-    
-    page_set_owner(pg, d);
-    pg->count_info = 1;
-    list_add_tail(&pg->list, &d->arch.paging.hap.p2m_freelist);
-
-    return 1;
-}
-
 struct page_info * hap_alloc_p2m_page(struct domain *d)
 {
-    struct list_head *entry;
     struct page_info *pg;
     mfn_t mfn;
     void *p;
 
     hap_lock(d);
-    
-    if ( list_empty(&d->arch.paging.hap.p2m_freelist) && 
-         !hap_alloc_p2m_pages(d) ) {
-        hap_unlock(d);
-        return NULL;
-    }
-    entry = d->arch.paging.hap.p2m_freelist.next;
-    list_del(entry);
-    
+
+#if CONFIG_PAGING_LEVELS == 3
+    /* Under PAE mode, top-level P2M table should be allocated below 4GB space
+     * because the size of h_cr3 is only 32-bit. We use alloc_domheap_pages to 
+     * force this requirement. This page will be de-allocated in 
+     * hap_free_p2m_page(), like other P2M pages.
+    */
+    if ( d->arch.paging.hap.p2m_pages == 0 ) 
+    {
+       pg = alloc_domheap_pages(NULL, 0, MEMF_bits(32));
+       d->arch.paging.hap.p2m_pages += 1;
+    }
+    else
+#endif
+    {
+       pg = mfn_to_page(hap_alloc(d));
+       
+       d->arch.paging.hap.p2m_pages += 1;
+       d->arch.paging.hap.total_pages -= 1;
+    }  
+
+    if ( pg == NULL ) {
+       hap_unlock(d);
+       return NULL;
+    }   
+
     hap_unlock(d);
 
-    pg = list_entry(entry, struct page_info, list);
+    page_set_owner(pg, d);
+    pg->count_info = 1;
     mfn = page_to_mfn(pg);
     p = hap_map_domain_page(mfn);
     clear_page(p);
@@ -141,6 +141,7 @@ void hap_free_p2m_page(struct domain *d,
     page_set_owner(pg, NULL); 
     free_domheap_pages(pg, 0);
     d->arch.paging.hap.p2m_pages--;
+    ASSERT( d->arch.paging.hap.p2m_pages >= 0 );
 }
 
 /* Return the size of the pool, rounded up to the nearest MB */
@@ -320,7 +321,7 @@ mfn_t hap_make_monitor_table(struct vcpu
 #if CONFIG_PAGING_LEVELS == 4
     {
         mfn_t m4mfn;
-        m4mfn = hap_alloc(d, 0);
+        m4mfn = hap_alloc(d);
         hap_install_xen_entries_in_l4(v, m4mfn, m4mfn);
         return m4mfn;
     }
@@ -331,12 +332,12 @@ mfn_t hap_make_monitor_table(struct vcpu
         l2_pgentry_t *l2e;
         int i;
 
-        m3mfn = hap_alloc(d, 0);
+        m3mfn = hap_alloc(d);
 
         /* Install a monitor l2 table in slot 3 of the l3 table.
          * This is used for all Xen entries, including linear maps
          */
-        m2mfn = hap_alloc(d, 0);
+        m2mfn = hap_alloc(d);
         l3e = hap_map_domain_page(m3mfn);
         l3e[3] = l3e_from_pfn(mfn_x(m2mfn), _PAGE_PRESENT);
         hap_install_xen_entries_in_l2h(v, m2mfn);
@@ -357,7 +358,7 @@ mfn_t hap_make_monitor_table(struct vcpu
     {
         mfn_t m2mfn;
         
-        m2mfn = hap_alloc(d, 0);
+        m2mfn = hap_alloc(d);
         hap_install_xen_entries_in_l2(v, m2mfn, m2mfn);
     
         return m2mfn;
@@ -390,7 +391,6 @@ void hap_domain_init(struct domain *d)
 {
     hap_lock_init(d);
     INIT_LIST_HEAD(&d->arch.paging.hap.freelists);
-    INIT_LIST_HEAD(&d->arch.paging.hap.p2m_freelist);
 }
 
 /* return 0 for success, -errno for failure */
diff -r 149943a5d2c8 -r f0f9533b2a23 xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h      Mon Apr 02 11:50:06 2007 +0100
+++ b/xen/include/asm-x86/domain.h      Mon Apr 02 13:05:59 2007 +0100
@@ -115,7 +115,6 @@ struct hap_domain {
     const char       *locker_function;
     
     struct list_head  freelists;
-    struct list_head  p2m_freelist;
     unsigned int      total_pages;  /* number of pages allocated */
     unsigned int      free_pages;   /* number of pages on freelists */
     unsigned int      p2m_pages;    /* number of pages allocates to p2m */

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