Mailing List Archive

[PATCH 12/14] arm: implement get/put page functions
arm: implement get/put page functions

xen/arch/arm/xen/mm.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++------
1 files changed, 55 insertions(+), 6 deletions(-)

Signed-off-by: Jaemin Ryu <jm77.ryu@samsung.com>

diff -r c3e7333eefc3 xen/arch/arm/xen/mm.c
--- a/xen/arch/arm/xen/mm.c Sun Feb 12 15:04:24 2012 +0900
+++ b/xen/arch/arm/xen/mm.c Sun Feb 12 15:13:09 2012 +0900
@@ -73,29 +73,78 @@ void memguard_unguard_range(void *p, uns

void put_page(struct page_info *page)
{
- NOT_YET();
+ u32 nx, x, y = page->count_info;
+
+ do {
+ x = y;
+ nx = x - 1;
+ } while ( unlikely((y = cmpxchg(&page->count_info, x, nx)) != x) );
+
+ if ( unlikely((nx & PGC_count_mask) == 0) ) {
+ free_domheap_page(page);
+ }
+
}

struct domain *page_get_owner_and_reference(struct page_info *page)
{
- NOT_YET();
+ unsigned long x, y = page->count_info;
+
+ do {
+ x = y;
+ if(unlikely(((x + 2) & PGC_count_mask) <= 2) )
+ return NULL;
+ } while((y = cmpxchg(&page->count_info,x,x+1)) != x);
+
+ return page_get_owner(page);
+
}

int get_page(struct page_info *page, struct domain *domain)
{
- NOT_YET();
+ struct domain *owner = page_get_owner_and_reference(page);

- return 0;
+ if (likely(owner == domain))
+ return 1;
+
+ if (owner != domain)
+ put_page(page);
+
+ return 0;
}

void share_xen_page_with_guest(struct page_info *page, struct domain *d, int readonly)
{
- NOT_YET();
+ if(page_get_owner(page) == d)
+ return;
+
+ set_gpfn_from_mfn(page_to_mfn(page), INVALID_M2P_ENTRY);
+
+ spin_lock(&d->page_alloc_lock);
+
+ /* The incremented type count pins as writable or read-only. */
+ page->u.inuse.type_info = (readonly ? PGT_none : PGT_writable_page);
+ page->u.inuse.type_info |= PGT_validated | 1;
+
+ page_set_owner(page, d);
+ wmb(); /* install valid domain ptr before updating refcnt. */
+ ASSERT((page->count_info & ~PGC_xen_heap) == 0);
+
+ if (!d->is_dying) {
+ page->count_info |= PGC_allocated | 1;
+
+ if ( unlikely(d->xenheap_pages++ == 0) )
+ get_knownalive_domain(d);
+
+ page_list_add_tail(page, &d->xenpage_list);
+ }
+
+ spin_unlock(&d->page_alloc_lock);
}

void share_xen_page_with_privileged_guests(struct page_info *page, int readonly)
{
- NOT_YET();
+ share_xen_page_with_guest(page, dom_xen, readonly);
}

static int pin_page_table(u32 mfn, struct domain *d)