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

Re: [Xen-devel] [PATCH] xen: arm: implement XENMEM_add_to_physmap_range



On Thu, 4 Oct 2012, Ian Campbell wrote:
> This is an implementation of XENMEM_add_to_physmap_range as previously
> discussed.
> 
> This applies on top of
> git://xenbits.xen.org/people/ianc/xen-unstable.git arm-for-4.3 +
> Stefano's "ARM hypercall ABI: 64 bit ready" series.
> 
> I think this should replace "HACK: arm: initial
> XENMAPSPACE_gmfn_foreign" (from the branch) and "xen: improve changes to
> xen_add_to_physmap" (from Stefano's series) and we should make it
> invalid to call XENMEM_add_to_physmap with XENMAPSPACE_gmfn_foreign
> (i.e. get rid of the union etc).
> 
> I intend to do this as as I rebase the arm-for-4.3 branch to post for
> inclusion in mainline. i.e. drop the original HACK in favour of this
> patch.
> 
> What is the status of Stefano's "ARM hypercall ABI: 64 bit ready"? It
> touches common and arch/x86 code/interfaces so it'll need pretty wide
> ranging ack's I think.
> 
> 8<-------------------------------------------------------
> 
> 
> From 1e889407a8e93fdbaf591c74fb3f2fe01f9016ac Mon Sep 17 00:00:00 2001
> From: Ian Campbell <ian.campbell@xxxxxxxxxx>
> Date: Thu, 4 Oct 2012 11:25:18 +0000
> Subject: [PATCH] xen: arm: implement XENMEM_add_to_physmap_range
> 
> This allows for foreign mappings as well as batching, fitting all that
> into XENMEM_add_to_physmap wasn't possible.
> 
> Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>

looks reasonable to me


>  xen/arch/arm/mm.c           |  103 
> ++++++++++++++++++++++++++++++++++++-------
>  xen/include/public/memory.h |   41 +++++++++++++----
>  xen/include/public/xen.h    |    1 +
>  3 files changed, 119 insertions(+), 26 deletions(-)
> 
> diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c
> index 3e8b6cc..9e7d2d2 100644
> --- a/xen/arch/arm/mm.c
> +++ b/xen/arch/arm/mm.c
> @@ -26,6 +26,8 @@
>  #include <xen/preempt.h>
>  #include <xen/errno.h>
>  #include <xen/grant_table.h>
> +#include <xen/softirq.h>
> +#include <xen/event.h>
>  #include <xen/guest_access.h>
>  #include <xen/domain_page.h>
>  #include <asm/page.h>
> @@ -462,14 +464,17 @@ void share_xen_page_with_guest(struct page_info *page,
>      spin_unlock(&d->page_alloc_lock);
>  }
>  
> -static int xenmem_add_to_physmap_once(
> +static int xenmem_add_to_physmap_one(
>      struct domain *d,
> -    const struct xen_add_to_physmap *xatp)
> +    uint16_t space,
> +    domid_t foreign_domid,
> +    unsigned long idx,
> +    xen_pfn_t gpfn)
>  {
> -    unsigned long mfn = 0, idx = 0;
> +    unsigned long mfn = 0;
>      int rc;
>  
> -    switch ( xatp->space )
> +    switch ( space )
>      {
>      case XENMAPSPACE_grant_table:
>          spin_lock(&d->grant_table->lock);
> @@ -477,9 +482,8 @@ static int xenmem_add_to_physmap_once(
>          if ( d->grant_table->gt_version == 0 )
>              d->grant_table->gt_version = 1;
>  
> -        idx = xatp->idx;
>          if ( d->grant_table->gt_version == 2 &&
> -                (xatp->idx & XENMAPIDX_grant_table_status) )
> +                (idx & XENMAPIDX_grant_table_status) )
>          {
>              idx &= ~XENMAPIDX_grant_table_status;
>              if ( idx < nr_status_frames(d->grant_table) )
> @@ -498,29 +502,31 @@ static int xenmem_add_to_physmap_once(
>          spin_unlock(&d->grant_table->lock);
>          break;
>      case XENMAPSPACE_shared_info:
> -        if ( xatp->idx == 0 )
> +        if ( idx == 0 )
>              mfn = virt_to_mfn(d->shared_info);
>          break;
>      case XENMAPSPACE_gmfn_foreign:
>      {
>          paddr_t maddr;
>          struct domain *od;
> -
> -        rc = rcu_lock_target_domain_by_id(xatp->u.foreign_domid, &od);
> +        rc = rcu_lock_target_domain_by_id(foreign_domid, &od);
>          if ( rc < 0 )
>              return rc;
> -        maddr = p2m_lookup(od, xatp->idx << PAGE_SHIFT);
> +
> +        maddr = p2m_lookup(od, idx << PAGE_SHIFT);
>          if ( maddr == INVALID_PADDR )
>          {
> -            printk("bad p2m lookup\n");
> -            dump_p2m_lookup(od, xatp->idx << PAGE_SHIFT);
> +            dump_p2m_lookup(od, idx << PAGE_SHIFT);
>              rcu_unlock_domain(od);
>              return -EINVAL;
>          }
> +
>          mfn = maddr >> PAGE_SHIFT;
> +
>          rcu_unlock_domain(od);
>          break;
>      }
> +
>      default:
>          return -ENOSYS;
>      }
> @@ -528,17 +534,51 @@ static int xenmem_add_to_physmap_once(
>      domain_lock(d);
>  
>      /* Map at new location. */
> -    rc = guest_physmap_add_page(d, xatp->gpfn, mfn, 0);
> +    rc = guest_physmap_add_page(d, gpfn, mfn, 0);
>  
>      domain_unlock(d);
>  
>      return rc;
>  }
>  
> -static int xenmem_add_to_physmap(struct domain *d,
> -                                 struct xen_add_to_physmap *xatp)
> +static int xenmem_add_to_physmap_range(struct domain *d,
> +                                       struct xen_add_to_physmap_range 
> *xatpr)
>  {
> -    return xenmem_add_to_physmap_once(d, xatp);
> +    int rc;
> +
> +    /* Process entries in reverse order to allow continuations */
> +    while ( xatpr->size > 0 )
> +    {
> +        xen_ulong_t idx;
> +        xen_pfn_t gpfn;
> +
> +        rc = copy_from_guest_offset(&idx, xatpr->idxs, xatpr->size-1, 1);
> +        if ( rc < 0 )
> +            goto out;
> +
> +        rc = copy_from_guest_offset(&gpfn, xatpr->gpfns, xatpr->size-1, 1);
> +        if ( rc < 0 )
> +            goto out;
> +
> +        rc = xenmem_add_to_physmap_one(d, xatpr->space,
> +                                       xatpr->foreign_domid,
> +                                       idx, gpfn);
> +
> +        xatpr->size--;
> +
> +        /* Check for continuation if it's not the last interation */
> +        if ( xatpr->size > 0 && hypercall_preempt_check() )
> +        {
> +            rc = -EAGAIN;
> +            goto out;
> +        }
> +    }
> +
> +    rc = 0;
> +
> +out:
> +    return rc;
> +
>  }
>  
>  long arch_memory_op(int op, XEN_GUEST_HANDLE_PARAM(void) arg)
> @@ -559,13 +599,42 @@ long arch_memory_op(int op, 
> XEN_GUEST_HANDLE_PARAM(void) arg)
>          if ( rc != 0 )
>              return rc;
>  
> -        rc = xenmem_add_to_physmap(d, &xatp);
> +        rc = xenmem_add_to_physmap_one(d, xatp.space,
> +                                       xatp.space == 
> XENMAPSPACE_gmfn_foreign ?
> +                                           xatp.u.foreign_domid : 
> DOMID_INVALID,
> +                                       xatp.idx, xatp.gpfn);
>  
>          rcu_unlock_domain(d);
>  
>          return rc;
>      }
>  
> +    case XENMEM_add_to_physmap_range:
> +    {
> +        struct xen_add_to_physmap_range xatpr;
> +        struct domain *d;
> +
> +        if ( copy_from_guest(&xatpr, arg, 1) )
> +            return -EFAULT;
> +
> +        rc = rcu_lock_target_domain_by_id(xatpr.domid, &d);
> +        if ( rc != 0 )
> +            return rc;
> +
> +        rc = xenmem_add_to_physmap_range(d, &xatpr);
> +
> +        rcu_unlock_domain(d);
> +
> +        if ( rc && copy_to_guest(arg, &xatpr, 1) )
> +            rc = -EFAULT;
> +
> +        if ( rc == -EAGAIN )
> +            rc = hypercall_create_continuation(
> +                __HYPERVISOR_memory_op, "ih", op, arg);
> +
> +        return rc;
> +    }
> +
>      default:
>          return -ENOSYS;
>      }
> diff --git a/xen/include/public/memory.h b/xen/include/public/memory.h
> index 7d4ee26..29d0b94 100644
> --- a/xen/include/public/memory.h
> +++ b/xen/include/public/memory.h
> @@ -198,6 +198,15 @@ struct xen_machphys_mapping {
>  typedef struct xen_machphys_mapping xen_machphys_mapping_t;
>  DEFINE_XEN_GUEST_HANDLE(xen_machphys_mapping_t);
>  
> +/* Source mapping space. */
> +/* ` enum phys_map_space { */
> +#define XENMAPSPACE_shared_info  0 /* shared info page */
> +#define XENMAPSPACE_grant_table  1 /* grant table page */
> +#define XENMAPSPACE_gmfn         2 /* GMFN */
> +#define XENMAPSPACE_gmfn_range   3 /* GMFN range */
> +#define XENMAPSPACE_gmfn_foreign 4 /* GMFN from another dom */
> +/* ` } */
> +
>  /*
>   * Sets the GPFN at which a particular page appears in the specified guest's
>   * pseudophysical address space.
> @@ -215,25 +224,39 @@ struct xen_add_to_physmap {
>          domid_t foreign_domid;
>      } u;
>  
> -    /* Source mapping space. */
> -#define XENMAPSPACE_shared_info  0 /* shared info page */
> -#define XENMAPSPACE_grant_table  1 /* grant table page */
> -#define XENMAPSPACE_gmfn         2 /* GMFN */
> -#define XENMAPSPACE_gmfn_range   3 /* GMFN range */
> -#define XENMAPSPACE_gmfn_foreign 4 /* GMFN from another guest */
> -    unsigned int space;
> +    unsigned int space; /* => enum phys_map_space */
>  
>  #define XENMAPIDX_grant_table_status 0x80000000
>  
> -    /* Index into source mapping space. */
> +    /* Index into space being mapped. */
>      xen_ulong_t idx;
>  
> -    /* GPFN where the source mapping page should appear. */
> +    /* GPFN in domid where the source mapping page should appear. */
>      xen_pfn_t     gpfn;
>  };
>  typedef struct xen_add_to_physmap xen_add_to_physmap_t;
>  DEFINE_XEN_GUEST_HANDLE(xen_add_to_physmap_t);
>  
> +/* A batched version of add_to_physmap. */
> +#define XENMEM_add_to_physmap_range 23
> +struct xen_add_to_physmap_range {
> +    /* Which domain to change the mapping for. */
> +    domid_t domid;
> +    uint16_t space; /* => enum phys_map_space */
> +
> +    /* Number of pages to go through */
> +    uint16_t size;
> +    domid_t foreign_domid; /* IFF gmfn_foreign */
> +
> +    /* Indexes into space being mapped. */
> +    XEN_GUEST_HANDLE(xen_ulong_t) idxs;
> +
> +    /* GPFN in domdwhere the source mapping page should appear. */
> +    XEN_GUEST_HANDLE(xen_pfn_t) gpfns;
> +};
> +typedef struct xen_add_to_physmap_range xen_add_to_physmap_range_t;
> +DEFINE_XEN_GUEST_HANDLE(xen_add_to_physmap_range_t);
> +
>  /*
>   * Unmaps the page appearing at a particular GPFN from the specified guest's
>   * pseudophysical address space.
> diff --git a/xen/include/public/xen.h b/xen/include/public/xen.h
> index b2f6c50..9425520 100644
> --- a/xen/include/public/xen.h
> +++ b/xen/include/public/xen.h
> @@ -51,6 +51,7 @@ DEFINE_XEN_GUEST_HANDLE(void);
>  
>  DEFINE_XEN_GUEST_HANDLE(uint64_t);
>  DEFINE_XEN_GUEST_HANDLE(xen_pfn_t);
> +DEFINE_XEN_GUEST_HANDLE(xen_ulong_t);
>  #endif
>  
>  /*
> -- 
> 1.7.9.1
> 
> 
> 
> 

_______________________________________________
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®.