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

Re: [Xen-devel] [PATCH v2 4/6] xen/arm: implement get/put_page_type



At 16:05 +0100 on 20 Jul (1342800356), Stefano Stabellini wrote:
> 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.

OK, we definitely decided that ARM didn't need page typecounts. :)  Is
this needed for some common code?

Tim.

> 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

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.