# 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
|