[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v2 4/6] xen/arm: implement get/put_page_type
Add a basic get_page_type and put_page_type implementation: the implementation is similar to the x86 one, without all the code to handle shadow pagetables and other unneeded features. Also remove PGT_shared_page, that is unused. Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx> --- xen/arch/arm/dummy.S | 4 -- xen/arch/arm/mm.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++ xen/include/asm-arm/mm.h | 1 - 3 files changed, 91 insertions(+), 5 deletions(-) diff --git a/xen/arch/arm/dummy.S b/xen/arch/arm/dummy.S index baced25..2b96d22 100644 --- a/xen/arch/arm/dummy.S +++ b/xen/arch/arm/dummy.S @@ -22,10 +22,6 @@ DUMMY(arch_get_info_guest); DUMMY(arch_vcpu_reset); NOP(update_vcpu_system_time); -/* Page Reference & Type Maintenance */ -DUMMY(get_page_type); -DUMMY(put_page_type); - /* Grant Tables */ DUMMY(steal_page); diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c index 01a6781..7033023 100644 --- a/xen/arch/arm/mm.c +++ b/xen/arch/arm/mm.c @@ -28,8 +28,10 @@ #include <xen/guest_access.h> #include <asm/page.h> #include <asm/current.h> +#include <asm/flushtlb.h> #include <public/memory.h> #include <xen/sched.h> +#include <xen/perfc.h> struct domain *dom_xen, *dom_io; @@ -604,6 +606,95 @@ int get_page(struct page_info *page, struct domain *domain) return 0; } +void put_page_type(struct page_info *page) +{ + unsigned long nx, x, y = page->u.inuse.type_info; + + for ( ; ; ) + { + x = y; + nx = x - 1; + + ASSERT((x & PGT_count_mask) != 0); + + if ( unlikely((nx & PGT_count_mask) == 0) ) + /* + * Record TLB information for flush later + */ + page->tlbflush_timestamp = tlbflush_current_time(); + + if ( likely((y = cmpxchg(&page->u.inuse.type_info, x, nx)) == x) ) + break; + } +} + +int get_page_type(struct page_info *page, unsigned long type) +{ + unsigned long nx, x, y = page->u.inuse.type_info; + + for ( ; ; ) + { + x = y; + nx = x + 1; + if ( unlikely((nx & PGT_count_mask) == 0) ) + { + printk("Type count overflow on pfn %lx", page_to_mfn(page)); + return -EINVAL; + } + else if ( (x & PGT_count_mask) == 0 ) + { + struct domain *d = page_get_owner(page); + + if ( (x & PGT_type_mask) != type ) + { + /* + * On type change we check to flush stale TLB entries. This + * may be unnecessary (e.g., page was GDT/LDT) but those + * circumstances should be very rare. + */ + cpumask_t mask; + + cpumask_copy(&mask, d->domain_dirty_cpumask); + + /* Don't flush if the timestamp is old enough */ + tlbflush_filter(mask, page->tlbflush_timestamp); + + if ( unlikely(!cpumask_empty(&mask)) ) + { + perfc_incr(need_flush_tlb_flush); + flush_tlb_mask(&mask); + } + + /* We lose existing type and validity. */ + nx &= ~(PGT_type_mask | PGT_validated); + nx |= type; + + /* No special validation needed for writable pages. */ + /* Page tables and GDT/LDT need to be scanned for validity. */ + if ( type == PGT_writable_page ) + nx |= PGT_validated; + } + } + else if ( unlikely(!(x & PGT_validated)) ) + { + /* Someone else is updating validation of this page. Wait... */ + while ( (y = page->u.inuse.type_info) == x ) + { + cpu_relax(); + } + continue; + } + + if ( likely((y = cmpxchg(&page->u.inuse.type_info, x, nx)) == x) ) + break; + } + + if ( unlikely(!(nx & PGT_validated)) ) + BUG(); + + return 1; +} + void gnttab_clear_flag(unsigned long nr, uint16_t *addr) { /* diff --git a/xen/include/asm-arm/mm.h b/xen/include/asm-arm/mm.h index 53801b0..b37bd35 100644 --- a/xen/include/asm-arm/mm.h +++ b/xen/include/asm-arm/mm.h @@ -71,7 +71,6 @@ struct page_info #define PGT_none PG_mask(0, 4) /* no special uses of this page */ #define PGT_writable_page PG_mask(7, 4) /* has writable mappings? */ -#define PGT_shared_page PG_mask(8, 4) /* CoW sharable page */ #define PGT_type_mask PG_mask(15, 4) /* Bits 28-31 or 60-63. */ /* Owning guest has pinned this page to its current type? */ -- 1.7.2.5 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |