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) _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel